Fossil SCM

Merge from trunk.

brickviking 2026-08-21 10:35 UTC bv-infotool merge
Commit e63e0803b7c80670b3c39fcc6f85bcbcfe61661334478425433f955432e30286
99 files changed +1 -1 +23 -3 +1298 -472 +4085 -1741 +108 -17 +17 -41 +43 -73 +30 -37 +72 -10 +1 -1 +1199 -181 +2 -4 +66 -38 +4 -1 +32 -1 +1 -1 +2 +10 -6 +3 -2 +8 -3 +2 +2 +37 -8 +3 -2 +178 -2 +26 -14 +12 -11 +1 -1 +88 -14 +82 -20 +2 -2 +14 -7 +2 -2 +1 -1 +1307 -216 +663 +8 -5 +4 +28 -8 +1386 -35 +1 +5 -6 +10 -10 +62 -7 +3 -2 +2 -2 +95 -2 +64 -12 +257 -141 +10 -1 +10 -14 +6 -1 +98 -53 +44 -5 +61 -21 +129 -2 +251 -58 +19 +4 -2 +33 -3 +2 -2 +34 -28 +13 -10 +4 +4 +21 -5 +34 +271 -62 +32 -4 +109 +108 -28 +4 -1 +2 -2 +112 -43 +12 -7 +2 -2 +14 -44 +16 -15 +171 -51 +2 -1 +1 -1 +4 -1 +2 +4 +19 -6 +45 -36 +39 +2 -2 +46 -11 +204 -1 +2 -1 +142 -119 +1093 +6 -6 +1 +1 -1 +3 -1 +3 -3 +1 -1
~ auto.def ~ extsrc/qrf.h ~ extsrc/shell.c ~ extsrc/sqlite3.c ~ extsrc/sqlite3.h ~ skins/ardoise/css.txt ~ skins/blitz/css.txt ~ skins/darkmode/css.txt ~ src/ajax.c ~ src/alerts.c ~ src/attach.c ~ src/backlink.c ~ src/blob.c ~ src/branch.c ~ src/builtin.c ~ src/bundle.c ~ src/capabilities.c ~ src/captcha.c ~ src/cgi.c ~ src/checkin.c ~ src/comformat.c ~ src/configure.c ~ src/content.c ~ src/db.c ~ src/default.css ~ src/delta.c ~ src/deltafunc.c ~ src/descendants.c ~ src/diff.tcl ~ src/diffcmd.c ~ src/doc.c ~ src/event.c ~ src/fileedit.c ~ src/finfo.c ~ src/forum.c ~ src/fossil.attach.js ~ src/fossil.bootstrap.js ~ src/fossil.dom.js ~ src/fossil.page.chat.js ~ src/fossil.page.forumpost.js ~ src/fossil.page.ticket.js ~ src/fossil.page.wikiedit.js ~ src/fossil.popupwidget.js ~ src/fossil.storage.js ~ src/fossil.tabs.js ~ src/graph.c ~ src/http.c ~ src/http_transport.c ~ src/info.c ~ src/login.c ~ src/main.c ~ src/main.mk ~ src/manifest.c ~ src/markdown.md ~ src/merge.c ~ src/moderate.c ~ src/name.c ~ src/path.c ~ src/repolist.c ~ src/robot.c ~ src/schema.c ~ src/security_audit.c ~ src/setup.c ~ src/setupuser.c ~ src/sqlcmd.c ~ src/stash.c ~ src/stat.c ~ src/statrep.c ~ src/style.c ~ src/style.forum.css ~ src/tag.c ~ src/tar.c ~ src/th_main.c ~ src/timeline.c ~ src/tkt.c ~ src/util.c ~ src/wiki.c ~ src/wiki.wiki ~ src/wikiformat.c ~ src/xfer.c ~ src/xsystem.c ~ tools/makemake.tcl ~ win/Makefile.mingw ~ win/Makefile.msc ~ www/antibot.wiki ~ www/caps/ref.html ~ www/changes.wiki ~ www/customskin.md ~ www/fileformat.wiki ~ www/forum.wiki ~ www/fossil-is-not-relational.md ~ www/fossil-v-git.wiki ~ www/hundredandone.md ~ www/javascript.md ~ www/mkindex.tcl ~ www/permutedindex.html ~ www/server/any/cgi.md ~ www/sync.wiki ~ www/wikitheory.wiki
+1 -1
--- auto.def
+++ auto.def
@@ -36,11 +36,11 @@
3636
}
3737
3838
# Update the minimum required SQLite version number here, and also
3939
# in src/main.c near the sqlite3_libversion_number() call. Take care
4040
# that both places agree!
41
-define MINIMUM_SQLITE_VERSION "3.49.0"
41
+define MINIMUM_SQLITE_VERSION "3.54.0"
4242
4343
# This is useful for people wanting Fossil to use an external SQLite library
4444
# to compare the one they have against the minimum required
4545
if {[opt-bool print-minimum-sqlite-version]} {
4646
puts [get-define MINIMUM_SQLITE_VERSION]
4747
--- auto.def
+++ auto.def
@@ -36,11 +36,11 @@
36 }
37
38 # Update the minimum required SQLite version number here, and also
39 # in src/main.c near the sqlite3_libversion_number() call. Take care
40 # that both places agree!
41 define MINIMUM_SQLITE_VERSION "3.49.0"
42
43 # This is useful for people wanting Fossil to use an external SQLite library
44 # to compare the one they have against the minimum required
45 if {[opt-bool print-minimum-sqlite-version]} {
46 puts [get-define MINIMUM_SQLITE_VERSION]
47
--- auto.def
+++ auto.def
@@ -36,11 +36,11 @@
36 }
37
38 # Update the minimum required SQLite version number here, and also
39 # in src/main.c near the sqlite3_libversion_number() call. Take care
40 # that both places agree!
41 define MINIMUM_SQLITE_VERSION "3.54.0"
42
43 # This is useful for people wanting Fossil to use an external SQLite library
44 # to compare the one they have against the minimum required
45 if {[opt-bool print-minimum-sqlite-version]} {
46 puts [get-define MINIMUM_SQLITE_VERSION]
47
+23 -3
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,14 @@
5555
char *(*xRender)(void*,sqlite3_value*); /* Render a value */
5656
int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
5757
void *pRenderArg; /* First argument to the xRender callback */
5858
void *pWriteArg; /* First argument to the xWrite callback */
5959
char **pzOutput; /* Storage location for output string */
60
+ /* The following are available in iVersion 2 and later */
61
+ unsigned char bRowCount; /* Show the number of rows at end of each query */
62
+ char *zIFmt; /* Format string for integers */
63
+ char *zFpFmt; /* Format string for floating point */
6064
/* Additional fields may be added in the future */
6165
};
6266
6367
/*
6468
** Interfaces
@@ -68,12 +72,11 @@
6872
const sqlite3_qrf_spec *pSpec, /* Result format specification */
6973
char **pzErr /* OUT: Write error message here */
7074
);
7175
7276
/*
73
-** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
74
-** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
77
+** Range of values for sqlite3_qrf_spec.aWidth[] entries.
7578
*/
7679
#define QRF_MAX_WIDTH 10000
7780
#define QRF_MIN_WIDTH 0
7881
7982
/*
@@ -84,11 +87,11 @@
8487
#define QRF_STYLE_Column 2 /* One record per line in neat columns */
8588
#define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
8689
#define QRF_STYLE_Csv 4 /* Comma-separated-value */
8790
#define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
8891
#define QRF_STYLE_Explain 6 /* EXPLAIN output */
89
-#define QRF_STYLE_Html 7 /* Generate an XHTML table */
92
+#define QRF_STYLE_Html 7 /* Generate HTML-style <tr><td> output */
9093
#define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
9194
#define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
9295
#define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
9396
#define QRF_STYLE_Line 11 /* One column per line. */
9497
#define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -144,10 +147,15 @@
144147
#define QRF_SW_On 2 /* This setting is forced on */
145148
#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
146149
#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
147150
#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
148151
152
+/*
153
+** Additional value allowed for bTitles
154
+*/
155
+#define QRF_Always 3 /* Always show titles, even if no rows */
156
+
149157
/*
150158
** Possible alignment values alignment settings
151159
**
152160
** Horizontal Vertial
153161
** ---------- -------- */
@@ -192,10 +200,22 @@
192200
** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
193201
** are assigned a width of zero.
194202
*/
195203
size_t sqlite3_qrf_wcswidth(const char*);
196204
205
+/*
206
+** The argument is a proposed format string for the zIFmt or zFpFmt
207
+** parameters. Return value indicates:
208
+**
209
+** 0 The input is not a valid format string. If this string
210
+** appears in either zIFmt or zFpFmt, it will be ignored.
211
+**
212
+** 1 The input is a valid format string for integers.
213
+**
214
+** 2 The input is a valid format string for floating point.
215
+*/
216
+int sqlite3_qrf_ckformat(const char*);
197217
198218
#ifdef __cplusplus
199219
}
200220
#endif
201221
#endif /* !defined(SQLITE_QRF_H) */
202222
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,14 @@
55 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
56 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
57 void *pRenderArg; /* First argument to the xRender callback */
58 void *pWriteArg; /* First argument to the xWrite callback */
59 char **pzOutput; /* Storage location for output string */
 
 
 
 
60 /* Additional fields may be added in the future */
61 };
62
63 /*
64 ** Interfaces
@@ -68,12 +72,11 @@
68 const sqlite3_qrf_spec *pSpec, /* Result format specification */
69 char **pzErr /* OUT: Write error message here */
70 );
71
72 /*
73 ** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
74 ** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
75 */
76 #define QRF_MAX_WIDTH 10000
77 #define QRF_MIN_WIDTH 0
78
79 /*
@@ -84,11 +87,11 @@
84 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
85 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
86 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
87 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
88 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
89 #define QRF_STYLE_Html 7 /* Generate an XHTML table */
90 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
91 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
92 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
93 #define QRF_STYLE_Line 11 /* One column per line. */
94 #define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -144,10 +147,15 @@
144 #define QRF_SW_On 2 /* This setting is forced on */
145 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
146 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
147 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
148
 
 
 
 
 
149 /*
150 ** Possible alignment values alignment settings
151 **
152 ** Horizontal Vertial
153 ** ---------- -------- */
@@ -192,10 +200,22 @@
192 ** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
193 ** are assigned a width of zero.
194 */
195 size_t sqlite3_qrf_wcswidth(const char*);
196
 
 
 
 
 
 
 
 
 
 
 
 
197
198 #ifdef __cplusplus
199 }
200 #endif
201 #endif /* !defined(SQLITE_QRF_H) */
202
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,14 @@
55 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
56 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
57 void *pRenderArg; /* First argument to the xRender callback */
58 void *pWriteArg; /* First argument to the xWrite callback */
59 char **pzOutput; /* Storage location for output string */
60 /* The following are available in iVersion 2 and later */
61 unsigned char bRowCount; /* Show the number of rows at end of each query */
62 char *zIFmt; /* Format string for integers */
63 char *zFpFmt; /* Format string for floating point */
64 /* Additional fields may be added in the future */
65 };
66
67 /*
68 ** Interfaces
@@ -68,12 +72,11 @@
72 const sqlite3_qrf_spec *pSpec, /* Result format specification */
73 char **pzErr /* OUT: Write error message here */
74 );
75
76 /*
77 ** Range of values for sqlite3_qrf_spec.aWidth[] entries.
 
78 */
79 #define QRF_MAX_WIDTH 10000
80 #define QRF_MIN_WIDTH 0
81
82 /*
@@ -84,11 +87,11 @@
87 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
88 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
89 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
90 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
91 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
92 #define QRF_STYLE_Html 7 /* Generate HTML-style <tr><td> output */
93 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
94 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
95 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
96 #define QRF_STYLE_Line 11 /* One column per line. */
97 #define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -144,10 +147,15 @@
147 #define QRF_SW_On 2 /* This setting is forced on */
148 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
149 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
150 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
151
152 /*
153 ** Additional value allowed for bTitles
154 */
155 #define QRF_Always 3 /* Always show titles, even if no rows */
156
157 /*
158 ** Possible alignment values alignment settings
159 **
160 ** Horizontal Vertial
161 ** ---------- -------- */
@@ -192,10 +200,22 @@
200 ** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
201 ** are assigned a width of zero.
202 */
203 size_t sqlite3_qrf_wcswidth(const char*);
204
205 /*
206 ** The argument is a proposed format string for the zIFmt or zFpFmt
207 ** parameters. Return value indicates:
208 **
209 ** 0 The input is not a valid format string. If this string
210 ** appears in either zIFmt or zFpFmt, it will be ignored.
211 **
212 ** 1 The input is a valid format string for integers.
213 **
214 ** 2 The input is a valid format string for floating point.
215 */
216 int sqlite3_qrf_ckformat(const char*);
217
218 #ifdef __cplusplus
219 }
220 #endif
221 #endif /* !defined(SQLITE_QRF_H) */
222
+1298 -472
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5,16 +5,16 @@
55
**
66
** ext/expert/sqlite3expert.c
77
** ext/expert/sqlite3expert.h
88
** ext/intck/sqlite3intck.c
99
** ext/intck/sqlite3intck.h
10
-** ext/misc/analyze.c
1110
** ext/misc/appendvfs.c
1211
** ext/misc/base64.c
1312
** ext/misc/base85.c
1413
** ext/misc/completion.c
1514
** ext/misc/decimal.c
15
+** ext/misc/diskused.c
1616
** ext/misc/fileio.c
1717
** ext/misc/ieee754.c
1818
** ext/misc/memtrace.c
1919
** ext/misc/pcachetrace.c
2020
** ext/misc/regexp.c
@@ -23,10 +23,11 @@
2323
** ext/misc/shathree.c
2424
** ext/misc/sqlar.c
2525
** ext/misc/sqlite3_stdio.c
2626
** ext/misc/sqlite3_stdio.h
2727
** ext/misc/stmtrand.c
28
+** ext/misc/strdup.c
2829
** ext/misc/uint.c
2930
** ext/misc/vfstrace.c
3031
** ext/misc/windirent.h
3132
** ext/misc/zipfile.c
3233
** ext/qrf/qrf.c
@@ -154,10 +155,11 @@
154155
#include <string.h>
155156
#include <stdio.h>
156157
#include <assert.h>
157158
#include <math.h>
158159
#include <stdint.h>
160
+#include <time.h>
159161
#include "sqlite3.h"
160162
typedef sqlite3_int64 i64;
161163
typedef sqlite3_uint64 u64;
162164
typedef unsigned char u8;
163165
#include <ctype.h>
@@ -190,13 +192,14 @@
190192
#include <sys/stat.h>
191193
192194
#if HAVE_READLINE
193195
# include <readline/readline.h>
194196
# include <readline/history.h>
195
-#endif
196
-
197
-#if HAVE_EDITLINE
197
+#elif HAVE_EDITLINE
198
+/* If both HAVE_READLINE and HAVE_EDITLINE are true, assume that this
199
+** libedit installation does not have its own headers, instead using
200
+** those from libreadline. */
198201
# include <editline/readline.h>
199202
#endif
200203
201204
#if HAVE_EDITLINE || HAVE_READLINE
202205
@@ -203,28 +206,38 @@
203206
# define shell_add_history(X) add_history(X)
204207
# define shell_read_history(X) read_history(X)
205208
# define shell_write_history(X) write_history(X)
206209
# define shell_stifle_history(X) stifle_history(X)
207210
# define shell_readline(X) readline(X)
211
+# define SHELL_CMDLINE_EDIT_AVAILABLE 1 /* command-line editing available */
208212
209213
#elif HAVE_LINENOISE
210214
211215
# include "linenoise.h"
212216
# define shell_add_history(X) linenoiseHistoryAdd(X)
213217
# define shell_read_history(X) linenoiseHistoryLoad(X)
214218
# define shell_write_history(X) linenoiseHistorySave(X)
215219
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
216220
# define shell_readline(X) linenoise(X)
221
+# define SHELL_CMDLINE_EDIT_AVAILABLE 1 /* command-line editing available */
217222
218223
#else
219224
220225
# define shell_read_history(X)
221226
# define shell_write_history(X)
222227
# define shell_stifle_history(X)
228
+# define SHELL_CMDLINE_EDIT_AVAILABLE 0 /* command-line editing not available */
229
+#endif
223230
224
-# define SHELL_USE_LOCAL_GETLINE 1
225
-#endif
231
+/*
232
+** Global variable shellCmdLineEdit determines whether or not command-line
233
+** editing is enabled. It defaults to 1 if the CLI is linked against a
234
+** command-line editing library (linenoise, readline, or editline) and
235
+** to 0 if no command-line editing library is available. The
236
+** "--cmdline-edit off" command-line option will change this value to 0.
237
+*/
238
+static int shellCmdLineEdit = SHELL_CMDLINE_EDIT_AVAILABLE;
226239
227240
#ifndef deliberate_fall_through
228241
/* Quiet some compilers about some of our intentional code. */
229242
# if defined(GCC_VERSION) && GCC_VERSION>=7000000
230243
# define deliberate_fall_through __attribute__((fallthrough));
@@ -731,10 +744,14 @@
731744
char *(*xRender)(void*,sqlite3_value*); /* Render a value */
732745
int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
733746
void *pRenderArg; /* First argument to the xRender callback */
734747
void *pWriteArg; /* First argument to the xWrite callback */
735748
char **pzOutput; /* Storage location for output string */
749
+ /* The following are available in iVersion 2 and later */
750
+ unsigned char bRowCount; /* Show the number of rows at end of each query */
751
+ char *zIFmt; /* Format string for integers */
752
+ char *zFpFmt; /* Format string for floating point */
736753
/* Additional fields may be added in the future */
737754
};
738755
739756
/*
740757
** Interfaces
@@ -744,12 +761,11 @@
744761
const sqlite3_qrf_spec *pSpec, /* Result format specification */
745762
char **pzErr /* OUT: Write error message here */
746763
);
747764
748765
/*
749
-** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
750
-** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
766
+** Range of values for sqlite3_qrf_spec.aWidth[] entries.
751767
*/
752768
#define QRF_MAX_WIDTH 10000
753769
#define QRF_MIN_WIDTH 0
754770
755771
/*
@@ -760,11 +776,11 @@
760776
#define QRF_STYLE_Column 2 /* One record per line in neat columns */
761777
#define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
762778
#define QRF_STYLE_Csv 4 /* Comma-separated-value */
763779
#define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
764780
#define QRF_STYLE_Explain 6 /* EXPLAIN output */
765
-#define QRF_STYLE_Html 7 /* Generate an XHTML table */
781
+#define QRF_STYLE_Html 7 /* Generate HTML-style <tr><td> output */
766782
#define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
767783
#define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
768784
#define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
769785
#define QRF_STYLE_Line 11 /* One column per line. */
770786
#define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -820,10 +836,15 @@
820836
#define QRF_SW_On 2 /* This setting is forced on */
821837
#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
822838
#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
823839
#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
824840
841
+/*
842
+** Additional value allowed for bTitles
843
+*/
844
+#define QRF_Always 3 /* Always show titles, even if no rows */
845
+
825846
/*
826847
** Possible alignment values alignment settings
827848
**
828849
** Horizontal Vertial
829850
** ---------- -------- */
@@ -868,10 +889,22 @@
868889
** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
869890
** are assigned a width of zero.
870891
*/
871892
size_t sqlite3_qrf_wcswidth(const char*);
872893
894
+/*
895
+** The argument is a proposed format string for the zIFmt or zFpFmt
896
+** parameters. Return value indicates:
897
+**
898
+** 0 The input is not a valid format string. If this string
899
+** appears in either zIFmt or zFpFmt, it will be ignored.
900
+**
901
+** 1 The input is a valid format string for integers.
902
+**
903
+** 2 The input is a valid format string for floating point.
904
+*/
905
+int sqlite3_qrf_ckformat(const char*);
873906
874907
#ifdef __cplusplus
875908
}
876909
#endif
877910
#endif /* !defined(SQLITE_QRF_H) */
@@ -950,10 +983,11 @@
950983
} sExpln;
951984
unsigned int nIns; /* Bytes used for current INSERT stmt */
952985
} u;
953986
sqlite3_int64 nRow; /* Number of rows handled so far */
954987
int *actualWidth; /* Actual width of each column */
988
+ char zFmt[24]; /* Space to hold the true integer rendering fmt */
955989
sqlite3_qrf_spec spec; /* Copy of the original spec */
956990
};
957991
958992
/*
959993
** Data for substitute ctype.h functions. Used for x-platform
@@ -993,10 +1027,48 @@
9931027
# define deliberate_fall_through __attribute__((fallthrough));
9941028
# else
9951029
# define deliberate_fall_through
9961030
# endif
9971031
#endif
1032
+
1033
+/*
1034
+** The argument is a proposed format string for the zIFmt or zFpFmt
1035
+** parameters. Return value indicates:
1036
+**
1037
+** 0 The input is not a valid format string. If this string
1038
+** appears in either zIFmt or zFpFmt, it will be ignored.
1039
+**
1040
+** 1 The input is a valid format string for integers.
1041
+**
1042
+** 2 The input is a valid format string for floating point.
1043
+*/
1044
+int sqlite3_qrf_ckformat(const char *z){
1045
+ size_t n;
1046
+ if( z==0 ) return 0;
1047
+ if( z[0]!='%' ) return 0;
1048
+ z++;
1049
+ n = strspn(z,"+-,#0");
1050
+ if( n>5 ) return 0;
1051
+ z += n;
1052
+ if( z[0]>='1' && z[0]<='9' ){
1053
+ n = strspn(z,"0123456789");
1054
+ if( n>3 ) return 0;
1055
+ z += n;
1056
+ }
1057
+ if( z[0]=='.' ){
1058
+ z++;
1059
+ n = strspn(z,"0123456789");
1060
+ if( n>3 ) return 0;
1061
+ z += n;
1062
+ }
1063
+ n = strspn(z,"eEgGf");
1064
+ if( n==1 && z[1]==0 ) return 2;
1065
+ n = strspn(z,"dxXo");
1066
+ if( n==1 && z[1]==0 ) return 1;
1067
+ return 0;
1068
+}
1069
+
9981070
9991071
/*
10001072
** Set an error code and error message.
10011073
*/
10021074
static void qrfError(
@@ -1129,10 +1201,14 @@
11291201
sqlite3_str_append(pOut, "-", 1);
11301202
}
11311203
if( N<10000 ){
11321204
sqlite3_str_appendf(pOut, "%4lld ", N);
11331205
return;
1206
+ }
1207
+ if( N>=9223372036854775800LL ){
1208
+ sqlite3_str_appendf(pOut, "%.2fE", 1e-18*(double)N);
1209
+ return;
11341210
}
11351211
for(i=1; i<=18; i++){
11361212
N = (N+5)/10;
11371213
if( N<10000 ){
11381214
int n = (int)N;
@@ -1289,12 +1365,12 @@
12891365
if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
12901366
int nSp = 0;
12911367
sqlite3_str_reset(pStats);
12921368
if( nCycle>=0 && nTotal>0 ){
12931369
qrfApproxInt64(pStats, nCycle);
1294
- sqlite3_str_appendf(pStats, " %3d%%",
1295
- ((nCycle*100)+nTotal/2) / nTotal
1370
+ sqlite3_str_appendf(pStats, " %3.0f%%",
1371
+ ((100.0*(double)nCycle)+nTotal/2.0) / (double)nTotal
12961372
);
12971373
nSp = 2;
12981374
}
12991375
if( nLoop>=0 ){
13001376
if( nSp ) sqlite3_str_appendchar(pStats, nSp, ' ');
@@ -1787,11 +1863,11 @@
17871863
}
17881864
if( i>0 ){
17891865
sqlite3_str_append(pOut, (const char*)z, i);
17901866
}
17911867
switch( z[i] ){
1792
- case '>': sqlite3_str_append(pOut, "&lt;", 4); break;
1868
+ case '>': sqlite3_str_append(pOut, "&gt;", 4); break;
17931869
case '&': sqlite3_str_append(pOut, "&amp;", 5); break;
17941870
case '<': sqlite3_str_append(pOut, "&lt;", 4); break;
17951871
case '"': sqlite3_str_append(pOut, "&quot;", 6); break;
17961872
case '\'': sqlite3_str_append(pOut, "&#39;", 5); break;
17971873
default: i--;
@@ -1977,16 +2053,22 @@
19772053
return;
19782054
}
19792055
}
19802056
switch( sqlite3_column_type(p->pStmt,iCol) ){
19812057
case SQLITE_INTEGER: {
1982
- sqlite3_str_appendf(pOut, "%lld", sqlite3_column_int64(p->pStmt,iCol));
2058
+ sqlite3_str_appendf(pOut, p->spec.zIFmt,
2059
+ sqlite3_column_int64(p->pStmt,iCol));
19832060
break;
19842061
}
19852062
case SQLITE_FLOAT: {
1986
- const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1987
- sqlite3_str_appendall(pOut, zTxt);
2063
+ if( p->spec.zFpFmt ){
2064
+ double r = sqlite3_column_double(p->pStmt,iCol);
2065
+ sqlite3_str_appendf(pOut,p->spec.zFpFmt,r);
2066
+ }else{
2067
+ const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
2068
+ sqlite3_str_appendall(pOut, zTxt);
2069
+ }
19882070
break;
19892071
}
19902072
case SQLITE_BLOB: {
19912073
if( p->spec.bTextJsonb==QRF_Yes ){
19922074
const char *zJson = qrfJsonbToJson(p, iCol);
@@ -2281,11 +2363,11 @@
22812363
if( bWrap && z[i]!=0 && !qrfSpace(z[i]) && qrfAlnum(c)==qrfAlnum(z[i]) ){
22822364
/* Perhaps try to back up to a better place to break the line */
22832365
for(k=i-1; k>=i/2; k--){
22842366
if( qrfSpace(z[k]) ) break;
22852367
}
2286
- if( k<i/2 ){
2368
+ if( k<i/2 && i/2>0 ){
22872369
for(k=i; k>=i/2; k--){
22882370
if( qrfAlnum(z[k-1])!=qrfAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
22892371
}
22902372
}
22912373
if( k>=i/2 ){
@@ -2522,10 +2604,14 @@
25222604
/* Doubled horizontal lines: */
25232605
#define DBL_24 "\342\225\220" /* U+2550 === */
25242606
#define DBL_123 "\342\225\236" /* U+255e |= */
25252607
#define DBL_134 "\342\225\241" /* U+2561 =| */
25262608
#define DBL_1234 "\342\225\252" /* U+256a =|= */
2609
+#define DBL_12 "\342\225\230" /* U+2558 `= */
2610
+#define DBL_14 "\342\225\233" /* U+255b =' */
2611
+#define DBL_124 "\342\225\247" /* U+2567 ='= */
2612
+
25272613
25282614
/* Draw horizontal line N characters long using unicode box
25292615
** characters
25302616
*/
25312617
static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2532,28 +2618,28 @@
25322618
const char *azDash[2] = {
25332619
BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24,
25342620
DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24
25352621
};/* 0 1 2 3 4 5 6 7 8 9 */
25362622
const int nDash = 30;
2537
- N *= 3;
2538
- while( N>nDash ){
2623
+ i64 nn = 3*(i64)N;
2624
+ while( nn>nDash ){
25392625
sqlite3_str_append(pOut, azDash[bDbl], nDash);
2540
- N -= nDash;
2626
+ nn -= nDash;
25412627
}
2542
- sqlite3_str_append(pOut, azDash[bDbl], N);
2628
+ sqlite3_str_append(pOut, azDash[bDbl], (int)nn);
25432629
}
25442630
25452631
/*
25462632
** Draw a horizontal separator for a QRF_STYLE_Box table.
25472633
*/
25482634
static void qrfBoxSeparator(
2549
- sqlite3_str *pOut,
2550
- qrfColData *p,
2551
- const char *zSep1,
2552
- const char *zSep2,
2553
- const char *zSep3,
2554
- int bDbl
2635
+ sqlite3_str *pOut, /* Output to this sqlite3_str */
2636
+ qrfColData *p, /* Columnar data */
2637
+ const char *zSep1, /* Left margin */
2638
+ const char *zSep2, /* Column separator */
2639
+ const char *zSep3, /* Right margin */
2640
+ int bDbl /* True for double-lines */
25552641
){
25562642
int i;
25572643
if( p->nCol>0 ){
25582644
int useBorder = p->p->spec.bBorder!=QRF_No;
25592645
if( useBorder ){
@@ -2568,10 +2654,36 @@
25682654
sqlite3_str_appendall(pOut, zSep3);
25692655
}
25702656
}
25712657
sqlite3_str_append(pOut, "\n", 1);
25722658
}
2659
+
2660
+/*
2661
+** Draw a horizontal separator for a QRF_STYLE_Column table.
2662
+** This style of separator is only used for separating the title
2663
+** from the content.
2664
+*/
2665
+static void qrfColumnSeparator(
2666
+ sqlite3_str *pOut, /* Output to this sqlite3_str */
2667
+ qrfColData *p, /* Columnar data */
2668
+ const char *colSep, /* Column separator text */
2669
+ int szColSep, /* Size of zColSep in bytes */
2670
+ const char *rowSep, /* Row separator text */
2671
+ int szRowSep /* Size of zRowSep in bytes */
2672
+){
2673
+ int j;
2674
+ int nColumn = p->nCol;
2675
+ for(j=0; j<nColumn; j++){
2676
+ sqlite3_str_appendchar(pOut, p->a[j].w, '-');
2677
+ if( j<nColumn-1 ){
2678
+ sqlite3_str_append(pOut, colSep, szColSep);
2679
+ }else{
2680
+ qrfRTrim(pOut);
2681
+ sqlite3_str_append(pOut, rowSep, szRowSep);
2682
+ }
2683
+ }
2684
+}
25732685
25742686
/*
25752687
** Load into pData the default alignment for the body of a table.
25762688
*/
25772689
static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2610,11 +2722,11 @@
26102722
int nSW /* Screen width */
26112723
){
26122724
int i; /* Loop counter */
26132725
int nr; /* Number of rows */
26142726
int w = 0; /* Width of the current column */
2615
- int t; /* Total width of all columns */
2727
+ i64 t; /* Total width of all columns */
26162728
int *aw; /* Array of individual column widths */
26172729
26182730
aw = sqlite3_malloc64( sizeof(int)*nCol );
26192731
if( aw==0 ){
26202732
qrfOom(p);
@@ -2748,12 +2860,15 @@
27482860
}else{
27492861
sepW = pData->nCol*3 + 1;
27502862
if( p->spec.bBorder==QRF_No ) sepW -= 2;
27512863
}
27522864
nCol = pData->nCol;
2753
- for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
2754
- if( p->spec.nScreenWidth >= sumW+sepW ) return;
2865
+ for(i=0, sumW=0; i<nCol; i++){
2866
+ if( sumW > 2147483647 - pData->a[i].w ) return;
2867
+ sumW += pData->a[i].w;
2868
+ }
2869
+ if( p->spec.nScreenWidth >= (i64)sumW + sepW ) return;
27552870
27562871
/* First thing to do is reduce the separation between columns */
27572872
pData->nMargin = 0;
27582873
if( p->spec.eStyle==QRF_STYLE_Column ){
27592874
sepW = pData->nCol - 1;
@@ -2823,11 +2938,25 @@
28232938
sqlite3_str *pStr; /* Temporary rendering */
28242939
qrfColData data; /* Columnar layout data */
28252940
int bRTrim; /* Trim trailing space */
28262941
28272942
rc = sqlite3_step(p->pStmt);
2828
- if( rc!=SQLITE_ROW || nColumn==0 ){
2943
+ if( nColumn==0 ){
2944
+ return; /* Not a query. No results every shown. */
2945
+ }
2946
+ if( rc==SQLITE_DONE && nColumn>0 ){
2947
+ /* Empty query */
2948
+ if( p->spec.bTitles==QRF_Always ){
2949
+ /* fall through into the columnar logic below */
2950
+ }else{
2951
+ if( p->spec.bRowCount==QRF_Yes ){
2952
+ sqlite3_str_appendf(p->pOut, "(0 rows)\n");
2953
+ qrfWrite(p);
2954
+ }
2955
+ return; /* No output, other than the row count */
2956
+ }
2957
+ }else if( rc!=SQLITE_ROW ){
28292958
return; /* No output */
28302959
}
28312960
28322961
/* Initialize the data container */
28332962
memset(&data, 0, sizeof(data));
@@ -2840,12 +2969,12 @@
28402969
}
28412970
memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
28422971
if( qrfColDataEnlarge(&data) ) return;
28432972
assert( data.az!=0 );
28442973
2845
- /* Load the column header names and all cell content into data */
2846
- if( p->spec.bTitles==QRF_Yes ){
2974
+ /* Load the column header names into data */
2975
+ if( p->spec.bTitles>=QRF_Yes ){
28472976
unsigned char saved_eText = p->spec.eText;
28482977
p->spec.eText = p->spec.eTitle;
28492978
memset(data.abNum, 0, nColumn);
28502979
for(i=0; i<nColumn; i++){
28512980
const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2866,13 +2995,14 @@
28662995
data.n++;
28672996
if( w>data.a[i].mxW ) data.a[i].mxW = w;
28682997
if( nNL ) data.bMultiRow = 1;
28692998
}
28702999
p->spec.eText = saved_eText;
2871
- p->nRow++;
28723000
}
2873
- do{
3001
+
3002
+ /* Load query results into data */
3003
+ while( rc==SQLITE_ROW && p->iErr==SQLITE_OK ){
28743004
if( data.n+nColumn > data.nAlloc ){
28753005
if( qrfColDataEnlarge(&data) ) return;
28763006
}
28773007
for(i=0; i<nColumn; i++){
28783008
char *z;
@@ -2889,11 +3019,12 @@
28893019
data.n++;
28903020
if( w>data.a[i].mxW ) data.a[i].mxW = w;
28913021
if( nNL ) data.bMultiRow = 1;
28923022
}
28933023
p->nRow++;
2894
- }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
3024
+ rc = sqlite3_step(p->pStmt);
3025
+ }
28953026
if( p->iErr ){
28963027
qrfColDataFree(&data);
28973028
return;
28983029
}
28993030
@@ -3097,11 +3228,11 @@
30973228
/* Draw either (1) the separator between the title line and the body
30983229
** of the table, or (2) separators between individual rows of the table
30993230
** body. isTitleDataSeparator will be true if we are doing (1).
31003231
*/
31013232
if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3102
- int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
3233
+ int isTitleDataSeparator = (i==0 && p->spec.bTitles>=QRF_Yes);
31033234
if( isTitleDataSeparator ){
31043235
qrfLoadAlignment(&data, p);
31053236
}
31063237
switch( p->spec.eStyle ){
31073238
case QRF_STYLE_Table: {
@@ -3124,19 +3255,12 @@
31243255
}
31253256
break;
31263257
}
31273258
case QRF_STYLE_Column: {
31283259
if( isTitleDataSeparator ){
3129
- for(j=0; j<nColumn; j++){
3130
- sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
3131
- if( j<nColumn-1 ){
3132
- sqlite3_str_append(p->pOut, colSep, szColSep);
3133
- }else{
3134
- qrfRTrim(p->pOut);
3135
- sqlite3_str_append(p->pOut, rowSep, szRowSep);
3136
- }
3137
- }
3260
+ qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3261
+ rowSep, szRowSep);
31383262
}else if( data.bMultiRow ){
31393263
qrfRTrim(p->pOut);
31403264
sqlite3_str_append(p->pOut, "\n", 1);
31413265
}
31423266
break;
@@ -3144,20 +3268,39 @@
31443268
}
31453269
}
31463270
}
31473271
31483272
/* Draw the line across the bottom of the table */
3149
- if( p->spec.bBorder!=QRF_No ){
3273
+ if( p->spec.bBorder!=QRF_No || p->nRow==0 ){
31503274
switch( p->spec.eStyle ){
31513275
case QRF_STYLE_Box:
3152
- qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3276
+ if( p->nRow>0 ){
3277
+ qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3278
+ }else{
3279
+ qrfBoxSeparator(p->pOut, &data, DBL_12, DBL_124, DBL_14, 1);
3280
+ }
31533281
break;
31543282
case QRF_STYLE_Table:
31553283
qrfRowSeparator(p->pOut, &data, '+');
31563284
break;
3285
+ case QRF_STYLE_Markdown:
3286
+ if( p->nRow==0 ){
3287
+ qrfRowSeparator(p->pOut, &data, '|');
3288
+ }
3289
+ break;
3290
+ case QRF_STYLE_Column:
3291
+ if( p->nRow==0 ){
3292
+ qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3293
+ rowSep, szRowSep);
3294
+ }
3295
+ break;
31573296
}
31583297
}
3298
+ if( p->spec.bRowCount==QRF_Yes ){
3299
+ sqlite3_int64 n = p->nRow;
3300
+ sqlite3_str_appendf(p->pOut, "(%lld row%s)\n", n, n==1 ? "" : "s");
3301
+ }
31593302
qrfWrite(p);
31603303
31613304
qrfColDataFree(&data);
31623305
return;
31633306
}
@@ -3404,10 +3547,49 @@
34043547
sqlite3_str_append(p->pOut, ":", 1);
34053548
qrfRenderValue(p, p->pOut, i);
34063549
}
34073550
qrfWrite(p);
34083551
}
3552
+
3553
+/*
3554
+** Render a title row (a row containing column names) if the spec
3555
+** calls for one and if it makes sense for the eStyle. Title rows
3556
+** do not make sense for some eStyles, such as QRF_STYLE_Off,
3557
+** QRF_STYLE_Count, QRF_STYLE_Json, and similar.
3558
+*/
3559
+static void qrfSimpleTitle(Qrf *p){
3560
+ assert( p->nRow==0 );
3561
+ assert( p->spec.bTitles>=QRF_Yes );
3562
+ switch( p->spec.eStyle ){
3563
+ case QRF_STYLE_Html: {
3564
+ int i;
3565
+ sqlite3_str_append(p->pOut, "<tr>", 4);
3566
+ for(i=0; i<p->nCol; i++){
3567
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
3568
+ sqlite3_str_append(p->pOut, "\n<th>", 5);
3569
+ qrfEncodeText(p, p->pOut, zCName);
3570
+ }
3571
+ sqlite3_str_append(p->pOut, "\n</tr>\n", 7);
3572
+ break;
3573
+ }
3574
+ case QRF_STYLE_Quote:
3575
+ case QRF_STYLE_List: {
3576
+ int i;
3577
+ int saved_eText = p->spec.eText;
3578
+ p->spec.eText = p->spec.eTitle;
3579
+ for(i=0; i<p->nCol; i++){
3580
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
3581
+ if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3582
+ qrfEncodeText(p, p->pOut, zCName);
3583
+ }
3584
+ sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3585
+ qrfWrite(p);
3586
+ p->spec.eText = saved_eText;
3587
+ break;
3588
+ }
3589
+ }
3590
+}
34093591
34103592
/*
34113593
** Render a single row of output for non-columnar styles - any
34123594
** style that lets us render row by row as the content is received
34133595
** from the query.
@@ -3437,25 +3619,19 @@
34373619
}
34383620
qrfOneJsonRow(p);
34393621
break;
34403622
}
34413623
case QRF_STYLE_Html: {
3442
- if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3443
- sqlite3_str_append(p->pOut, "<TR>", 4);
3444
- for(i=0; i<p->nCol; i++){
3445
- const char *zCName = sqlite3_column_name(p->pStmt, i);
3446
- sqlite3_str_append(p->pOut, "\n<TH>", 5);
3447
- qrfEncodeText(p, p->pOut, zCName);
3448
- }
3449
- sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3450
- }
3451
- sqlite3_str_append(p->pOut, "<TR>", 4);
3452
- for(i=0; i<p->nCol; i++){
3453
- sqlite3_str_append(p->pOut, "\n<TD>", 5);
3624
+ if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3625
+ qrfSimpleTitle(p);
3626
+ }
3627
+ sqlite3_str_append(p->pOut, "<tr>", 4);
3628
+ for(i=0; i<p->nCol; i++){
3629
+ sqlite3_str_append(p->pOut, "\n<td>", 5);
34543630
qrfRenderValue(p, p->pOut, i);
34553631
}
3456
- sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3632
+ sqlite3_str_append(p->pOut, "\n</tr>\n", 7);
34573633
qrfWrite(p);
34583634
break;
34593635
}
34603636
case QRF_STYLE_Insert: {
34613637
unsigned int mxIns = p->spec.nMultiInsert;
@@ -3468,11 +3644,11 @@
34683644
if( qrf_need_quote(p->spec.zTableName) ){
34693645
sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
34703646
}else{
34713647
sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
34723648
}
3473
- if( p->spec.bTitles==QRF_Yes ){
3649
+ if( p->spec.bTitles>=QRF_Yes ){
34743650
for(i=0; i<p->nCol; i++){
34753651
const char *zCName = sqlite3_column_name(p->pStmt, i);
34763652
if( qrf_need_quote(zCName) ){
34773653
sqlite3_str_appendf(p->pOut, "%c\"%w\"",
34783654
i==0 ? '(' : ',', zCName);
@@ -3568,21 +3744,12 @@
35683744
if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
35693745
qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
35703746
break;
35713747
}
35723748
default: { /* QRF_STYLE_List */
3573
- if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3574
- int saved_eText = p->spec.eText;
3575
- p->spec.eText = p->spec.eTitle;
3576
- for(i=0; i<p->nCol; i++){
3577
- const char *zCName = sqlite3_column_name(p->pStmt, i);
3578
- if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3579
- qrfEncodeText(p, p->pOut, zCName);
3580
- }
3581
- sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3582
- qrfWrite(p);
3583
- p->spec.eText = saved_eText;
3749
+ if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3750
+ qrfSimpleTitle(p);
35843751
}
35853752
for(i=0; i<p->nCol; i++){
35863753
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
35873754
qrfRenderValue(p, p->pOut, i);
35883755
}
@@ -3604,11 +3771,11 @@
36043771
char **pzErr /* Write errors here */
36053772
){
36063773
size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
36073774
memset(p, 0, sizeof(*p));
36083775
p->pzErr = pzErr;
3609
- if( pSpec->iVersion>1 ){
3776
+ if( pSpec->iVersion>2 ){
36103777
qrfError(p, SQLITE_ERROR,
36113778
"unusable sqlite3_qrf_spec.iVersion (%d)",
36123779
pSpec->iVersion);
36133780
return;
36143781
}
@@ -3620,15 +3787,19 @@
36203787
return;
36213788
}
36223789
p->iErr = SQLITE_OK;
36233790
p->nCol = sqlite3_column_count(p->pStmt);
36243791
p->nRow = 0;
3625
- sz = sizeof(sqlite3_qrf_spec);
3792
+ switch( pSpec->iVersion ){
3793
+ case 0: sz = offsetof(sqlite3_qrf_spec, bRowCount); break;
3794
+ case 1: sz = offsetof(sqlite3_qrf_spec, bRowCount); break;
3795
+ default: sz = sizeof(sqlite3_qrf_spec); break;
3796
+ }
36263797
memcpy(&p->spec, pSpec, sz);
36273798
if( p->spec.zNull==0 ) p->spec.zNull = "";
36283799
p->mxWidth = p->spec.nScreenWidth;
3629
- if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3800
+ if( p->mxWidth<=0 ) p->mxWidth = 2147483647;
36303801
p->mxHeight = p->spec.nLineLimit;
36313802
if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
36323803
if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
36333804
if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
36343805
if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
@@ -3756,10 +3927,24 @@
37563927
if( p->spec.bTextJsonb==QRF_Auto ){
37573928
p->spec.bTextJsonb = QRF_No;
37583929
}
37593930
if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = ",";
37603931
if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3932
+ if( p->spec.zIFmt==0 || sqlite3_qrf_ckformat(p->spec.zIFmt)!=1 ){
3933
+ p->spec.zIFmt = "%lld";
3934
+ }else{
3935
+ size_t n = strlen(p->spec.zIFmt);
3936
+ memcpy(p->zFmt, p->spec.zIFmt, n-1);
3937
+ p->zFmt[n-1] = 'l';
3938
+ p->zFmt[n] = 'l';
3939
+ p->zFmt[n+1] = p->spec.zIFmt[n-1];
3940
+ p->zFmt[n+2] = 0;
3941
+ p->spec.zIFmt = p->zFmt;
3942
+ }
3943
+ if( p->spec.zFpFmt && sqlite3_qrf_ckformat(p->spec.zFpFmt)!=2 ){
3944
+ p->spec.zFpFmt = 0;
3945
+ }
37613946
}
37623947
37633948
/*
37643949
** Finish rendering the results
37653950
*/
@@ -3890,10 +4075,34 @@
38904075
default: {
38914076
/* Non-columnar modes where the output can occur after each row
38924077
** of result is received */
38934078
while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
38944079
qrfOneSimpleRow(&qrf);
4080
+ }
4081
+ if( qrf.nCol>0 && qrf.nRow==0 && qrf.spec.bTitles==QRF_Always ){
4082
+ qrfSimpleTitle(&qrf);
4083
+ }
4084
+ if( qrf.nCol>0 && qrf.spec.bRowCount==QRF_Yes ){
4085
+ const char *zPlural = qrf.nRow==1 ? "" : "s";
4086
+ switch( qrf.spec.eStyle ){
4087
+ case QRF_STYLE_Line:
4088
+ if( qrf.nRow>0 ) sqlite3_str_append(qrf.pOut, "\n", 1);
4089
+ /* Fall through */
4090
+ case QRF_STYLE_Csv:
4091
+ case QRF_STYLE_List:
4092
+ case QRF_STYLE_Quote:
4093
+ sqlite3_str_appendf(qrf.pOut,"(%lld row%s)\n",qrf.nRow,zPlural);
4094
+ break;
4095
+ case QRF_STYLE_Html:
4096
+ sqlite3_str_appendf(qrf.pOut,"<!-- %lld row%s -->\n",
4097
+ qrf.nRow, zPlural);
4098
+ break;
4099
+ case QRF_STYLE_Insert:
4100
+ sqlite3_str_appendf(qrf.pOut,"/* %lld row%s inserted */\n",
4101
+ qrf.nRow, zPlural);
4102
+ break;
4103
+ }
38954104
}
38964105
break;
38974106
}
38984107
}
38994108
qrfResetStmt(&qrf);
@@ -5106,10 +5315,12 @@
51065315
int rc;
51075316
int n;
51085317
const char *z;
51095318
SHA3Context cx;
51105319
int iSize;
5320
+ int isRecursive = 0;
5321
+ int *pIsRecursive;
51115322
51125323
if( argc==1 ){
51135324
iSize = 256;
51145325
}else{
51155326
iSize = sqlite3_value_int(argv[1]);
@@ -5119,10 +5330,15 @@
51195330
return;
51205331
}
51215332
}
51225333
if( zSql==0 ) return;
51235334
SHA3Init(&cx, iSize);
5335
+ pIsRecursive = (int*)sqlite3_get_clientdata(db,"sha3_query()");
5336
+ if( pIsRecursive ){
5337
+ *pIsRecursive = 1;
5338
+ return;
5339
+ }
51245340
while( zSql[0] ){
51255341
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
51265342
if( rc ){
51275343
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
51285344
zSql, sqlite3_errmsg(db));
@@ -5145,19 +5361,25 @@
51455361
sha3_step_vformat(&cx,"S%d:",n);
51465362
SHA3Update(&cx,(unsigned char*)z,n);
51475363
}
51485364
51495365
/* Compute a hash over the result of the query */
5366
+ sqlite3_set_clientdata(db, "sha3_query()", &isRecursive, 0);
51505367
while( SQLITE_ROW==sqlite3_step(pStmt) ){
51515368
SHA3Update(&cx,(const unsigned char*)"R",1);
51525369
for(i=0; i<nCol; i++){
51535370
sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
51545371
}
51555372
}
51565373
sqlite3_finalize(pStmt);
5374
+ sqlite3_set_clientdata(db, "sha3_query()", 0, 0);
51575375
}
5158
- sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5376
+ if( isRecursive ){
5377
+ sqlite3_result_error(context, "recursive use of sha3_query()", -1);
5378
+ }else{
5379
+ sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5380
+ }
51595381
}
51605382
51615383
/*
51625384
** xStep function for sha3_agg().
51635385
*/
@@ -5272,10 +5494,14 @@
52725494
#include <stdarg.h>
52735495
52745496
/******************************************************************************
52755497
** The Hash Engine
52765498
*/
5499
+#if defined(__GNUC__) && __GNUC__>=11
5500
+# pragma GCC diagnostic push
5501
+# pragma GCC diagnostic ignored "-Wstringop-overread"
5502
+#endif
52775503
/* Context for the SHA1 hash */
52785504
typedef struct SHA1Context SHA1Context;
52795505
struct SHA1Context {
52805506
unsigned int state[5];
52815507
unsigned int count[2];
@@ -5412,11 +5638,11 @@
54125638
}
54135639
j = 0;
54145640
}else{
54155641
i = 0;
54165642
}
5417
- (void)memcpy(&p->buffer[j], &data[i], len - i);
5643
+ if( len-i>0 ) (void)memcpy(&p->buffer[j], &data[i], len - i);
54185644
}
54195645
54205646
/* Compute a string using sqlite3_vsnprintf() and hash it */
54215647
static void hash_step_vformat(
54225648
SHA1Context *p, /* Add content to this context */
@@ -5467,10 +5693,13 @@
54675693
zOut[i*2+1] = zEncode[digest[i] & 0xf];
54685694
}
54695695
zOut[i*2]= 0;
54705696
}
54715697
}
5698
+#if defined(__GNUC__) && __GNUC__>=11
5699
+# pragma GCC diagnostic pop
5700
+#endif
54725701
/* End of the hashing logic
54735702
*****************************************************************************/
54745703
54755704
/*
54765705
** Two SQL functions: sha1(X) and sha1b(X).
@@ -5501,11 +5730,14 @@
55015730
if( eType==SQLITE_BLOB ){
55025731
pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
55035732
}else{
55045733
pData = (const unsigned char*)sqlite3_value_text(argv[0]);
55055734
}
5506
- if( pData==0 ) return;
5735
+ if( pData==0 ){
5736
+ if( nByte ) return;
5737
+ pData = (const unsigned char*)"";
5738
+ }
55075739
hash_step(&cx, pData, nByte);
55085740
if( sqlite3_user_data(context)!=0 ){
55095741
/* sha1b() - binary result */
55105742
hash_finish(&cx, zOut, 1);
55115743
sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5541,13 +5773,20 @@
55415773
int rc;
55425774
int n;
55435775
const char *z;
55445776
SHA1Context cx;
55455777
char zOut[44];
5778
+ int isRecursive = 0;
5779
+ int *pIsRecursive;
55465780
55475781
assert( argc==1 );
55485782
if( zSql==0 ) return;
5783
+ pIsRecursive = sqlite3_get_clientdata(db, "sha1_query()");
5784
+ if( pIsRecursive ){
5785
+ *pIsRecursive = 1;
5786
+ return;
5787
+ }
55495788
hash_init(&cx);
55505789
while( zSql[0] ){
55515790
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
55525791
if( rc ){
55535792
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5570,10 +5809,11 @@
55705809
n = (int)strlen(z);
55715810
hash_step_vformat(&cx,"S%d:",n);
55725811
hash_step(&cx,(unsigned char*)z,n);
55735812
55745813
/* Compute a hash over the result of the query */
5814
+ sqlite3_set_clientdata(db, "sha1_query()", &isRecursive, 0);
55755815
while( SQLITE_ROW==sqlite3_step(pStmt) ){
55765816
hash_step(&cx,(const unsigned char*)"R",1);
55775817
for(i=0; i<nCol; i++){
55785818
switch( sqlite3_column_type(pStmt,i) ){
55795819
case SQLITE_NULL: {
@@ -5624,13 +5864,18 @@
56245864
}
56255865
}
56265866
}
56275867
}
56285868
sqlite3_finalize(pStmt);
5869
+ sqlite3_set_clientdata(db, "sha1_query()", 0, 0);
56295870
}
56305871
hash_finish(&cx, zOut, 0);
5631
- sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5872
+ if( isRecursive ){
5873
+ sqlite3_result_error(context, "recursive use of sha1_query()", -1);
5874
+ }else{
5875
+ sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5876
+ }
56325877
}
56335878
56345879
56355880
#ifdef _WIN32
56365881
@@ -5824,10 +6069,13 @@
58246069
}
58256070
58266071
/*
58276072
** Allocate a new Decimal object initialized to the text in zIn[].
58286073
** Return NULL if any kind of error occurs.
6074
+**
6075
+** Note that zIn[] is not necessarily zero-terminated. Always
6076
+** respect the boundary imposed by the n argument.
58296077
*/
58306078
static Decimal *decimalNewFromText(const char *zIn, int n){
58316079
Decimal *p = 0;
58326080
int i;
58336081
int iExp = 0;
@@ -5841,15 +6089,15 @@
58416089
p->isNull = 0;
58426090
p->nDigit = 0;
58436091
p->nFrac = 0;
58446092
p->a = sqlite3_malloc64( n+1 );
58456093
if( p->a==0 ) goto new_from_text_failed;
5846
- for(i=0; IsSpace(zIn[i]); i++){}
5847
- if( zIn[i]=='-' ){
6094
+ for(i=0; i<n && IsSpace(zIn[i]); i++){}
6095
+ if( i<n && zIn[i]=='-' ){
58486096
p->sign = 1;
58496097
i++;
5850
- }else if( zIn[i]=='+' ){
6098
+ }else if( i<n && zIn[i]=='+' ){
58516099
i++;
58526100
}
58536101
while( i<n && zIn[i]=='0' ) i++;
58546102
while( i<n ){
58556103
char c = zIn[i];
@@ -6056,32 +6304,41 @@
60566304
}
60576305
z[i] = 0;
60586306
sqlite3_result_text(pCtx, z, i, sqlite3_free);
60596307
}
60606308
6309
+/* Forward declaration */
6310
+static void decimal_expand(Decimal *p, int nDigit, int nFrac);
6311
+
60616312
/*
60626313
** Round a decimal value to N significant digits. N must be positive.
60636314
*/
60646315
static void decimal_round(Decimal *p, int N){
60656316
int i;
6066
- int nZero;
6317
+ int nZero; /* Number of leading zeros */
60676318
if( N<1 ) return;
60686319
if( p==0 ) return;
60696320
if( p->nDigit<=N ) return;
60706321
for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
60716322
N += nZero;
60726323
if( p->nDigit<=N ) return;
6073
- if( p->a[N]>4 ){
6324
+ if( p->a[N]>=5 ){
6325
+ /* If all leading digits are 9, increase the number of digits
6326
+ ** by adding a new 0 to the front */
6327
+ for(i=0; i<N && p->a[i]==9; i++){}
6328
+ if( i==N ){
6329
+ decimal_expand(p, p->nDigit+1, p->nFrac);
6330
+ if( p->oom ) return;
6331
+ }
6332
+
6333
+ /* Do the rounding */
60746334
p->a[N-1]++;
60756335
for(i=N-1; i>0 && p->a[i]>9; i--){
60766336
p->a[i] = 0;
60776337
p->a[i-1]++;
60786338
}
6079
- if( p->a[0]>9 ){
6080
- p->a[0] = 1;
6081
- p->nFrac--;
6082
- }
6339
+ assert( p->a[0]<=9 );
60836340
}
60846341
memset(&p->a[N], 0, p->nDigit - N);
60856342
}
60866343
60876344
/*
@@ -6225,10 +6482,11 @@
62256482
int nAddSig;
62266483
int nAddFrac;
62276484
signed char *a;
62286485
if( p==0 ) return;
62296486
nAddFrac = nFrac - p->nFrac;
6487
+ assert( nAddFrac>=0 );
62306488
nAddSig = (nDigit - p->nDigit) - nAddFrac;
62316489
if( nAddFrac==0 && nAddSig==0 ) return;
62326490
if( nDigit+1>SQLITE_DECIMAL_MAX_DIGIT ){ p->oom = 1; return; }
62336491
a = sqlite3_realloc64(p->a, nDigit+1);
62346492
if( a==0 ){
@@ -8232,10 +8490,20 @@
82328490
if( r==(double)x ) return r;
82338491
if( r<(double)x ) x--;
82348492
return (double)x;
82358493
}
82368494
#endif
8495
+
8496
+/* Convert a floating point value to its closest integer. Do so in
8497
+** a way that avoids 'outside the range of representable values' warnings
8498
+** from UBSAN.
8499
+*/
8500
+static sqlite3_int64 seriesRealToI64(double r){
8501
+ if( r<-9223372036854774784.0 ) return SMALLEST_INT64;
8502
+ if( r>+9223372036854774784.0 ) return LARGEST_INT64;
8503
+ return (sqlite3_int64)r;
8504
+}
82378505
82388506
/*
82398507
** This method is called to "rewind" the series_cursor object back
82408508
** to the first row of output. This method is always called at least
82418509
** once prior to any call to seriesColumn() or seriesRowid() or
@@ -8355,27 +8623,31 @@
83558623
double r = sqlite3_value_double(argv[iArg++]);
83568624
if( r==seriesCeil(r)
83578625
&& r>=(double)SMALLEST_INT64
83588626
&& r<=(double)LARGEST_INT64
83598627
){
8360
- iMin = iMax = (sqlite3_int64)r;
8628
+ iMin = iMax = seriesRealToI64(r);
83618629
}else{
83628630
goto series_no_rows;
83638631
}
83648632
}else{
83658633
iMin = iMax = sqlite3_value_int64(argv[iArg++]);
83668634
}
83678635
}else{
8368
- if( idxNum & 0x0300 ){ /* value>X or value>=X */
8636
+ if( idxNum & 0x0300 ){ /* value>X (0x200) or value>=X (0x100) */
83698637
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
83708638
double r = sqlite3_value_double(argv[iArg++]);
8371
- if( r<(double)SMALLEST_INT64 ){
8639
+ if( r<=(double)SMALLEST_INT64 ){
83728640
iMin = SMALLEST_INT64;
8373
- }else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
8374
- iMin = (sqlite3_int64)seriesCeil(r+1.0);
8641
+ }else if( r>(double)LARGEST_INT64 ){
8642
+ goto series_no_rows;
83758643
}else{
8376
- iMin = (sqlite3_int64)seriesCeil(r);
8644
+ iMin = seriesRealToI64(seriesCeil(r));
8645
+ if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
8646
+ if( iMin==LARGEST_INT64 ) goto series_no_rows;
8647
+ iMin++;
8648
+ }
83778649
}
83788650
}else{
83798651
iMin = sqlite3_value_int64(argv[iArg++]);
83808652
if( (idxNum & 0x0200)!=0 ){
83818653
if( iMin==LARGEST_INT64 ){
@@ -8384,19 +8656,23 @@
83848656
iMin++;
83858657
}
83868658
}
83878659
}
83888660
}
8389
- if( idxNum & 0x3000 ){ /* value<X or value<=X */
8661
+ if( idxNum & 0x3000 ){ /* value<X (0x2000) or value<=X (0x1000) */
83908662
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
83918663
double r = sqlite3_value_double(argv[iArg++]);
8392
- if( r>(double)LARGEST_INT64 ){
8664
+ if( r>=(double)LARGEST_INT64 ){
83938665
iMax = LARGEST_INT64;
8394
- }else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
8395
- iMax = (sqlite3_int64)(r-1.0);
8666
+ }else if( r<=(double)SMALLEST_INT64 ){
8667
+ goto series_no_rows;
83968668
}else{
8397
- iMax = (sqlite3_int64)seriesFloor(r);
8669
+ iMax = seriesRealToI64(seriesFloor(r));
8670
+ if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
8671
+ if( iMax==SMALLEST_INT64 ) goto series_no_rows;
8672
+ iMax--;
8673
+ }
83988674
}
83998675
}else{
84008676
iMax = sqlite3_value_int64(argv[iArg++]);
84018677
if( idxNum & 0x2000 ){
84028678
if( iMax==SMALLEST_INT64 ){
@@ -9638,11 +9914,10 @@
96389914
if( pRe==0 ){
96399915
sqlite3_result_error_nomem(context);
96409916
return;
96419917
}
96429918
pStr = sqlite3_str_new(0);
9643
- if( pStr==0 ) goto re_bytecode_func_err;
96449919
if( pRe->nInit>0 ){
96459920
sqlite3_str_appendf(pStr, "INIT ");
96469921
for(i=0; i<pRe->nInit; i++){
96479922
sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]);
96489923
}
@@ -9649,20 +9924,20 @@
96499924
sqlite3_str_appendf(pStr, "\n");
96509925
}
96519926
for(i=0; (unsigned)i<pRe->nState; i++){
96529927
sqlite3_str_appendf(pStr, "%-8s %4d\n",
96539928
ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
9929
+ }
9930
+ if( sqlite3_str_errcode(pStr)==SQLITE_NOMEM ){
9931
+ sqlite3_str_finish(pStr);
9932
+ re_free(pRe);
9933
+ sqlite3_result_error_nomem(context);
9934
+ return;
96549935
}
96559936
n = sqlite3_str_length(pStr);
96569937
z = sqlite3_str_finish(pStr);
9657
- if( n==0 ){
9658
- sqlite3_free(z);
9659
- }else{
9660
- sqlite3_result_text(context, z, n-1, sqlite3_free);
9661
- }
9662
-
9663
-re_bytecode_func_err:
9938
+ sqlite3_result_text(context, z, n-1, sqlite3_free);
96649939
re_free(pRe);
96659940
}
96669941
96679942
#endif /* SQLITE_DEBUG */
96689943
@@ -10557,11 +10832,15 @@
1055710832
sqlite3_result_error_nomem(ctx);
1055810833
return SQLITE_NOMEM;
1055910834
}
1056010835
}
1056110836
10562
- sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10837
+ if( n>0 ){
10838
+ sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10839
+ }else{
10840
+ sqlite3_result_null(ctx);
10841
+ }
1056310842
if( aBuf!=aStatic ) sqlite3_free(aBuf);
1056410843
#endif
1056510844
}else{
1056610845
readFileContents(ctx, pCur->zPath);
1056710846
}
@@ -10870,10 +11149,13 @@
1087011149
** Return NULL if unable.
1087111150
**
1087211151
** The file or directory X is not required to exist. The answer is formed
1087311152
** by calling system realpath() on the prefix of X that does exist and
1087411153
** appending the tail of X that does not (yet) exist.
11154
+**
11155
+** FIXME: This routine sometimes returns NULL rather than raising
11156
+** an SQLITE_NOMEM error if an OOM is encountered.
1087511157
*/
1087611158
static void realpathFunc(
1087711159
sqlite3_context *context,
1087811160
int argc,
1087911161
sqlite3_value **argv
@@ -10892,10 +11174,11 @@
1089211174
(void)argc;
1089311175
zPath = (const char*)sqlite3_value_text(argv[0]);
1089411176
if( zPath==0 ) return;
1089511177
if( zPath[0]==0 ) zPath = ".";
1089611178
zCopy = sqlite3_mprintf("%s",zPath);
11179
+ if( zCopy==0 ) return;
1089711180
len = strlen(zCopy);
1089811181
while( len>1 && (zCopy[len-1]=='/' || (isWin && zCopy[len-1]=='\\')) ){
1089911182
len--;
1090011183
}
1090111184
zCopy[len] = 0;
@@ -11802,11 +12085,13 @@
1180212085
int iAmt,
1180312086
sqlite_int64 iOfst
1180412087
){
1180512088
ApndFile *paf = (ApndFile *)pFile;
1180612089
sqlite_int64 iWriteEnd = iOfst + iAmt;
11807
- if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
12090
+ if( iWriteEnd + paf->iPgOne >= APND_MAX_SIZE-APND_MARK_SIZE ){
12091
+ return SQLITE_FULL;
12092
+ }
1180812093
pFile = ORIGFILE(pFile);
1180912094
/* If append-mark is absent or will be overwritten, write it. */
1181012095
if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
1181112096
int rc = apndWriteMark(paf, pFile, iWriteEnd);
1181212097
if( SQLITE_OK!=rc ) return rc;
@@ -12220,10 +12505,12 @@
1222012505
**
1222112506
** * No support for encryption
1222212507
** * No support for ZIP archives spanning multiple files
1222312508
** * No support for zip64 extensions
1222412509
** * Only the "inflate/deflate" (zlib) compression method is supported
12510
+** * No support for transactions. ROLLBACK is the same as COMMIT.
12511
+** A crash mid-transaction can leave the ZIP archive in a corrupt state.
1222512512
*/
1222612513
/* #include "sqlite3ext.h" */
1222712514
SQLITE_EXTENSION_INIT1
1222812515
#include <stdio.h>
1222912516
#include <string.h>
@@ -12685,10 +12972,11 @@
1268512972
1268612973
for(p=pCsr->pFreeEntry; p; p=pNext){
1268712974
pNext = p->pNext;
1268812975
zipfileEntryFree(p);
1268912976
}
12977
+ pCsr->pFreeEntry = 0;
1269012978
}
1269112979
1269212980
/*
1269312981
** Destructor for an ZipfileCsr.
1269412982
*/
@@ -13087,11 +13375,17 @@
1308713375
}
1308813376
}
1308913377
1309013378
if( rc==SQLITE_OK ){
1309113379
u32 *pt = &pNew->mUnixTime;
13092
- pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
13380
+ /* aRead[0..nFile-1] might contain embedded \000 characters
13381
+ ** See Bug 2026-05-31T11:43:05Z */
13382
+ pNew->cds.zFile = sqlite3_malloc64(nFile+1);
13383
+ if( pNew->cds.zFile!=0 ){
13384
+ memcpy(pNew->cds.zFile, aRead, nFile);
13385
+ pNew->cds.zFile[nFile] = 0;
13386
+ }
1309313387
pNew->aExtra = (u8*)&pNew[1];
1309413388
memcpy(pNew->aExtra, &aRead[nFile], nExtra);
1309513389
if( pNew->cds.zFile==0 ){
1309613390
rc = SQLITE_NOMEM;
1309713391
}else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
@@ -13844,14 +14138,14 @@
1384414138
if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
1384514139
bUpdate = 1;
1384614140
}
1384714141
}
1384814142
for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
14143
+ if( pOld==0 ) return SQLITE_OK;
1384914144
if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
1385014145
break;
1385114146
}
13852
- assert( pOld->pNext );
1385314147
}
1385414148
}
1385514149
1385614150
if( nVal>1 ){
1385714151
/* Check that "sz" and "rawdata" are both NULL: */
@@ -14191,14 +14485,14 @@
1419114485
ZipfileBuffer body;
1419214486
ZipfileBuffer cds;
1419314487
};
1419414488
1419514489
static int zipfileBufferGrow(ZipfileBuffer *pBuf, i64 nByte){
14196
- if( pBuf->n+nByte>pBuf->nAlloc ){
14490
+ if( (pBuf->nAlloc-pBuf->n)<nByte ){
1419714491
u8 *aNew;
14198
- sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
14199
- int nReq = pBuf->n + nByte;
14492
+ i64 nNew = pBuf->n ? (i64)pBuf->n*2 : 512;
14493
+ i64 nReq = pBuf->n + nByte;
1420014494
1420114495
while( nNew<nReq ) nNew = nNew*2;
1420214496
aNew = sqlite3_realloc64(pBuf->a, nNew);
1420314497
if( aNew==0 ) return SQLITE_NOMEM;
1420414498
pBuf->a = aNew;
@@ -14410,11 +14704,11 @@
1441014704
eocd.nEntry = (u16)p->nEntry;
1441114705
eocd.nEntryTotal = (u16)p->nEntry;
1441214706
eocd.nSize = p->cds.n;
1441314707
eocd.iOffset = p->body.n;
1441414708
14415
- nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
14709
+ nZip = (i64)p->body.n + (i64)p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
1441614710
aZip = (u8*)sqlite3_malloc64(nZip);
1441714711
if( aZip==0 ){
1441814712
sqlite3_result_error_nomem(pCtx);
1441914713
}else{
1442014714
memcpy(aZip, p->body.a, p->body.n);
@@ -16296,11 +16590,11 @@
1629616590
p->pTable = pTab;
1629716591
1629816592
/* The statement the vtab will pass to sqlite3_declare_vtab() */
1629916593
zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
1630016594
for(i=0; i<pTab->nCol; i++){
16301
- zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
16595
+ zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %Q",
1630216596
(i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
1630316597
);
1630416598
}
1630516599
zInner = idxAppendText(&rc, zInner, ")");
1630616600
@@ -16496,11 +16790,11 @@
1649616790
sqlite3_free(zCols);
1649716791
sqlite3_free(zOrder);
1649816792
return sqlite3_reset(pIndexXInfo);
1649916793
}
1650016794
zCols = idxAppendText(&rc, zCols,
16501
- "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
16795
+ "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %Q",
1650216796
zComma, zName, nCol, zName, zColl
1650316797
);
1650416798
zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
1650516799
}
1650616800
sqlite3_reset(pIndexXInfo);
@@ -17537,16 +17831,19 @@
1753717831
}
1753817832
iRet++;
1753917833
}
1754017834
}
1754117835
else if( c=='[' ){
17542
- while( z[iRet++]!=']' && z[iRet] );
17836
+ while( z[iRet] && z[iRet++]!=']' ){}
1754317837
}
1754417838
else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
1754517839
while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
1754617840
iRet++;
1754717841
}
17842
+ }
17843
+ else if( c==0 ){
17844
+ iRet = 0;
1754817845
}
1754917846
1755017847
return iRet;
1755117848
}
1755217849
@@ -17983,10 +18280,27 @@
1798318280
intckFinalize(p, pStmt);
1798418281
1798518282
if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
1798618283
return zRet;
1798718284
}
18285
+
18286
+/*
18287
+** Register or unregister special SQL functions implemented by intck.
18288
+**
18289
+** Normally the custom SQL functions used by intck are only available
18290
+** in between sqlite3_intck_open() and sqlite3_intck_close(). However,
18291
+** for testing and debugging, it is sometimes useful to make those
18292
+** functions available generally. This routine provides as a separate
18293
+** interface in order to provide that capability.
18294
+*/
18295
+int sqlite3_intck_register(sqlite3 *db, int bCreate){
18296
+ int rc;
18297
+ rc = sqlite3_create_function(db, "parse_create_index",
18298
+ 2, SQLITE_UTF8, 0, bCreate ? intckParseCreateIndexFunc : 0, 0, 0
18299
+ );
18300
+ return rc;
18301
+}
1798818302
1798918303
/*
1799018304
** Open a new integrity-check object.
1799118305
*/
1799218306
int sqlite3_intck_open(
@@ -18005,13 +18319,11 @@
1800518319
}else{
1800618320
memset(pNew, 0, sizeof(*pNew));
1800718321
pNew->db = db;
1800818322
pNew->zDb = (const char*)&pNew[1];
1800918323
memcpy(&pNew[1], zDb, nDb+1);
18010
- rc = sqlite3_create_function(db, "parse_create_index",
18011
- 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
18012
- );
18324
+ rc = sqlite3_intck_register(db, 1);
1801318325
if( rc!=SQLITE_OK ){
1801418326
sqlite3_intck_close(pNew);
1801518327
pNew = 0;
1801618328
}
1801718329
}
@@ -18024,13 +18336,11 @@
1802418336
** Free the integrity-check object.
1802518337
*/
1802618338
void sqlite3_intck_close(sqlite3_intck *p){
1802718339
if( p ){
1802818340
sqlite3_finalize(p->pCheck);
18029
- sqlite3_create_function(
18030
- p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
18031
- );
18341
+ sqlite3_intck_register(p->db, 0);
1803218342
sqlite3_free(p->zObj);
1803318343
sqlite3_free(p->zKey);
1803418344
sqlite3_free(p->zTestSql);
1803518345
sqlite3_free(p->zErr);
1803618346
sqlite3_free(p->zMessage);
@@ -19464,11 +19774,11 @@
1946419774
sqlite3_vfs_unregister(pVfs);
1946519775
sqlite3_free(pVfs);
1946619776
}
1946719777
1946819778
/************************* End ext/misc/vfstrace.c ********************/
19469
-/************************* Begin ext/misc/analyze.c ******************/
19779
+/************************* Begin ext/misc/diskused.c ******************/
1947019780
/*
1947119781
** 2026-04-13
1947219782
**
1947319783
** The author disclaims copyright to this source code. In place of
1947419784
** a legal notice, here is a blessing:
@@ -19477,12 +19787,21 @@
1947719787
** May you find forgiveness for yourself and forgive others.
1947819788
** May you share freely, never taking more than you give.
1947919789
**
1948019790
******************************************************************************
1948119791
**
19482
-** Partial reimplement of the sqlite3_analyzer utility program as
19483
-** loadable SQL function.
19792
+** This extension implements an SQL function:
19793
+**
19794
+** diskused(X)
19795
+**
19796
+** Where X is the schema name (typically 'main'). The output is text
19797
+** that describes how much filesystem space the various tables and indexes
19798
+** of the database consume.
19799
+**
19800
+** This function is a replacement for the (now deprecated)
19801
+** "sqlite3_analyzer" utility program. This function is built
19802
+** into the CLI and is used to implement the ".diskused" command there.
1948419803
*/
1948519804
/* #include "sqlite3ext.h" */
1948619805
SQLITE_EXTENSION_INIT1
1948719806
#include <assert.h>
1948819807
#include <string.h>
@@ -19490,28 +19809,28 @@
1949019809
#include <math.h>
1949119810
1949219811
/*
1949319812
** State information for the analysis
1949419813
*/
19495
-typedef struct Analysis Analysis;
19496
-struct Analysis {
19814
+typedef struct DiskUsed DiskUsed;
19815
+struct DiskUsed {
1949719816
sqlite3 *db; /* Database connection */
1949819817
sqlite3_context *context; /* SQL function context */
1949919818
sqlite3_str *pOut; /* Write output here */
1950019819
char *zSU; /* Name of the temp.space_used table */
1950119820
const char *zSchema; /* Schema to be analyzed */
1950219821
};
1950319822
1950419823
/*
19505
-** Free all resources that the Analysis object references and
19506
-** reset the Analysis object.
19824
+** Free all resources that the DiskUsed object references and
19825
+** reset the DiskUsed object.
1950719826
**
19508
-** Call this routine multiple times on the same Analysis object
19827
+** Call this routine multiple times on the same DiskUsed object
1950919828
** is a harmless no-op, as long as the memory for the object itself
1951019829
** has not been freed.
1951119830
*/
19512
-static void analysisReset(Analysis *p){
19831
+static void diskusedReset(DiskUsed *p){
1951319832
if( p->zSU ){
1951419833
char *zSql = sqlite3_mprintf("DROP TABLE temp.%s;", p->zSU);
1951519834
if( zSql ){
1951619835
sqlite3_exec(p->db, zSql, 0, 0, 0);
1951719836
sqlite3_free(zSql);
@@ -19524,11 +19843,11 @@
1952419843
1952519844
/*
1952619845
** Report an error using formatted text. If zFormat==NULL then report
1952719846
** an OOM error.
1952819847
*/
19529
-static void analysisError(Analysis *p, const char *zFormat, ...){
19848
+static void diskusedError(DiskUsed *p, const char *zFormat, ...){
1953019849
char *zErr;
1953119850
if( zFormat ){
1953219851
va_list ap;
1953319852
va_start(ap, zFormat);
1953419853
zErr = sqlite3_vmprintf(zFormat, ap);
@@ -19540,38 +19859,38 @@
1954019859
sqlite3_result_error_nomem(p->context);
1954119860
}else{
1954219861
sqlite3_result_error(p->context, zErr, -1);
1954319862
sqlite3_free(zErr);
1954419863
}
19545
- analysisReset(p);
19864
+ diskusedReset(p);
1954619865
}
1954719866
1954819867
/*
1954919868
** Prepare and return an SQL statement.
1955019869
*/
19551
-static sqlite3_stmt *analysisVPrep(Analysis *p, const char *zFmt, va_list ap){
19870
+static sqlite3_stmt *diskusedVPrep(DiskUsed *p, const char *zFmt, va_list ap){
1955219871
char *zSql;
1955319872
int rc;
1955419873
sqlite3_stmt *pStmt = 0;
1955519874
zSql = sqlite3_vmprintf(zFmt, ap);
19556
- if( zSql==0 ){ analysisError(p,0); return 0; }
19875
+ if( zSql==0 ){ diskusedError(p,0); return 0; }
1955719876
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1955819877
if( rc ){
19559
- analysisError(p, "SQL parse error: %s\nOriginal SQL: %s",
19878
+ diskusedError(p, "SQL parse error: %s\nOriginal SQL: %s",
1956019879
sqlite3_errmsg(p->db), zSql);
1956119880
sqlite3_finalize(pStmt);
19562
- analysisReset(p);
19881
+ diskusedReset(p);
1956319882
pStmt = 0;
1956419883
}
1956519884
sqlite3_free(zSql);
1956619885
return pStmt;
1956719886
}
19568
-static sqlite3_stmt *analysisPrepare(Analysis *p, const char *zFormat, ...){
19887
+static sqlite3_stmt *diskusedPrepare(DiskUsed *p, const char *zFormat, ...){
1956919888
va_list ap;
1957019889
sqlite3_stmt *pStmt = 0;
1957119890
va_start(ap, zFormat);
19572
- pStmt = analysisVPrep(p,zFormat,ap);
19891
+ pStmt = diskusedVPrep(p,zFormat,ap);
1957319892
va_end(ap);
1957419893
return pStmt;
1957519894
}
1957619895
1957719896
/*
@@ -19580,60 +19899,60 @@
1958019899
**
1958119900
** If rc is SQLITE_DONE or SQLITE_OK, then return false.
1958219901
**
1958319902
** The prepared statement is closed in either case.
1958419903
*/
19585
-static int analysisStmtFinish(Analysis *p, int rc, sqlite3_stmt *pStmt){
19904
+static int diskusedStmtFinish(DiskUsed *p, int rc, sqlite3_stmt *pStmt){
1958619905
if( rc==SQLITE_DONE ){
1958719906
rc = SQLITE_OK;
1958819907
}
1958919908
if( rc!=SQLITE_OK || (rc = sqlite3_reset(pStmt))!=SQLITE_OK ){
19590
- analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19909
+ diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
1959119910
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19592
- analysisReset(p);
19911
+ diskusedReset(p);
1959319912
}
1959419913
sqlite3_finalize(pStmt);
1959519914
return rc;
1959619915
}
1959719916
1959819917
/*
1959919918
** Run SQL. Return the number of errors.
1960019919
*/
19601
-static int analysisSql(Analysis *p, const char *zFormat, ...){
19920
+static int diskusedSql(DiskUsed *p, const char *zFormat, ...){
1960219921
va_list ap;
1960319922
int rc;
1960419923
sqlite3_stmt *pStmt = 0;
1960519924
va_start(ap, zFormat);
19606
- pStmt = analysisVPrep(p,zFormat,ap);
19925
+ pStmt = diskusedVPrep(p,zFormat,ap);
1960719926
va_end(ap);
1960819927
if( pStmt==0 ) return 1;
1960919928
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
1961019929
if( rc==SQLITE_DONE ){
1961119930
rc = SQLITE_OK;
1961219931
}else{
19613
- analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19932
+ diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
1961419933
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19615
- analysisReset(p);
19934
+ diskusedReset(p);
1961619935
}
1961719936
sqlite3_finalize(pStmt);
1961819937
return rc;
1961919938
}
1962019939
1962119940
/*
1962219941
** Run an SQL query that returns an integer. Write that integer
1962319942
** into *piRes. Return the number of errors.
1962419943
*/
19625
-static int analysisSqlInt(
19626
- Analysis *p,
19944
+static int diskusedSqlInt(
19945
+ DiskUsed *p,
1962719946
sqlite3_int64 *piRes,
1962819947
const char *zFormat, ...
1962919948
){
1963019949
va_list ap;
1963119950
int rc;
1963219951
sqlite3_stmt *pStmt = 0;
1963319952
va_start(ap, zFormat);
19634
- pStmt = analysisVPrep(p,zFormat,ap);
19953
+ pStmt = diskusedVPrep(p,zFormat,ap);
1963519954
va_end(ap);
1963619955
if( pStmt==0 ) return 1;
1963719956
rc = sqlite3_step(pStmt);
1963819957
if( rc==SQLITE_ROW ){
1963919958
*piRes = sqlite3_column_int64(pStmt, 0);
@@ -19641,14 +19960,14 @@
1964119960
}else if( rc==SQLITE_DONE ){
1964219961
rc = SQLITE_OK;
1964319962
}else{
1964419963
if( p->db ){
1964519964
/* p->db is NULL if there was some prior error */
19646
- analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19965
+ diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
1964719966
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
1964819967
}
19649
- analysisReset(p);
19968
+ diskusedReset(p);
1965019969
}
1965119970
sqlite3_finalize(pStmt);
1965219971
return rc;
1965319972
}
1965419973
@@ -19657,20 +19976,20 @@
1965719976
** by the format string. If the output is initially empty, begin
1965819977
** the title line with "/" so that it forms the beginning of a C-style
1965919978
** comment. Otherwise begin with a new-line. Always finish with a
1966019979
** newline.
1966119980
*/
19662
-static void analysisTitle(Analysis *p, const char *zFormat, ...){
19981
+static void diskusedTitle(DiskUsed *p, const char *zFormat, ...){
1966319982
char *zFirst;
1966419983
char *zTitle;
1966519984
size_t nTitle;
1966619985
va_list ap;
1966719986
va_start(ap, zFormat);
1966819987
zTitle = sqlite3_vmprintf(zFormat, ap);
1966919988
va_end(ap);
1967019989
if( zTitle==0 ){
19671
- analysisError(p, 0);
19990
+ diskusedError(p, 0);
1967219991
return;
1967319992
}
1967419993
zFirst = sqlite3_str_length(p->pOut)==0 ? "/" : "\n*";
1967519994
nTitle = strlen(zTitle);
1967619995
if( nTitle>=75 ){
@@ -19685,12 +20004,12 @@
1968520004
/*
1968620005
** Add an output line that begins with the zDesc text extended out to
1968720006
** 50 columns with "." characters, and followed by whatever text is
1968820007
** described by zFormat.
1968920008
*/
19690
-static void analysisLine(
19691
- Analysis *p, /* Analysis context */
20009
+static void diskusedLine(
20010
+ DiskUsed *p, /* DiskUsed context */
1969220011
const char *zDesc, /* Description */
1969320012
const char *zFormat, /* Argument to the description */
1969420013
...
1969520014
){
1969620015
char *zTxt;
@@ -19698,14 +20017,14 @@
1969820017
va_list ap;
1969920018
va_start(ap, zFormat);
1970020019
zTxt = sqlite3_vmprintf(zFormat, ap);
1970120020
va_end(ap);
1970220021
if( zTxt==0 ){
19703
- analysisError(p, 0);
20022
+ diskusedError(p, 0);
1970420023
return;
1970520024
}
19706
- nDesc = strlen(zDesc);
20025
+ nDesc = zDesc ? strlen(zDesc) : 0;
1970720026
if( nDesc>=50 ){
1970820027
sqlite3_str_appendf(p->pOut, "%s %z", zDesc, zTxt);
1970920028
}else{
1971020029
int nExtra = 50 - (int)nDesc;
1971120030
sqlite3_str_appendf(p->pOut, "%s%.*c %z", zDesc, nExtra, '.', zTxt);
@@ -19715,15 +20034,28 @@
1971520034
/*
1971620035
** Write a percentage into the output. The number written should show
1971720036
** two or three significant digits, with the decimal point being the fourth
1971820037
** character.
1971920038
*/
19720
-static void analysisPercent(Analysis *p, double r){
20039
+static void diskusedPercent(
20040
+ DiskUsed *p, /* Context of the disk-usage analysis */
20041
+ sqlite3_int64 num, /* Numerator of the fraction */
20042
+ sqlite3_int64 denom /* Denominator of the fraction. Might be zero! */
20043
+){
1972120044
char zNum[100];
1972220045
char *zDP;
1972320046
int nLeadingDigit;
1972420047
int sz;
20048
+ double r;
20049
+ if( num==0 ){
20050
+ r = 0.0;
20051
+ }else if( denom==0 ){
20052
+ sqlite3_str_appendchar(p->pOut, 1, '\n');
20053
+ return;
20054
+ }else{
20055
+ r = num*100.0/(double)denom;
20056
+ }
1972520057
sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
1972620058
sz = (int)strlen(zNum);
1972720059
zDP = strchr(zNum, '.');
1972820060
if( zDP==0 ){
1972920061
memcpy(zNum+sz,".0",3);
@@ -19744,12 +20076,12 @@
1974420076
**
1974520077
** The title if the subreport is given by zTitle. zWhere is
1974620078
** a boolean expression that can go in the WHERE clause to select
1974720079
** the relevant rows of the s.zSU table.
1974820080
*/
19749
-static int analysisSubreport(
19750
- Analysis *p, /* Analysis context */
20081
+static int diskusedSubreport(
20082
+ DiskUsed *p, /* DiskUsed context */
1975120083
char *zTitle, /* Title for this subreport */
1975220084
char *zWhere, /* WHERE clause for this subreport */
1975320085
sqlite3_int64 pgsz, /* Database page size */
1975420086
sqlite3_int64 nPage /* Number of pages in entire database */
1975520087
){
@@ -19773,14 +20105,14 @@
1977320105
sqlite3_int64 total_unused; /* Total unused bytes */
1977420106
sqlite3_int64 total_meta; /* Total metadata */
1977520107
int rc;
1977620108
1977720109
if( zTitle==0 || zWhere==0 ){
19778
- analysisError(p, 0);
20110
+ diskusedError(p, 0);
1977920111
return SQLITE_NOMEM;
1978020112
}
19781
- pStmt = analysisPrepare(p,
20113
+ pStmt = diskusedPrepare(p,
1978220114
"SELECT\n"
1978320115
" sum(if(is_without_rowid OR is_index,nentry,leaf_entries)),\n" /* 0 */
1978420116
" sum(payload),\n" /* 1 */
1978520117
" sum(ovfl_payload),\n" /* 2 */
1978620118
" max(mx_payload),\n" /* 3 */
@@ -19797,11 +20129,11 @@
1979720129
" FROM temp.%s WHERE %s",
1979820130
p->zSU, zWhere);
1979920131
if( pStmt==0 ) return 1;
1980020132
rc = sqlite3_step(pStmt);
1980120133
if( rc==SQLITE_ROW ){
19802
- analysisTitle(p, zTitle);
20134
+ diskusedTitle(p, "%s", zTitle);
1980320135
1980420136
nentry = sqlite3_column_int64(pStmt, 0);
1980520137
payload = sqlite3_column_int64(pStmt, 1);
1980620138
ovfl_payload = sqlite3_column_int64(pStmt, 2);
1980720139
mx_payload = sqlite3_column_int64(pStmt, 3);
@@ -19816,73 +20148,73 @@
1981620148
cnt = sqlite3_column_int64(pStmt, 12);
1981720149
int_cell = sqlite3_column_int64(pStmt, 13);
1981820150
rc = SQLITE_DONE;
1981920151
1982020152
total_pages = leaf_pages + int_pages + ovfl_pages;
19821
- analysisLine(p, "Percentage of total database", "%.3g%%\n",
20153
+ diskusedLine(p, "Percentage of total database", "%.3g%%\n",
1982220154
(total_pages*100.0)/(double)nPage);
19823
- analysisLine(p, "Number of entries", "%lld\n", nentry);
20155
+ diskusedLine(p, "Number of entries", "%lld\n", nentry);
1982420156
storage = total_pages*pgsz;
19825
- analysisLine(p, "Bytes of storage consumed", "%lld\n", storage);
19826
- analysisLine(p, "Bytes of payload", "%-11lld ", payload);
19827
- analysisPercent(p, payload*100.0/(double)storage);
20157
+ diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
20158
+ diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
20159
+ diskusedPercent(p, payload, storage);
1982820160
if( ovfl_cnt>0 ){
19829
- analysisLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
19830
- analysisPercent(p, ovfl_payload*100.0/(double)payload);
20161
+ diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
20162
+ diskusedPercent(p, ovfl_payload, payload);
1983120163
}
1983220164
total_unused = leaf_unused + int_unused + ovfl_unused;
1983320165
total_meta = storage - payload - total_unused;
19834
- analysisLine(p, "Bytes of metadata","%-11lld ", total_meta);
19835
- analysisPercent(p, total_meta*100.0/(double)storage);
20166
+ diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
20167
+ diskusedPercent(p, total_meta, storage);
1983620168
if( cnt==1 ){
19837
- analysisLine(p, "B-tree depth", "%lld\n", depth);
20169
+ diskusedLine(p, "B-tree depth", "%lld\n", depth);
1983820170
if( int_cell>1 ){
19839
- analysisLine(p, "Average fanout", "%.1f\n",
20171
+ diskusedLine(p, "Average fanout", "%.1f\n",
1984020172
(double)(int_cell+int_pages)/(double)int_pages);
1984120173
}
1984220174
}
1984320175
if( nentry>0 ){
19844
- analysisLine(p, "Average payload per entry", "%.1f\n",
20176
+ diskusedLine(p, "Average payload per entry", "%.1f\n",
1984520177
(double)payload/(double)nentry);
19846
- analysisLine(p, "Average unused bytes per entry", "%.1f\n",
20178
+ diskusedLine(p, "Average unused bytes per entry", "%.1f\n",
1984720179
(double)total_unused/(double)nentry);
19848
- analysisLine(p, "Average metadata per entry", "%.1f\n",
20180
+ diskusedLine(p, "Average metadata per entry", "%.1f\n",
1984920181
(double)total_meta/(double)nentry);
1985020182
}
19851
- analysisLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
19852
- if( nentry>0 ){
19853
- analysisLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
19854
- analysisPercent(p, ovfl_cnt*100.0/(double)nentry);
19855
- }
19856
- if( int_pages>0 ){
19857
- analysisLine(p, "Index pages used", "%lld\n", int_pages);
19858
- }
19859
- analysisLine(p, "Primary pages used", "%lld\n", leaf_pages);
19860
- if( ovfl_cnt ){
19861
- analysisLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
19862
- }
19863
- analysisLine(p, "Total pages used", "%lld\n", total_pages);
19864
- if( int_pages>0 ){
19865
- analysisLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
19866
- }
19867
- analysisLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
19868
- if( ovfl_cnt ){
19869
- analysisLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
19870
- }
19871
- analysisLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
19872
- analysisPercent(p, total_unused*100.0/(double)storage);
19873
- }
19874
- return analysisStmtFinish(p, rc, pStmt);
19875
-}
19876
-
19877
-/*
19878
-** SQL Function: analyze(SCHEMA)
20183
+ diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
20184
+ if( nentry>0 ){
20185
+ diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
20186
+ diskusedPercent(p, ovfl_cnt, nentry);
20187
+ }
20188
+ if( int_pages>0 ){
20189
+ diskusedLine(p, "Index pages used", "%lld\n", int_pages);
20190
+ }
20191
+ diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
20192
+ if( ovfl_cnt ){
20193
+ diskusedLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
20194
+ }
20195
+ diskusedLine(p, "Total pages used", "%lld\n", total_pages);
20196
+ if( int_pages>0 ){
20197
+ diskusedLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
20198
+ }
20199
+ diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
20200
+ if( ovfl_cnt ){
20201
+ diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
20202
+ }
20203
+ diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
20204
+ diskusedPercent(p, total_unused, storage);
20205
+ }
20206
+ return diskusedStmtFinish(p, rc, pStmt);
20207
+}
20208
+
20209
+/*
20210
+** SQL Function: diskused(SCHEMA)
1987920211
**
1988020212
** Analyze the database schema named in the argument. Return text
19881
-** containing the analysis.
20213
+** containing the space utilization stats.
1988220214
*/
19883
-static void analyzeFunc(
20215
+static void diskusedFunc(
1988420216
sqlite3_context *context,
1988520217
int argc,
1988620218
sqlite3_value **argv
1988720219
){
1988820220
int rc;
@@ -19893,47 +20225,47 @@
1989320225
sqlite3_int64 nPage;
1989420226
sqlite3_int64 nPageInUse;
1989520227
sqlite3_int64 nFreeList;
1989620228
sqlite3_int64 nIndex;
1989720229
sqlite3_int64 nWORowid;
19898
- Analysis s;
20230
+ DiskUsed s;
1989920231
sqlite3_uint64 r[2];
1990020232
1990120233
(void)argc;
1990220234
memset(&s, 0, sizeof(s));
1990320235
s.db = sqlite3_context_db_handle(context);
1990420236
s.context = context;
1990520237
s.pOut = sqlite3_str_new(0);
1990620238
if( sqlite3_str_errcode(s.pOut) ){
19907
- analysisError(&s, 0);
20239
+ diskusedError(&s, 0);
1990820240
return;
1990920241
}
1991020242
s.zSchema = (const char*)sqlite3_value_text(argv[0]);
1991120243
if( s.zSchema==0 ){
1991220244
s.zSchema = "main";
1991320245
}else if( sqlite3_strlike("temp",s.zSchema,0)==0 ){
19914
- analysisReset(&s);
20246
+ diskusedReset(&s);
1991520247
sqlite3_result_text(context, "cannot analyze \"temp\"",-1,SQLITE_STATIC);
1991620248
return;
1991720249
}
1991820250
ii = 0;
19919
- rc = analysisSqlInt(&s,&ii,"SELECT 1 FROM pragma_database_list"
20251
+ rc = diskusedSqlInt(&s,&ii,"SELECT 1 FROM pragma_database_list"
1992020252
" WHERE name=%Q COLLATE nocase",s.zSchema);
1992120253
if( rc || ii==0 ){
19922
- analysisReset(&s);
20254
+ diskusedReset(&s);
1992320255
sqlite3_result_text(context,"no such database",-1,SQLITE_STATIC);
1992420256
return;
1992520257
}
1992620258
sqlite3_randomness(sizeof(r), &r);
19927
- s.zSU = sqlite3_mprintf("analysis%016llx%016llx", r[0], r[1]);
19928
- if( s.zSU==0 ){ analysisError(&s, 0); return; }
20259
+ s.zSU = sqlite3_mprintf("diskused%016llx%016llx", r[0], r[1]);
20260
+ if( s.zSU==0 ){ diskusedError(&s, 0); return; }
1992920261
1993020262
/* The s.zSU table contains the data used for the analysis.
1993120263
** The table name contains 128-bits of randomness to avoid
1993220264
** collisions with preexisting tables in temp.
1993320265
*/
19934
- rc = analysisSql(&s,
20266
+ rc = diskusedSql(&s,
1993520267
"CREATE TABLE temp.%s(\n"
1993620268
" name text, -- A table or index\n"
1993720269
" tblname text, -- Table that owns name\n"
1993820270
" is_index boolean, -- TRUE if it is an index\n"
1993920271
" is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n"
@@ -19956,11 +20288,11 @@
1995620288
);
1995720289
if( rc ) return;
1995820290
1995920291
/* Populate the s.zSU table
1996020292
*/
19961
- rc = analysisSql(&s,
20293
+ rc = diskusedSql(&s,
1996220294
"WITH\n"
1996320295
" allidx(idxname) AS (\n"
1996420296
" SELECT name FROM \"%w\".sqlite_schema WHERE type='index'\n"
1996520297
" ),\n"
1996620298
" allobj(allname,tblname,isidx,isworowid) AS (\n"
@@ -20008,141 +20340,143 @@
2000820340
s.zSchema /* JOIN dbstat(%Q) */
2000920341
);
2001020342
if( rc ) return;
2001120343
2001220344
nPage = 0;
20013
- rc = analysisSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
20345
+ rc = diskusedSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
2001420346
if( rc ) return;
2001520347
if( nPage<=0 ){
2001620348
/* Very brief reply for an empty database */
20017
- analysisReset(&s);
20349
+ diskusedReset(&s);
2001820350
sqlite3_result_text(context, "empty database", -1, SQLITE_STATIC);
2001920351
return;
2002020352
}
2002120353
2002220354
/* Begin generating the report */
20023
- analysisTitle(&s, "Database storage utilization report");
20355
+ diskusedTitle(&s, "Database storage utilization report");
2002420356
pgsz = 0;
20025
- rc = analysisSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
20357
+ rc = diskusedSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
2002620358
if( rc ) return;
20027
- analysisLine(&s, "Page size in bytes","%lld\n",pgsz);
20028
- analysisLine(&s, "Pages in the database", "%lld\n", nPage);
20359
+ diskusedLine(&s, "Page size in bytes","%lld\n",pgsz);
20360
+ diskusedLine(&s, "Pages in the database", "%lld\n", nPage);
2002920361
2003020362
nPageInUse = 0;
20031
- rc = analysisSqlInt(&s, &nPageInUse,
20363
+ rc = diskusedSqlInt(&s, &nPageInUse,
2003220364
"SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
2003320365
if( rc ) return;
20034
- analysisLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20035
- analysisPercent(&s, (nPageInUse*100.0)/(double)nPage);
20366
+ diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20367
+ diskusedPercent(&s, nPageInUse, nPage);
2003620368
2003720369
nFreeList = 0;
20038
- rc = analysisSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
20370
+ rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
2003920371
if( rc ) return;
20040
- analysisLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20041
- analysisPercent(&s, (nFreeList*100.0)/(double)nPage);
20372
+ diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20373
+ diskusedPercent(&s, nFreeList, nPage);
2004220374
2004320375
ii = 0;
20044
- rc = analysisSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
20376
+ rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
2004520377
if( rc ) return;
2004620378
if( ii==0 || nPage<=1 ){
2004720379
ii = 0;
2004820380
}else{
2004920381
double rPtrsPerPage = pgsz/5;
2005020382
double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
2005120383
ii = (sqlite3_int64)ceil(rAvPage);
2005220384
}
20053
- analysisLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20054
- analysisPercent(&s, (ii*100.0)/(double)nPage);
20385
+ diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20386
+ diskusedPercent(&s, ii, nPage);
2005520387
2005620388
ii = 0;
20057
- rc = analysisSqlInt(&s, &ii,
20389
+ rc = diskusedSqlInt(&s, &ii,
2005820390
"SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
2005920391
s.zSchema);
2006020392
if( rc ) return;
20061
- analysisLine(&s, "Number of tables", "%lld\n", ii);
20393
+ diskusedLine(&s, "Number of tables", "%lld\n", ii);
2006220394
nWORowid = 0;
20063
- rc = analysisSqlInt(&s, &nWORowid,
20395
+ rc = diskusedSqlInt(&s, &nWORowid,
2006420396
"SELECT count(*) FROM \"%w\".pragma_table_list WHERE wr",
2006520397
s.zSchema);
2006620398
if( rc ) return;
2006720399
if( nWORowid>0 ){
20068
- analysisLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
20069
- analysisLine(&s, "Number of rowid tables", "%lld\n", ii - nWORowid);
20400
+ diskusedLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
20401
+ diskusedLine(&s, "Number of rowid tables", "%lld\n", ii - nWORowid);
2007020402
}
2007120403
nIndex = 0;
20072
- rc = analysisSqlInt(&s, &nIndex,
20404
+ rc = diskusedSqlInt(&s, &nIndex,
2007320405
"SELECT count(*) FROM \"%w\".sqlite_schema WHERE type='index'",
2007420406
s.zSchema);
2007520407
if( rc ) return;
20076
- analysisLine(&s, "Number of indexes", "%lld\n", nIndex);
20408
+ diskusedLine(&s, "Number of indexes", "%lld\n", nIndex);
2007720409
ii = 0;
20078
- rc = analysisSqlInt(&s, &ii,
20410
+ rc = diskusedSqlInt(&s, &ii,
2007920411
"SELECT count(*) FROM \"%w\".sqlite_schema"
2008020412
" WHERE name GLOB 'sqlite_autoindex_*' AND type='index'",
2008120413
s.zSchema);
2008220414
if( rc ) return;
20083
- analysisLine(&s, "Number of defined indexes", "%lld\n", nIndex - ii);
20084
- analysisLine(&s, "Number of implied indexes", "%lld\n", ii);
20085
- analysisLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
20415
+ diskusedLine(&s, "Number of defined indexes", "%lld\n", nIndex - ii);
20416
+ diskusedLine(&s, "Number of implied indexes", "%lld\n", ii);
20417
+ diskusedLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
2008620418
ii = 0;
20087
- rc = analysisSqlInt(&s, &ii,
20419
+ rc = diskusedSqlInt(&s, &ii,
2008820420
"SELECT sum(payload) FROM temp.%s"
2008920421
" WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
2009020422
s.zSU);
2009120423
if( rc ) return;
20092
- analysisLine(&s, "Bytes of payload", "%-11lld ", ii);
20093
- analysisPercent(&s, ii*100.0/(double)(pgsz*nPage));
20424
+ diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
20425
+ diskusedPercent(&s, ii, pgsz*nPage);
2009420426
20095
- analysisTitle(&s, "Page counts for all tables with their indexes");
20096
- pStmt = analysisPrepare(&s,
20427
+ diskusedTitle(&s, "Page counts for all tables with their indexes");
20428
+ pStmt = diskusedPrepare(&s,
2009720429
"SELECT upper(tblname),\n"
2009820430
" sum(int_pages+leaf_pages+ovfl_pages)\n"
2009920431
" FROM temp.%s\n"
20432
+ " WHERE tblname IS NOT NULL\n"
20433
+ " GROUP BY 1\n"
20434
+ " ORDER BY 2 DESC, 1;",
20435
+ s.zSU);
20436
+ if( pStmt==0 ) return;
20437
+ while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20438
+ sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20439
+ diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20440
+ diskusedPercent(&s, nn, nPage);
20441
+ }
20442
+ if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20443
+
20444
+ diskusedTitle(&s, "Page counts for all tables and indexes separately");
20445
+ pStmt = diskusedPrepare(&s,
20446
+ "SELECT upper(name),\n"
20447
+ " sum(int_pages+leaf_pages+ovfl_pages)\n"
20448
+ " FROM temp.%s\n"
20449
+ " WHERE name IS NOT NULL\n"
2010020450
" GROUP BY 1\n"
2010120451
" ORDER BY 2 DESC, 1;",
2010220452
s.zSU);
2010320453
if( pStmt==0 ) return;
2010420454
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
2010520455
sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20106
- analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20107
- analysisPercent(&s, (nn*100.0)/(double)nPage);
20108
- }
20109
- if( analysisStmtFinish(&s, rc, pStmt) ) return;
20110
-
20111
- analysisTitle(&s, "Page counts for all tables and indexes separately");
20112
- pStmt = analysisPrepare(&s,
20113
- "SELECT upper(name),\n"
20114
- " sum(int_pages+leaf_pages+ovfl_pages)\n"
20115
- " FROM temp.%s\n"
20116
- " GROUP BY 1\n"
20117
- " ORDER BY 2 DESC, 1;",
20118
- s.zSU);
20119
- if( pStmt==0 ) return;
20120
- while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20121
- sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20122
- analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20123
- analysisPercent(&s, (nn*100.0)/(double)nPage);
20124
- }
20125
- if( analysisStmtFinish(&s, rc, pStmt) ) return;
20126
-
20127
- rc = analysisSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
20456
+ diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20457
+ diskusedPercent(&s, nn, nPage);
20458
+ }
20459
+ if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20460
+
20461
+ rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
2012820462
if( rc ) return;
20129
- rc = analysisSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
20463
+ rc = diskusedSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
2013020464
if( rc ) return;
2013120465
if( nWORowid>0 ){
20132
- rc = analysisSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
20466
+ rc = diskusedSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
2013320467
pgsz, nPage);
2013420468
if( rc ) return;
20135
- rc = analysisSubreport(&s, "All rowid tables",
20469
+ rc = diskusedSubreport(&s, "All rowid tables",
2013620470
"NOT is_without_rowid AND NOT is_index",
2013720471
pgsz, nPage);
2013820472
if( rc ) return;
2013920473
}
20140
- rc = analysisSubreport(&s, "All indexes", "is_index", pgsz, nPage);
20474
+ rc = diskusedSubreport(&s, "All indexes", "is_index", pgsz, nPage);
2014120475
if( rc ) return;
2014220476
20143
- pStmt = analysisPrepare(&s,
20477
+ pStmt = diskusedPrepare(&s,
2014420478
"SELECT upper(tblname), tblname, sum(is_index) FROM temp.%s"
2014520479
" GROUP BY 1 ORDER BY 1",
2014620480
s.zSU);
2014720481
if( pStmt==0 ) return;
2014820482
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
@@ -20150,37 +20484,37 @@
2015020484
const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
2015120485
int nSubIndex = sqlite3_column_int(pStmt, 2);
2015220486
if( nSubIndex==0 ){
2015320487
char *zTitle = sqlite3_mprintf("Table %s", zUpper);
2015420488
char *zWhere = sqlite3_mprintf("name=%Q", zName);
20155
- rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20489
+ rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
2015620490
sqlite3_free(zTitle);
2015720491
sqlite3_free(zWhere);
2015820492
if( rc ) break;
2015920493
}else{
2016020494
sqlite3_stmt *pS2;
2016120495
char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper);
2016220496
char *zWhere = sqlite3_mprintf("tblname=%Q", zName);
20163
- rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20497
+ rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
2016420498
sqlite3_free(zTitle);
2016520499
sqlite3_free(zWhere);
2016620500
if( rc ) break;
2016720501
zTitle = sqlite3_mprintf("Table %s w/o any indexes", zUpper);
2016820502
zWhere = sqlite3_mprintf("name=%Q", zName);
20169
- rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20503
+ rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
2017020504
sqlite3_free(zTitle);
2017120505
sqlite3_free(zWhere);
2017220506
if( rc ) break;
2017320507
if( nSubIndex>1 ){
2017420508
zTitle = sqlite3_mprintf("All indexes of table %s", zUpper);
2017520509
zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName);
20176
- rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20510
+ rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
2017720511
sqlite3_free(zTitle);
2017820512
sqlite3_free(zWhere);
2017920513
if( rc ) break;
2018020514
}
20181
- pS2 = analysisPrepare(&s,
20515
+ pS2 = diskusedPrepare(&s,
2018220516
"SELECT name, upper(name) FROM temp.%s"
2018320517
" WHERE is_index AND tblname=%Q",
2018420518
s.zSU, zName);
2018520519
if( pS2==0 ){
2018620520
rc = SQLITE_NOMEM;
@@ -20189,25 +20523,25 @@
2018920523
while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){
2019020524
const char *zU = (const char*)sqlite3_column_text(pS2, 1);
2019120525
const char *zN = (const char*)sqlite3_column_text(pS2, 0);
2019220526
zTitle = sqlite3_mprintf("Index %s", zU);
2019320527
zWhere = sqlite3_mprintf("name=%Q", zN);
20194
- rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20528
+ rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
2019520529
sqlite3_free(zTitle);
2019620530
sqlite3_free(zWhere);
2019720531
if( rc ) break;
2019820532
}
20199
- rc = analysisStmtFinish(&s, rc, pS2);
20533
+ rc = diskusedStmtFinish(&s, rc, pS2);
2020020534
if( rc ) break;
2020120535
}
2020220536
}
20203
- if( analysisStmtFinish(&s, rc, pStmt) ) return;
20537
+ if( diskusedStmtFinish(&s, rc, pStmt) ) return;
2020420538
2020520539
/* Append SQL statements that will recreate the raw data used for
2020620540
** the analysis.
2020720541
*/
20208
- analysisTitle(&s, "Raw data used to generate this report");
20542
+ diskusedTitle(&s, "Raw data used to generate this report");
2020920543
sqlite3_str_appendf(s.pOut,
2021020544
"The following SQL will create a table named \"space_used\" which\n"
2021120545
"contains most of the information used to generate the report above.\n"
2021220546
"*/\n"
2021320547
);
@@ -20233,11 +20567,11 @@
2023320567
" ovfl_unused int, -- Unused bytes on overflow pages\n" /* 16 */
2023420568
" int_entries int -- B-tree entries on internal pages\n"/* 17 */
2023520569
");\n"
2023620570
"INSERT INTO space_used VALUES\n"
2023720571
);
20238
- pStmt = analysisPrepare(&s,
20572
+ pStmt = diskusedPrepare(&s,
2023920573
"SELECT quote(name), quote(tblname),\n" /* 0..1 */
2024020574
" is_index, is_without_rowid, nentry, leaf_entries,\n" /* 2..5 */
2024120575
" depth, payload, ovfl_payload, ovfl_cnt, mx_payload,\n" /* 6..10 */
2024220576
" int_pages, leaf_pages, ovfl_pages, int_unused,\n" /* 11..14 */
2024320577
" leaf_unused, ovfl_unused, int_entries\n" /* 15..17 */
@@ -20268,11 +20602,11 @@
2026820602
sqlite3_column_int64(pStmt, 15),
2026920603
sqlite3_column_int64(pStmt, 16),
2027020604
sqlite3_column_int64(pStmt, 17));
2027120605
}
2027220606
if( rc!=SQLITE_DONE ){
20273
- analysisError(&s, "SQL run-time error: %s\nSQL: %s",
20607
+ diskusedError(&s, "SQL run-time error: %s\nSQL: %s",
2027420608
sqlite3_errmsg(s.db), sqlite3_sql(pStmt));
2027520609
sqlite3_finalize(pStmt);
2027620610
return;
2027720611
}
2027820612
sqlite3_str_appendf(s.pOut,";\nCOMMIT;");
@@ -20281,32 +20615,144 @@
2028120615
if( sqlite3_str_length(s.pOut) ){
2028220616
sqlite3_result_text(context, sqlite3_str_finish(s.pOut), -1,
2028320617
sqlite3_free);
2028420618
s.pOut = 0;
2028520619
}
20286
- analysisReset(&s);
20620
+ diskusedReset(&s);
2028720621
}
2028820622
20623
+
20624
+#ifdef _WIN32
20625
+
20626
+#endif
20627
+int sqlite3_diskused_init(
20628
+ sqlite3 *db,
20629
+ char **pzErrMsg,
20630
+ const sqlite3_api_routines *pApi
20631
+){
20632
+ int rc = SQLITE_OK;
20633
+ SQLITE_EXTENSION_INIT2(pApi);
20634
+ (void)pzErrMsg; /* Unused parameter */
20635
+ rc = sqlite3_create_function(db, "diskused", 1,
20636
+ SQLITE_UTF8|SQLITE_DIRECTONLY,
20637
+ 0, diskusedFunc, 0, 0);
20638
+ return rc;
20639
+}
20640
+
20641
+/************************* End ext/misc/diskused.c ********************/
20642
+/************************* Begin ext/misc/strdup.c ******************/
20643
+/*
20644
+** 2026-07-04
20645
+**
20646
+** The author disclaims copyright to this source code. In place of
20647
+** a legal notice, here is a blessing:
20648
+**
20649
+** May you do good and not evil.
20650
+** May you find forgiveness for yourself and forgive others.
20651
+** May you share freely, never taking more than you give.
20652
+**
20653
+******************************************************************************
20654
+**
20655
+** Since this module was written (coincidentally) on the 250th anniversary
20656
+** of the signing of the Declaration of Independence of The United States,
20657
+** it seems fitting to quote from that document:
20658
+**
20659
+** We hold these truths to be self-evident, that all men are created
20660
+** equal, that they are endowed by their Creator with certain unalienable
20661
+** Rights, that among these are Life, Liberty and the pursuit of Happiness
20662
+** - That to secure these rights, Governments are instituted among Men,
20663
+** deriving their just powers from the consent of the governed,....
20664
+**
20665
+** Two core ideas that (1) rights come from God and not from government,
20666
+** and that (2) there should not be special privileged classes of people
20667
+** were radical thoughts then, and are indeed disputed even today. Many
20668
+** people still hold that human rights derive from the beneficence of
20669
+** government and that certain classes of people have special rights and
20670
+** privileges not available to all. Yet, were it not for the crazy ideas
20671
+** espoused in the original Declaration of Independence, this software
20672
+** project, and indeed most of modern technology, would not exist.
20673
+**
20674
+** Therefore let us give thanks for the bold leadership and vision
20675
+** demonstrated by the authors of the American Revolution, 250 years ago
20676
+** this day.
20677
+**
20678
+******************************************************************************
20679
+**
20680
+** Implementation of the strdup() SQL function. strdup() makes a copy
20681
+** of its argument (a string or a BLOB) into memory obtained directly
20682
+** from system malloc() (not from sqlite3_malloc()) and sized exactly
20683
+** to hold the string or BLOB. This is intended for testing purposes,
20684
+** particularly testing with ASAN. This function serves no practical
20685
+** purpose beyond testing and not not intended for production use.
20686
+**
20687
+** NULL, BLOB, and TEXT values come through as NULL, BLOB, and TEXT,
20688
+** respectively. Numeric values are rendered as strings and come out
20689
+** as text.
20690
+*/
20691
+/* #include "sqlite3ext.h" */
20692
+SQLITE_EXTENSION_INIT1
20693
+#include <assert.h>
20694
+#include <string.h>
20695
+#include <stdlib.h>
20696
+
20697
+/*
20698
+** Make a copy of a string or BLOB in memory obtained from malloc().
20699
+*/
20700
+static void strdupfunc(
20701
+ sqlite3_context *context,
20702
+ int argc,
20703
+ sqlite3_value **argv
20704
+){
20705
+ const unsigned char *zIn;
20706
+ int nIn;
20707
+ unsigned char *zOut;
20708
+
20709
+ assert( argc==1 );
20710
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
20711
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
20712
+ zIn = (const unsigned char*)sqlite3_value_blob(argv[0]);
20713
+ nIn = sqlite3_value_bytes(argv[0]);
20714
+ zOut = malloc( nIn==0 ? 1 : nIn );
20715
+ if( zOut==0 ){
20716
+ sqlite3_result_error_nomem(context);
20717
+ return;
20718
+ }
20719
+ if( nIn>0 ) memcpy(zOut, zIn, nIn);
20720
+ sqlite3_result_blob(context, zOut, nIn, free);
20721
+ }else{
20722
+ zIn = (const unsigned char*)sqlite3_value_text(argv[0]);
20723
+ if( zIn==0 ) return;
20724
+ nIn = (int)strlen((char*)zIn);
20725
+ zOut = malloc( nIn+1 );
20726
+ if( zOut==0 ){
20727
+ sqlite3_result_error_nomem(context);
20728
+ return;
20729
+ }
20730
+ memcpy(zOut, zIn, nIn);
20731
+ zOut[nIn] = 0;
20732
+ sqlite3_result_text64(context, (char*)zOut, nIn, free,
20733
+ SQLITE_UTF8_ZT);
20734
+ }
20735
+}
2028920736
2029020737
#ifdef _WIN32
2029120738
2029220739
#endif
20293
-int sqlite3_analyze_init(
20740
+int sqlite3_strdup_init(
2029420741
sqlite3 *db,
2029520742
char **pzErrMsg,
2029620743
const sqlite3_api_routines *pApi
2029720744
){
2029820745
int rc = SQLITE_OK;
2029920746
SQLITE_EXTENSION_INIT2(pApi);
2030020747
(void)pzErrMsg; /* Unused parameter */
20301
- rc = sqlite3_create_function(db, "analyze", 1,
20302
- SQLITE_UTF8|SQLITE_INNOCUOUS,
20303
- 0, analyzeFunc, 0, 0);
20748
+ rc = sqlite3_create_function(db, "strdup", 1, SQLITE_UTF8,
20749
+ 0, strdupfunc, 0, 0);
2030420750
return rc;
2030520751
}
2030620752
20307
-/************************* End ext/misc/analyze.c ********************/
20753
+/************************* End ext/misc/strdup.c ********************/
2030820754
2030920755
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
2031020756
#define SQLITE_SHELL_HAVE_RECOVER 1
2031120757
#else
2031220758
#define SQLITE_SHELL_HAVE_RECOVER 0
@@ -22123,23 +22569,44 @@
2212322569
int rc = sqlite3_finalize(pStmt);
2212422570
if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){
2212522571
recoverDbError(p, db);
2212622572
}
2212722573
}
22574
+
22575
+/*
22576
+** Run a single SQL statement in zSql. If zSql contains two or more
22577
+** SQL statements separated by ';', only the first is run.
22578
+**
22579
+** Return the sqlite3_finalizer() or sqlite3_prepare() result code
22580
+** from running the zSql statement.
22581
+*/
22582
+static int recoverOneStmt(sqlite3 *db, const char *zSql){
22583
+ sqlite3_stmt *pStmt = 0;
22584
+ int rc;
22585
+ if( zSql==0 ) return SQLITE_OK;
22586
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
22587
+ if( rc ){
22588
+ sqlite3_finalize(pStmt);
22589
+ return rc;
22590
+ }
22591
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){}
22592
+ return sqlite3_finalize(pStmt);
22593
+}
2212822594
2212922595
/*
2213022596
** This function is a no-op if recover handle p already contains an error
2213122597
** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this
2213222598
** case.
2213322599
**
22134
-** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK.
22135
-** Or, if an error occurs, leave an error code and message in the recover
22136
-** handle and return a copy of the error code.
22600
+** Otherwise, execute a single SQL statment in zSql. Even if zSql contains
22601
+** two or more SQL statements separated by ';', only execute the first one.
22602
+** If successful, return SQLITE_OK. Or, if an error occurs, leave an error
22603
+** code and message in the recover handle and return a copy of the error code.
2213722604
*/
2213822605
static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){
2213922606
if( p->errCode==SQLITE_OK ){
22140
- int rc = sqlite3_exec(db, zSql, 0, 0, 0);
22607
+ int rc = recoverOneStmt(db, zSql);
2214122608
if( rc ){
2214222609
recoverDbError(p, db);
2214322610
}
2214422611
}
2214522612
return p->errCode;
@@ -22535,11 +23002,12 @@
2253523002
recoverError(p, SQLITE_NOMEM, 0);
2253623003
}
2253723004
}
2253823005
recoverFinalize(p, p1);
2253923006
}
22540
- recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;");
23007
+ recoverExec(p, db2, "CREATE TABLE t1(a)");
23008
+ recoverExec(p, db2, "DROP TABLE t1");
2254123009
2254223010
if( p->errCode==SQLITE_OK ){
2254323011
sqlite3 *db = p->dbOut;
2254423012
sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main");
2254523013
if( pBackup ){
@@ -22617,16 +23085,16 @@
2261723085
** discarded.
2261823086
*/
2261923087
static void recoverOpenRecovery(sqlite3_recover *p){
2262023088
char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb);
2262123089
recoverExec(p, p->dbOut, zSql);
23090
+ sqlite3_free(zSql);
23091
+ recoverExec(p, p->dbOut, "PRAGMA writable_schema = 1");
23092
+ recoverExec(p, p->dbOut,
23093
+ "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT)");
2262223094
recoverExec(p, p->dbOut,
22623
- "PRAGMA writable_schema = 1;"
22624
- "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
22625
- "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
22626
- );
22627
- sqlite3_free(zSql);
23095
+ "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql)");
2262823096
}
2262923097
2263023098
2263123099
/*
2263223100
** This function is a no-op if recover handle p already contains an error
@@ -22762,11 +23230,11 @@
2276223230
" (type='index' AND (sql LIKE '%unique%' OR ?1))"
2276323231
" FROM recovery.schema"
2276423232
")"
2276523233
"SELECT rootpage, tbl, isVirtual, name, sql"
2276623234
" FROM dbschema "
22767
- " WHERE tbl OR isIndex"
23235
+ " WHERE (tbl OR isIndex) AND sql GLOB 'CREATE *'"
2276823236
" ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
2276923237
);
2277023238
2277123239
pTblname = recoverPrepare(p, p->dbOut,
2277223240
"SELECT name FROM sqlite_schema "
@@ -22788,11 +23256,11 @@
2278823256
zSql = (const char*)(zFree = recoverMPrintf(p,
2278923257
"INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
2279023258
zName, zName, zSql
2279123259
));
2279223260
}
22793
- rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
23261
+ rc = recoverOneStmt(p->dbOut, zSql);
2279423262
if( rc==SQLITE_OK ){
2279523263
recoverSqlCallback(p, zSql);
2279623264
if( bTable && !bVirtual ){
2279723265
if( SQLITE_ROW==sqlite3_step(pTblname) ){
2279823266
const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
@@ -22830,19 +23298,21 @@
2283023298
2283123299
pSelect = recoverPrepare(p, p->dbOut,
2283223300
p->bSlowIndexes ?
2283323301
"SELECT rootpage, sql FROM recovery.schema "
2283423302
" WHERE type!='table' AND type!='index'"
23303
+ " AND sql GLOB 'CREATE *'"
2283523304
:
2283623305
"SELECT rootpage, sql FROM recovery.schema "
2283723306
" WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
23307
+ " AND sql GLOB 'CREATE *'"
2283823308
);
2283923309
2284023310
if( pSelect ){
2284123311
while( sqlite3_step(pSelect)==SQLITE_ROW ){
2284223312
const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
22843
- int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
23313
+ int rc = recoverOneStmt(p->dbOut, zSql);
2284423314
if( rc==SQLITE_OK ){
2284523315
recoverSqlCallback(p, zSql);
2284623316
}else if( rc!=SQLITE_ERROR ){
2284723317
recoverDbError(p, p->dbOut);
2284823318
}
@@ -24216,11 +24686,11 @@
2421624686
recoverCacheSchema(p);
2421724687
2421824688
if( bUseWrapper ) recoverUninstallWrapper(p);
2421924689
}while( p->errCode==SQLITE_NOTADB
2422024690
&& (bUseWrapper--)
24221
- && SQLITE_OK==sqlite3_exec(p->dbIn, "ROLLBACK", 0, 0, 0)
24691
+ && SQLITE_OK==recoverOneStmt(p->dbIn, "ROLLBACK")
2422224692
);
2422324693
}
2422424694
2422524695
recoverLeaveMutex();
2422624696
recoverExec(p, p->dbOut, "BEGIN");
@@ -24281,11 +24751,11 @@
2428124751
2428224752
/* If no error has occurred, commit the write transaction on the output
2428324753
** database. Regardless of whether or not an error has occurred, make
2428424754
** an attempt to end the read transaction on the input database. */
2428524755
recoverExec(p, p->dbOut, "COMMIT");
24286
- rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
24756
+ rc = recoverOneStmt(p->dbIn, "END");
2428724757
if( p->errCode==SQLITE_OK ) p->errCode = rc;
2428824758
2428924759
recoverSqlCallback(p, "PRAGMA writable_schema = off");
2429024760
recoverSqlCallback(p, "COMMIT");
2429124761
p->eState = RECOVER_STATE_DONE;
@@ -24477,11 +24947,11 @@
2447724947
if( p==0 ){
2447824948
rc = SQLITE_NOMEM;
2447924949
}else{
2448024950
recoverFinalCleanup(p);
2448124951
if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){
24482
- rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
24952
+ rc = recoverOneStmt(p->dbIn, "END");
2448324953
if( p->errCode==SQLITE_OK ) p->errCode = rc;
2448424954
}
2448524955
rc = p->errCode;
2448624956
sqlite3_free(p->zErrMsg);
2448724957
sqlite3_free(p->zStateDb);
@@ -24499,10 +24969,20 @@
2449924969
#endif
2450024970
#ifdef SQLITE_SHELL_EXTSRC
2450124971
# include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
2450224972
#endif
2450324973
24974
+/*
24975
+** Set the SQLITE_SHELL_EDITION to a YYYYMMDD date string and the
24976
+** code will attempt to use defaults for the prompt and for the
24977
+** initial output mode (and maybe other feature) that were for
24978
+** the most recent version not newer than the specified date.
24979
+*/
24980
+#ifndef SQLITE_SHELL_EDITION
24981
+# define SQLITE_SHELL_EDITION 99991231 /* Use the latest if unspecified */
24982
+#endif
24983
+
2450424984
#if defined(SQLITE_ENABLE_SESSION)
2450524985
/*
2450624986
** State information for a single open session
2450724987
*/
2450824988
typedef struct OpenSession OpenSession;
@@ -24530,10 +25010,12 @@
2453025010
u8 autoEQPtrace; /* autoEQP is in trace mode */
2453125011
u8 scanstatsOn; /* True to display scan stats before each finalize */
2453225012
u8 bAutoScreenWidth; /* Using the TTY to determine screen width */
2453325013
u8 mFlags; /* MFLG_ECHO, MFLG_CRLF, etc. */
2453425014
u8 eMode; /* One of the MODE_ values */
25015
+ char zIFmt[24]; /* Space to hold the --ifmt value */
25016
+ char zFpFmt[24]; /* Space to hold the --fpfmt value */
2453525017
sqlite3_qrf_spec spec; /* Spec to be passed into QRF */
2453625018
} Mode;
2453725019
2453825020
/* Flags for Mode.mFlags */
2453925021
#define MFLG_ECHO 0x01 /* Echo inputs to output */
@@ -24564,10 +25046,11 @@
2456425046
unsigned statsOn; /* True to display memory stats before each finalize */
2456525047
unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
2456625048
u8 nPopOutput; /* Revert .output settings when reaching zero */
2456725049
u8 nPopMode; /* Revert .mode settings when reaching zero */
2456825050
u8 enableTimer; /* Enable the timer. 2: permanently 1: only once */
25051
+ u8 bDelimitNonprint; /* Add \001...\002 around non-printing in prompts */
2456925052
int inputNesting; /* Track nesting level of .read and other redirects */
2457025053
double prevTimer; /* Last reported timer value */
2457125054
double tmProgress; /* --timeout option for .progress */
2457225055
i64 lineno; /* Line number of last line read from in */
2457325056
const char *zInFile; /* Name of the input file */
@@ -24745,11 +25228,11 @@
2474525228
unsigned char eHdr; /* Default header encoding. */
2474625229
unsigned char eBlob; /* Default blob encoding. */
2474725230
unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
2474825231
unsigned char eStyle; /* Underlying QRF style */
2474925232
unsigned char eCx; /* 0: other, 1: line, 2: columnar */
24750
- unsigned char mFlg; /* Flags. 1=border-off 2=split-column */
25233
+ unsigned char mFlg; /* Flags. 1=border-off 2=split-column 4=rowcount */
2475125234
};
2475225235
2475325236
/* String constants used by built-in modes */
2475425237
static const char *aModeStr[] =
2475525238
/* 0 1 2 3 4 5 6 7 8 */
@@ -24758,45 +25241,45 @@
2475825241
/* 9 10 11 12 13 */
2475925242
2476025243
static const ModeInfo aModeInfo[] = {
2476125244
/* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
2476225245
{ "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
24763
- { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2, 0 },
25246
+ { "box", 0, 0, 9, 1, 1, 0, 3, 1, 2, 0 },
2476425247
{ "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
24765
- { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2, 0 },
25248
+ { "column", 0, 0, 9, 1, 1, 0, 3, 2, 2, 0 },
2476625249
{ "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
2476725250
{ "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
24768
- { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 },
25251
+ { "html", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 },
2476925252
{ "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
2477025253
{ "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
2477125254
{ "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
2477225255
{ "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
2477325256
{ "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
2477425257
{ "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
24775
- { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2, 0 },
25258
+ { "markdown", 0, 0, 9, 1, 1, 0, 3, 13, 2, 0 },
2477625259
{ "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
24777
- { "psql", 0, 0, 9, 1, 1, 0, 2, 19, 2, 1 },
24778
- { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2, 0 },
25260
+ { "psql", 0, 0, 9, 1, 1, 0, 3, 19, 2, 5 },
25261
+ { "qbox", 0, 0, 10, 2, 1, 0, 3, 1, 2, 0 },
2477925262
{ "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
2478025263
{ "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
24781
- { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2, 0 },
25264
+ { "table", 0, 0, 9, 1, 1, 0, 3, 19, 2, 0 },
2478225265
{ "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
2478325266
{ "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
24784
- { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 }
24785
-}; /* | / / | / / | | \
24786
- ** | / / | / / | | \_ 2: columnar
24787
- ** Index into aModeStr[] | / / | | 1: line
24788
- ** | / / | | 0: other
24789
- ** | / / | \
24790
- ** text encoding |/ | show | \
24791
- ** v-------------------' | hdrs? | The QRF style
24792
- ** 0: n/a blob | v-----'
24793
- ** 1: plain v----------' 0: n/a
24794
- ** 2: sql 0: auto 1: no
24795
- ** 3: csv 1: as-text 2: yes
24796
- ** 4: html 2: sql
24797
- ** 5: c 3: hex
25267
+ { "www", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 }
25268
+}; /* | / / | / / | | / \____
25269
+ ** | / / | / / | | / |
25270
+ ** Index into aModeStr[] | / / | | 2: columnar |
25271
+ ** | / / | | 1: line |
25272
+ ** | / / | | 0: other |
25273
+ ** text encoding |/ | show | | |
25274
+ ** v-------------------' | hdrs? | The QRF style |
25275
+ ** 0: n/a blob | v-----' /
25276
+ ** 1: plain v----------' 0: n/a _________/
25277
+ ** 2: sql 0: auto 1: no |
25278
+ ** 3: csv 1: as-text 2: yes 1: border-off
25279
+ ** 4: html 2: sql 3: always 2: split-column
25280
+ ** 5: c 3: hex 4: rowcount
2479825281
** 6: json 4: c
2479925282
** 5: json
2480025283
** 6: size
2480125284
******************************************************************/
2480225285
@@ -25079,11 +25562,11 @@
2507925562
*/
2508025563
static char *local_getline(char *zLine, FILE *in){
2508125564
int nLine = zLine==0 ? 0 : 100;
2508225565
int n = 0;
2508325566
25084
- while( 1 ){
25567
+ while( seenInterrupt<2 ){
2508525568
if( n+100>nLine ){
2508625569
if( nLine>=1073741773 ){
2508725570
free(zLine);
2508825571
return 0;
2508925572
}
@@ -25107,10 +25590,22 @@
2510725590
break;
2510825591
}
2510925592
}
2511025593
return zLine;
2511125594
}
25595
+
25596
+/*
25597
+** Return true if either the SQLITE_NO_COLOR compile-time option is used
25598
+** or if the NO_COLOR environment variable exists
25599
+*/
25600
+static int shellNoColor(void){
25601
+#if defined(SQLITE_NO_COLOR) || defined(SQLITE_SHELL_FIDDLE)
25602
+ return 1;
25603
+#else
25604
+ return getenv("NO_COLOR")!=0;
25605
+#endif
25606
+}
2511225607
2511325608
/*
2511425609
** The SQLITE_PS_APPDEF macro should be set to the name of a function
2511525610
** that accepts a single "int" argument and returns a "const char *"
2511625611
** that is guaranteed to be non-NULL. The value returned depends on the
@@ -25131,35 +25626,47 @@
2513125626
# define SQLITE_PS_APPDEF shellPromptAppDef
2513225627
static const char *shellPromptAppDef(int c){
2513325628
switch( c ){
2513425629
/* The default main prompt string */
2513525630
case 1:
25136
-#if defined(SQLITE_PS1)
25631
+#if SQLITE_SHELL_EDITION<20260423
25632
+ return "sqlite> "; /* Legacy prompt for backwards compatibility */
25633
+#elif defined(SQLITE_PS1)
2513725634
return SQLITE_PS1;
25138
-#elif defined(SQLITE_PS_NOANSI)
25139
- return "/A-/v /~> ";
2514025635
#else
25141
- return "/e[1;32m/A-/v /e[1;/x33/:36/;m/m/e[3m/;/f/;/e[0m-> ";
25636
+ if( shellNoColor() ){
25637
+ return "/A-/v /f-> ";
25638
+ }else{
25639
+ return "/e[1;32m/A-/v /e[1;/x33/:36/;m/m/e[3m/;/f/;/e[0m-> ";
25640
+ }
2514225641
#endif
2514325642
2514425643
/* The default continuation prompt string */
2514525644
case 2:
25146
-#if defined(SQLITE_PS2)
25645
+#if SQLITE_SHELL_EDITION<20260423
25646
+ return " ...> "; /* Legacy continuation prompt */
25647
+#elif defined(SQLITE_PS2)
2514725648
return SQLITE_PS2;
25148
-#elif defined(SQLITE_PS_NOANSI)
25149
- return "/B/C> ";
2515025649
#else
25151
- return "/B/e[1;/x33/:36/;m/C/e[0m-> ";
25650
+ if( shellNoColor() ){
25651
+ return "/B/C-> ";
25652
+ }else{
25653
+ return "/B/e[1;/x33/:36/;m/C/e[0m-> ";
25654
+ }
2515225655
#endif
2515325656
2515425657
/* Name of environment variables that override the prompt strings
2515525658
** of cases 1 and 2 */
2515625659
case 3: return "SQLITE_PS1";
2515725660
case 4: return "SQLITE_PS2";
2515825661
2515925662
/* Name of the application */
25663
+#ifndef SQLITE_CLI_APPNAME
2516025664
case 'A': return "SQLite";
25665
+#else
25666
+ case 'A': return SHELL_STRINGIFY(SQLITE_CLI_APPNAME);
25667
+#endif
2516125668
2516225669
/* Full version number of the application, including patch level */
2516325670
case 'V': return sqlite3_libversion();
2516425671
2516525672
/* Version number without the patch level */
@@ -25218,13 +25725,13 @@
2521825725
}else if( p->db && (pFN = sqlite3_db_filename(p->db,0))!=0 ){
2521925726
zFN = sqlite3_filename_database(pFN);
2522025727
}
2522125728
if( zFN==0 || zFN[0]==0 ){
2522225729
zFN = p->pAuxDb->zDbFilename;
25223
- if( zFN==0 || zFN[0]==0 || cli_strcmp(zFN,":memory:")==0 ){
25224
- zFN = zMemoryName;
25225
- }
25730
+ }
25731
+ if( zFN==0 || zFN[0]==0 || cli_strcmp(zFN,":memory:")==0 ){
25732
+ zFN = zMemoryName;
2522625733
}
2522725734
return zFN;
2522825735
}
2522925736
2523025737
/*
@@ -25263,10 +25770,26 @@
2526325770
if( z==0 || z[0]==0 ) z = getenv("LOGNAME");
2526425771
if( z==0 || z[0]==0 ) z = "?";
2526525772
#endif
2526625773
return z;
2526725774
}
25775
+
25776
+/* If z[] begins with one or more ANSI X3.64 (VT100) escape sequences
25777
+** return the number of bytes in all such escape sequences. Return
25778
+** zero if there are no valid escape sequences.
25779
+*/
25780
+static int nAnsiEscape(const char *z){
25781
+ int i = 0;
25782
+ while( z[i]=='\033' && z[i+1]=='[' ){
25783
+ int k = i+2;
25784
+ while( z[k]>=0x30 && z[k]<=0x3f ){ k++; }
25785
+ while( z[k]>=0x20 && z[k]<=0x2f ){ k++; }
25786
+ if( z[k]<0x40 || z[k]>0x7e ) break;
25787
+ i = k+1;
25788
+ }
25789
+ return i;
25790
+}
2526825791
2526925792
/*
2527025793
** Expand escapes in the given input prompt string. Return the
2527125794
** expanded prompt in memory obtained from sqlite3_malloc(). The
2527225795
** caller is responsible for freeing the memory.
@@ -25311,10 +25834,11 @@
2531125834
continue;
2531225835
}
2531325836
if( c>='0' && c<='7' ){
2531425837
/* /nnn becomes a single byte given by octal nnn */
2531525838
int v = c - '0';
25839
+ i++;
2531625840
while( i<=2 && zPrompt[i+1]>='0' && zPrompt[i+1]<='7' ){
2531725841
v = v*8 + zPrompt[++i] - '0';
2531825842
}
2531925843
if( !mOff ) sqlite3_str_appendchar(pOut, 1, v);
2532025844
zPrompt += i+1;
@@ -25533,15 +26057,36 @@
2553326057
memmove(z+idxSpace+nNew, z+idxSpace, len-nNew-idxSpace);
2553426058
memset(z+idxSpace, ' ', nNew);
2553526059
}
2553626060
}
2553726061
}
25538
-
2553926062
if( 0==sqlite3_str_length(pOut) ){
2554026063
/* Avoid a bogus OOM */
2554126064
sqlite3_str_appendchar(pOut, 1, '\0');
2554226065
}
26066
+
26067
+ /* Editline does not recognize ANSI X3.64 escape sequences. So we have
26068
+ ** to find them all and enclose them inside '\001'...'\002' delimiters.
26069
+ ** Some versions of readline also require this, but others do not.
26070
+ */
26071
+ if( p->bDelimitNonprint && strstr(sqlite3_str_value(pOut),"\033[")!=0 ){
26072
+ char *zOrig = sqlite3_str_finish(pOut);
26073
+ int n;
26074
+ pOut = sqlite3_str_new(0);
26075
+ for(i=0; zOrig[i]; i++){
26076
+ if( zOrig[i]=='\033' && (n = nAnsiEscape(zOrig+i))>0 ){
26077
+ sqlite3_str_appendchar(pOut, 1, 1);
26078
+ sqlite3_str_append(pOut, &zOrig[i], n);
26079
+ sqlite3_str_appendchar(pOut, 1, 2);
26080
+ i += n-1;
26081
+ }else{
26082
+ sqlite3_str_appendchar(pOut, 1, zOrig[i]);
26083
+ }
26084
+ }
26085
+ sqlite3_free(zOrig);
26086
+ }
26087
+
2554326088
return sqlite3_str_finish(pOut);
2554426089
}
2554526090
2554626091
/*
2554726092
** Retrieve a single line of input text.
@@ -25570,30 +26115,33 @@
2557026115
zResult = local_getline(zPrior, in);
2557126116
}else{
2557226117
const char *zBase = prompt_string(p, bContinue!=0);
2557326118
char *zPrompt = expand_prompt(p, zAll, zBase);
2557426119
shell_check_oom(zPrompt);
25575
-#if SHELL_USE_LOCAL_GETLINE
25576
- sputz(stdout, zPrompt);
25577
- fflush(stdout);
25578
- do{
25579
- zResult = local_getline(zPrior, stdin);
25580
- zPrior = 0;
25581
- /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
25582
- if( zResult==0 ) sqlite3_sleep(50);
25583
- }while( zResult==0 && seenInterrupt>0 );
25584
-#else
25585
- free(zPrior);
25586
- zResult = shell_readline(zPrompt);
25587
- while( zResult==0 ){
25588
- /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
25589
- sqlite3_sleep(50);
25590
- if( seenInterrupt==0 ) break;
25591
- zResult = shell_readline("");
25592
- }
25593
- if( zResult && *zResult ) shell_add_history(zResult);
25594
-#endif
26120
+#if SHELL_CMDLINE_EDIT_AVAILABLE
26121
+ if( shellCmdLineEdit ){
26122
+ free(zPrior);
26123
+ zResult = shell_readline(zPrompt);
26124
+ while( zResult==0 ){
26125
+ /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
26126
+ sqlite3_sleep(50);
26127
+ if( seenInterrupt==0 ) break;
26128
+ zResult = shell_readline("");
26129
+ }
26130
+ if( zResult && *zResult ) shell_add_history(zResult);
26131
+ }else
26132
+#endif
26133
+ {
26134
+ sputz(stdout, zPrompt);
26135
+ fflush(stdout);
26136
+ do{
26137
+ zResult = local_getline(zPrior, stdin);
26138
+ zPrior = 0;
26139
+ /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
26140
+ if( zResult==0 ) sqlite3_sleep(50);
26141
+ }while( zResult==0 && seenInterrupt>0 );
26142
+ }
2559526143
sqlite3_free(zPrompt);
2559626144
}
2559726145
return zResult;
2559826146
}
2559926147
#endif /* !SQLITE_SHELL_FIDDLE */
@@ -25834,11 +26382,12 @@
2583426382
double r = sqlite3_value_double(apVal[0]);
2583526383
int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
2583626384
char z[400];
2583726385
if( n<1 ) n = 1;
2583826386
if( n>350 ) n = 350;
25839
- sprintf(z, "%#+.*e", n, r);
26387
+ z[sizeof(z)-1] = 0;
26388
+ snprintf(z, sizeof(z)-1, "%#+.*e", n, r);
2584026389
sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
2584126390
}
2584226391
2584326392
/*
2584426393
** SQL function: shell_add_schema(S,X)
@@ -25912,21 +26461,27 @@
2591226461
}
2591326462
sqlite3_result_value(pCtx, apVal[0]);
2591426463
}
2591526464
2591626465
/*
25917
-** SQL function: shell_prompt_test(PROMPT)
25918
-** shell_prompt_test(PROMPT,PRIOR)
25919
-** shell_prompt_test(PROMPT,PRIOR,FILENAME)
26466
+** SQL function: shell_prompt_test(PROMPT,PRIOR,FILENAME,FLAGS)
2592026467
**
2592126468
** Return the shell prompt, with escapes expanded, for testing purposes.
2592226469
** The first argument is the raw (unexpanded) prompt string. Or if the
2592326470
** first argument is NULL, then use whatever prompt string is currently
2592426471
** configured. If the second argument exists and is not NULL, then the
2592526472
** second argument is understood to be prior incomplete text and a
2592626473
** continuation prompt is generated. If a third argument is provided,
25927
-** it is assumed to be the full pathname of the database file.
26474
+** it is assumed to be the full pathname of the database file. The
26475
+** fourth argument, if provided, is an integer of flags:
26476
+**
26477
+** 0x0001 Always insert \001..\002 delimiters around ANSI escapes
26478
+** 0x0002 Never insert \001..\002 delimiters
26479
+**
26480
+** This function is for testing purposes only. The interface may change.
26481
+** The function itself might be renamed or removed in future releases. Do
26482
+** not use this function in applications.
2592826483
*/
2592926484
static void shellExpandPrompt(
2593026485
sqlite3_context *pCtx,
2593126486
int nVal,
2593226487
sqlite3_value **apVal
@@ -25936,11 +26491,14 @@
2593626491
const char *zPrior;
2593726492
const char *zSavedDbFile;
2593826493
int mSavedFlgs;
2593926494
const char *zFName;
2594026495
char *zRes;
26496
+ int mFlags;
26497
+ char bSavedDelimit = p->bDelimitNonprint;
2594126498
26499
+ if( nVal<1 ) return;
2594226500
if( nVal<2
2594326501
|| (zPrior = (const char*)sqlite3_value_text(apVal[1]))==0
2594426502
|| zPrior[0]==0
2594526503
){
2594626504
zPrior = 0;
@@ -25952,12 +26510,19 @@
2595226510
zSavedDbFile = p->pAuxDb->zDbFilename;
2595326511
mSavedFlgs = p->pAuxDb->mFlgs;
2595426512
if( nVal>=3 && (zFName = (const char*)sqlite3_value_text(apVal[2]))!=0 ){
2595526513
p->pAuxDb->zDbFilename = zFName;
2595626514
p->pAuxDb->mFlgs |= 0x001;
26515
+ }
26516
+ mFlags = nVal>=4 ? sqlite3_value_int(apVal[3]) : 0;
26517
+ if( mFlags & 0x0001 ){
26518
+ p->bDelimitNonprint = 1;
26519
+ }else if( mFlags & 0x0002 ){
26520
+ p->bDelimitNonprint = 0;
2595726521
}
2595826522
zRes = expand_prompt(p, zPrior, zPrompt);
26523
+ p->bDelimitNonprint = bSavedDelimit;
2595926524
p->pAuxDb->zDbFilename = zSavedDbFile;
2596026525
p->pAuxDb->mFlgs = mSavedFlgs;
2596126526
sqlite3_result_text(pCtx, zRes, -1, SQLITE_TRANSIENT);
2596226527
sqlite3_free(zRes);
2596326528
}
@@ -26150,11 +26715,11 @@
2615026715
free(p->spec.zColumnSep);
2615126716
free(p->spec.zRowSep);
2615226717
free(p->spec.zTableName);
2615326718
free(p->spec.zNull);
2615426719
memset(p, 0, sizeof(*p));
26155
- p->spec.iVersion = 1;
26720
+ p->spec.iVersion = 2;
2615626721
p->autoExplain = autoExplain;
2615726722
}
2615826723
2615926724
/*
2616026725
** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26190,10 +26755,18 @@
2619026755
pDest->spec.zTableName = strdup(pSrc->spec.zTableName);
2619126756
}
2619226757
if( pDest->spec.zNull ){
2619326758
pDest->spec.zNull = strdup(pSrc->spec.zNull);
2619426759
}
26760
+ if( pDest->spec.zFpFmt ){
26761
+ assert( pDest->spec.zFpFmt==pSrc->zFpFmt );
26762
+ pDest->spec.zFpFmt = pDest->zFpFmt;
26763
+ }
26764
+ if( pDest->spec.zIFmt ){
26765
+ assert( pDest->spec.zIFmt==pSrc->zIFmt );
26766
+ pDest->spec.zIFmt = pDest->zIFmt;
26767
+ }
2619526768
}
2619626769
2619726770
/*
2619826771
** Set a string value to a copy of the zNew string in memory
2619926772
** obtained from system malloc().
@@ -26208,10 +26781,47 @@
2620826781
if( *az ){
2620926782
memcpy(*az, zNew, n+1 );
2621026783
}
2621126784
}
2621226785
}
26786
+
26787
+/* Forward reference */
26788
+static int pickStr(const char *zArg, char **pzErr, ...);
26789
+
26790
+/*
26791
+** Change the limits on the display mode. Return 0 on
26792
+** success. Return non-zero if zArg is mis-formatted.
26793
+**
26794
+** Valid arguments:
26795
+**
26796
+** "on" Default limits
26797
+** "off" All limits turned off
26798
+** L,C Line and Characters limits set
26799
+** L,C,T Line, Character, and Title limits set
26800
+**
26801
+** Anything else returns non-zero
26802
+*/
26803
+static int modeSetLimit(ShellState *p, const char *zArg){
26804
+ int k = zArg==0 ? 1 : pickStr(zArg,0,"on","off","");
26805
+ if( k==0 ){
26806
+ p->mode.spec.nLineLimit = DFLT_LINE_LIMIT;
26807
+ p->mode.spec.nCharLimit = DFLT_CHAR_LIMIT;
26808
+ p->mode.spec.nTitleLimit = DFLT_TITLE_LIMIT;
26809
+ }else if( k==1 ){
26810
+ p->mode.spec.nLineLimit = 0;
26811
+ p->mode.spec.nCharLimit = 0;
26812
+ p->mode.spec.nTitleLimit = 0;
26813
+ }else{
26814
+ int L, C, T = 0;
26815
+ int nNum = sscanf(zArg, "%d,%d,%d", &L, &C, &T);
26816
+ if( nNum<2 || L<0 || C<0 || T<0) return 1;
26817
+ p->mode.spec.nLineLimit = L;
26818
+ p->mode.spec.nCharLimit = C;
26819
+ if( nNum==3 ) p->mode.spec.nTitleLimit = T;
26820
+ }
26821
+ return 0;
26822
+}
2621326823
2621426824
/*
2621526825
** Change the mode to eMode
2621626826
*/
2621726827
static void modeChange(ShellState *p, unsigned char eMode){
@@ -26238,17 +26848,23 @@
2623826848
pM->spec.bSplitColumn = QRF_Yes;
2623926849
pM->bAutoScreenWidth = 1;
2624026850
}else{
2624126851
pM->spec.bSplitColumn = QRF_No;
2624226852
}
26853
+ if( pI->mFlg & 0x04 ){
26854
+ pM->spec.bRowCount = QRF_Yes;
26855
+ }else{
26856
+ pM->spec.bRowCount = QRF_No;
26857
+ }
2624326858
}else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
2624426859
modeFree(&p->mode);
2624526860
modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
2624626861
}else if( eMode==MODE_BATCH ){
2624726862
u8 mFlags = p->mode.mFlags;
2624826863
modeFree(&p->mode);
2624926864
modeChange(p, MODE_List);
26865
+ modeSetLimit(p, "off");
2625026866
p->mode.mFlags = mFlags;
2625126867
}else if( eMode==MODE_TTY ){
2625226868
u8 mFlags = p->mode.mFlags;
2625326869
modeFree(&p->mode);
2625426870
modeChange(p, MODE_QBox);
@@ -26266,13 +26882,15 @@
2626626882
/*
2626726883
** Set the mode to the default. It assumed that the mode has
2626826884
** already been freed and zeroed prior to calling this routine.
2626926885
*/
2627026886
static void modeDefault(ShellState *p){
26271
- p->mode.spec.iVersion = 1;
26887
+ p->mode.spec.iVersion = 2;
2627226888
p->mode.autoExplain = 1;
26273
- if( stdin_is_interactive || stdout_is_console ){
26889
+ if( (stdin_is_interactive || stdout_is_console)
26890
+ && SQLITE_SHELL_EDITION>=20260409
26891
+ ){
2627426892
modeChange(p, MODE_TTY);
2627526893
}else{
2627626894
modeChange(p, MODE_BATCH);
2627726895
}
2627826896
}
@@ -26881,11 +27499,11 @@
2688127499
return SQLITE_OK;
2688227500
}
2688327501
#endif
2688427502
2688527503
/*
26886
-** Print a schema statement. This is helper routine to dump_callbac().
27504
+** Print a schema statement. This is a helper routine to dump_callback().
2688727505
**
2688827506
** This routine converts some CREATE TABLE statements for shadow tables
2688927507
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
2689027508
**
2689127509
** If the schema statement in z[] contains a start-of-comment and if
@@ -28333,12 +28951,12 @@
2833328951
".databases List names and files of attached databases",
2833428952
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
2833528953
#if SQLITE_SHELL_HAVE_RECOVER
2833628954
".dbinfo ?DB? Show status information about the database",
2833728955
#endif
28338
- ".dbstat ?SCHEMA? Report database space and size stats",
2833928956
".dbtotxt Hex dump of the database file",
28957
+ ".diskused ?SCHEMA? Report database space and size stats",
2834028958
".dump ?OBJECTS? Render database content as SQL",
2834128959
" Options:",
2834228960
" --data-only Output only INSERT statements",
2834328961
" --newlines Allow unescaped newline characters in output",
2834428962
" --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -28445,10 +29063,13 @@
2844529063
" --reset Reset the count for each input and interrupt",
2844629064
" --timeout S Halt after running for S seconds",
2844729065
#endif
2844829066
".prompt MAIN CONTINUE Replace the standard prompts",
2844929067
" --hard-reset Unset SQLITE_PS1/2 and then --reset",
29068
+#ifndef SQLITE_NO_COLOR
29069
+ " --no-color Disable color prompts. Use --color to re-enable",
29070
+#endif
2845029071
" --reset Revert to default prompts",
2845129072
" --show Show the current prompt strings",
2845229073
" -- No more options. Subsequent args are prompts",
2845329074
#ifndef SQLITE_SHELL_FIDDLE
2845429075
".quit Stop interpreting input stream, exit if primary.",
@@ -28609,10 +29230,14 @@
2860929230
" truncated. Zero means \"no limit\".\n"
2861029231
" --colsep STRING Use STRING as the column separator\n"
2861129232
" --escape ESC Enable/disable escaping of control characters\n"
2861229233
" found in the output. ESC can be \"off\", \"ascii\",\n"
2861329234
" or \"symbol\".\n"
29235
+" --fpfmt STRING String is a printf-style format string used to\n"
29236
+" render floating-point values.\n"
29237
+" --ifmt STRING String is a printf-style format string used to\n"
29238
+" render integer values.\n"
2861429239
" --linelimit N Set the maximum number of output lines to show for\n"
2861529240
" any single SQL value to N. Longer values are\n"
2861629241
" truncated. Zero means \"no limit\". Only works\n"
2861729242
" in \"line\" mode and in columnar modes.\n"
2861829243
" --limits L,C,T Shorthand for \"--linelimit L --charlimit C\n"
@@ -28629,10 +29254,11 @@
2862929254
" --quote ARG Enable/disable quoting of text. ARG can be\n"
2863029255
" \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
2863129256
" \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
2863229257
" \"on\" is an alias for \"sql\".\n"
2863329258
" --reset Changes all mode settings back to their default.\n"
29259
+" --rowcount BOOLEAN Show \"(N rows)\" at the end of query results.\n"
2863429260
" --rowsep STRING Use STRING as the row separator\n"
2863529261
" --sw|--screenwidth N Declare the screen width of the output device\n"
2863629262
" to be N characters. An attempt may be made to\n"
2863729263
" wrap output text to fit within this limit. Zero\n"
2863829264
" means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28640,11 +29266,11 @@
2864029266
" --tablename NAME Set the name of the table for \"insert\" mode.\n"
2864129267
" --tag NAME Save mode to the left as NAME.\n"
2864229268
" --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
2864329269
" --title ARG Whether or not to show column headers, and if so\n"
2864429270
" how to encode them. ARG can be \"off\", \"on\",\n"
28645
-" \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
29271
+" \"always\", \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
2864629272
" --titlelimit N Limit the length of column titles to N characters.\n"
2864729273
" -v|--verbose Verbose output\n"
2864829274
" --widths LIST Set the columns widths for columnar modes. The\n"
2864929275
" argument is a list of integers, one for each\n"
2865029276
" column. A \"0\" width means use a dynamic width\n"
@@ -29345,11 +29971,12 @@
2934529971
sqlite3_base64_init(p->db, 0, 0);
2934629972
sqlite3_base85_init(p->db, 0, 0);
2934729973
sqlite3_regexp_init(p->db, 0, 0);
2934829974
sqlite3_ieee_init(p->db, 0, 0);
2934929975
sqlite3_series_init(p->db, 0, 0);
29350
- sqlite3_analyze_init(p->db, 0, 0);
29976
+ sqlite3_diskused_init(p->db, 0, 0);
29977
+ sqlite3_strdup_init(p->db, 0, 0);
2935129978
#ifndef SQLITE_SHELL_FIDDLE
2935229979
sqlite3_fileio_init(p->db, 0, 0);
2935329980
sqlite3_completion_init(p->db, 0, 0);
2935429981
#endif
2935529982
#ifdef SQLITE_HAVE_ZLIB
@@ -29406,15 +30033,11 @@
2940630033
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
2940730034
editFunc, 0, 0);
2940830035
sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
2940930036
editFunc, 0, 0);
2941030037
#endif
29411
- sqlite3_create_function(p->db, "shell_prompt_test", 1, SQLITE_UTF8,
29412
- p, shellExpandPrompt, 0, 0);
29413
- sqlite3_create_function(p->db, "shell_prompt_test", 2, SQLITE_UTF8,
29414
- p, shellExpandPrompt, 0, 0);
29415
- sqlite3_create_function(p->db, "shell_prompt_test", 3, SQLITE_UTF8,
30038
+ sqlite3_create_function(p->db, "shell_prompt_test", -1, SQLITE_UTF8,
2941630039
p, shellExpandPrompt, 0, 0);
2941730040
sqlite3_create_function(p->db, "shell_temp_filename", 1, SQLITE_UTF8,
2941830041
p, shellTempFilenameFunc, 0, 0);
2941930042
2942030043
@@ -31155,11 +31778,11 @@
3115531778
typedef struct ArCommand ArCommand;
3115631779
struct ArCommand {
3115731780
u8 eCmd; /* An AR_CMD_* value */
3115831781
u8 bVerbose; /* True if --verbose */
3115931782
u8 bZip; /* True if the archive is a ZIP */
31160
- u8 bDryRun; /* True if --dry-run */
31783
+ u8 bDryRun; /* 1 for --dry-run, 2 for --debug */
3116131784
u8 bAppend; /* True if --append */
3116231785
u8 bGlob; /* True if --glob */
3116331786
u8 fromCmdLine; /* Run from -A instead of .archive */
3116431787
int nArg; /* Number of command arguments */
3116531788
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
@@ -31217,10 +31840,11 @@
3121731840
#define AR_SWITCH_FILE 9
3121831841
#define AR_SWITCH_DIRECTORY 10
3121931842
#define AR_SWITCH_APPEND 11
3122031843
#define AR_SWITCH_DRYRUN 12
3122131844
#define AR_SWITCH_GLOB 13
31845
+#define AR_SWITCH_DEBUG 14
3122231846
3122331847
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
3122431848
switch( eSwitch ){
3122531849
case AR_CMD_CREATE:
3122631850
case AR_CMD_EXTRACT:
@@ -31234,11 +31858,14 @@
3123431858
}
3123531859
pAr->eCmd = eSwitch;
3123631860
break;
3123731861
3123831862
case AR_SWITCH_DRYRUN:
31239
- pAr->bDryRun = 1;
31863
+ if( pAr->bDryRun<2 ) pAr->bDryRun = 1;
31864
+ break;
31865
+ case AR_SWITCH_DEBUG:
31866
+ pAr->bDryRun = 2;
3124031867
break;
3124131868
case AR_SWITCH_GLOB:
3124231869
pAr->bGlob = 1;
3124331870
break;
3124431871
case AR_SWITCH_VERBOSE:
@@ -31285,10 +31912,11 @@
3128531912
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
3128631913
{ "file", 'f', AR_SWITCH_FILE, 1 },
3128731914
{ "append", 'a', AR_SWITCH_APPEND, 1 },
3128831915
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
3128931916
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
31917
+ { "debug", 0, AR_SWITCH_DEBUG, 0 },
3129031918
{ "glob", 'g', AR_SWITCH_GLOB, 0 },
3129131919
};
3129231920
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
3129331921
struct ArSwitch *pEnd = &aSwitch[nSwitch];
3129431922
@@ -31585,18 +32213,41 @@
3158532213
3158632214
/*
3158732215
** Implementation of .ar "eXtract" command.
3158832216
*/
3158932217
static int arExtractCommand(ArCommand *pAr){
32218
+ /* The zSql1[] string is a template for the query that does the
32219
+ ** extraction. Notes:
32220
+ **
32221
+ ** * $dir is the directory into which the archive is to be extracted
32222
+ ** * $pass is the integer pass number: 0, 1, or 2
32223
+ ** * The dest CTE is created so that realpath($dir) only needs
32224
+ ** to be called once.
32225
+ */
3159032226
const char *zSql1 =
31591
- "WITH dest(dpath,dlen) AS (SELECT realpath($dir),length(realpath($dir)))\n"
31592
- "SELECT ($dir || name),\n"
31593
- " CASE WHEN $dryrun THEN 0\n"
31594
- " ELSE writefile($dir||name, %s, mode, mtime) END\n"
32227
+ "WITH dest(dpath,dlen) AS (\n"
32228
+#ifdef _WIN32
32229
+ " SELECT realpath($dir) || '\\',\n"
32230
+#else
32231
+ " SELECT realpath($dir) || '/',\n"
32232
+#endif
32233
+ " 1+length(realpath($dir))\n"
32234
+ ")\n"
32235
+ "SELECT\n"
32236
+ " ($dir || name),\n"
32237
+ " CASE $dryrun\n" /* vv--- azExtraArg */
32238
+ " WHEN 0 THEN writefile($dir||name, %s, mode, mtime)\n"
32239
+ " WHEN 1 THEN 0\n"
32240
+ " ELSE shell_putsnl(format('writefile(%%Q,%%s,%%0o,%%d)',"
32241
+ "$dir||name,quote(%s),mode,mtime)) IS NULL\n"
32242
+ " END\n" /* ^^--- azExtraArg */
3159532243
" FROM dest CROSS JOIN %s\n"
31596
- " WHERE (%s)\n"
31597
- " AND (data IS NULL OR $pass==0)\n" /* Dirs both passes */
32244
+ " WHERE (%s)\n" /* ^^-- pAr->zSrcTable */
32245
+ /* ^^--- zWhere */
32246
+ " AND (CASE $pass WHEN 0 THEN (mode&0xf000)<>0xa000\n"
32247
+ " WHEN 1 THEN (mode&0xf000)=0xa000\n"
32248
+ " ELSE data IS NULL END)\n"
3159832249
" AND dpath=substr(realpath($dir||name),1,dlen)\n" /* No escapes */
3159932250
" AND name NOT GLOB '*..[/\\]*'\n"; /* No /../ in paths */
3160032251
3160132252
const char *azExtraArg[] = {
3160232253
"sqlar_uncompress(data, sz)",
@@ -31623,39 +32274,48 @@
3162332274
}
3162432275
if( zDir==0 ) rc = SQLITE_NOMEM;
3162532276
}
3162632277
3162732278
shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
31628
- azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
32279
+ azExtraArg[pAr->bZip],
32280
+ azExtraArg[pAr->bZip],
32281
+ pAr->zSrcTable,
32282
+ zWhere
3162932283
);
3163032284
3163132285
if( rc==SQLITE_OK ){
3163232286
j = sqlite3_bind_parameter_index(pSql, "$dir");
3163332287
sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
3163432288
j = sqlite3_bind_parameter_index(pSql, "$dryrun");
3163532289
sqlite3_bind_int(pSql, j, pAr->bDryRun);
3163632290
3163732291
/* Run the SELECT statement twice
31638
- ** (0) writefile() all files and directories
31639
- ** (1) writefile() for directory again
31640
- ** The second pass is so that the timestamps for extracted directories
32292
+ ** (0) writefile() files and directories
32293
+ ** (1) writefile() symlinks
32294
+ ** (2) writefile() for directory again
32295
+ ** The third pass is so that the timestamps for extracted directories
3164132296
** will be reset to the value in the archive, since populating them
3164232297
** in the first pass will have changed the timestamp. */
31643
- for(i=0; i<2; i++){
32298
+ for(i=0; i<3; i++){
32299
+ if( pAr->bDryRun>=2 ){
32300
+ cli_printf(pAr->out, "*** BEGIN PASS %d ***\n", i+1);
32301
+ }
3164432302
j = sqlite3_bind_parameter_index(pSql, "$pass");
3164532303
sqlite3_bind_int(pSql, j, i);
31646
- if( pAr->bDryRun ){
32304
+ if( pAr->bDryRun && i==0 ){
3164732305
cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
31648
- if( pAr->bVerbose==0 ) break;
3164932306
}
3165032307
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
3165132308
if( i==0 && pAr->bVerbose ){
3165232309
cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
3165332310
}
3165432311
}
31655
- if( pAr->bDryRun ) break;
32312
+ if( pAr->bDryRun==1 ) break;
3165632313
shellReset(&rc, pSql);
32314
+ if( pAr->bDryRun>=2 ){
32315
+ cli_printf(pAr->out, "*** END PASS %d ***\n", i+1);
32316
+ }
3165732317
}
3165832318
shellFinalize(&rc, pSql);
3165932319
}
3166032320
3166132321
sqlite3_free(zDir);
@@ -32166,11 +32826,11 @@
3216632826
;
3216732827
static const char * const zCollectVar = "\
3216832828
SELECT\
3216932829
'('||x'0a'\
3217032830
|| group_concat(\
32171
- cname||' ANY',\
32831
+ cname,\
3217232832
','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
3217332833
||')' AS ColsSpec \
3217432834
FROM (\
3217532835
SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \
3217632836
FROM ColNames ORDER BY cpos\
@@ -32767,14 +33427,16 @@
3276733427
/*
3276833428
** This function computes what to show the user about the configured
3276933429
** titles (or column-names). Output is an integer between 0 and 3:
3277033430
**
3277133431
** 0: The titles do not matter. Never show anything.
32772
-** 1: Show "--titles off"
32773
-** 2: Show "--titles on"
32774
-** 3: Show "--title VALUE" where VALUE is an encoding method
33432
+** 1: Show "--title off"
33433
+** 2: Show "--title on"
33434
+** 3: Show "--title always"
33435
+** 4: Show "--title VALUE" where VALUE is an encoding method
3277533436
** to use, one of: plain sql csv html tcl json
33437
+** 5: Show "--title VALUE" as in 3, followed by "--title always"
3277633438
**
3277733439
** Inputs are:
3277833440
**
3277933441
** spec.bTitles (bT) Whether or not to show the titles
3278033442
** spec.eTitle (eT) The actual encoding to be used for titles
@@ -32807,11 +33469,27 @@
3280733469
if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
3280833470
if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
3280933471
if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
3281033472
if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
3281133473
32812
- return v & 3; /* Return the selected truth-table entry */
33474
+ v &= 3;
33475
+ /* At this point v means:
33476
+ ** 0: The titles do not matter. Never show anything.
33477
+ ** 1: Show "--title off"
33478
+ ** 2: Show "--title on"
33479
+ ** 3: Show "--title VALUE" where VALUE is an encoding method
33480
+ ** to use, one of: plain sql csv html tcl json
33481
+ ** If bTitles is QRF_Always, convert 2->3, 3->5. If bTitles is not
33482
+ ** QRF_Always, convert 3->4.
33483
+ */
33484
+ if( p->mode.spec.bTitles==QRF_Always ){
33485
+ if( v==3 ) v = 5;
33486
+ if( v==2 ) v = 3;
33487
+ }else{
33488
+ if( v==3 ) v = 4;
33489
+ }
33490
+ return v;
3281333491
}
3281433492
3281533493
/*
3281633494
** DOT-COMMAND: .mode
3281733495
**
@@ -32835,10 +33513,14 @@
3283533513
** truncated. Zero means "no limit".
3283633514
** --colsep STRING Use STRING as the column separator
3283733515
** --escape ESC Enable/disable escaping of control characters
3283833516
** found in the output. ESC can be "off", "ascii",
3283933517
** or "symbol".
33518
+** --fpfmt STRING String is a printf-style format string used to
33519
+** render floating-point values.
33520
+** --ifmt STRING String is a printf-style format string used to
33521
+** render integer values.
3284033522
** --linelimit N Set the maximum number of output lines to show for
3284133523
** any single SQL value to N. Longer values are
3284233524
** truncated. Zero means "no limit". Only works
3284333525
** in "line" mode and in columnar modes.
3284433526
** --limits L,C,T Shorthand for "--linelimit L --charlimit C
@@ -32855,10 +33537,11 @@
3285533537
** --quote ARG Enable/disable quoting of text. ARG can be
3285633538
** "off", "on", "sql", "relaxed", "csv", "html",
3285733539
** "tcl", or "json". "off" means show the text as-is.
3285833540
** "on" is an alias for "sql".
3285933541
** --reset Changes all mode settings back to their default.
33542
+** --rowcount BOOLEAN Show "(N rows)" at the end of query results.
3286033543
** --rowsep STRING Use STRING as the row separator
3286133544
** --sw|--screenwidth N Declare the screen width of the output device
3286233545
** to be N characters. An attempt may be made to
3286333546
** wrap output text to fit within this limit. Zero
3286433547
** means "no limit". Or N can be "auto" to set the
@@ -32866,11 +33549,11 @@
3286633549
** --tablename NAME Set the name of the table for "insert" mode.
3286733550
** --tag NAME Save mode to the left as NAME.
3286833551
** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
3286933552
** --title ARG Whether or not to show column headers, and if so
3287033553
** how to encode them. ARG can be "off", "on",
32871
-** "sql", "csv", "html", "tcl", or "json".
33554
+** "always", "sql", "csv", "html", "tcl", or "json".
3287233555
** --titlelimit N Limit the length of column titles to N characters.
3287333556
** -v|--verbose Verbose output
3287433557
** --widths LIST Set the columns widths for columnar modes. The
3287533558
** argument is a list of integers, one for each
3287633559
** column. A "0" width means use a dynamic width
@@ -33011,30 +33694,14 @@
3301133694
}else if( optionMatch(z,"limits") ){
3301233695
if( (++i)>=nArg ){
3301333696
dotCmdError(p, i-1, "missing argument", 0);
3301433697
return 1;
3301533698
}
33016
- k = pickStr(azArg[i],0,"on","off","");
33017
- if( k==0 ){
33018
- p->mode.spec.nLineLimit = DFLT_LINE_LIMIT;
33019
- p->mode.spec.nCharLimit = DFLT_CHAR_LIMIT;
33020
- p->mode.spec.nTitleLimit = DFLT_TITLE_LIMIT;
33021
- }else if( k==1 ){
33022
- p->mode.spec.nLineLimit = 0;
33023
- p->mode.spec.nCharLimit = 0;
33024
- p->mode.spec.nTitleLimit = 0;
33025
- }else{
33026
- int L, C, T = 0;
33027
- int nNum = sscanf(azArg[i], "%d,%d,%d", &L, &C, &T);
33028
- if( nNum<2 || L<0 || C<0 || T<0){
33029
- dotCmdError(p, i, "bad argument", "Should be \"L,C,T\" where L, C"
33030
- " and T are unsigned integers");
33031
- return 1;
33032
- }
33033
- p->mode.spec.nLineLimit = L;
33034
- p->mode.spec.nCharLimit = C;
33035
- if( nNum==3 ) p->mode.spec.nTitleLimit = T;
33699
+ if( modeSetLimit(p, azArg[i]) ){
33700
+ dotCmdError(p, i, "bad argument", "Should be \"on\" or \"off\" or "
33701
+ "\"L,C,T\" where L, C, and T are unsigned integers");
33702
+ return 1;
3303633703
}
3303733704
chng = 1;
3303833705
}else if( optionMatch(z,"list") ){
3303933706
int ii;
3304033707
cli_puts("available modes:", p->out);
@@ -33105,15 +33772,56 @@
3310533772
break;
3310633773
default: /* off */
3310733774
p->mode.spec.eText = QRF_TEXT_Plain;
3310833775
break;
3310933776
}
33777
+ chng = 1;
33778
+ }else if( optionMatch(z,"ifmt") ){
33779
+ if( i+1>=nArg ){
33780
+ dotCmdError(p, i, "missing argument", 0);
33781
+ return 1;
33782
+ }
33783
+ i++;
33784
+ if( azArg[i][0]==0 || cli_strcmp(azArg[i],"auto")==0 ){
33785
+ p->mode.spec.zIFmt = 0;
33786
+ }else if( sqlite3_qrf_ckformat(azArg[i])!=1 ){
33787
+ dotCmdError(p, i, "not a valid integer format", 0);
33788
+ return 1;
33789
+ }else{
33790
+ assert( strlen(azArg[i])<sizeof(p->mode.zIFmt)-1 );
33791
+ memcpy(p->mode.zIFmt, azArg[i], strlen(azArg[i])+1);
33792
+ p->mode.spec.zIFmt = p->mode.zIFmt;
33793
+ }
33794
+ chng = 1;
33795
+ }else if( optionMatch(z,"fpfmt") ){
33796
+ if( i+1>=nArg ){
33797
+ dotCmdError(p, i, "missing argument", 0);
33798
+ return 1;
33799
+ }
33800
+ i++;
33801
+ if( azArg[i][0]==0 || cli_strcmp(azArg[i],"auto")==0 ){
33802
+ p->mode.spec.zFpFmt = 0;
33803
+ }else if( sqlite3_qrf_ckformat(azArg[i])!=2 ){
33804
+ dotCmdError(p, i, "not a valid floating-point format", 0);
33805
+ return 1;
33806
+ }else{
33807
+ assert( strlen(azArg[i])<sizeof(p->mode.zFpFmt)-1 );
33808
+ memcpy(p->mode.zFpFmt, azArg[i], strlen(azArg[i])+1);
33809
+ p->mode.spec.zFpFmt = p->mode.zFpFmt;
33810
+ }
3311033811
chng = 1;
3311133812
}else if( optionMatch(z,"reset") ){
3311233813
int saved_eMode = p->mode.eMode;
3311333814
modeFree(&p->mode);
3311433815
modeChange(p, saved_eMode);
33816
+ }else if( optionMatch(z,"rowcount") ){
33817
+ if( i+1>=nArg ){
33818
+ dotCmdError(p, i, "missing argument", 0);
33819
+ return 1;
33820
+ }
33821
+ p->mode.spec.bRowCount = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33822
+ chng = 1;
3311533823
}else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
3311633824
if( (++i)>=nArg ){
3311733825
dotCmdError(p, i-1, "missing argument", 0);
3311833826
return 1;
3311933827
}
@@ -33163,25 +33871,63 @@
3316333871
return 1;
3316433872
}
3316533873
p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
3316633874
chng = 1;
3316733875
}else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
33876
+ /* The --titles option controls two fields of the
33877
+ ** sqlite3_qrf_spec object: eTitle and bTitles.
33878
+ **
33879
+ ** --titles eTitle bTitles
33880
+ ** -------- --------------- ---------------------
33881
+ ** "off" (unchanged) QRF_Off
33882
+ ** "on" (unchanged) QRF_On
33883
+ ** "always" (unchanged) QRF_Always
33884
+ ** "auto", (default) (default)
33885
+ ** "plain" QRF_TEXT_Plain QRF_Always or QRF_On
33886
+ ** "sql" QRF_TEXT_Sql QRF_Always or QRF_On
33887
+ ** "csv" QRF_TEXT_Csv QRF_Always or QRF_On
33888
+ ** "html" QRF_TEXT_Html QRF_Always or QRF_On
33889
+ ** "tcl" QRF_TEXT_Tcl QRF_Always or QRF_On
33890
+ ** "json" QRF_TEXT_Json QRF_Always or QRF_On
33891
+ **
33892
+ ** This mapping is different from the -title option to the "format"
33893
+ ** method of the TCL interface. In this mapping:
33894
+ **
33895
+ ** * "off", "on", and "always" affect only bTitles and leave
33896
+ ** eTitle unchanged
33897
+ **
33898
+ ** * "auto" sets both bTitles and eTitle to the default value
33899
+ ** in aModeInfo[] according to the current --style.
33900
+ **
33901
+ ** * "plain" through "json" set eTitle but leave bTitles
33902
+ ** unchanged if it is not QRF_Off. If bTitles is QRF_Off,
33903
+ ** then it is changed QRF_Always.
33904
+ */
3316833905
char *zErr = 0;
3316933906
if( i+1>=nArg ){
3317033907
dotCmdError(p, i, "missing argument", 0);
3317133908
return 1;
3317233909
}
3317333910
k = pickStr(azArg[++i],&zErr,
33174
- "off","on","plain","sql","csv","html","tcl","json","");
33175
- /* 0 1 2 3 4 5 6 7 */
33911
+ "off","on","always","auto","plain","sql","csv","html","tcl","json","");
33912
+ /* 0 1 2 3 4 5 6 7 8 9 */
3317633913
if( k<0 ){
3317733914
dotCmdError(p, i, "bad --titles value","%z", zErr);
3317833915
return 1;
3317933916
}
33180
- p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
3318133917
p->mode.mFlags &= ~MFLG_HDR;
33182
- p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
33918
+ if( k<=2 ){
33919
+ p->mode.spec.bTitles = QRF_No+k;
33920
+ }else if( k==3 ){
33921
+ p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
33922
+ p->mode.spec.bTitles = aModeInfo[p->mode.eMode].bHdr;
33923
+ }else{
33924
+ p->mode.spec.eTitle = (k-4)+QRF_TEXT_Plain;
33925
+ if( p->mode.spec.bTitles==QRF_No ){
33926
+ p->mode.spec.bTitles = QRF_Always;
33927
+ }
33928
+ }
3318333929
chng = 1;
3318433930
}else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
3318533931
int nWidth = 0;
3318633932
short int *aWidth;
3318733933
const char *zW;
@@ -33295,10 +34041,18 @@
3329534041
append_c_string(pDesc, p->mode.spec.zColumnSep);
3329634042
}
3329734043
if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
3329834044
sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
3329934045
}
34046
+ if( bAll || p->mode.spec.zFpFmt!=0 ){
34047
+ const char *z = p->mode.spec.zFpFmt;
34048
+ sqlite3_str_appendf(pDesc, " --fpfmt %s", z ? z : "auto");
34049
+ }
34050
+ if( bAll || p->mode.spec.zIFmt!=0 ){
34051
+ const char *z = p->mode.spec.zIFmt;
34052
+ sqlite3_str_appendf(pDesc, " --ifmt %s", z ? z : "auto");
34053
+ }
3330034054
if( bAll
3330134055
|| (p->mode.spec.nLineLimit>0 && pI->eCx>0)
3330234056
|| p->mode.spec.nCharLimit>0
3330334057
|| (p->mode.spec.nTitleLimit>0 && pI->eCx>0)
3330434058
){
@@ -33332,10 +34086,16 @@
3333234086
if( bAll
3333334087
|| (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
3333434088
){
3333534089
sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
3333634090
}
34091
+ if( bAll
34092
+ || ((p->mode.spec.bRowCount==QRF_Yes) != ((pI->mFlg&4)!=0))
34093
+ ){
34094
+ sqlite3_str_appendf(pDesc," --rowcount %s",
34095
+ p->mode.spec.bRowCount==QRF_Yes ? "on" : "off");
34096
+ }
3333734097
zSetting = aModeStr[pI->eRSep];
3333834098
if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
3333934099
sqlite3_str_appendf(pDesc, " --rowsep ");
3334034100
append_c_string(pDesc, p->mode.spec.zRowSep);
3334134101
}
@@ -33361,14 +34121,19 @@
3336134121
if( k==1 ){
3336234122
sqlite3_str_appendall(pDesc, " --titles off");
3336334123
}else if( k==2 ){
3336434124
sqlite3_str_appendall(pDesc, " --titles on");
3336534125
}else if( k==3 ){
34126
+ sqlite3_str_appendall(pDesc, " --titles always");
34127
+ }else if( k>=4 ){
3336634128
static const char *azTitle[] =
3336734129
{ "plain", "sql", "csv", "html", "tcl", "json"};
3336834130
sqlite3_str_appendf(pDesc, " --titles %s",
3336934131
azTitle[p->mode.spec.eTitle-1]);
34132
+ if( k==5 ){
34133
+ sqlite3_str_appendf(pDesc, " --titles always");
34134
+ }
3337034135
}
3337134136
if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
3337234137
int ii;
3337334138
const char *zSep = " --widths ";
3337434139
for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34248,11 +35013,16 @@
3424835013
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
3424935014
rc = shell_dbinfo_command(p, nArg, azArg);
3425035015
}else
3425135016
#endif /* SQLITE_SHELL_HAVE_RECOVER */
3425235017
34253
- if( c=='d' && n==6 && cli_strncmp(azArg[0], "dbstat", n)==0 ){
35018
+ if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
35019
+ open_db(p, 0);
35020
+ rc = shell_dbtotxt_command(p, nArg, azArg);
35021
+ }else
35022
+
35023
+ if( c=='d' && n==8 && cli_strncmp(azArg[0], "diskused", n)==0 ){
3425435024
const char *zSchema = 0;
3425535025
int ii;
3425635026
char *zSql;
3425735027
open_db(p, 0);
3425835028
for(ii=1; ii<nArg; ii++){
@@ -34267,27 +35037,19 @@
3426735037
rc = 1;
3426835038
goto meta_command_exit;
3426935039
}
3427035040
zSchema = z;
3427135041
}
34272
- zSql = sqlite3_mprintf("SELECT analyze(%Q)", zSchema);
35042
+ zSql = sqlite3_mprintf("SELECT diskused(%Q)", zSchema);
3427335043
shell_check_oom(zSql);
3427435044
modePush(p);
3427535045
modeChange(p, MODE_BATCH);
34276
- p->mode.spec.nLineLimit = 0;
34277
- p->mode.spec.nCharLimit = 0;
34278
- p->mode.spec.nTitleLimit = 0;
3427935046
shell_exec(p, zSql, 0);
3428035047
modePop(p);
3428135048
sqlite3_free(zSql);
3428235049
}else
3428335050
34284
- if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
34285
- open_db(p, 0);
34286
- rc = shell_dbtotxt_command(p, nArg, azArg);
34287
- }else
34288
-
3428935051
if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
3429035052
char *zLike = 0;
3429135053
char *zSql;
3429235054
int i;
3429335055
int savedShellFlags = p->shellFlgs;
@@ -34689,15 +35451,19 @@
3468935451
}
3469035452
}else
3469135453
3469235454
if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
3469335455
if( nArg==2 ){
34694
- p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35456
+ if( cli_strcmp(azArg[1],"always")==0 ){
35457
+ p->mode.spec.bTitles = QRF_Always;
35458
+ }else{
35459
+ p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35460
+ }
3469535461
p->mode.mFlags |= MFLG_HDR;
3469635462
p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
3469735463
}else{
34698
- eputz("Usage: .headers on|off\n");
35464
+ eputz("Usage: .headers off|on|always\n");
3469935465
rc = 1;
3470035466
}
3470135467
}else
3470235468
3470335469
if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -34901,13 +35667,21 @@
3490135667
sqlite3_str_free(pSql);
3490235668
}else
3490335669
3490435670
if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
3490535671
i64 iArg = 0;
35672
+ open_db(p, 0);
3490635673
if( nArg==2 ){
3490735674
iArg = integerValue(azArg[1]);
34908
- if( iArg==0 ) iArg = -1;
35675
+ if( iArg==0 ){
35676
+ if( cli_strcmp(azArg[1],"register")==0 ){
35677
+ sqlite3_intck_register(p->db, 1);
35678
+ rc = 0;
35679
+ goto meta_command_exit;
35680
+ }
35681
+ iArg = -1;
35682
+ }
3490935683
}
3491035684
if( (nArg!=1 && nArg!=2) || iArg<0 ){
3491135685
cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
3491235686
rc = 1;
3491335687
goto meta_command_exit;
@@ -34955,10 +35729,12 @@
3495535729
{ "attached", SQLITE_LIMIT_ATTACHED },
3495635730
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3495735731
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3495835732
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3495935733
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
35734
+ { "schema", SQLITE_LIMIT_SCHEMA },
35735
+ { "trigger_steps", SQLITE_LIMIT_TRIGGER_STEPS },
3496035736
};
3496135737
int i, n2;
3496235738
open_db(p, 0);
3496335739
if( nArg==1 ){
3496435740
for(i=0; i<ArraySize(aLimit); i++){
@@ -35400,10 +36176,26 @@
3540036176
}else
3540136177
if( strcmp(z,"-show")==0 ){
3540236178
cli_printf(stdout,"Main prompt: '%s'\n", prompt_string(p, 0));
3540336179
cli_printf(stdout,"Continuation: '%s'\n", prompt_string(p, 1));
3540436180
}else
36181
+#ifndef SQLITE_NO_COLOR
36182
+ if( strcmp(z,"-color")==0 ){
36183
+#ifdef _WIN32
36184
+ _putenv("NO_COLOR=");
36185
+#else
36186
+ unsetenv("NO_COLOR");
36187
+#endif
36188
+ }else
36189
+ if( strcmp(z,"-no-color")==0 ){
36190
+#ifdef _WIN32
36191
+ _putenv("NO_COLOR=1");
36192
+#else
36193
+ setenv("NO_COLOR","1",1);
36194
+#endif
36195
+ }else
36196
+#endif
3540536197
if( strcmp(z,"-")==0 ){
3540636198
noOpt = 1;
3540736199
}else
3540836200
{
3540936201
dotCmdError(p, i, "unknown option", 0);
@@ -35414,10 +36206,11 @@
3541436206
dotCmdError(p, i, "extra argument", 0);
3541536207
rc = 1;
3541636208
goto meta_command_exit;
3541736209
}else if( !p->dot.abQuot[i] && sqlite3_strglob("*[^a-z]*",z)!=0 ){
3541836210
dotCmdError(p, i, "use quotes around the prompt string", 0);
36211
+ rc = 1;
3541936212
}else{
3542036213
free(p->azPrompt[cnt]);
3542136214
p->azPrompt[cnt] = strdup(z);
3542236215
cnt++;
3542336216
}
@@ -36264,11 +37057,12 @@
3626437057
azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
3626537058
cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
3626637059
cli_printf(p->out, "%12.12s: %s\n","explain",
3626737060
p->mode.autoExplain ? "auto" : "off");
3626837061
cli_printf(p->out, "%12.12s: %s\n","headers",
36269
- azBool[p->mode.spec.bTitles==QRF_Yes]);
37062
+ p->mode.spec.bTitles==QRF_Always ? "always" :
37063
+ azBool[p->mode.spec.bTitles==QRF_Yes]);
3627037064
if( p->mode.spec.eStyle==QRF_STYLE_Column
3627137065
|| p->mode.spec.eStyle==QRF_STYLE_Box
3627237066
|| p->mode.spec.eStyle==QRF_STYLE_Table
3627337067
|| p->mode.spec.eStyle==QRF_STYLE_Markdown
3627437068
){
@@ -37626,17 +38420,18 @@
3762638420
" -- treat no subsequent arguments as options\n"
3762738421
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
3762838422
" -A ARGS... run \".archive ARGS\" and exit\n"
3762938423
#endif
3763038424
" -append append the database to the end of the file\n"
37631
- " -ascii set output mode to 'ascii'\n"
38425
+ " -ascii set '.mode ascii'\n"
3763238426
" -bail stop after hitting an error\n"
3763338427
" -batch force batch I/O\n"
37634
- " -box set output mode to 'box'\n"
38428
+ " -box set '.mode box'\n"
3763538429
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
37636
- " -column set output mode to 'column'\n"
37637
- " -csv set output mode to 'csv'\n"
38430
+ " -cmdline-edit BOOL enable or disable command-line editing\n"
38431
+ " -column set '.mode column'\n"
38432
+ " -csv set '.mode csv -limits off'\n"
3763838433
#if !defined(SQLITE_OMIT_DESERIALIZE)
3763938434
" -deserialize open the database using sqlite3_deserialize()\n"
3764038435
#endif
3764138436
" -echo print inputs before execution\n"
3764238437
" -escape T ctrl-char escape; T is one of: symbol, ascii, off\n"
@@ -37644,18 +38439,18 @@
3764438439
" -[no]header turn headers on or off\n"
3764538440
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3764638441
" -heap SIZE Size of heap for memsys3 or memsys5\n"
3764738442
#endif
3764838443
" -help show this message\n"
37649
- " -html set output mode to HTML\n"
38444
+ " -html set '.mode html'\n"
3765038445
" -ifexists only open if database already exists\n"
3765138446
" -interactive force interactive I/O\n"
37652
- " -json set output mode to 'json'\n"
37653
- " -line set output mode to 'line'\n"
37654
- " -list set output mode to 'list'\n"
38447
+ " -json set '.mode json'\n"
38448
+ " -line set '.mode line'\n"
38449
+ " -list set '.mode list'\n"
3765538450
" -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
37656
- " -markdown set output mode to 'markdown'\n"
38451
+ " -markdown set '.mode markdown'\n"
3765738452
#if !defined(SQLITE_OMIT_DESERIALIZE)
3765838453
" -maxsize N maximum size for a --deserialize database\n"
3765938454
#endif
3766038455
" -memtrace trace all memory allocations and deallocations\n"
3766138456
" -mmap N default mmap size set to N\n"
@@ -37668,21 +38463,21 @@
3766838463
" -nonce STRING set the safe-mode escape nonce\n"
3766938464
" -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
3767038465
" -nullvalue TEXT set text string for NULL values. Default ''\n"
3767138466
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
3767238467
" -pcachetrace trace all page cache operations\n"
37673
- " -quote set output mode to 'quote'\n"
38468
+ " -quote set '.mode quote'\n"
3767438469
" -readonly open the database read-only\n"
3767538470
" -safe enable safe-mode\n"
3767638471
" -screenwidth N use N as the default screenwidth \n"
3767738472
" -separator SEP set output column separator. Default: '|'\n"
3767838473
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
3767938474
" -sorterref SIZE sorter references threshold size\n"
3768038475
#endif
3768138476
" -stats print memory stats before each finalize\n"
37682
- " -table set output mode to 'table'\n"
37683
- " -tabs set output mode to 'tabs'\n"
38477
+ " -table set '.mode table'\n"
38478
+ " -tabs set '.mode tabs'\n"
3768438479
" -unsafe-testing allow unsafe commands and modes for testing\n"
3768538480
" -version show SQLite version\n"
3768638481
" -vfs NAME use NAME as the default VFS\n"
3768738482
" -vfstrace enable tracing of all VFS calls\n"
3768838483
#ifdef SQLITE_HAVE_ZLIB
@@ -37710,10 +38505,23 @@
3771038505
sputz(stdout, "WARNING: attempt to configure SQLite after"
3771138506
" initialization.\n");
3771238507
}
3771338508
}
3771438509
38510
+#if HAVE_EDITLINE
38511
+/*
38512
+** https://sqlite.org/forum/forumpost/aad7a634916ff050:
38513
+**
38514
+** Calling setlocale(LC_...,"") is required to get libedit to accept
38515
+** non-ASCII input.
38516
+*/
38517
+#define DO_SET_LOCALE 1
38518
+#include <locale.h>
38519
+#else
38520
+#define DO_SET_LOCALE 0
38521
+#endif
38522
+
3771538523
/*
3771638524
** Initialize the state information in data
3771738525
*/
3771838526
static void main_init(ShellState *p) {
3771938527
memset(p, 0, sizeof(*p));
@@ -37724,31 +38532,36 @@
3772438532
verify_uninitialized();
3772538533
#endif
3772638534
sqlite3_config(SQLITE_CONFIG_URI, 1);
3772738535
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
3772838536
globalShellState = p;
38537
+#if HAVE_EDITLINE || HAVE_READLINE
38538
+ /* Editline requires \001...\002 delimiters around ANSI x3.64 escapes in
38539
+ ** prompt strings. Readline does sometimes, depending on how it is
38540
+ ** compiled and installed. */
38541
+ p->bDelimitNonprint = 1;
38542
+#else
38543
+ /* No \001...\002 escapes required for linenoise or when not using a
38544
+ ** command-line editing library */
38545
+ p->bDelimitNonprint = 0;
38546
+#endif
38547
+#if DO_SET_LOCALE
38548
+ setlocale(LC_CTYPE,"");
38549
+#endif
38550
+#undef DO_SET_LOCALE
3772938551
}
3773038552
3773138553
/*
3773238554
** Output text to the console in a font that attracts extra attention.
3773338555
*/
37734
-#if 0 /* Windows now handles ANSI escape codes */
37735
-static void printBold(const char *zText){
37736
- HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
37737
- CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
37738
- GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
37739
- SetConsoleTextAttribute(out,
37740
- FOREGROUND_RED|FOREGROUND_INTENSITY
37741
- );
37742
- sputz(stdout, zText);
37743
- SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
37744
-}
37745
-#else
37746
-static void printBold(const char *zText){
37747
- cli_printf(stdout, "\033[1;36m\033[3m%s\033[0m", zText);
37748
-}
37749
-#endif
38556
+static void printBold(const char *zText){
38557
+ if( shellNoColor() ){
38558
+ cli_printf(stdout, "%s", zText);
38559
+ }else{
38560
+ cli_printf(stdout, "\033[1;36m\033[3m%s\033[0m", zText);
38561
+ }
38562
+}
3775038563
3775138564
/*
3775238565
** Get the argument to an --option. Throw an error and die if no argument
3775338566
** is available.
3775438567
*/
@@ -37762,11 +38575,11 @@
3776238575
}
3776338576
3776438577
/*
3776538578
** The callback from atexit().
3776638579
*/
37767
-static void abnormalExit(void){
38580
+static void SQLITE_CDECL abnormalExit(void){
3776838581
if( seenInterrupt ) eputz("Program interrupted.\n");
3776938582
if( globalShellState ){
3777038583
clearTempFile(globalShellState, 1, 1);
3777138584
}
3777238585
}
@@ -37837,10 +38650,11 @@
3783738650
}
3783838651
argv[argc] = 0;
3783938652
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
3784038653
GetConsoleMode(hOut, &mode);
3784138654
SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
38655
+ _setmode(_fileno(stdout),_O_BINARY); /* Bug 2026-08-03T08:52:42Z */
3784238656
rc = utf8_main(argc, argv);
3784338657
for(i=0; i<argc; i++) free(orig[i]);
3784438658
free(argv);
3784538659
return rc;
3784638660
}
@@ -37883,10 +38697,13 @@
3788338697
stdout_is_console = 1;
3788438698
data.wasm.zDefaultDbName = "/fiddle.sqlite3";
3788538699
#else
3788638700
stdin_is_interactive = isatty(0);
3788738701
stdout_is_console = isatty(1);
38702
+ if( !stdin_is_interactive || !stdout_is_console ){
38703
+ shellCmdLineEdit = 0;
38704
+ }
3788838705
#endif
3788938706
atexit(abnormalExit);
3789038707
#ifdef SQLITE_DEBUG
3789138708
mem_main_enter = sqlite3_memory_used();
3789238709
#endif
@@ -37973,11 +38790,11 @@
3797338790
stdin_is_interactive = 0;
3797438791
nCmd++;
3797538792
azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
3797638793
shell_check_oom(azCmd);
3797738794
aiCmd = realloc(aiCmd, sizeof(aiCmd[0])*nCmd);
37978
- shell_check_oom(azCmd);
38795
+ shell_check_oom(aiCmd);
3797938796
azCmd[nCmd-1] = z;
3798038797
aiCmd[nCmd-1] = i;
3798138798
}
3798238799
continue;
3798338800
}
@@ -38130,10 +38947,12 @@
3813038947
}else if( cli_strcmp(z,"-safe")==0 ){
3813138948
/* no-op - catch this on the second pass */
3813238949
}else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
3813338950
/* skip over the argument */
3813438951
i++;
38952
+ }else if( cli_strcmp(z,"-cmdline-edit")==0 ){
38953
+ shellCmdLineEdit = booleanValue(cmdline_option_value(argc,argv,++i));
3813538954
}else if( cli_strcmp(z,"-test-argv")==0 ){
3813638955
/* Undocumented test option. Print the values in argv[] and exit.
3813738956
** Use this to verify that any translation of the argv[], for example
3813838957
** on Windows that receives wargv[] from the OS and must convert
3813938958
** to UTF8 prior to calling this routine. */
@@ -38262,10 +39081,11 @@
3826239081
modeChange(&data, MODE_Psql);
3826339082
}else if( cli_strcmp(z,"-box")==0 ){
3826439083
modeChange(&data, MODE_Box);
3826539084
}else if( cli_strcmp(z,"-csv")==0 ){
3826639085
modeChange(&data, MODE_Csv);
39086
+ modeSetLimit(&data, "off");
3826739087
}else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
3826839088
/* See similar code at tag-20250224-1 */
3826939089
const char *zEsc = argv[++i];
3827039090
int k;
3827139091
for(k=0; k<ArraySize(qrfEscNames); k++){
@@ -38319,13 +39139,15 @@
3831939139
cmdline_option_value(argc,argv,++i));
3832039140
}else if( cli_strcmp(z,"-nullvalue")==0 ){
3832139141
modeSetStr(&data.mode.spec.zNull,
3832239142
cmdline_option_value(argc,argv,++i));
3832339143
}else if( cli_strcmp(z,"-header")==0 ){
38324
- data.mode.spec.bTitles = QRF_Yes;
39144
+ data.mode.spec.bTitles = QRF_Always;
39145
+ data.mode.mFlags |= MFLG_HDR;
3832539146
}else if( cli_strcmp(z,"-noheader")==0 ){
3832639147
data.mode.spec.bTitles = QRF_No;
39148
+ data.mode.mFlags |= MFLG_HDR;
3832739149
}else if( cli_strcmp(z,"-echo")==0 ){
3832839150
data.mode.mFlags |= MFLG_ECHO;
3832939151
}else if( cli_strcmp(z,"-eqp")==0 ){
3833039152
data.mode.autoEQP = AUTOEQP_on;
3833139153
}else if( cli_strcmp(z,"-eqpfull")==0 ){
@@ -38389,10 +39211,12 @@
3838939211
i++;
3839039212
#ifdef SQLITE_ENABLE_MULTIPLEX
3839139213
}else if( cli_strcmp(z,"-multiplex")==0 ){
3839239214
i++;
3839339215
#endif
39216
+ }else if( cli_strcmp(z,"-cmdline-edit")==0 ){
39217
+ i+=2;
3839439218
}else if( cli_strcmp(z,"-help")==0 ){
3839539219
usage(1);
3839639220
}else if( cli_strcmp(z,"-cmd")==0 ){
3839739221
/* Run commands that follow -cmd first and separately from commands
3839839222
** that simply appear on the command-line. This seems goofy. It would
@@ -38418,12 +39242,14 @@
3841839242
rc = 1;
3841939243
goto shell_main_exit;
3842039244
}
3842139245
open_db(&data, OPEN_DB_ZIPFILE);
3842239246
if( z[2] ){
39247
+ char *zSaved = argv[i];
3842339248
argv[i] = &z[2];
3842439249
arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
39250
+ argv[i] = zSaved;
3842539251
}else{
3842639252
arDotCommand(&data, 1, argv+i, argc-i);
3842739253
}
3842839254
readStdin = 0;
3842939255
stdin_is_interactive = 0;
3843039256
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5,16 +5,16 @@
5 **
6 ** ext/expert/sqlite3expert.c
7 ** ext/expert/sqlite3expert.h
8 ** ext/intck/sqlite3intck.c
9 ** ext/intck/sqlite3intck.h
10 ** ext/misc/analyze.c
11 ** ext/misc/appendvfs.c
12 ** ext/misc/base64.c
13 ** ext/misc/base85.c
14 ** ext/misc/completion.c
15 ** ext/misc/decimal.c
 
16 ** ext/misc/fileio.c
17 ** ext/misc/ieee754.c
18 ** ext/misc/memtrace.c
19 ** ext/misc/pcachetrace.c
20 ** ext/misc/regexp.c
@@ -23,10 +23,11 @@
23 ** ext/misc/shathree.c
24 ** ext/misc/sqlar.c
25 ** ext/misc/sqlite3_stdio.c
26 ** ext/misc/sqlite3_stdio.h
27 ** ext/misc/stmtrand.c
 
28 ** ext/misc/uint.c
29 ** ext/misc/vfstrace.c
30 ** ext/misc/windirent.h
31 ** ext/misc/zipfile.c
32 ** ext/qrf/qrf.c
@@ -154,10 +155,11 @@
154 #include <string.h>
155 #include <stdio.h>
156 #include <assert.h>
157 #include <math.h>
158 #include <stdint.h>
 
159 #include "sqlite3.h"
160 typedef sqlite3_int64 i64;
161 typedef sqlite3_uint64 u64;
162 typedef unsigned char u8;
163 #include <ctype.h>
@@ -190,13 +192,14 @@
190 #include <sys/stat.h>
191
192 #if HAVE_READLINE
193 # include <readline/readline.h>
194 # include <readline/history.h>
195 #endif
196
197 #if HAVE_EDITLINE
 
198 # include <editline/readline.h>
199 #endif
200
201 #if HAVE_EDITLINE || HAVE_READLINE
202
@@ -203,28 +206,38 @@
203 # define shell_add_history(X) add_history(X)
204 # define shell_read_history(X) read_history(X)
205 # define shell_write_history(X) write_history(X)
206 # define shell_stifle_history(X) stifle_history(X)
207 # define shell_readline(X) readline(X)
 
208
209 #elif HAVE_LINENOISE
210
211 # include "linenoise.h"
212 # define shell_add_history(X) linenoiseHistoryAdd(X)
213 # define shell_read_history(X) linenoiseHistoryLoad(X)
214 # define shell_write_history(X) linenoiseHistorySave(X)
215 # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
216 # define shell_readline(X) linenoise(X)
 
217
218 #else
219
220 # define shell_read_history(X)
221 # define shell_write_history(X)
222 # define shell_stifle_history(X)
 
 
223
224 # define SHELL_USE_LOCAL_GETLINE 1
225 #endif
 
 
 
 
 
 
226
227 #ifndef deliberate_fall_through
228 /* Quiet some compilers about some of our intentional code. */
229 # if defined(GCC_VERSION) && GCC_VERSION>=7000000
230 # define deliberate_fall_through __attribute__((fallthrough));
@@ -731,10 +744,14 @@
731 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
732 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
733 void *pRenderArg; /* First argument to the xRender callback */
734 void *pWriteArg; /* First argument to the xWrite callback */
735 char **pzOutput; /* Storage location for output string */
 
 
 
 
736 /* Additional fields may be added in the future */
737 };
738
739 /*
740 ** Interfaces
@@ -744,12 +761,11 @@
744 const sqlite3_qrf_spec *pSpec, /* Result format specification */
745 char **pzErr /* OUT: Write error message here */
746 );
747
748 /*
749 ** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
750 ** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
751 */
752 #define QRF_MAX_WIDTH 10000
753 #define QRF_MIN_WIDTH 0
754
755 /*
@@ -760,11 +776,11 @@
760 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
761 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
762 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
763 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
764 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
765 #define QRF_STYLE_Html 7 /* Generate an XHTML table */
766 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
767 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
768 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
769 #define QRF_STYLE_Line 11 /* One column per line. */
770 #define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -820,10 +836,15 @@
820 #define QRF_SW_On 2 /* This setting is forced on */
821 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
822 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
823 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
824
 
 
 
 
 
825 /*
826 ** Possible alignment values alignment settings
827 **
828 ** Horizontal Vertial
829 ** ---------- -------- */
@@ -868,10 +889,22 @@
868 ** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
869 ** are assigned a width of zero.
870 */
871 size_t sqlite3_qrf_wcswidth(const char*);
872
 
 
 
 
 
 
 
 
 
 
 
 
873
874 #ifdef __cplusplus
875 }
876 #endif
877 #endif /* !defined(SQLITE_QRF_H) */
@@ -950,10 +983,11 @@
950 } sExpln;
951 unsigned int nIns; /* Bytes used for current INSERT stmt */
952 } u;
953 sqlite3_int64 nRow; /* Number of rows handled so far */
954 int *actualWidth; /* Actual width of each column */
 
955 sqlite3_qrf_spec spec; /* Copy of the original spec */
956 };
957
958 /*
959 ** Data for substitute ctype.h functions. Used for x-platform
@@ -993,10 +1027,48 @@
993 # define deliberate_fall_through __attribute__((fallthrough));
994 # else
995 # define deliberate_fall_through
996 # endif
997 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
998
999 /*
1000 ** Set an error code and error message.
1001 */
1002 static void qrfError(
@@ -1129,10 +1201,14 @@
1129 sqlite3_str_append(pOut, "-", 1);
1130 }
1131 if( N<10000 ){
1132 sqlite3_str_appendf(pOut, "%4lld ", N);
1133 return;
 
 
 
 
1134 }
1135 for(i=1; i<=18; i++){
1136 N = (N+5)/10;
1137 if( N<10000 ){
1138 int n = (int)N;
@@ -1289,12 +1365,12 @@
1289 if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
1290 int nSp = 0;
1291 sqlite3_str_reset(pStats);
1292 if( nCycle>=0 && nTotal>0 ){
1293 qrfApproxInt64(pStats, nCycle);
1294 sqlite3_str_appendf(pStats, " %3d%%",
1295 ((nCycle*100)+nTotal/2) / nTotal
1296 );
1297 nSp = 2;
1298 }
1299 if( nLoop>=0 ){
1300 if( nSp ) sqlite3_str_appendchar(pStats, nSp, ' ');
@@ -1787,11 +1863,11 @@
1787 }
1788 if( i>0 ){
1789 sqlite3_str_append(pOut, (const char*)z, i);
1790 }
1791 switch( z[i] ){
1792 case '>': sqlite3_str_append(pOut, "&lt;", 4); break;
1793 case '&': sqlite3_str_append(pOut, "&amp;", 5); break;
1794 case '<': sqlite3_str_append(pOut, "&lt;", 4); break;
1795 case '"': sqlite3_str_append(pOut, "&quot;", 6); break;
1796 case '\'': sqlite3_str_append(pOut, "&#39;", 5); break;
1797 default: i--;
@@ -1977,16 +2053,22 @@
1977 return;
1978 }
1979 }
1980 switch( sqlite3_column_type(p->pStmt,iCol) ){
1981 case SQLITE_INTEGER: {
1982 sqlite3_str_appendf(pOut, "%lld", sqlite3_column_int64(p->pStmt,iCol));
 
1983 break;
1984 }
1985 case SQLITE_FLOAT: {
1986 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1987 sqlite3_str_appendall(pOut, zTxt);
 
 
 
 
 
1988 break;
1989 }
1990 case SQLITE_BLOB: {
1991 if( p->spec.bTextJsonb==QRF_Yes ){
1992 const char *zJson = qrfJsonbToJson(p, iCol);
@@ -2281,11 +2363,11 @@
2281 if( bWrap && z[i]!=0 && !qrfSpace(z[i]) && qrfAlnum(c)==qrfAlnum(z[i]) ){
2282 /* Perhaps try to back up to a better place to break the line */
2283 for(k=i-1; k>=i/2; k--){
2284 if( qrfSpace(z[k]) ) break;
2285 }
2286 if( k<i/2 ){
2287 for(k=i; k>=i/2; k--){
2288 if( qrfAlnum(z[k-1])!=qrfAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
2289 }
2290 }
2291 if( k>=i/2 ){
@@ -2522,10 +2604,14 @@
2522 /* Doubled horizontal lines: */
2523 #define DBL_24 "\342\225\220" /* U+2550 === */
2524 #define DBL_123 "\342\225\236" /* U+255e |= */
2525 #define DBL_134 "\342\225\241" /* U+2561 =| */
2526 #define DBL_1234 "\342\225\252" /* U+256a =|= */
 
 
 
 
2527
2528 /* Draw horizontal line N characters long using unicode box
2529 ** characters
2530 */
2531 static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2532,28 +2618,28 @@
2532 const char *azDash[2] = {
2533 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24,
2534 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24
2535 };/* 0 1 2 3 4 5 6 7 8 9 */
2536 const int nDash = 30;
2537 N *= 3;
2538 while( N>nDash ){
2539 sqlite3_str_append(pOut, azDash[bDbl], nDash);
2540 N -= nDash;
2541 }
2542 sqlite3_str_append(pOut, azDash[bDbl], N);
2543 }
2544
2545 /*
2546 ** Draw a horizontal separator for a QRF_STYLE_Box table.
2547 */
2548 static void qrfBoxSeparator(
2549 sqlite3_str *pOut,
2550 qrfColData *p,
2551 const char *zSep1,
2552 const char *zSep2,
2553 const char *zSep3,
2554 int bDbl
2555 ){
2556 int i;
2557 if( p->nCol>0 ){
2558 int useBorder = p->p->spec.bBorder!=QRF_No;
2559 if( useBorder ){
@@ -2568,10 +2654,36 @@
2568 sqlite3_str_appendall(pOut, zSep3);
2569 }
2570 }
2571 sqlite3_str_append(pOut, "\n", 1);
2572 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2573
2574 /*
2575 ** Load into pData the default alignment for the body of a table.
2576 */
2577 static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2610,11 +2722,11 @@
2610 int nSW /* Screen width */
2611 ){
2612 int i; /* Loop counter */
2613 int nr; /* Number of rows */
2614 int w = 0; /* Width of the current column */
2615 int t; /* Total width of all columns */
2616 int *aw; /* Array of individual column widths */
2617
2618 aw = sqlite3_malloc64( sizeof(int)*nCol );
2619 if( aw==0 ){
2620 qrfOom(p);
@@ -2748,12 +2860,15 @@
2748 }else{
2749 sepW = pData->nCol*3 + 1;
2750 if( p->spec.bBorder==QRF_No ) sepW -= 2;
2751 }
2752 nCol = pData->nCol;
2753 for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
2754 if( p->spec.nScreenWidth >= sumW+sepW ) return;
 
 
 
2755
2756 /* First thing to do is reduce the separation between columns */
2757 pData->nMargin = 0;
2758 if( p->spec.eStyle==QRF_STYLE_Column ){
2759 sepW = pData->nCol - 1;
@@ -2823,11 +2938,25 @@
2823 sqlite3_str *pStr; /* Temporary rendering */
2824 qrfColData data; /* Columnar layout data */
2825 int bRTrim; /* Trim trailing space */
2826
2827 rc = sqlite3_step(p->pStmt);
2828 if( rc!=SQLITE_ROW || nColumn==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2829 return; /* No output */
2830 }
2831
2832 /* Initialize the data container */
2833 memset(&data, 0, sizeof(data));
@@ -2840,12 +2969,12 @@
2840 }
2841 memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2842 if( qrfColDataEnlarge(&data) ) return;
2843 assert( data.az!=0 );
2844
2845 /* Load the column header names and all cell content into data */
2846 if( p->spec.bTitles==QRF_Yes ){
2847 unsigned char saved_eText = p->spec.eText;
2848 p->spec.eText = p->spec.eTitle;
2849 memset(data.abNum, 0, nColumn);
2850 for(i=0; i<nColumn; i++){
2851 const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2866,13 +2995,14 @@
2866 data.n++;
2867 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2868 if( nNL ) data.bMultiRow = 1;
2869 }
2870 p->spec.eText = saved_eText;
2871 p->nRow++;
2872 }
2873 do{
 
 
2874 if( data.n+nColumn > data.nAlloc ){
2875 if( qrfColDataEnlarge(&data) ) return;
2876 }
2877 for(i=0; i<nColumn; i++){
2878 char *z;
@@ -2889,11 +3019,12 @@
2889 data.n++;
2890 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2891 if( nNL ) data.bMultiRow = 1;
2892 }
2893 p->nRow++;
2894 }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
 
2895 if( p->iErr ){
2896 qrfColDataFree(&data);
2897 return;
2898 }
2899
@@ -3097,11 +3228,11 @@
3097 /* Draw either (1) the separator between the title line and the body
3098 ** of the table, or (2) separators between individual rows of the table
3099 ** body. isTitleDataSeparator will be true if we are doing (1).
3100 */
3101 if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3102 int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
3103 if( isTitleDataSeparator ){
3104 qrfLoadAlignment(&data, p);
3105 }
3106 switch( p->spec.eStyle ){
3107 case QRF_STYLE_Table: {
@@ -3124,19 +3255,12 @@
3124 }
3125 break;
3126 }
3127 case QRF_STYLE_Column: {
3128 if( isTitleDataSeparator ){
3129 for(j=0; j<nColumn; j++){
3130 sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
3131 if( j<nColumn-1 ){
3132 sqlite3_str_append(p->pOut, colSep, szColSep);
3133 }else{
3134 qrfRTrim(p->pOut);
3135 sqlite3_str_append(p->pOut, rowSep, szRowSep);
3136 }
3137 }
3138 }else if( data.bMultiRow ){
3139 qrfRTrim(p->pOut);
3140 sqlite3_str_append(p->pOut, "\n", 1);
3141 }
3142 break;
@@ -3144,20 +3268,39 @@
3144 }
3145 }
3146 }
3147
3148 /* Draw the line across the bottom of the table */
3149 if( p->spec.bBorder!=QRF_No ){
3150 switch( p->spec.eStyle ){
3151 case QRF_STYLE_Box:
3152 qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
 
 
 
 
3153 break;
3154 case QRF_STYLE_Table:
3155 qrfRowSeparator(p->pOut, &data, '+');
3156 break;
 
 
 
 
 
 
 
 
 
 
 
3157 }
3158 }
 
 
 
 
3159 qrfWrite(p);
3160
3161 qrfColDataFree(&data);
3162 return;
3163 }
@@ -3404,10 +3547,49 @@
3404 sqlite3_str_append(p->pOut, ":", 1);
3405 qrfRenderValue(p, p->pOut, i);
3406 }
3407 qrfWrite(p);
3408 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3409
3410 /*
3411 ** Render a single row of output for non-columnar styles - any
3412 ** style that lets us render row by row as the content is received
3413 ** from the query.
@@ -3437,25 +3619,19 @@
3437 }
3438 qrfOneJsonRow(p);
3439 break;
3440 }
3441 case QRF_STYLE_Html: {
3442 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3443 sqlite3_str_append(p->pOut, "<TR>", 4);
3444 for(i=0; i<p->nCol; i++){
3445 const char *zCName = sqlite3_column_name(p->pStmt, i);
3446 sqlite3_str_append(p->pOut, "\n<TH>", 5);
3447 qrfEncodeText(p, p->pOut, zCName);
3448 }
3449 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3450 }
3451 sqlite3_str_append(p->pOut, "<TR>", 4);
3452 for(i=0; i<p->nCol; i++){
3453 sqlite3_str_append(p->pOut, "\n<TD>", 5);
3454 qrfRenderValue(p, p->pOut, i);
3455 }
3456 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3457 qrfWrite(p);
3458 break;
3459 }
3460 case QRF_STYLE_Insert: {
3461 unsigned int mxIns = p->spec.nMultiInsert;
@@ -3468,11 +3644,11 @@
3468 if( qrf_need_quote(p->spec.zTableName) ){
3469 sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
3470 }else{
3471 sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
3472 }
3473 if( p->spec.bTitles==QRF_Yes ){
3474 for(i=0; i<p->nCol; i++){
3475 const char *zCName = sqlite3_column_name(p->pStmt, i);
3476 if( qrf_need_quote(zCName) ){
3477 sqlite3_str_appendf(p->pOut, "%c\"%w\"",
3478 i==0 ? '(' : ',', zCName);
@@ -3568,21 +3744,12 @@
3568 if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3569 qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3570 break;
3571 }
3572 default: { /* QRF_STYLE_List */
3573 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3574 int saved_eText = p->spec.eText;
3575 p->spec.eText = p->spec.eTitle;
3576 for(i=0; i<p->nCol; i++){
3577 const char *zCName = sqlite3_column_name(p->pStmt, i);
3578 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3579 qrfEncodeText(p, p->pOut, zCName);
3580 }
3581 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3582 qrfWrite(p);
3583 p->spec.eText = saved_eText;
3584 }
3585 for(i=0; i<p->nCol; i++){
3586 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3587 qrfRenderValue(p, p->pOut, i);
3588 }
@@ -3604,11 +3771,11 @@
3604 char **pzErr /* Write errors here */
3605 ){
3606 size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3607 memset(p, 0, sizeof(*p));
3608 p->pzErr = pzErr;
3609 if( pSpec->iVersion>1 ){
3610 qrfError(p, SQLITE_ERROR,
3611 "unusable sqlite3_qrf_spec.iVersion (%d)",
3612 pSpec->iVersion);
3613 return;
3614 }
@@ -3620,15 +3787,19 @@
3620 return;
3621 }
3622 p->iErr = SQLITE_OK;
3623 p->nCol = sqlite3_column_count(p->pStmt);
3624 p->nRow = 0;
3625 sz = sizeof(sqlite3_qrf_spec);
 
 
 
 
3626 memcpy(&p->spec, pSpec, sz);
3627 if( p->spec.zNull==0 ) p->spec.zNull = "";
3628 p->mxWidth = p->spec.nScreenWidth;
3629 if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3630 p->mxHeight = p->spec.nLineLimit;
3631 if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3632 if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3633 if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3634 if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
@@ -3756,10 +3927,24 @@
3756 if( p->spec.bTextJsonb==QRF_Auto ){
3757 p->spec.bTextJsonb = QRF_No;
3758 }
3759 if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = ",";
3760 if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3761 }
3762
3763 /*
3764 ** Finish rendering the results
3765 */
@@ -3890,10 +4075,34 @@
3890 default: {
3891 /* Non-columnar modes where the output can occur after each row
3892 ** of result is received */
3893 while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
3894 qrfOneSimpleRow(&qrf);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3895 }
3896 break;
3897 }
3898 }
3899 qrfResetStmt(&qrf);
@@ -5106,10 +5315,12 @@
5106 int rc;
5107 int n;
5108 const char *z;
5109 SHA3Context cx;
5110 int iSize;
 
 
5111
5112 if( argc==1 ){
5113 iSize = 256;
5114 }else{
5115 iSize = sqlite3_value_int(argv[1]);
@@ -5119,10 +5330,15 @@
5119 return;
5120 }
5121 }
5122 if( zSql==0 ) return;
5123 SHA3Init(&cx, iSize);
 
 
 
 
 
5124 while( zSql[0] ){
5125 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5126 if( rc ){
5127 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
5128 zSql, sqlite3_errmsg(db));
@@ -5145,19 +5361,25 @@
5145 sha3_step_vformat(&cx,"S%d:",n);
5146 SHA3Update(&cx,(unsigned char*)z,n);
5147 }
5148
5149 /* Compute a hash over the result of the query */
 
5150 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5151 SHA3Update(&cx,(const unsigned char*)"R",1);
5152 for(i=0; i<nCol; i++){
5153 sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
5154 }
5155 }
5156 sqlite3_finalize(pStmt);
 
5157 }
5158 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
 
 
 
 
5159 }
5160
5161 /*
5162 ** xStep function for sha3_agg().
5163 */
@@ -5272,10 +5494,14 @@
5272 #include <stdarg.h>
5273
5274 /******************************************************************************
5275 ** The Hash Engine
5276 */
 
 
 
 
5277 /* Context for the SHA1 hash */
5278 typedef struct SHA1Context SHA1Context;
5279 struct SHA1Context {
5280 unsigned int state[5];
5281 unsigned int count[2];
@@ -5412,11 +5638,11 @@
5412 }
5413 j = 0;
5414 }else{
5415 i = 0;
5416 }
5417 (void)memcpy(&p->buffer[j], &data[i], len - i);
5418 }
5419
5420 /* Compute a string using sqlite3_vsnprintf() and hash it */
5421 static void hash_step_vformat(
5422 SHA1Context *p, /* Add content to this context */
@@ -5467,10 +5693,13 @@
5467 zOut[i*2+1] = zEncode[digest[i] & 0xf];
5468 }
5469 zOut[i*2]= 0;
5470 }
5471 }
 
 
 
5472 /* End of the hashing logic
5473 *****************************************************************************/
5474
5475 /*
5476 ** Two SQL functions: sha1(X) and sha1b(X).
@@ -5501,11 +5730,14 @@
5501 if( eType==SQLITE_BLOB ){
5502 pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
5503 }else{
5504 pData = (const unsigned char*)sqlite3_value_text(argv[0]);
5505 }
5506 if( pData==0 ) return;
 
 
 
5507 hash_step(&cx, pData, nByte);
5508 if( sqlite3_user_data(context)!=0 ){
5509 /* sha1b() - binary result */
5510 hash_finish(&cx, zOut, 1);
5511 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5541,13 +5773,20 @@
5541 int rc;
5542 int n;
5543 const char *z;
5544 SHA1Context cx;
5545 char zOut[44];
 
 
5546
5547 assert( argc==1 );
5548 if( zSql==0 ) return;
 
 
 
 
 
5549 hash_init(&cx);
5550 while( zSql[0] ){
5551 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5552 if( rc ){
5553 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5570,10 +5809,11 @@
5570 n = (int)strlen(z);
5571 hash_step_vformat(&cx,"S%d:",n);
5572 hash_step(&cx,(unsigned char*)z,n);
5573
5574 /* Compute a hash over the result of the query */
 
5575 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5576 hash_step(&cx,(const unsigned char*)"R",1);
5577 for(i=0; i<nCol; i++){
5578 switch( sqlite3_column_type(pStmt,i) ){
5579 case SQLITE_NULL: {
@@ -5624,13 +5864,18 @@
5624 }
5625 }
5626 }
5627 }
5628 sqlite3_finalize(pStmt);
 
5629 }
5630 hash_finish(&cx, zOut, 0);
5631 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
 
 
 
 
5632 }
5633
5634
5635 #ifdef _WIN32
5636
@@ -5824,10 +6069,13 @@
5824 }
5825
5826 /*
5827 ** Allocate a new Decimal object initialized to the text in zIn[].
5828 ** Return NULL if any kind of error occurs.
 
 
 
5829 */
5830 static Decimal *decimalNewFromText(const char *zIn, int n){
5831 Decimal *p = 0;
5832 int i;
5833 int iExp = 0;
@@ -5841,15 +6089,15 @@
5841 p->isNull = 0;
5842 p->nDigit = 0;
5843 p->nFrac = 0;
5844 p->a = sqlite3_malloc64( n+1 );
5845 if( p->a==0 ) goto new_from_text_failed;
5846 for(i=0; IsSpace(zIn[i]); i++){}
5847 if( zIn[i]=='-' ){
5848 p->sign = 1;
5849 i++;
5850 }else if( zIn[i]=='+' ){
5851 i++;
5852 }
5853 while( i<n && zIn[i]=='0' ) i++;
5854 while( i<n ){
5855 char c = zIn[i];
@@ -6056,32 +6304,41 @@
6056 }
6057 z[i] = 0;
6058 sqlite3_result_text(pCtx, z, i, sqlite3_free);
6059 }
6060
 
 
 
6061 /*
6062 ** Round a decimal value to N significant digits. N must be positive.
6063 */
6064 static void decimal_round(Decimal *p, int N){
6065 int i;
6066 int nZero;
6067 if( N<1 ) return;
6068 if( p==0 ) return;
6069 if( p->nDigit<=N ) return;
6070 for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
6071 N += nZero;
6072 if( p->nDigit<=N ) return;
6073 if( p->a[N]>4 ){
 
 
 
 
 
 
 
 
 
6074 p->a[N-1]++;
6075 for(i=N-1; i>0 && p->a[i]>9; i--){
6076 p->a[i] = 0;
6077 p->a[i-1]++;
6078 }
6079 if( p->a[0]>9 ){
6080 p->a[0] = 1;
6081 p->nFrac--;
6082 }
6083 }
6084 memset(&p->a[N], 0, p->nDigit - N);
6085 }
6086
6087 /*
@@ -6225,10 +6482,11 @@
6225 int nAddSig;
6226 int nAddFrac;
6227 signed char *a;
6228 if( p==0 ) return;
6229 nAddFrac = nFrac - p->nFrac;
 
6230 nAddSig = (nDigit - p->nDigit) - nAddFrac;
6231 if( nAddFrac==0 && nAddSig==0 ) return;
6232 if( nDigit+1>SQLITE_DECIMAL_MAX_DIGIT ){ p->oom = 1; return; }
6233 a = sqlite3_realloc64(p->a, nDigit+1);
6234 if( a==0 ){
@@ -8232,10 +8490,20 @@
8232 if( r==(double)x ) return r;
8233 if( r<(double)x ) x--;
8234 return (double)x;
8235 }
8236 #endif
 
 
 
 
 
 
 
 
 
 
8237
8238 /*
8239 ** This method is called to "rewind" the series_cursor object back
8240 ** to the first row of output. This method is always called at least
8241 ** once prior to any call to seriesColumn() or seriesRowid() or
@@ -8355,27 +8623,31 @@
8355 double r = sqlite3_value_double(argv[iArg++]);
8356 if( r==seriesCeil(r)
8357 && r>=(double)SMALLEST_INT64
8358 && r<=(double)LARGEST_INT64
8359 ){
8360 iMin = iMax = (sqlite3_int64)r;
8361 }else{
8362 goto series_no_rows;
8363 }
8364 }else{
8365 iMin = iMax = sqlite3_value_int64(argv[iArg++]);
8366 }
8367 }else{
8368 if( idxNum & 0x0300 ){ /* value>X or value>=X */
8369 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
8370 double r = sqlite3_value_double(argv[iArg++]);
8371 if( r<(double)SMALLEST_INT64 ){
8372 iMin = SMALLEST_INT64;
8373 }else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
8374 iMin = (sqlite3_int64)seriesCeil(r+1.0);
8375 }else{
8376 iMin = (sqlite3_int64)seriesCeil(r);
 
 
 
 
8377 }
8378 }else{
8379 iMin = sqlite3_value_int64(argv[iArg++]);
8380 if( (idxNum & 0x0200)!=0 ){
8381 if( iMin==LARGEST_INT64 ){
@@ -8384,19 +8656,23 @@
8384 iMin++;
8385 }
8386 }
8387 }
8388 }
8389 if( idxNum & 0x3000 ){ /* value<X or value<=X */
8390 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
8391 double r = sqlite3_value_double(argv[iArg++]);
8392 if( r>(double)LARGEST_INT64 ){
8393 iMax = LARGEST_INT64;
8394 }else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
8395 iMax = (sqlite3_int64)(r-1.0);
8396 }else{
8397 iMax = (sqlite3_int64)seriesFloor(r);
 
 
 
 
8398 }
8399 }else{
8400 iMax = sqlite3_value_int64(argv[iArg++]);
8401 if( idxNum & 0x2000 ){
8402 if( iMax==SMALLEST_INT64 ){
@@ -9638,11 +9914,10 @@
9638 if( pRe==0 ){
9639 sqlite3_result_error_nomem(context);
9640 return;
9641 }
9642 pStr = sqlite3_str_new(0);
9643 if( pStr==0 ) goto re_bytecode_func_err;
9644 if( pRe->nInit>0 ){
9645 sqlite3_str_appendf(pStr, "INIT ");
9646 for(i=0; i<pRe->nInit; i++){
9647 sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]);
9648 }
@@ -9649,20 +9924,20 @@
9649 sqlite3_str_appendf(pStr, "\n");
9650 }
9651 for(i=0; (unsigned)i<pRe->nState; i++){
9652 sqlite3_str_appendf(pStr, "%-8s %4d\n",
9653 ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
 
 
 
 
 
 
9654 }
9655 n = sqlite3_str_length(pStr);
9656 z = sqlite3_str_finish(pStr);
9657 if( n==0 ){
9658 sqlite3_free(z);
9659 }else{
9660 sqlite3_result_text(context, z, n-1, sqlite3_free);
9661 }
9662
9663 re_bytecode_func_err:
9664 re_free(pRe);
9665 }
9666
9667 #endif /* SQLITE_DEBUG */
9668
@@ -10557,11 +10832,15 @@
10557 sqlite3_result_error_nomem(ctx);
10558 return SQLITE_NOMEM;
10559 }
10560 }
10561
10562 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
 
 
 
 
10563 if( aBuf!=aStatic ) sqlite3_free(aBuf);
10564 #endif
10565 }else{
10566 readFileContents(ctx, pCur->zPath);
10567 }
@@ -10870,10 +11149,13 @@
10870 ** Return NULL if unable.
10871 **
10872 ** The file or directory X is not required to exist. The answer is formed
10873 ** by calling system realpath() on the prefix of X that does exist and
10874 ** appending the tail of X that does not (yet) exist.
 
 
 
10875 */
10876 static void realpathFunc(
10877 sqlite3_context *context,
10878 int argc,
10879 sqlite3_value **argv
@@ -10892,10 +11174,11 @@
10892 (void)argc;
10893 zPath = (const char*)sqlite3_value_text(argv[0]);
10894 if( zPath==0 ) return;
10895 if( zPath[0]==0 ) zPath = ".";
10896 zCopy = sqlite3_mprintf("%s",zPath);
 
10897 len = strlen(zCopy);
10898 while( len>1 && (zCopy[len-1]=='/' || (isWin && zCopy[len-1]=='\\')) ){
10899 len--;
10900 }
10901 zCopy[len] = 0;
@@ -11802,11 +12085,13 @@
11802 int iAmt,
11803 sqlite_int64 iOfst
11804 ){
11805 ApndFile *paf = (ApndFile *)pFile;
11806 sqlite_int64 iWriteEnd = iOfst + iAmt;
11807 if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
 
 
11808 pFile = ORIGFILE(pFile);
11809 /* If append-mark is absent or will be overwritten, write it. */
11810 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
11811 int rc = apndWriteMark(paf, pFile, iWriteEnd);
11812 if( SQLITE_OK!=rc ) return rc;
@@ -12220,10 +12505,12 @@
12220 **
12221 ** * No support for encryption
12222 ** * No support for ZIP archives spanning multiple files
12223 ** * No support for zip64 extensions
12224 ** * Only the "inflate/deflate" (zlib) compression method is supported
 
 
12225 */
12226 /* #include "sqlite3ext.h" */
12227 SQLITE_EXTENSION_INIT1
12228 #include <stdio.h>
12229 #include <string.h>
@@ -12685,10 +12972,11 @@
12685
12686 for(p=pCsr->pFreeEntry; p; p=pNext){
12687 pNext = p->pNext;
12688 zipfileEntryFree(p);
12689 }
 
12690 }
12691
12692 /*
12693 ** Destructor for an ZipfileCsr.
12694 */
@@ -13087,11 +13375,17 @@
13087 }
13088 }
13089
13090 if( rc==SQLITE_OK ){
13091 u32 *pt = &pNew->mUnixTime;
13092 pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
 
 
 
 
 
 
13093 pNew->aExtra = (u8*)&pNew[1];
13094 memcpy(pNew->aExtra, &aRead[nFile], nExtra);
13095 if( pNew->cds.zFile==0 ){
13096 rc = SQLITE_NOMEM;
13097 }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
@@ -13844,14 +14138,14 @@
13844 if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
13845 bUpdate = 1;
13846 }
13847 }
13848 for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
 
13849 if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
13850 break;
13851 }
13852 assert( pOld->pNext );
13853 }
13854 }
13855
13856 if( nVal>1 ){
13857 /* Check that "sz" and "rawdata" are both NULL: */
@@ -14191,14 +14485,14 @@
14191 ZipfileBuffer body;
14192 ZipfileBuffer cds;
14193 };
14194
14195 static int zipfileBufferGrow(ZipfileBuffer *pBuf, i64 nByte){
14196 if( pBuf->n+nByte>pBuf->nAlloc ){
14197 u8 *aNew;
14198 sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
14199 int nReq = pBuf->n + nByte;
14200
14201 while( nNew<nReq ) nNew = nNew*2;
14202 aNew = sqlite3_realloc64(pBuf->a, nNew);
14203 if( aNew==0 ) return SQLITE_NOMEM;
14204 pBuf->a = aNew;
@@ -14410,11 +14704,11 @@
14410 eocd.nEntry = (u16)p->nEntry;
14411 eocd.nEntryTotal = (u16)p->nEntry;
14412 eocd.nSize = p->cds.n;
14413 eocd.iOffset = p->body.n;
14414
14415 nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
14416 aZip = (u8*)sqlite3_malloc64(nZip);
14417 if( aZip==0 ){
14418 sqlite3_result_error_nomem(pCtx);
14419 }else{
14420 memcpy(aZip, p->body.a, p->body.n);
@@ -16296,11 +16590,11 @@
16296 p->pTable = pTab;
16297
16298 /* The statement the vtab will pass to sqlite3_declare_vtab() */
16299 zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
16300 for(i=0; i<pTab->nCol; i++){
16301 zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
16302 (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
16303 );
16304 }
16305 zInner = idxAppendText(&rc, zInner, ")");
16306
@@ -16496,11 +16790,11 @@
16496 sqlite3_free(zCols);
16497 sqlite3_free(zOrder);
16498 return sqlite3_reset(pIndexXInfo);
16499 }
16500 zCols = idxAppendText(&rc, zCols,
16501 "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
16502 zComma, zName, nCol, zName, zColl
16503 );
16504 zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
16505 }
16506 sqlite3_reset(pIndexXInfo);
@@ -17537,16 +17831,19 @@
17537 }
17538 iRet++;
17539 }
17540 }
17541 else if( c=='[' ){
17542 while( z[iRet++]!=']' && z[iRet] );
17543 }
17544 else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
17545 while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
17546 iRet++;
17547 }
 
 
 
17548 }
17549
17550 return iRet;
17551 }
17552
@@ -17983,10 +18280,27 @@
17983 intckFinalize(p, pStmt);
17984
17985 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
17986 return zRet;
17987 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17988
17989 /*
17990 ** Open a new integrity-check object.
17991 */
17992 int sqlite3_intck_open(
@@ -18005,13 +18319,11 @@
18005 }else{
18006 memset(pNew, 0, sizeof(*pNew));
18007 pNew->db = db;
18008 pNew->zDb = (const char*)&pNew[1];
18009 memcpy(&pNew[1], zDb, nDb+1);
18010 rc = sqlite3_create_function(db, "parse_create_index",
18011 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
18012 );
18013 if( rc!=SQLITE_OK ){
18014 sqlite3_intck_close(pNew);
18015 pNew = 0;
18016 }
18017 }
@@ -18024,13 +18336,11 @@
18024 ** Free the integrity-check object.
18025 */
18026 void sqlite3_intck_close(sqlite3_intck *p){
18027 if( p ){
18028 sqlite3_finalize(p->pCheck);
18029 sqlite3_create_function(
18030 p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
18031 );
18032 sqlite3_free(p->zObj);
18033 sqlite3_free(p->zKey);
18034 sqlite3_free(p->zTestSql);
18035 sqlite3_free(p->zErr);
18036 sqlite3_free(p->zMessage);
@@ -19464,11 +19774,11 @@
19464 sqlite3_vfs_unregister(pVfs);
19465 sqlite3_free(pVfs);
19466 }
19467
19468 /************************* End ext/misc/vfstrace.c ********************/
19469 /************************* Begin ext/misc/analyze.c ******************/
19470 /*
19471 ** 2026-04-13
19472 **
19473 ** The author disclaims copyright to this source code. In place of
19474 ** a legal notice, here is a blessing:
@@ -19477,12 +19787,21 @@
19477 ** May you find forgiveness for yourself and forgive others.
19478 ** May you share freely, never taking more than you give.
19479 **
19480 ******************************************************************************
19481 **
19482 ** Partial reimplement of the sqlite3_analyzer utility program as
19483 ** loadable SQL function.
 
 
 
 
 
 
 
 
 
19484 */
19485 /* #include "sqlite3ext.h" */
19486 SQLITE_EXTENSION_INIT1
19487 #include <assert.h>
19488 #include <string.h>
@@ -19490,28 +19809,28 @@
19490 #include <math.h>
19491
19492 /*
19493 ** State information for the analysis
19494 */
19495 typedef struct Analysis Analysis;
19496 struct Analysis {
19497 sqlite3 *db; /* Database connection */
19498 sqlite3_context *context; /* SQL function context */
19499 sqlite3_str *pOut; /* Write output here */
19500 char *zSU; /* Name of the temp.space_used table */
19501 const char *zSchema; /* Schema to be analyzed */
19502 };
19503
19504 /*
19505 ** Free all resources that the Analysis object references and
19506 ** reset the Analysis object.
19507 **
19508 ** Call this routine multiple times on the same Analysis object
19509 ** is a harmless no-op, as long as the memory for the object itself
19510 ** has not been freed.
19511 */
19512 static void analysisReset(Analysis *p){
19513 if( p->zSU ){
19514 char *zSql = sqlite3_mprintf("DROP TABLE temp.%s;", p->zSU);
19515 if( zSql ){
19516 sqlite3_exec(p->db, zSql, 0, 0, 0);
19517 sqlite3_free(zSql);
@@ -19524,11 +19843,11 @@
19524
19525 /*
19526 ** Report an error using formatted text. If zFormat==NULL then report
19527 ** an OOM error.
19528 */
19529 static void analysisError(Analysis *p, const char *zFormat, ...){
19530 char *zErr;
19531 if( zFormat ){
19532 va_list ap;
19533 va_start(ap, zFormat);
19534 zErr = sqlite3_vmprintf(zFormat, ap);
@@ -19540,38 +19859,38 @@
19540 sqlite3_result_error_nomem(p->context);
19541 }else{
19542 sqlite3_result_error(p->context, zErr, -1);
19543 sqlite3_free(zErr);
19544 }
19545 analysisReset(p);
19546 }
19547
19548 /*
19549 ** Prepare and return an SQL statement.
19550 */
19551 static sqlite3_stmt *analysisVPrep(Analysis *p, const char *zFmt, va_list ap){
19552 char *zSql;
19553 int rc;
19554 sqlite3_stmt *pStmt = 0;
19555 zSql = sqlite3_vmprintf(zFmt, ap);
19556 if( zSql==0 ){ analysisError(p,0); return 0; }
19557 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19558 if( rc ){
19559 analysisError(p, "SQL parse error: %s\nOriginal SQL: %s",
19560 sqlite3_errmsg(p->db), zSql);
19561 sqlite3_finalize(pStmt);
19562 analysisReset(p);
19563 pStmt = 0;
19564 }
19565 sqlite3_free(zSql);
19566 return pStmt;
19567 }
19568 static sqlite3_stmt *analysisPrepare(Analysis *p, const char *zFormat, ...){
19569 va_list ap;
19570 sqlite3_stmt *pStmt = 0;
19571 va_start(ap, zFormat);
19572 pStmt = analysisVPrep(p,zFormat,ap);
19573 va_end(ap);
19574 return pStmt;
19575 }
19576
19577 /*
@@ -19580,60 +19899,60 @@
19580 **
19581 ** If rc is SQLITE_DONE or SQLITE_OK, then return false.
19582 **
19583 ** The prepared statement is closed in either case.
19584 */
19585 static int analysisStmtFinish(Analysis *p, int rc, sqlite3_stmt *pStmt){
19586 if( rc==SQLITE_DONE ){
19587 rc = SQLITE_OK;
19588 }
19589 if( rc!=SQLITE_OK || (rc = sqlite3_reset(pStmt))!=SQLITE_OK ){
19590 analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19591 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19592 analysisReset(p);
19593 }
19594 sqlite3_finalize(pStmt);
19595 return rc;
19596 }
19597
19598 /*
19599 ** Run SQL. Return the number of errors.
19600 */
19601 static int analysisSql(Analysis *p, const char *zFormat, ...){
19602 va_list ap;
19603 int rc;
19604 sqlite3_stmt *pStmt = 0;
19605 va_start(ap, zFormat);
19606 pStmt = analysisVPrep(p,zFormat,ap);
19607 va_end(ap);
19608 if( pStmt==0 ) return 1;
19609 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
19610 if( rc==SQLITE_DONE ){
19611 rc = SQLITE_OK;
19612 }else{
19613 analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19614 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19615 analysisReset(p);
19616 }
19617 sqlite3_finalize(pStmt);
19618 return rc;
19619 }
19620
19621 /*
19622 ** Run an SQL query that returns an integer. Write that integer
19623 ** into *piRes. Return the number of errors.
19624 */
19625 static int analysisSqlInt(
19626 Analysis *p,
19627 sqlite3_int64 *piRes,
19628 const char *zFormat, ...
19629 ){
19630 va_list ap;
19631 int rc;
19632 sqlite3_stmt *pStmt = 0;
19633 va_start(ap, zFormat);
19634 pStmt = analysisVPrep(p,zFormat,ap);
19635 va_end(ap);
19636 if( pStmt==0 ) return 1;
19637 rc = sqlite3_step(pStmt);
19638 if( rc==SQLITE_ROW ){
19639 *piRes = sqlite3_column_int64(pStmt, 0);
@@ -19641,14 +19960,14 @@
19641 }else if( rc==SQLITE_DONE ){
19642 rc = SQLITE_OK;
19643 }else{
19644 if( p->db ){
19645 /* p->db is NULL if there was some prior error */
19646 analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19647 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19648 }
19649 analysisReset(p);
19650 }
19651 sqlite3_finalize(pStmt);
19652 return rc;
19653 }
19654
@@ -19657,20 +19976,20 @@
19657 ** by the format string. If the output is initially empty, begin
19658 ** the title line with "/" so that it forms the beginning of a C-style
19659 ** comment. Otherwise begin with a new-line. Always finish with a
19660 ** newline.
19661 */
19662 static void analysisTitle(Analysis *p, const char *zFormat, ...){
19663 char *zFirst;
19664 char *zTitle;
19665 size_t nTitle;
19666 va_list ap;
19667 va_start(ap, zFormat);
19668 zTitle = sqlite3_vmprintf(zFormat, ap);
19669 va_end(ap);
19670 if( zTitle==0 ){
19671 analysisError(p, 0);
19672 return;
19673 }
19674 zFirst = sqlite3_str_length(p->pOut)==0 ? "/" : "\n*";
19675 nTitle = strlen(zTitle);
19676 if( nTitle>=75 ){
@@ -19685,12 +20004,12 @@
19685 /*
19686 ** Add an output line that begins with the zDesc text extended out to
19687 ** 50 columns with "." characters, and followed by whatever text is
19688 ** described by zFormat.
19689 */
19690 static void analysisLine(
19691 Analysis *p, /* Analysis context */
19692 const char *zDesc, /* Description */
19693 const char *zFormat, /* Argument to the description */
19694 ...
19695 ){
19696 char *zTxt;
@@ -19698,14 +20017,14 @@
19698 va_list ap;
19699 va_start(ap, zFormat);
19700 zTxt = sqlite3_vmprintf(zFormat, ap);
19701 va_end(ap);
19702 if( zTxt==0 ){
19703 analysisError(p, 0);
19704 return;
19705 }
19706 nDesc = strlen(zDesc);
19707 if( nDesc>=50 ){
19708 sqlite3_str_appendf(p->pOut, "%s %z", zDesc, zTxt);
19709 }else{
19710 int nExtra = 50 - (int)nDesc;
19711 sqlite3_str_appendf(p->pOut, "%s%.*c %z", zDesc, nExtra, '.', zTxt);
@@ -19715,15 +20034,28 @@
19715 /*
19716 ** Write a percentage into the output. The number written should show
19717 ** two or three significant digits, with the decimal point being the fourth
19718 ** character.
19719 */
19720 static void analysisPercent(Analysis *p, double r){
 
 
 
 
19721 char zNum[100];
19722 char *zDP;
19723 int nLeadingDigit;
19724 int sz;
 
 
 
 
 
 
 
 
 
19725 sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
19726 sz = (int)strlen(zNum);
19727 zDP = strchr(zNum, '.');
19728 if( zDP==0 ){
19729 memcpy(zNum+sz,".0",3);
@@ -19744,12 +20076,12 @@
19744 **
19745 ** The title if the subreport is given by zTitle. zWhere is
19746 ** a boolean expression that can go in the WHERE clause to select
19747 ** the relevant rows of the s.zSU table.
19748 */
19749 static int analysisSubreport(
19750 Analysis *p, /* Analysis context */
19751 char *zTitle, /* Title for this subreport */
19752 char *zWhere, /* WHERE clause for this subreport */
19753 sqlite3_int64 pgsz, /* Database page size */
19754 sqlite3_int64 nPage /* Number of pages in entire database */
19755 ){
@@ -19773,14 +20105,14 @@
19773 sqlite3_int64 total_unused; /* Total unused bytes */
19774 sqlite3_int64 total_meta; /* Total metadata */
19775 int rc;
19776
19777 if( zTitle==0 || zWhere==0 ){
19778 analysisError(p, 0);
19779 return SQLITE_NOMEM;
19780 }
19781 pStmt = analysisPrepare(p,
19782 "SELECT\n"
19783 " sum(if(is_without_rowid OR is_index,nentry,leaf_entries)),\n" /* 0 */
19784 " sum(payload),\n" /* 1 */
19785 " sum(ovfl_payload),\n" /* 2 */
19786 " max(mx_payload),\n" /* 3 */
@@ -19797,11 +20129,11 @@
19797 " FROM temp.%s WHERE %s",
19798 p->zSU, zWhere);
19799 if( pStmt==0 ) return 1;
19800 rc = sqlite3_step(pStmt);
19801 if( rc==SQLITE_ROW ){
19802 analysisTitle(p, zTitle);
19803
19804 nentry = sqlite3_column_int64(pStmt, 0);
19805 payload = sqlite3_column_int64(pStmt, 1);
19806 ovfl_payload = sqlite3_column_int64(pStmt, 2);
19807 mx_payload = sqlite3_column_int64(pStmt, 3);
@@ -19816,73 +20148,73 @@
19816 cnt = sqlite3_column_int64(pStmt, 12);
19817 int_cell = sqlite3_column_int64(pStmt, 13);
19818 rc = SQLITE_DONE;
19819
19820 total_pages = leaf_pages + int_pages + ovfl_pages;
19821 analysisLine(p, "Percentage of total database", "%.3g%%\n",
19822 (total_pages*100.0)/(double)nPage);
19823 analysisLine(p, "Number of entries", "%lld\n", nentry);
19824 storage = total_pages*pgsz;
19825 analysisLine(p, "Bytes of storage consumed", "%lld\n", storage);
19826 analysisLine(p, "Bytes of payload", "%-11lld ", payload);
19827 analysisPercent(p, payload*100.0/(double)storage);
19828 if( ovfl_cnt>0 ){
19829 analysisLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
19830 analysisPercent(p, ovfl_payload*100.0/(double)payload);
19831 }
19832 total_unused = leaf_unused + int_unused + ovfl_unused;
19833 total_meta = storage - payload - total_unused;
19834 analysisLine(p, "Bytes of metadata","%-11lld ", total_meta);
19835 analysisPercent(p, total_meta*100.0/(double)storage);
19836 if( cnt==1 ){
19837 analysisLine(p, "B-tree depth", "%lld\n", depth);
19838 if( int_cell>1 ){
19839 analysisLine(p, "Average fanout", "%.1f\n",
19840 (double)(int_cell+int_pages)/(double)int_pages);
19841 }
19842 }
19843 if( nentry>0 ){
19844 analysisLine(p, "Average payload per entry", "%.1f\n",
19845 (double)payload/(double)nentry);
19846 analysisLine(p, "Average unused bytes per entry", "%.1f\n",
19847 (double)total_unused/(double)nentry);
19848 analysisLine(p, "Average metadata per entry", "%.1f\n",
19849 (double)total_meta/(double)nentry);
19850 }
19851 analysisLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
19852 if( nentry>0 ){
19853 analysisLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
19854 analysisPercent(p, ovfl_cnt*100.0/(double)nentry);
19855 }
19856 if( int_pages>0 ){
19857 analysisLine(p, "Index pages used", "%lld\n", int_pages);
19858 }
19859 analysisLine(p, "Primary pages used", "%lld\n", leaf_pages);
19860 if( ovfl_cnt ){
19861 analysisLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
19862 }
19863 analysisLine(p, "Total pages used", "%lld\n", total_pages);
19864 if( int_pages>0 ){
19865 analysisLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
19866 }
19867 analysisLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
19868 if( ovfl_cnt ){
19869 analysisLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
19870 }
19871 analysisLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
19872 analysisPercent(p, total_unused*100.0/(double)storage);
19873 }
19874 return analysisStmtFinish(p, rc, pStmt);
19875 }
19876
19877 /*
19878 ** SQL Function: analyze(SCHEMA)
19879 **
19880 ** Analyze the database schema named in the argument. Return text
19881 ** containing the analysis.
19882 */
19883 static void analyzeFunc(
19884 sqlite3_context *context,
19885 int argc,
19886 sqlite3_value **argv
19887 ){
19888 int rc;
@@ -19893,47 +20225,47 @@
19893 sqlite3_int64 nPage;
19894 sqlite3_int64 nPageInUse;
19895 sqlite3_int64 nFreeList;
19896 sqlite3_int64 nIndex;
19897 sqlite3_int64 nWORowid;
19898 Analysis s;
19899 sqlite3_uint64 r[2];
19900
19901 (void)argc;
19902 memset(&s, 0, sizeof(s));
19903 s.db = sqlite3_context_db_handle(context);
19904 s.context = context;
19905 s.pOut = sqlite3_str_new(0);
19906 if( sqlite3_str_errcode(s.pOut) ){
19907 analysisError(&s, 0);
19908 return;
19909 }
19910 s.zSchema = (const char*)sqlite3_value_text(argv[0]);
19911 if( s.zSchema==0 ){
19912 s.zSchema = "main";
19913 }else if( sqlite3_strlike("temp",s.zSchema,0)==0 ){
19914 analysisReset(&s);
19915 sqlite3_result_text(context, "cannot analyze \"temp\"",-1,SQLITE_STATIC);
19916 return;
19917 }
19918 ii = 0;
19919 rc = analysisSqlInt(&s,&ii,"SELECT 1 FROM pragma_database_list"
19920 " WHERE name=%Q COLLATE nocase",s.zSchema);
19921 if( rc || ii==0 ){
19922 analysisReset(&s);
19923 sqlite3_result_text(context,"no such database",-1,SQLITE_STATIC);
19924 return;
19925 }
19926 sqlite3_randomness(sizeof(r), &r);
19927 s.zSU = sqlite3_mprintf("analysis%016llx%016llx", r[0], r[1]);
19928 if( s.zSU==0 ){ analysisError(&s, 0); return; }
19929
19930 /* The s.zSU table contains the data used for the analysis.
19931 ** The table name contains 128-bits of randomness to avoid
19932 ** collisions with preexisting tables in temp.
19933 */
19934 rc = analysisSql(&s,
19935 "CREATE TABLE temp.%s(\n"
19936 " name text, -- A table or index\n"
19937 " tblname text, -- Table that owns name\n"
19938 " is_index boolean, -- TRUE if it is an index\n"
19939 " is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n"
@@ -19956,11 +20288,11 @@
19956 );
19957 if( rc ) return;
19958
19959 /* Populate the s.zSU table
19960 */
19961 rc = analysisSql(&s,
19962 "WITH\n"
19963 " allidx(idxname) AS (\n"
19964 " SELECT name FROM \"%w\".sqlite_schema WHERE type='index'\n"
19965 " ),\n"
19966 " allobj(allname,tblname,isidx,isworowid) AS (\n"
@@ -20008,141 +20340,143 @@
20008 s.zSchema /* JOIN dbstat(%Q) */
20009 );
20010 if( rc ) return;
20011
20012 nPage = 0;
20013 rc = analysisSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
20014 if( rc ) return;
20015 if( nPage<=0 ){
20016 /* Very brief reply for an empty database */
20017 analysisReset(&s);
20018 sqlite3_result_text(context, "empty database", -1, SQLITE_STATIC);
20019 return;
20020 }
20021
20022 /* Begin generating the report */
20023 analysisTitle(&s, "Database storage utilization report");
20024 pgsz = 0;
20025 rc = analysisSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
20026 if( rc ) return;
20027 analysisLine(&s, "Page size in bytes","%lld\n",pgsz);
20028 analysisLine(&s, "Pages in the database", "%lld\n", nPage);
20029
20030 nPageInUse = 0;
20031 rc = analysisSqlInt(&s, &nPageInUse,
20032 "SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
20033 if( rc ) return;
20034 analysisLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20035 analysisPercent(&s, (nPageInUse*100.0)/(double)nPage);
20036
20037 nFreeList = 0;
20038 rc = analysisSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
20039 if( rc ) return;
20040 analysisLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20041 analysisPercent(&s, (nFreeList*100.0)/(double)nPage);
20042
20043 ii = 0;
20044 rc = analysisSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
20045 if( rc ) return;
20046 if( ii==0 || nPage<=1 ){
20047 ii = 0;
20048 }else{
20049 double rPtrsPerPage = pgsz/5;
20050 double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
20051 ii = (sqlite3_int64)ceil(rAvPage);
20052 }
20053 analysisLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20054 analysisPercent(&s, (ii*100.0)/(double)nPage);
20055
20056 ii = 0;
20057 rc = analysisSqlInt(&s, &ii,
20058 "SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
20059 s.zSchema);
20060 if( rc ) return;
20061 analysisLine(&s, "Number of tables", "%lld\n", ii);
20062 nWORowid = 0;
20063 rc = analysisSqlInt(&s, &nWORowid,
20064 "SELECT count(*) FROM \"%w\".pragma_table_list WHERE wr",
20065 s.zSchema);
20066 if( rc ) return;
20067 if( nWORowid>0 ){
20068 analysisLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
20069 analysisLine(&s, "Number of rowid tables", "%lld\n", ii - nWORowid);
20070 }
20071 nIndex = 0;
20072 rc = analysisSqlInt(&s, &nIndex,
20073 "SELECT count(*) FROM \"%w\".sqlite_schema WHERE type='index'",
20074 s.zSchema);
20075 if( rc ) return;
20076 analysisLine(&s, "Number of indexes", "%lld\n", nIndex);
20077 ii = 0;
20078 rc = analysisSqlInt(&s, &ii,
20079 "SELECT count(*) FROM \"%w\".sqlite_schema"
20080 " WHERE name GLOB 'sqlite_autoindex_*' AND type='index'",
20081 s.zSchema);
20082 if( rc ) return;
20083 analysisLine(&s, "Number of defined indexes", "%lld\n", nIndex - ii);
20084 analysisLine(&s, "Number of implied indexes", "%lld\n", ii);
20085 analysisLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
20086 ii = 0;
20087 rc = analysisSqlInt(&s, &ii,
20088 "SELECT sum(payload) FROM temp.%s"
20089 " WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
20090 s.zSU);
20091 if( rc ) return;
20092 analysisLine(&s, "Bytes of payload", "%-11lld ", ii);
20093 analysisPercent(&s, ii*100.0/(double)(pgsz*nPage));
20094
20095 analysisTitle(&s, "Page counts for all tables with their indexes");
20096 pStmt = analysisPrepare(&s,
20097 "SELECT upper(tblname),\n"
20098 " sum(int_pages+leaf_pages+ovfl_pages)\n"
20099 " FROM temp.%s\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20100 " GROUP BY 1\n"
20101 " ORDER BY 2 DESC, 1;",
20102 s.zSU);
20103 if( pStmt==0 ) return;
20104 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20105 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20106 analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20107 analysisPercent(&s, (nn*100.0)/(double)nPage);
20108 }
20109 if( analysisStmtFinish(&s, rc, pStmt) ) return;
20110
20111 analysisTitle(&s, "Page counts for all tables and indexes separately");
20112 pStmt = analysisPrepare(&s,
20113 "SELECT upper(name),\n"
20114 " sum(int_pages+leaf_pages+ovfl_pages)\n"
20115 " FROM temp.%s\n"
20116 " GROUP BY 1\n"
20117 " ORDER BY 2 DESC, 1;",
20118 s.zSU);
20119 if( pStmt==0 ) return;
20120 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20121 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20122 analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20123 analysisPercent(&s, (nn*100.0)/(double)nPage);
20124 }
20125 if( analysisStmtFinish(&s, rc, pStmt) ) return;
20126
20127 rc = analysisSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
20128 if( rc ) return;
20129 rc = analysisSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
20130 if( rc ) return;
20131 if( nWORowid>0 ){
20132 rc = analysisSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
20133 pgsz, nPage);
20134 if( rc ) return;
20135 rc = analysisSubreport(&s, "All rowid tables",
20136 "NOT is_without_rowid AND NOT is_index",
20137 pgsz, nPage);
20138 if( rc ) return;
20139 }
20140 rc = analysisSubreport(&s, "All indexes", "is_index", pgsz, nPage);
20141 if( rc ) return;
20142
20143 pStmt = analysisPrepare(&s,
20144 "SELECT upper(tblname), tblname, sum(is_index) FROM temp.%s"
20145 " GROUP BY 1 ORDER BY 1",
20146 s.zSU);
20147 if( pStmt==0 ) return;
20148 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
@@ -20150,37 +20484,37 @@
20150 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
20151 int nSubIndex = sqlite3_column_int(pStmt, 2);
20152 if( nSubIndex==0 ){
20153 char *zTitle = sqlite3_mprintf("Table %s", zUpper);
20154 char *zWhere = sqlite3_mprintf("name=%Q", zName);
20155 rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20156 sqlite3_free(zTitle);
20157 sqlite3_free(zWhere);
20158 if( rc ) break;
20159 }else{
20160 sqlite3_stmt *pS2;
20161 char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper);
20162 char *zWhere = sqlite3_mprintf("tblname=%Q", zName);
20163 rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20164 sqlite3_free(zTitle);
20165 sqlite3_free(zWhere);
20166 if( rc ) break;
20167 zTitle = sqlite3_mprintf("Table %s w/o any indexes", zUpper);
20168 zWhere = sqlite3_mprintf("name=%Q", zName);
20169 rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20170 sqlite3_free(zTitle);
20171 sqlite3_free(zWhere);
20172 if( rc ) break;
20173 if( nSubIndex>1 ){
20174 zTitle = sqlite3_mprintf("All indexes of table %s", zUpper);
20175 zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName);
20176 rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20177 sqlite3_free(zTitle);
20178 sqlite3_free(zWhere);
20179 if( rc ) break;
20180 }
20181 pS2 = analysisPrepare(&s,
20182 "SELECT name, upper(name) FROM temp.%s"
20183 " WHERE is_index AND tblname=%Q",
20184 s.zSU, zName);
20185 if( pS2==0 ){
20186 rc = SQLITE_NOMEM;
@@ -20189,25 +20523,25 @@
20189 while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){
20190 const char *zU = (const char*)sqlite3_column_text(pS2, 1);
20191 const char *zN = (const char*)sqlite3_column_text(pS2, 0);
20192 zTitle = sqlite3_mprintf("Index %s", zU);
20193 zWhere = sqlite3_mprintf("name=%Q", zN);
20194 rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
20195 sqlite3_free(zTitle);
20196 sqlite3_free(zWhere);
20197 if( rc ) break;
20198 }
20199 rc = analysisStmtFinish(&s, rc, pS2);
20200 if( rc ) break;
20201 }
20202 }
20203 if( analysisStmtFinish(&s, rc, pStmt) ) return;
20204
20205 /* Append SQL statements that will recreate the raw data used for
20206 ** the analysis.
20207 */
20208 analysisTitle(&s, "Raw data used to generate this report");
20209 sqlite3_str_appendf(s.pOut,
20210 "The following SQL will create a table named \"space_used\" which\n"
20211 "contains most of the information used to generate the report above.\n"
20212 "*/\n"
20213 );
@@ -20233,11 +20567,11 @@
20233 " ovfl_unused int, -- Unused bytes on overflow pages\n" /* 16 */
20234 " int_entries int -- B-tree entries on internal pages\n"/* 17 */
20235 ");\n"
20236 "INSERT INTO space_used VALUES\n"
20237 );
20238 pStmt = analysisPrepare(&s,
20239 "SELECT quote(name), quote(tblname),\n" /* 0..1 */
20240 " is_index, is_without_rowid, nentry, leaf_entries,\n" /* 2..5 */
20241 " depth, payload, ovfl_payload, ovfl_cnt, mx_payload,\n" /* 6..10 */
20242 " int_pages, leaf_pages, ovfl_pages, int_unused,\n" /* 11..14 */
20243 " leaf_unused, ovfl_unused, int_entries\n" /* 15..17 */
@@ -20268,11 +20602,11 @@
20268 sqlite3_column_int64(pStmt, 15),
20269 sqlite3_column_int64(pStmt, 16),
20270 sqlite3_column_int64(pStmt, 17));
20271 }
20272 if( rc!=SQLITE_DONE ){
20273 analysisError(&s, "SQL run-time error: %s\nSQL: %s",
20274 sqlite3_errmsg(s.db), sqlite3_sql(pStmt));
20275 sqlite3_finalize(pStmt);
20276 return;
20277 }
20278 sqlite3_str_appendf(s.pOut,";\nCOMMIT;");
@@ -20281,32 +20615,144 @@
20281 if( sqlite3_str_length(s.pOut) ){
20282 sqlite3_result_text(context, sqlite3_str_finish(s.pOut), -1,
20283 sqlite3_free);
20284 s.pOut = 0;
20285 }
20286 analysisReset(&s);
20287 }
20288
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20289
20290 #ifdef _WIN32
20291
20292 #endif
20293 int sqlite3_analyze_init(
20294 sqlite3 *db,
20295 char **pzErrMsg,
20296 const sqlite3_api_routines *pApi
20297 ){
20298 int rc = SQLITE_OK;
20299 SQLITE_EXTENSION_INIT2(pApi);
20300 (void)pzErrMsg; /* Unused parameter */
20301 rc = sqlite3_create_function(db, "analyze", 1,
20302 SQLITE_UTF8|SQLITE_INNOCUOUS,
20303 0, analyzeFunc, 0, 0);
20304 return rc;
20305 }
20306
20307 /************************* End ext/misc/analyze.c ********************/
20308
20309 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
20310 #define SQLITE_SHELL_HAVE_RECOVER 1
20311 #else
20312 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -22123,23 +22569,44 @@
22123 int rc = sqlite3_finalize(pStmt);
22124 if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){
22125 recoverDbError(p, db);
22126 }
22127 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22128
22129 /*
22130 ** This function is a no-op if recover handle p already contains an error
22131 ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this
22132 ** case.
22133 **
22134 ** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK.
22135 ** Or, if an error occurs, leave an error code and message in the recover
22136 ** handle and return a copy of the error code.
 
22137 */
22138 static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){
22139 if( p->errCode==SQLITE_OK ){
22140 int rc = sqlite3_exec(db, zSql, 0, 0, 0);
22141 if( rc ){
22142 recoverDbError(p, db);
22143 }
22144 }
22145 return p->errCode;
@@ -22535,11 +23002,12 @@
22535 recoverError(p, SQLITE_NOMEM, 0);
22536 }
22537 }
22538 recoverFinalize(p, p1);
22539 }
22540 recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;");
 
22541
22542 if( p->errCode==SQLITE_OK ){
22543 sqlite3 *db = p->dbOut;
22544 sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main");
22545 if( pBackup ){
@@ -22617,16 +23085,16 @@
22617 ** discarded.
22618 */
22619 static void recoverOpenRecovery(sqlite3_recover *p){
22620 char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb);
22621 recoverExec(p, p->dbOut, zSql);
 
 
 
 
22622 recoverExec(p, p->dbOut,
22623 "PRAGMA writable_schema = 1;"
22624 "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
22625 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
22626 );
22627 sqlite3_free(zSql);
22628 }
22629
22630
22631 /*
22632 ** This function is a no-op if recover handle p already contains an error
@@ -22762,11 +23230,11 @@
22762 " (type='index' AND (sql LIKE '%unique%' OR ?1))"
22763 " FROM recovery.schema"
22764 ")"
22765 "SELECT rootpage, tbl, isVirtual, name, sql"
22766 " FROM dbschema "
22767 " WHERE tbl OR isIndex"
22768 " ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
22769 );
22770
22771 pTblname = recoverPrepare(p, p->dbOut,
22772 "SELECT name FROM sqlite_schema "
@@ -22788,11 +23256,11 @@
22788 zSql = (const char*)(zFree = recoverMPrintf(p,
22789 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
22790 zName, zName, zSql
22791 ));
22792 }
22793 rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
22794 if( rc==SQLITE_OK ){
22795 recoverSqlCallback(p, zSql);
22796 if( bTable && !bVirtual ){
22797 if( SQLITE_ROW==sqlite3_step(pTblname) ){
22798 const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
@@ -22830,19 +23298,21 @@
22830
22831 pSelect = recoverPrepare(p, p->dbOut,
22832 p->bSlowIndexes ?
22833 "SELECT rootpage, sql FROM recovery.schema "
22834 " WHERE type!='table' AND type!='index'"
 
22835 :
22836 "SELECT rootpage, sql FROM recovery.schema "
22837 " WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
 
22838 );
22839
22840 if( pSelect ){
22841 while( sqlite3_step(pSelect)==SQLITE_ROW ){
22842 const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
22843 int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
22844 if( rc==SQLITE_OK ){
22845 recoverSqlCallback(p, zSql);
22846 }else if( rc!=SQLITE_ERROR ){
22847 recoverDbError(p, p->dbOut);
22848 }
@@ -24216,11 +24686,11 @@
24216 recoverCacheSchema(p);
24217
24218 if( bUseWrapper ) recoverUninstallWrapper(p);
24219 }while( p->errCode==SQLITE_NOTADB
24220 && (bUseWrapper--)
24221 && SQLITE_OK==sqlite3_exec(p->dbIn, "ROLLBACK", 0, 0, 0)
24222 );
24223 }
24224
24225 recoverLeaveMutex();
24226 recoverExec(p, p->dbOut, "BEGIN");
@@ -24281,11 +24751,11 @@
24281
24282 /* If no error has occurred, commit the write transaction on the output
24283 ** database. Regardless of whether or not an error has occurred, make
24284 ** an attempt to end the read transaction on the input database. */
24285 recoverExec(p, p->dbOut, "COMMIT");
24286 rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
24287 if( p->errCode==SQLITE_OK ) p->errCode = rc;
24288
24289 recoverSqlCallback(p, "PRAGMA writable_schema = off");
24290 recoverSqlCallback(p, "COMMIT");
24291 p->eState = RECOVER_STATE_DONE;
@@ -24477,11 +24947,11 @@
24477 if( p==0 ){
24478 rc = SQLITE_NOMEM;
24479 }else{
24480 recoverFinalCleanup(p);
24481 if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){
24482 rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
24483 if( p->errCode==SQLITE_OK ) p->errCode = rc;
24484 }
24485 rc = p->errCode;
24486 sqlite3_free(p->zErrMsg);
24487 sqlite3_free(p->zStateDb);
@@ -24499,10 +24969,20 @@
24499 #endif
24500 #ifdef SQLITE_SHELL_EXTSRC
24501 # include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
24502 #endif
24503
 
 
 
 
 
 
 
 
 
 
24504 #if defined(SQLITE_ENABLE_SESSION)
24505 /*
24506 ** State information for a single open session
24507 */
24508 typedef struct OpenSession OpenSession;
@@ -24530,10 +25010,12 @@
24530 u8 autoEQPtrace; /* autoEQP is in trace mode */
24531 u8 scanstatsOn; /* True to display scan stats before each finalize */
24532 u8 bAutoScreenWidth; /* Using the TTY to determine screen width */
24533 u8 mFlags; /* MFLG_ECHO, MFLG_CRLF, etc. */
24534 u8 eMode; /* One of the MODE_ values */
 
 
24535 sqlite3_qrf_spec spec; /* Spec to be passed into QRF */
24536 } Mode;
24537
24538 /* Flags for Mode.mFlags */
24539 #define MFLG_ECHO 0x01 /* Echo inputs to output */
@@ -24564,10 +25046,11 @@
24564 unsigned statsOn; /* True to display memory stats before each finalize */
24565 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
24566 u8 nPopOutput; /* Revert .output settings when reaching zero */
24567 u8 nPopMode; /* Revert .mode settings when reaching zero */
24568 u8 enableTimer; /* Enable the timer. 2: permanently 1: only once */
 
24569 int inputNesting; /* Track nesting level of .read and other redirects */
24570 double prevTimer; /* Last reported timer value */
24571 double tmProgress; /* --timeout option for .progress */
24572 i64 lineno; /* Line number of last line read from in */
24573 const char *zInFile; /* Name of the input file */
@@ -24745,11 +25228,11 @@
24745 unsigned char eHdr; /* Default header encoding. */
24746 unsigned char eBlob; /* Default blob encoding. */
24747 unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
24748 unsigned char eStyle; /* Underlying QRF style */
24749 unsigned char eCx; /* 0: other, 1: line, 2: columnar */
24750 unsigned char mFlg; /* Flags. 1=border-off 2=split-column */
24751 };
24752
24753 /* String constants used by built-in modes */
24754 static const char *aModeStr[] =
24755 /* 0 1 2 3 4 5 6 7 8 */
@@ -24758,45 +25241,45 @@
24758 /* 9 10 11 12 13 */
24759
24760 static const ModeInfo aModeInfo[] = {
24761 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
24762 { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
24763 { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2, 0 },
24764 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
24765 { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2, 0 },
24766 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
24767 { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
24768 { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 },
24769 { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
24770 { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
24771 { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
24772 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
24773 { "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
24774 { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
24775 { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2, 0 },
24776 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
24777 { "psql", 0, 0, 9, 1, 1, 0, 2, 19, 2, 1 },
24778 { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2, 0 },
24779 { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
24780 { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
24781 { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2, 0 },
24782 { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
24783 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
24784 { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 }
24785 }; /* | / / | / / | | \
24786 ** | / / | / / | | \_ 2: columnar
24787 ** Index into aModeStr[] | / / | | 1: line
24788 ** | / / | | 0: other
24789 ** | / / | \
24790 ** text encoding |/ | show | \
24791 ** v-------------------' | hdrs? | The QRF style
24792 ** 0: n/a blob | v-----'
24793 ** 1: plain v----------' 0: n/a
24794 ** 2: sql 0: auto 1: no
24795 ** 3: csv 1: as-text 2: yes
24796 ** 4: html 2: sql
24797 ** 5: c 3: hex
24798 ** 6: json 4: c
24799 ** 5: json
24800 ** 6: size
24801 ******************************************************************/
24802
@@ -25079,11 +25562,11 @@
25079 */
25080 static char *local_getline(char *zLine, FILE *in){
25081 int nLine = zLine==0 ? 0 : 100;
25082 int n = 0;
25083
25084 while( 1 ){
25085 if( n+100>nLine ){
25086 if( nLine>=1073741773 ){
25087 free(zLine);
25088 return 0;
25089 }
@@ -25107,10 +25590,22 @@
25107 break;
25108 }
25109 }
25110 return zLine;
25111 }
 
 
 
 
 
 
 
 
 
 
 
 
25112
25113 /*
25114 ** The SQLITE_PS_APPDEF macro should be set to the name of a function
25115 ** that accepts a single "int" argument and returns a "const char *"
25116 ** that is guaranteed to be non-NULL. The value returned depends on the
@@ -25131,35 +25626,47 @@
25131 # define SQLITE_PS_APPDEF shellPromptAppDef
25132 static const char *shellPromptAppDef(int c){
25133 switch( c ){
25134 /* The default main prompt string */
25135 case 1:
25136 #if defined(SQLITE_PS1)
 
 
25137 return SQLITE_PS1;
25138 #elif defined(SQLITE_PS_NOANSI)
25139 return "/A-/v /~> ";
25140 #else
25141 return "/e[1;32m/A-/v /e[1;/x33/:36/;m/m/e[3m/;/f/;/e[0m-> ";
 
 
 
 
25142 #endif
25143
25144 /* The default continuation prompt string */
25145 case 2:
25146 #if defined(SQLITE_PS2)
 
 
25147 return SQLITE_PS2;
25148 #elif defined(SQLITE_PS_NOANSI)
25149 return "/B/C> ";
25150 #else
25151 return "/B/e[1;/x33/:36/;m/C/e[0m-> ";
 
 
 
 
25152 #endif
25153
25154 /* Name of environment variables that override the prompt strings
25155 ** of cases 1 and 2 */
25156 case 3: return "SQLITE_PS1";
25157 case 4: return "SQLITE_PS2";
25158
25159 /* Name of the application */
 
25160 case 'A': return "SQLite";
 
 
 
25161
25162 /* Full version number of the application, including patch level */
25163 case 'V': return sqlite3_libversion();
25164
25165 /* Version number without the patch level */
@@ -25218,13 +25725,13 @@
25218 }else if( p->db && (pFN = sqlite3_db_filename(p->db,0))!=0 ){
25219 zFN = sqlite3_filename_database(pFN);
25220 }
25221 if( zFN==0 || zFN[0]==0 ){
25222 zFN = p->pAuxDb->zDbFilename;
25223 if( zFN==0 || zFN[0]==0 || cli_strcmp(zFN,":memory:")==0 ){
25224 zFN = zMemoryName;
25225 }
25226 }
25227 return zFN;
25228 }
25229
25230 /*
@@ -25263,10 +25770,26 @@
25263 if( z==0 || z[0]==0 ) z = getenv("LOGNAME");
25264 if( z==0 || z[0]==0 ) z = "?";
25265 #endif
25266 return z;
25267 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25268
25269 /*
25270 ** Expand escapes in the given input prompt string. Return the
25271 ** expanded prompt in memory obtained from sqlite3_malloc(). The
25272 ** caller is responsible for freeing the memory.
@@ -25311,10 +25834,11 @@
25311 continue;
25312 }
25313 if( c>='0' && c<='7' ){
25314 /* /nnn becomes a single byte given by octal nnn */
25315 int v = c - '0';
 
25316 while( i<=2 && zPrompt[i+1]>='0' && zPrompt[i+1]<='7' ){
25317 v = v*8 + zPrompt[++i] - '0';
25318 }
25319 if( !mOff ) sqlite3_str_appendchar(pOut, 1, v);
25320 zPrompt += i+1;
@@ -25533,15 +26057,36 @@
25533 memmove(z+idxSpace+nNew, z+idxSpace, len-nNew-idxSpace);
25534 memset(z+idxSpace, ' ', nNew);
25535 }
25536 }
25537 }
25538
25539 if( 0==sqlite3_str_length(pOut) ){
25540 /* Avoid a bogus OOM */
25541 sqlite3_str_appendchar(pOut, 1, '\0');
25542 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25543 return sqlite3_str_finish(pOut);
25544 }
25545
25546 /*
25547 ** Retrieve a single line of input text.
@@ -25570,30 +26115,33 @@
25570 zResult = local_getline(zPrior, in);
25571 }else{
25572 const char *zBase = prompt_string(p, bContinue!=0);
25573 char *zPrompt = expand_prompt(p, zAll, zBase);
25574 shell_check_oom(zPrompt);
25575 #if SHELL_USE_LOCAL_GETLINE
25576 sputz(stdout, zPrompt);
25577 fflush(stdout);
25578 do{
25579 zResult = local_getline(zPrior, stdin);
25580 zPrior = 0;
25581 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
25582 if( zResult==0 ) sqlite3_sleep(50);
25583 }while( zResult==0 && seenInterrupt>0 );
25584 #else
25585 free(zPrior);
25586 zResult = shell_readline(zPrompt);
25587 while( zResult==0 ){
25588 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
25589 sqlite3_sleep(50);
25590 if( seenInterrupt==0 ) break;
25591 zResult = shell_readline("");
25592 }
25593 if( zResult && *zResult ) shell_add_history(zResult);
25594 #endif
 
 
 
25595 sqlite3_free(zPrompt);
25596 }
25597 return zResult;
25598 }
25599 #endif /* !SQLITE_SHELL_FIDDLE */
@@ -25834,11 +26382,12 @@
25834 double r = sqlite3_value_double(apVal[0]);
25835 int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
25836 char z[400];
25837 if( n<1 ) n = 1;
25838 if( n>350 ) n = 350;
25839 sprintf(z, "%#+.*e", n, r);
 
25840 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
25841 }
25842
25843 /*
25844 ** SQL function: shell_add_schema(S,X)
@@ -25912,21 +26461,27 @@
25912 }
25913 sqlite3_result_value(pCtx, apVal[0]);
25914 }
25915
25916 /*
25917 ** SQL function: shell_prompt_test(PROMPT)
25918 ** shell_prompt_test(PROMPT,PRIOR)
25919 ** shell_prompt_test(PROMPT,PRIOR,FILENAME)
25920 **
25921 ** Return the shell prompt, with escapes expanded, for testing purposes.
25922 ** The first argument is the raw (unexpanded) prompt string. Or if the
25923 ** first argument is NULL, then use whatever prompt string is currently
25924 ** configured. If the second argument exists and is not NULL, then the
25925 ** second argument is understood to be prior incomplete text and a
25926 ** continuation prompt is generated. If a third argument is provided,
25927 ** it is assumed to be the full pathname of the database file.
 
 
 
 
 
 
 
 
25928 */
25929 static void shellExpandPrompt(
25930 sqlite3_context *pCtx,
25931 int nVal,
25932 sqlite3_value **apVal
@@ -25936,11 +26491,14 @@
25936 const char *zPrior;
25937 const char *zSavedDbFile;
25938 int mSavedFlgs;
25939 const char *zFName;
25940 char *zRes;
 
 
25941
 
25942 if( nVal<2
25943 || (zPrior = (const char*)sqlite3_value_text(apVal[1]))==0
25944 || zPrior[0]==0
25945 ){
25946 zPrior = 0;
@@ -25952,12 +26510,19 @@
25952 zSavedDbFile = p->pAuxDb->zDbFilename;
25953 mSavedFlgs = p->pAuxDb->mFlgs;
25954 if( nVal>=3 && (zFName = (const char*)sqlite3_value_text(apVal[2]))!=0 ){
25955 p->pAuxDb->zDbFilename = zFName;
25956 p->pAuxDb->mFlgs |= 0x001;
 
 
 
 
 
 
25957 }
25958 zRes = expand_prompt(p, zPrior, zPrompt);
 
25959 p->pAuxDb->zDbFilename = zSavedDbFile;
25960 p->pAuxDb->mFlgs = mSavedFlgs;
25961 sqlite3_result_text(pCtx, zRes, -1, SQLITE_TRANSIENT);
25962 sqlite3_free(zRes);
25963 }
@@ -26150,11 +26715,11 @@
26150 free(p->spec.zColumnSep);
26151 free(p->spec.zRowSep);
26152 free(p->spec.zTableName);
26153 free(p->spec.zNull);
26154 memset(p, 0, sizeof(*p));
26155 p->spec.iVersion = 1;
26156 p->autoExplain = autoExplain;
26157 }
26158
26159 /*
26160 ** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26190,10 +26755,18 @@
26190 pDest->spec.zTableName = strdup(pSrc->spec.zTableName);
26191 }
26192 if( pDest->spec.zNull ){
26193 pDest->spec.zNull = strdup(pSrc->spec.zNull);
26194 }
 
 
 
 
 
 
 
 
26195 }
26196
26197 /*
26198 ** Set a string value to a copy of the zNew string in memory
26199 ** obtained from system malloc().
@@ -26208,10 +26781,47 @@
26208 if( *az ){
26209 memcpy(*az, zNew, n+1 );
26210 }
26211 }
26212 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26213
26214 /*
26215 ** Change the mode to eMode
26216 */
26217 static void modeChange(ShellState *p, unsigned char eMode){
@@ -26238,17 +26848,23 @@
26238 pM->spec.bSplitColumn = QRF_Yes;
26239 pM->bAutoScreenWidth = 1;
26240 }else{
26241 pM->spec.bSplitColumn = QRF_No;
26242 }
 
 
 
 
 
26243 }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
26244 modeFree(&p->mode);
26245 modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
26246 }else if( eMode==MODE_BATCH ){
26247 u8 mFlags = p->mode.mFlags;
26248 modeFree(&p->mode);
26249 modeChange(p, MODE_List);
 
26250 p->mode.mFlags = mFlags;
26251 }else if( eMode==MODE_TTY ){
26252 u8 mFlags = p->mode.mFlags;
26253 modeFree(&p->mode);
26254 modeChange(p, MODE_QBox);
@@ -26266,13 +26882,15 @@
26266 /*
26267 ** Set the mode to the default. It assumed that the mode has
26268 ** already been freed and zeroed prior to calling this routine.
26269 */
26270 static void modeDefault(ShellState *p){
26271 p->mode.spec.iVersion = 1;
26272 p->mode.autoExplain = 1;
26273 if( stdin_is_interactive || stdout_is_console ){
 
 
26274 modeChange(p, MODE_TTY);
26275 }else{
26276 modeChange(p, MODE_BATCH);
26277 }
26278 }
@@ -26881,11 +27499,11 @@
26881 return SQLITE_OK;
26882 }
26883 #endif
26884
26885 /*
26886 ** Print a schema statement. This is helper routine to dump_callbac().
26887 **
26888 ** This routine converts some CREATE TABLE statements for shadow tables
26889 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
26890 **
26891 ** If the schema statement in z[] contains a start-of-comment and if
@@ -28333,12 +28951,12 @@
28333 ".databases List names and files of attached databases",
28334 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
28335 #if SQLITE_SHELL_HAVE_RECOVER
28336 ".dbinfo ?DB? Show status information about the database",
28337 #endif
28338 ".dbstat ?SCHEMA? Report database space and size stats",
28339 ".dbtotxt Hex dump of the database file",
 
28340 ".dump ?OBJECTS? Render database content as SQL",
28341 " Options:",
28342 " --data-only Output only INSERT statements",
28343 " --newlines Allow unescaped newline characters in output",
28344 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -28445,10 +29063,13 @@
28445 " --reset Reset the count for each input and interrupt",
28446 " --timeout S Halt after running for S seconds",
28447 #endif
28448 ".prompt MAIN CONTINUE Replace the standard prompts",
28449 " --hard-reset Unset SQLITE_PS1/2 and then --reset",
 
 
 
28450 " --reset Revert to default prompts",
28451 " --show Show the current prompt strings",
28452 " -- No more options. Subsequent args are prompts",
28453 #ifndef SQLITE_SHELL_FIDDLE
28454 ".quit Stop interpreting input stream, exit if primary.",
@@ -28609,10 +29230,14 @@
28609 " truncated. Zero means \"no limit\".\n"
28610 " --colsep STRING Use STRING as the column separator\n"
28611 " --escape ESC Enable/disable escaping of control characters\n"
28612 " found in the output. ESC can be \"off\", \"ascii\",\n"
28613 " or \"symbol\".\n"
 
 
 
 
28614 " --linelimit N Set the maximum number of output lines to show for\n"
28615 " any single SQL value to N. Longer values are\n"
28616 " truncated. Zero means \"no limit\". Only works\n"
28617 " in \"line\" mode and in columnar modes.\n"
28618 " --limits L,C,T Shorthand for \"--linelimit L --charlimit C\n"
@@ -28629,10 +29254,11 @@
28629 " --quote ARG Enable/disable quoting of text. ARG can be\n"
28630 " \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
28631 " \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
28632 " \"on\" is an alias for \"sql\".\n"
28633 " --reset Changes all mode settings back to their default.\n"
 
28634 " --rowsep STRING Use STRING as the row separator\n"
28635 " --sw|--screenwidth N Declare the screen width of the output device\n"
28636 " to be N characters. An attempt may be made to\n"
28637 " wrap output text to fit within this limit. Zero\n"
28638 " means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28640,11 +29266,11 @@
28640 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
28641 " --tag NAME Save mode to the left as NAME.\n"
28642 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
28643 " --title ARG Whether or not to show column headers, and if so\n"
28644 " how to encode them. ARG can be \"off\", \"on\",\n"
28645 " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
28646 " --titlelimit N Limit the length of column titles to N characters.\n"
28647 " -v|--verbose Verbose output\n"
28648 " --widths LIST Set the columns widths for columnar modes. The\n"
28649 " argument is a list of integers, one for each\n"
28650 " column. A \"0\" width means use a dynamic width\n"
@@ -29345,11 +29971,12 @@
29345 sqlite3_base64_init(p->db, 0, 0);
29346 sqlite3_base85_init(p->db, 0, 0);
29347 sqlite3_regexp_init(p->db, 0, 0);
29348 sqlite3_ieee_init(p->db, 0, 0);
29349 sqlite3_series_init(p->db, 0, 0);
29350 sqlite3_analyze_init(p->db, 0, 0);
 
29351 #ifndef SQLITE_SHELL_FIDDLE
29352 sqlite3_fileio_init(p->db, 0, 0);
29353 sqlite3_completion_init(p->db, 0, 0);
29354 #endif
29355 #ifdef SQLITE_HAVE_ZLIB
@@ -29406,15 +30033,11 @@
29406 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
29407 editFunc, 0, 0);
29408 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
29409 editFunc, 0, 0);
29410 #endif
29411 sqlite3_create_function(p->db, "shell_prompt_test", 1, SQLITE_UTF8,
29412 p, shellExpandPrompt, 0, 0);
29413 sqlite3_create_function(p->db, "shell_prompt_test", 2, SQLITE_UTF8,
29414 p, shellExpandPrompt, 0, 0);
29415 sqlite3_create_function(p->db, "shell_prompt_test", 3, SQLITE_UTF8,
29416 p, shellExpandPrompt, 0, 0);
29417 sqlite3_create_function(p->db, "shell_temp_filename", 1, SQLITE_UTF8,
29418 p, shellTempFilenameFunc, 0, 0);
29419
29420
@@ -31155,11 +31778,11 @@
31155 typedef struct ArCommand ArCommand;
31156 struct ArCommand {
31157 u8 eCmd; /* An AR_CMD_* value */
31158 u8 bVerbose; /* True if --verbose */
31159 u8 bZip; /* True if the archive is a ZIP */
31160 u8 bDryRun; /* True if --dry-run */
31161 u8 bAppend; /* True if --append */
31162 u8 bGlob; /* True if --glob */
31163 u8 fromCmdLine; /* Run from -A instead of .archive */
31164 int nArg; /* Number of command arguments */
31165 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
@@ -31217,10 +31840,11 @@
31217 #define AR_SWITCH_FILE 9
31218 #define AR_SWITCH_DIRECTORY 10
31219 #define AR_SWITCH_APPEND 11
31220 #define AR_SWITCH_DRYRUN 12
31221 #define AR_SWITCH_GLOB 13
 
31222
31223 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
31224 switch( eSwitch ){
31225 case AR_CMD_CREATE:
31226 case AR_CMD_EXTRACT:
@@ -31234,11 +31858,14 @@
31234 }
31235 pAr->eCmd = eSwitch;
31236 break;
31237
31238 case AR_SWITCH_DRYRUN:
31239 pAr->bDryRun = 1;
 
 
 
31240 break;
31241 case AR_SWITCH_GLOB:
31242 pAr->bGlob = 1;
31243 break;
31244 case AR_SWITCH_VERBOSE:
@@ -31285,10 +31912,11 @@
31285 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
31286 { "file", 'f', AR_SWITCH_FILE, 1 },
31287 { "append", 'a', AR_SWITCH_APPEND, 1 },
31288 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
31289 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
 
31290 { "glob", 'g', AR_SWITCH_GLOB, 0 },
31291 };
31292 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
31293 struct ArSwitch *pEnd = &aSwitch[nSwitch];
31294
@@ -31585,18 +32213,41 @@
31585
31586 /*
31587 ** Implementation of .ar "eXtract" command.
31588 */
31589 static int arExtractCommand(ArCommand *pAr){
 
 
 
 
 
 
 
 
31590 const char *zSql1 =
31591 "WITH dest(dpath,dlen) AS (SELECT realpath($dir),length(realpath($dir)))\n"
31592 "SELECT ($dir || name),\n"
31593 " CASE WHEN $dryrun THEN 0\n"
31594 " ELSE writefile($dir||name, %s, mode, mtime) END\n"
 
 
 
 
 
 
 
 
 
 
 
 
31595 " FROM dest CROSS JOIN %s\n"
31596 " WHERE (%s)\n"
31597 " AND (data IS NULL OR $pass==0)\n" /* Dirs both passes */
 
 
 
31598 " AND dpath=substr(realpath($dir||name),1,dlen)\n" /* No escapes */
31599 " AND name NOT GLOB '*..[/\\]*'\n"; /* No /../ in paths */
31600
31601 const char *azExtraArg[] = {
31602 "sqlar_uncompress(data, sz)",
@@ -31623,39 +32274,48 @@
31623 }
31624 if( zDir==0 ) rc = SQLITE_NOMEM;
31625 }
31626
31627 shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
31628 azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
 
 
 
31629 );
31630
31631 if( rc==SQLITE_OK ){
31632 j = sqlite3_bind_parameter_index(pSql, "$dir");
31633 sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
31634 j = sqlite3_bind_parameter_index(pSql, "$dryrun");
31635 sqlite3_bind_int(pSql, j, pAr->bDryRun);
31636
31637 /* Run the SELECT statement twice
31638 ** (0) writefile() all files and directories
31639 ** (1) writefile() for directory again
31640 ** The second pass is so that the timestamps for extracted directories
 
31641 ** will be reset to the value in the archive, since populating them
31642 ** in the first pass will have changed the timestamp. */
31643 for(i=0; i<2; i++){
 
 
 
31644 j = sqlite3_bind_parameter_index(pSql, "$pass");
31645 sqlite3_bind_int(pSql, j, i);
31646 if( pAr->bDryRun ){
31647 cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
31648 if( pAr->bVerbose==0 ) break;
31649 }
31650 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
31651 if( i==0 && pAr->bVerbose ){
31652 cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
31653 }
31654 }
31655 if( pAr->bDryRun ) break;
31656 shellReset(&rc, pSql);
 
 
 
31657 }
31658 shellFinalize(&rc, pSql);
31659 }
31660
31661 sqlite3_free(zDir);
@@ -32166,11 +32826,11 @@
32166 ;
32167 static const char * const zCollectVar = "\
32168 SELECT\
32169 '('||x'0a'\
32170 || group_concat(\
32171 cname||' ANY',\
32172 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
32173 ||')' AS ColsSpec \
32174 FROM (\
32175 SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \
32176 FROM ColNames ORDER BY cpos\
@@ -32767,14 +33427,16 @@
32767 /*
32768 ** This function computes what to show the user about the configured
32769 ** titles (or column-names). Output is an integer between 0 and 3:
32770 **
32771 ** 0: The titles do not matter. Never show anything.
32772 ** 1: Show "--titles off"
32773 ** 2: Show "--titles on"
32774 ** 3: Show "--title VALUE" where VALUE is an encoding method
 
32775 ** to use, one of: plain sql csv html tcl json
 
32776 **
32777 ** Inputs are:
32778 **
32779 ** spec.bTitles (bT) Whether or not to show the titles
32780 ** spec.eTitle (eT) The actual encoding to be used for titles
@@ -32807,11 +33469,27 @@
32807 if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
32808 if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
32809 if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
32810 if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
32811
32812 return v & 3; /* Return the selected truth-table entry */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32813 }
32814
32815 /*
32816 ** DOT-COMMAND: .mode
32817 **
@@ -32835,10 +33513,14 @@
32835 ** truncated. Zero means "no limit".
32836 ** --colsep STRING Use STRING as the column separator
32837 ** --escape ESC Enable/disable escaping of control characters
32838 ** found in the output. ESC can be "off", "ascii",
32839 ** or "symbol".
 
 
 
 
32840 ** --linelimit N Set the maximum number of output lines to show for
32841 ** any single SQL value to N. Longer values are
32842 ** truncated. Zero means "no limit". Only works
32843 ** in "line" mode and in columnar modes.
32844 ** --limits L,C,T Shorthand for "--linelimit L --charlimit C
@@ -32855,10 +33537,11 @@
32855 ** --quote ARG Enable/disable quoting of text. ARG can be
32856 ** "off", "on", "sql", "relaxed", "csv", "html",
32857 ** "tcl", or "json". "off" means show the text as-is.
32858 ** "on" is an alias for "sql".
32859 ** --reset Changes all mode settings back to their default.
 
32860 ** --rowsep STRING Use STRING as the row separator
32861 ** --sw|--screenwidth N Declare the screen width of the output device
32862 ** to be N characters. An attempt may be made to
32863 ** wrap output text to fit within this limit. Zero
32864 ** means "no limit". Or N can be "auto" to set the
@@ -32866,11 +33549,11 @@
32866 ** --tablename NAME Set the name of the table for "insert" mode.
32867 ** --tag NAME Save mode to the left as NAME.
32868 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
32869 ** --title ARG Whether or not to show column headers, and if so
32870 ** how to encode them. ARG can be "off", "on",
32871 ** "sql", "csv", "html", "tcl", or "json".
32872 ** --titlelimit N Limit the length of column titles to N characters.
32873 ** -v|--verbose Verbose output
32874 ** --widths LIST Set the columns widths for columnar modes. The
32875 ** argument is a list of integers, one for each
32876 ** column. A "0" width means use a dynamic width
@@ -33011,30 +33694,14 @@
33011 }else if( optionMatch(z,"limits") ){
33012 if( (++i)>=nArg ){
33013 dotCmdError(p, i-1, "missing argument", 0);
33014 return 1;
33015 }
33016 k = pickStr(azArg[i],0,"on","off","");
33017 if( k==0 ){
33018 p->mode.spec.nLineLimit = DFLT_LINE_LIMIT;
33019 p->mode.spec.nCharLimit = DFLT_CHAR_LIMIT;
33020 p->mode.spec.nTitleLimit = DFLT_TITLE_LIMIT;
33021 }else if( k==1 ){
33022 p->mode.spec.nLineLimit = 0;
33023 p->mode.spec.nCharLimit = 0;
33024 p->mode.spec.nTitleLimit = 0;
33025 }else{
33026 int L, C, T = 0;
33027 int nNum = sscanf(azArg[i], "%d,%d,%d", &L, &C, &T);
33028 if( nNum<2 || L<0 || C<0 || T<0){
33029 dotCmdError(p, i, "bad argument", "Should be \"L,C,T\" where L, C"
33030 " and T are unsigned integers");
33031 return 1;
33032 }
33033 p->mode.spec.nLineLimit = L;
33034 p->mode.spec.nCharLimit = C;
33035 if( nNum==3 ) p->mode.spec.nTitleLimit = T;
33036 }
33037 chng = 1;
33038 }else if( optionMatch(z,"list") ){
33039 int ii;
33040 cli_puts("available modes:", p->out);
@@ -33105,15 +33772,56 @@
33105 break;
33106 default: /* off */
33107 p->mode.spec.eText = QRF_TEXT_Plain;
33108 break;
33109 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33110 chng = 1;
33111 }else if( optionMatch(z,"reset") ){
33112 int saved_eMode = p->mode.eMode;
33113 modeFree(&p->mode);
33114 modeChange(p, saved_eMode);
 
 
 
 
 
 
 
33115 }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
33116 if( (++i)>=nArg ){
33117 dotCmdError(p, i-1, "missing argument", 0);
33118 return 1;
33119 }
@@ -33163,25 +33871,63 @@
33163 return 1;
33164 }
33165 p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33166 chng = 1;
33167 }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33168 char *zErr = 0;
33169 if( i+1>=nArg ){
33170 dotCmdError(p, i, "missing argument", 0);
33171 return 1;
33172 }
33173 k = pickStr(azArg[++i],&zErr,
33174 "off","on","plain","sql","csv","html","tcl","json","");
33175 /* 0 1 2 3 4 5 6 7 */
33176 if( k<0 ){
33177 dotCmdError(p, i, "bad --titles value","%z", zErr);
33178 return 1;
33179 }
33180 p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
33181 p->mode.mFlags &= ~MFLG_HDR;
33182 p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
 
 
 
 
 
 
 
 
 
 
33183 chng = 1;
33184 }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
33185 int nWidth = 0;
33186 short int *aWidth;
33187 const char *zW;
@@ -33295,10 +34041,18 @@
33295 append_c_string(pDesc, p->mode.spec.zColumnSep);
33296 }
33297 if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
33298 sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
33299 }
 
 
 
 
 
 
 
 
33300 if( bAll
33301 || (p->mode.spec.nLineLimit>0 && pI->eCx>0)
33302 || p->mode.spec.nCharLimit>0
33303 || (p->mode.spec.nTitleLimit>0 && pI->eCx>0)
33304 ){
@@ -33332,10 +34086,16 @@
33332 if( bAll
33333 || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
33334 ){
33335 sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
33336 }
 
 
 
 
 
 
33337 zSetting = aModeStr[pI->eRSep];
33338 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
33339 sqlite3_str_appendf(pDesc, " --rowsep ");
33340 append_c_string(pDesc, p->mode.spec.zRowSep);
33341 }
@@ -33361,14 +34121,19 @@
33361 if( k==1 ){
33362 sqlite3_str_appendall(pDesc, " --titles off");
33363 }else if( k==2 ){
33364 sqlite3_str_appendall(pDesc, " --titles on");
33365 }else if( k==3 ){
 
 
33366 static const char *azTitle[] =
33367 { "plain", "sql", "csv", "html", "tcl", "json"};
33368 sqlite3_str_appendf(pDesc, " --titles %s",
33369 azTitle[p->mode.spec.eTitle-1]);
 
 
 
33370 }
33371 if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
33372 int ii;
33373 const char *zSep = " --widths ";
33374 for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34248,11 +35013,16 @@
34248 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
34249 rc = shell_dbinfo_command(p, nArg, azArg);
34250 }else
34251 #endif /* SQLITE_SHELL_HAVE_RECOVER */
34252
34253 if( c=='d' && n==6 && cli_strncmp(azArg[0], "dbstat", n)==0 ){
 
 
 
 
 
34254 const char *zSchema = 0;
34255 int ii;
34256 char *zSql;
34257 open_db(p, 0);
34258 for(ii=1; ii<nArg; ii++){
@@ -34267,27 +35037,19 @@
34267 rc = 1;
34268 goto meta_command_exit;
34269 }
34270 zSchema = z;
34271 }
34272 zSql = sqlite3_mprintf("SELECT analyze(%Q)", zSchema);
34273 shell_check_oom(zSql);
34274 modePush(p);
34275 modeChange(p, MODE_BATCH);
34276 p->mode.spec.nLineLimit = 0;
34277 p->mode.spec.nCharLimit = 0;
34278 p->mode.spec.nTitleLimit = 0;
34279 shell_exec(p, zSql, 0);
34280 modePop(p);
34281 sqlite3_free(zSql);
34282 }else
34283
34284 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
34285 open_db(p, 0);
34286 rc = shell_dbtotxt_command(p, nArg, azArg);
34287 }else
34288
34289 if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
34290 char *zLike = 0;
34291 char *zSql;
34292 int i;
34293 int savedShellFlags = p->shellFlgs;
@@ -34689,15 +35451,19 @@
34689 }
34690 }else
34691
34692 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
34693 if( nArg==2 ){
34694 p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
 
 
 
 
34695 p->mode.mFlags |= MFLG_HDR;
34696 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
34697 }else{
34698 eputz("Usage: .headers on|off\n");
34699 rc = 1;
34700 }
34701 }else
34702
34703 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -34901,13 +35667,21 @@
34901 sqlite3_str_free(pSql);
34902 }else
34903
34904 if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
34905 i64 iArg = 0;
 
34906 if( nArg==2 ){
34907 iArg = integerValue(azArg[1]);
34908 if( iArg==0 ) iArg = -1;
 
 
 
 
 
 
 
34909 }
34910 if( (nArg!=1 && nArg!=2) || iArg<0 ){
34911 cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
34912 rc = 1;
34913 goto meta_command_exit;
@@ -34955,10 +35729,12 @@
34955 { "attached", SQLITE_LIMIT_ATTACHED },
34956 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
34957 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
34958 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
34959 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
 
 
34960 };
34961 int i, n2;
34962 open_db(p, 0);
34963 if( nArg==1 ){
34964 for(i=0; i<ArraySize(aLimit); i++){
@@ -35400,10 +36176,26 @@
35400 }else
35401 if( strcmp(z,"-show")==0 ){
35402 cli_printf(stdout,"Main prompt: '%s'\n", prompt_string(p, 0));
35403 cli_printf(stdout,"Continuation: '%s'\n", prompt_string(p, 1));
35404 }else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35405 if( strcmp(z,"-")==0 ){
35406 noOpt = 1;
35407 }else
35408 {
35409 dotCmdError(p, i, "unknown option", 0);
@@ -35414,10 +36206,11 @@
35414 dotCmdError(p, i, "extra argument", 0);
35415 rc = 1;
35416 goto meta_command_exit;
35417 }else if( !p->dot.abQuot[i] && sqlite3_strglob("*[^a-z]*",z)!=0 ){
35418 dotCmdError(p, i, "use quotes around the prompt string", 0);
 
35419 }else{
35420 free(p->azPrompt[cnt]);
35421 p->azPrompt[cnt] = strdup(z);
35422 cnt++;
35423 }
@@ -36264,11 +37057,12 @@
36264 azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
36265 cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
36266 cli_printf(p->out, "%12.12s: %s\n","explain",
36267 p->mode.autoExplain ? "auto" : "off");
36268 cli_printf(p->out, "%12.12s: %s\n","headers",
36269 azBool[p->mode.spec.bTitles==QRF_Yes]);
 
36270 if( p->mode.spec.eStyle==QRF_STYLE_Column
36271 || p->mode.spec.eStyle==QRF_STYLE_Box
36272 || p->mode.spec.eStyle==QRF_STYLE_Table
36273 || p->mode.spec.eStyle==QRF_STYLE_Markdown
36274 ){
@@ -37626,17 +38420,18 @@
37626 " -- treat no subsequent arguments as options\n"
37627 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
37628 " -A ARGS... run \".archive ARGS\" and exit\n"
37629 #endif
37630 " -append append the database to the end of the file\n"
37631 " -ascii set output mode to 'ascii'\n"
37632 " -bail stop after hitting an error\n"
37633 " -batch force batch I/O\n"
37634 " -box set output mode to 'box'\n"
37635 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
37636 " -column set output mode to 'column'\n"
37637 " -csv set output mode to 'csv'\n"
 
37638 #if !defined(SQLITE_OMIT_DESERIALIZE)
37639 " -deserialize open the database using sqlite3_deserialize()\n"
37640 #endif
37641 " -echo print inputs before execution\n"
37642 " -escape T ctrl-char escape; T is one of: symbol, ascii, off\n"
@@ -37644,18 +38439,18 @@
37644 " -[no]header turn headers on or off\n"
37645 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
37646 " -heap SIZE Size of heap for memsys3 or memsys5\n"
37647 #endif
37648 " -help show this message\n"
37649 " -html set output mode to HTML\n"
37650 " -ifexists only open if database already exists\n"
37651 " -interactive force interactive I/O\n"
37652 " -json set output mode to 'json'\n"
37653 " -line set output mode to 'line'\n"
37654 " -list set output mode to 'list'\n"
37655 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
37656 " -markdown set output mode to 'markdown'\n"
37657 #if !defined(SQLITE_OMIT_DESERIALIZE)
37658 " -maxsize N maximum size for a --deserialize database\n"
37659 #endif
37660 " -memtrace trace all memory allocations and deallocations\n"
37661 " -mmap N default mmap size set to N\n"
@@ -37668,21 +38463,21 @@
37668 " -nonce STRING set the safe-mode escape nonce\n"
37669 " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
37670 " -nullvalue TEXT set text string for NULL values. Default ''\n"
37671 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
37672 " -pcachetrace trace all page cache operations\n"
37673 " -quote set output mode to 'quote'\n"
37674 " -readonly open the database read-only\n"
37675 " -safe enable safe-mode\n"
37676 " -screenwidth N use N as the default screenwidth \n"
37677 " -separator SEP set output column separator. Default: '|'\n"
37678 #ifdef SQLITE_ENABLE_SORTER_REFERENCES
37679 " -sorterref SIZE sorter references threshold size\n"
37680 #endif
37681 " -stats print memory stats before each finalize\n"
37682 " -table set output mode to 'table'\n"
37683 " -tabs set output mode to 'tabs'\n"
37684 " -unsafe-testing allow unsafe commands and modes for testing\n"
37685 " -version show SQLite version\n"
37686 " -vfs NAME use NAME as the default VFS\n"
37687 " -vfstrace enable tracing of all VFS calls\n"
37688 #ifdef SQLITE_HAVE_ZLIB
@@ -37710,10 +38505,23 @@
37710 sputz(stdout, "WARNING: attempt to configure SQLite after"
37711 " initialization.\n");
37712 }
37713 }
37714
 
 
 
 
 
 
 
 
 
 
 
 
 
37715 /*
37716 ** Initialize the state information in data
37717 */
37718 static void main_init(ShellState *p) {
37719 memset(p, 0, sizeof(*p));
@@ -37724,31 +38532,36 @@
37724 verify_uninitialized();
37725 #endif
37726 sqlite3_config(SQLITE_CONFIG_URI, 1);
37727 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
37728 globalShellState = p;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37729 }
37730
37731 /*
37732 ** Output text to the console in a font that attracts extra attention.
37733 */
37734 #if 0 /* Windows now handles ANSI escape codes */
37735 static void printBold(const char *zText){
37736 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
37737 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
37738 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
37739 SetConsoleTextAttribute(out,
37740 FOREGROUND_RED|FOREGROUND_INTENSITY
37741 );
37742 sputz(stdout, zText);
37743 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
37744 }
37745 #else
37746 static void printBold(const char *zText){
37747 cli_printf(stdout, "\033[1;36m\033[3m%s\033[0m", zText);
37748 }
37749 #endif
37750
37751 /*
37752 ** Get the argument to an --option. Throw an error and die if no argument
37753 ** is available.
37754 */
@@ -37762,11 +38575,11 @@
37762 }
37763
37764 /*
37765 ** The callback from atexit().
37766 */
37767 static void abnormalExit(void){
37768 if( seenInterrupt ) eputz("Program interrupted.\n");
37769 if( globalShellState ){
37770 clearTempFile(globalShellState, 1, 1);
37771 }
37772 }
@@ -37837,10 +38650,11 @@
37837 }
37838 argv[argc] = 0;
37839 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
37840 GetConsoleMode(hOut, &mode);
37841 SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
 
37842 rc = utf8_main(argc, argv);
37843 for(i=0; i<argc; i++) free(orig[i]);
37844 free(argv);
37845 return rc;
37846 }
@@ -37883,10 +38697,13 @@
37883 stdout_is_console = 1;
37884 data.wasm.zDefaultDbName = "/fiddle.sqlite3";
37885 #else
37886 stdin_is_interactive = isatty(0);
37887 stdout_is_console = isatty(1);
 
 
 
37888 #endif
37889 atexit(abnormalExit);
37890 #ifdef SQLITE_DEBUG
37891 mem_main_enter = sqlite3_memory_used();
37892 #endif
@@ -37973,11 +38790,11 @@
37973 stdin_is_interactive = 0;
37974 nCmd++;
37975 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
37976 shell_check_oom(azCmd);
37977 aiCmd = realloc(aiCmd, sizeof(aiCmd[0])*nCmd);
37978 shell_check_oom(azCmd);
37979 azCmd[nCmd-1] = z;
37980 aiCmd[nCmd-1] = i;
37981 }
37982 continue;
37983 }
@@ -38130,10 +38947,12 @@
38130 }else if( cli_strcmp(z,"-safe")==0 ){
38131 /* no-op - catch this on the second pass */
38132 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
38133 /* skip over the argument */
38134 i++;
 
 
38135 }else if( cli_strcmp(z,"-test-argv")==0 ){
38136 /* Undocumented test option. Print the values in argv[] and exit.
38137 ** Use this to verify that any translation of the argv[], for example
38138 ** on Windows that receives wargv[] from the OS and must convert
38139 ** to UTF8 prior to calling this routine. */
@@ -38262,10 +39081,11 @@
38262 modeChange(&data, MODE_Psql);
38263 }else if( cli_strcmp(z,"-box")==0 ){
38264 modeChange(&data, MODE_Box);
38265 }else if( cli_strcmp(z,"-csv")==0 ){
38266 modeChange(&data, MODE_Csv);
 
38267 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
38268 /* See similar code at tag-20250224-1 */
38269 const char *zEsc = argv[++i];
38270 int k;
38271 for(k=0; k<ArraySize(qrfEscNames); k++){
@@ -38319,13 +39139,15 @@
38319 cmdline_option_value(argc,argv,++i));
38320 }else if( cli_strcmp(z,"-nullvalue")==0 ){
38321 modeSetStr(&data.mode.spec.zNull,
38322 cmdline_option_value(argc,argv,++i));
38323 }else if( cli_strcmp(z,"-header")==0 ){
38324 data.mode.spec.bTitles = QRF_Yes;
 
38325 }else if( cli_strcmp(z,"-noheader")==0 ){
38326 data.mode.spec.bTitles = QRF_No;
 
38327 }else if( cli_strcmp(z,"-echo")==0 ){
38328 data.mode.mFlags |= MFLG_ECHO;
38329 }else if( cli_strcmp(z,"-eqp")==0 ){
38330 data.mode.autoEQP = AUTOEQP_on;
38331 }else if( cli_strcmp(z,"-eqpfull")==0 ){
@@ -38389,10 +39211,12 @@
38389 i++;
38390 #ifdef SQLITE_ENABLE_MULTIPLEX
38391 }else if( cli_strcmp(z,"-multiplex")==0 ){
38392 i++;
38393 #endif
 
 
38394 }else if( cli_strcmp(z,"-help")==0 ){
38395 usage(1);
38396 }else if( cli_strcmp(z,"-cmd")==0 ){
38397 /* Run commands that follow -cmd first and separately from commands
38398 ** that simply appear on the command-line. This seems goofy. It would
@@ -38418,12 +39242,14 @@
38418 rc = 1;
38419 goto shell_main_exit;
38420 }
38421 open_db(&data, OPEN_DB_ZIPFILE);
38422 if( z[2] ){
 
38423 argv[i] = &z[2];
38424 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
 
38425 }else{
38426 arDotCommand(&data, 1, argv+i, argc-i);
38427 }
38428 readStdin = 0;
38429 stdin_is_interactive = 0;
38430
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5,16 +5,16 @@
5 **
6 ** ext/expert/sqlite3expert.c
7 ** ext/expert/sqlite3expert.h
8 ** ext/intck/sqlite3intck.c
9 ** ext/intck/sqlite3intck.h
 
10 ** ext/misc/appendvfs.c
11 ** ext/misc/base64.c
12 ** ext/misc/base85.c
13 ** ext/misc/completion.c
14 ** ext/misc/decimal.c
15 ** ext/misc/diskused.c
16 ** ext/misc/fileio.c
17 ** ext/misc/ieee754.c
18 ** ext/misc/memtrace.c
19 ** ext/misc/pcachetrace.c
20 ** ext/misc/regexp.c
@@ -23,10 +23,11 @@
23 ** ext/misc/shathree.c
24 ** ext/misc/sqlar.c
25 ** ext/misc/sqlite3_stdio.c
26 ** ext/misc/sqlite3_stdio.h
27 ** ext/misc/stmtrand.c
28 ** ext/misc/strdup.c
29 ** ext/misc/uint.c
30 ** ext/misc/vfstrace.c
31 ** ext/misc/windirent.h
32 ** ext/misc/zipfile.c
33 ** ext/qrf/qrf.c
@@ -154,10 +155,11 @@
155 #include <string.h>
156 #include <stdio.h>
157 #include <assert.h>
158 #include <math.h>
159 #include <stdint.h>
160 #include <time.h>
161 #include "sqlite3.h"
162 typedef sqlite3_int64 i64;
163 typedef sqlite3_uint64 u64;
164 typedef unsigned char u8;
165 #include <ctype.h>
@@ -190,13 +192,14 @@
192 #include <sys/stat.h>
193
194 #if HAVE_READLINE
195 # include <readline/readline.h>
196 # include <readline/history.h>
197 #elif HAVE_EDITLINE
198 /* If both HAVE_READLINE and HAVE_EDITLINE are true, assume that this
199 ** libedit installation does not have its own headers, instead using
200 ** those from libreadline. */
201 # include <editline/readline.h>
202 #endif
203
204 #if HAVE_EDITLINE || HAVE_READLINE
205
@@ -203,28 +206,38 @@
206 # define shell_add_history(X) add_history(X)
207 # define shell_read_history(X) read_history(X)
208 # define shell_write_history(X) write_history(X)
209 # define shell_stifle_history(X) stifle_history(X)
210 # define shell_readline(X) readline(X)
211 # define SHELL_CMDLINE_EDIT_AVAILABLE 1 /* command-line editing available */
212
213 #elif HAVE_LINENOISE
214
215 # include "linenoise.h"
216 # define shell_add_history(X) linenoiseHistoryAdd(X)
217 # define shell_read_history(X) linenoiseHistoryLoad(X)
218 # define shell_write_history(X) linenoiseHistorySave(X)
219 # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
220 # define shell_readline(X) linenoise(X)
221 # define SHELL_CMDLINE_EDIT_AVAILABLE 1 /* command-line editing available */
222
223 #else
224
225 # define shell_read_history(X)
226 # define shell_write_history(X)
227 # define shell_stifle_history(X)
228 # define SHELL_CMDLINE_EDIT_AVAILABLE 0 /* command-line editing not available */
229 #endif
230
231 /*
232 ** Global variable shellCmdLineEdit determines whether or not command-line
233 ** editing is enabled. It defaults to 1 if the CLI is linked against a
234 ** command-line editing library (linenoise, readline, or editline) and
235 ** to 0 if no command-line editing library is available. The
236 ** "--cmdline-edit off" command-line option will change this value to 0.
237 */
238 static int shellCmdLineEdit = SHELL_CMDLINE_EDIT_AVAILABLE;
239
240 #ifndef deliberate_fall_through
241 /* Quiet some compilers about some of our intentional code. */
242 # if defined(GCC_VERSION) && GCC_VERSION>=7000000
243 # define deliberate_fall_through __attribute__((fallthrough));
@@ -731,10 +744,14 @@
744 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
745 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
746 void *pRenderArg; /* First argument to the xRender callback */
747 void *pWriteArg; /* First argument to the xWrite callback */
748 char **pzOutput; /* Storage location for output string */
749 /* The following are available in iVersion 2 and later */
750 unsigned char bRowCount; /* Show the number of rows at end of each query */
751 char *zIFmt; /* Format string for integers */
752 char *zFpFmt; /* Format string for floating point */
753 /* Additional fields may be added in the future */
754 };
755
756 /*
757 ** Interfaces
@@ -744,12 +761,11 @@
761 const sqlite3_qrf_spec *pSpec, /* Result format specification */
762 char **pzErr /* OUT: Write error message here */
763 );
764
765 /*
766 ** Range of values for sqlite3_qrf_spec.aWidth[] entries.
 
767 */
768 #define QRF_MAX_WIDTH 10000
769 #define QRF_MIN_WIDTH 0
770
771 /*
@@ -760,11 +776,11 @@
776 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
777 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
778 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
779 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
780 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
781 #define QRF_STYLE_Html 7 /* Generate HTML-style <tr><td> output */
782 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
783 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
784 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
785 #define QRF_STYLE_Line 11 /* One column per line. */
786 #define QRF_STYLE_List 12 /* One record per line with a separator */
@@ -820,10 +836,15 @@
836 #define QRF_SW_On 2 /* This setting is forced on */
837 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
838 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
839 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
840
841 /*
842 ** Additional value allowed for bTitles
843 */
844 #define QRF_Always 3 /* Always show titles, even if no rows */
845
846 /*
847 ** Possible alignment values alignment settings
848 **
849 ** Horizontal Vertial
850 ** ---------- -------- */
@@ -868,10 +889,22 @@
889 ** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
890 ** are assigned a width of zero.
891 */
892 size_t sqlite3_qrf_wcswidth(const char*);
893
894 /*
895 ** The argument is a proposed format string for the zIFmt or zFpFmt
896 ** parameters. Return value indicates:
897 **
898 ** 0 The input is not a valid format string. If this string
899 ** appears in either zIFmt or zFpFmt, it will be ignored.
900 **
901 ** 1 The input is a valid format string for integers.
902 **
903 ** 2 The input is a valid format string for floating point.
904 */
905 int sqlite3_qrf_ckformat(const char*);
906
907 #ifdef __cplusplus
908 }
909 #endif
910 #endif /* !defined(SQLITE_QRF_H) */
@@ -950,10 +983,11 @@
983 } sExpln;
984 unsigned int nIns; /* Bytes used for current INSERT stmt */
985 } u;
986 sqlite3_int64 nRow; /* Number of rows handled so far */
987 int *actualWidth; /* Actual width of each column */
988 char zFmt[24]; /* Space to hold the true integer rendering fmt */
989 sqlite3_qrf_spec spec; /* Copy of the original spec */
990 };
991
992 /*
993 ** Data for substitute ctype.h functions. Used for x-platform
@@ -993,10 +1027,48 @@
1027 # define deliberate_fall_through __attribute__((fallthrough));
1028 # else
1029 # define deliberate_fall_through
1030 # endif
1031 #endif
1032
1033 /*
1034 ** The argument is a proposed format string for the zIFmt or zFpFmt
1035 ** parameters. Return value indicates:
1036 **
1037 ** 0 The input is not a valid format string. If this string
1038 ** appears in either zIFmt or zFpFmt, it will be ignored.
1039 **
1040 ** 1 The input is a valid format string for integers.
1041 **
1042 ** 2 The input is a valid format string for floating point.
1043 */
1044 int sqlite3_qrf_ckformat(const char *z){
1045 size_t n;
1046 if( z==0 ) return 0;
1047 if( z[0]!='%' ) return 0;
1048 z++;
1049 n = strspn(z,"+-,#0");
1050 if( n>5 ) return 0;
1051 z += n;
1052 if( z[0]>='1' && z[0]<='9' ){
1053 n = strspn(z,"0123456789");
1054 if( n>3 ) return 0;
1055 z += n;
1056 }
1057 if( z[0]=='.' ){
1058 z++;
1059 n = strspn(z,"0123456789");
1060 if( n>3 ) return 0;
1061 z += n;
1062 }
1063 n = strspn(z,"eEgGf");
1064 if( n==1 && z[1]==0 ) return 2;
1065 n = strspn(z,"dxXo");
1066 if( n==1 && z[1]==0 ) return 1;
1067 return 0;
1068 }
1069
1070
1071 /*
1072 ** Set an error code and error message.
1073 */
1074 static void qrfError(
@@ -1129,10 +1201,14 @@
1201 sqlite3_str_append(pOut, "-", 1);
1202 }
1203 if( N<10000 ){
1204 sqlite3_str_appendf(pOut, "%4lld ", N);
1205 return;
1206 }
1207 if( N>=9223372036854775800LL ){
1208 sqlite3_str_appendf(pOut, "%.2fE", 1e-18*(double)N);
1209 return;
1210 }
1211 for(i=1; i<=18; i++){
1212 N = (N+5)/10;
1213 if( N<10000 ){
1214 int n = (int)N;
@@ -1289,12 +1365,12 @@
1365 if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
1366 int nSp = 0;
1367 sqlite3_str_reset(pStats);
1368 if( nCycle>=0 && nTotal>0 ){
1369 qrfApproxInt64(pStats, nCycle);
1370 sqlite3_str_appendf(pStats, " %3.0f%%",
1371 ((100.0*(double)nCycle)+nTotal/2.0) / (double)nTotal
1372 );
1373 nSp = 2;
1374 }
1375 if( nLoop>=0 ){
1376 if( nSp ) sqlite3_str_appendchar(pStats, nSp, ' ');
@@ -1787,11 +1863,11 @@
1863 }
1864 if( i>0 ){
1865 sqlite3_str_append(pOut, (const char*)z, i);
1866 }
1867 switch( z[i] ){
1868 case '>': sqlite3_str_append(pOut, "&gt;", 4); break;
1869 case '&': sqlite3_str_append(pOut, "&amp;", 5); break;
1870 case '<': sqlite3_str_append(pOut, "&lt;", 4); break;
1871 case '"': sqlite3_str_append(pOut, "&quot;", 6); break;
1872 case '\'': sqlite3_str_append(pOut, "&#39;", 5); break;
1873 default: i--;
@@ -1977,16 +2053,22 @@
2053 return;
2054 }
2055 }
2056 switch( sqlite3_column_type(p->pStmt,iCol) ){
2057 case SQLITE_INTEGER: {
2058 sqlite3_str_appendf(pOut, p->spec.zIFmt,
2059 sqlite3_column_int64(p->pStmt,iCol));
2060 break;
2061 }
2062 case SQLITE_FLOAT: {
2063 if( p->spec.zFpFmt ){
2064 double r = sqlite3_column_double(p->pStmt,iCol);
2065 sqlite3_str_appendf(pOut,p->spec.zFpFmt,r);
2066 }else{
2067 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
2068 sqlite3_str_appendall(pOut, zTxt);
2069 }
2070 break;
2071 }
2072 case SQLITE_BLOB: {
2073 if( p->spec.bTextJsonb==QRF_Yes ){
2074 const char *zJson = qrfJsonbToJson(p, iCol);
@@ -2281,11 +2363,11 @@
2363 if( bWrap && z[i]!=0 && !qrfSpace(z[i]) && qrfAlnum(c)==qrfAlnum(z[i]) ){
2364 /* Perhaps try to back up to a better place to break the line */
2365 for(k=i-1; k>=i/2; k--){
2366 if( qrfSpace(z[k]) ) break;
2367 }
2368 if( k<i/2 && i/2>0 ){
2369 for(k=i; k>=i/2; k--){
2370 if( qrfAlnum(z[k-1])!=qrfAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
2371 }
2372 }
2373 if( k>=i/2 ){
@@ -2522,10 +2604,14 @@
2604 /* Doubled horizontal lines: */
2605 #define DBL_24 "\342\225\220" /* U+2550 === */
2606 #define DBL_123 "\342\225\236" /* U+255e |= */
2607 #define DBL_134 "\342\225\241" /* U+2561 =| */
2608 #define DBL_1234 "\342\225\252" /* U+256a =|= */
2609 #define DBL_12 "\342\225\230" /* U+2558 `= */
2610 #define DBL_14 "\342\225\233" /* U+255b =' */
2611 #define DBL_124 "\342\225\247" /* U+2567 ='= */
2612
2613
2614 /* Draw horizontal line N characters long using unicode box
2615 ** characters
2616 */
2617 static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2532,28 +2618,28 @@
2618 const char *azDash[2] = {
2619 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24,
2620 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24
2621 };/* 0 1 2 3 4 5 6 7 8 9 */
2622 const int nDash = 30;
2623 i64 nn = 3*(i64)N;
2624 while( nn>nDash ){
2625 sqlite3_str_append(pOut, azDash[bDbl], nDash);
2626 nn -= nDash;
2627 }
2628 sqlite3_str_append(pOut, azDash[bDbl], (int)nn);
2629 }
2630
2631 /*
2632 ** Draw a horizontal separator for a QRF_STYLE_Box table.
2633 */
2634 static void qrfBoxSeparator(
2635 sqlite3_str *pOut, /* Output to this sqlite3_str */
2636 qrfColData *p, /* Columnar data */
2637 const char *zSep1, /* Left margin */
2638 const char *zSep2, /* Column separator */
2639 const char *zSep3, /* Right margin */
2640 int bDbl /* True for double-lines */
2641 ){
2642 int i;
2643 if( p->nCol>0 ){
2644 int useBorder = p->p->spec.bBorder!=QRF_No;
2645 if( useBorder ){
@@ -2568,10 +2654,36 @@
2654 sqlite3_str_appendall(pOut, zSep3);
2655 }
2656 }
2657 sqlite3_str_append(pOut, "\n", 1);
2658 }
2659
2660 /*
2661 ** Draw a horizontal separator for a QRF_STYLE_Column table.
2662 ** This style of separator is only used for separating the title
2663 ** from the content.
2664 */
2665 static void qrfColumnSeparator(
2666 sqlite3_str *pOut, /* Output to this sqlite3_str */
2667 qrfColData *p, /* Columnar data */
2668 const char *colSep, /* Column separator text */
2669 int szColSep, /* Size of zColSep in bytes */
2670 const char *rowSep, /* Row separator text */
2671 int szRowSep /* Size of zRowSep in bytes */
2672 ){
2673 int j;
2674 int nColumn = p->nCol;
2675 for(j=0; j<nColumn; j++){
2676 sqlite3_str_appendchar(pOut, p->a[j].w, '-');
2677 if( j<nColumn-1 ){
2678 sqlite3_str_append(pOut, colSep, szColSep);
2679 }else{
2680 qrfRTrim(pOut);
2681 sqlite3_str_append(pOut, rowSep, szRowSep);
2682 }
2683 }
2684 }
2685
2686 /*
2687 ** Load into pData the default alignment for the body of a table.
2688 */
2689 static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2610,11 +2722,11 @@
2722 int nSW /* Screen width */
2723 ){
2724 int i; /* Loop counter */
2725 int nr; /* Number of rows */
2726 int w = 0; /* Width of the current column */
2727 i64 t; /* Total width of all columns */
2728 int *aw; /* Array of individual column widths */
2729
2730 aw = sqlite3_malloc64( sizeof(int)*nCol );
2731 if( aw==0 ){
2732 qrfOom(p);
@@ -2748,12 +2860,15 @@
2860 }else{
2861 sepW = pData->nCol*3 + 1;
2862 if( p->spec.bBorder==QRF_No ) sepW -= 2;
2863 }
2864 nCol = pData->nCol;
2865 for(i=0, sumW=0; i<nCol; i++){
2866 if( sumW > 2147483647 - pData->a[i].w ) return;
2867 sumW += pData->a[i].w;
2868 }
2869 if( p->spec.nScreenWidth >= (i64)sumW + sepW ) return;
2870
2871 /* First thing to do is reduce the separation between columns */
2872 pData->nMargin = 0;
2873 if( p->spec.eStyle==QRF_STYLE_Column ){
2874 sepW = pData->nCol - 1;
@@ -2823,11 +2938,25 @@
2938 sqlite3_str *pStr; /* Temporary rendering */
2939 qrfColData data; /* Columnar layout data */
2940 int bRTrim; /* Trim trailing space */
2941
2942 rc = sqlite3_step(p->pStmt);
2943 if( nColumn==0 ){
2944 return; /* Not a query. No results every shown. */
2945 }
2946 if( rc==SQLITE_DONE && nColumn>0 ){
2947 /* Empty query */
2948 if( p->spec.bTitles==QRF_Always ){
2949 /* fall through into the columnar logic below */
2950 }else{
2951 if( p->spec.bRowCount==QRF_Yes ){
2952 sqlite3_str_appendf(p->pOut, "(0 rows)\n");
2953 qrfWrite(p);
2954 }
2955 return; /* No output, other than the row count */
2956 }
2957 }else if( rc!=SQLITE_ROW ){
2958 return; /* No output */
2959 }
2960
2961 /* Initialize the data container */
2962 memset(&data, 0, sizeof(data));
@@ -2840,12 +2969,12 @@
2969 }
2970 memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2971 if( qrfColDataEnlarge(&data) ) return;
2972 assert( data.az!=0 );
2973
2974 /* Load the column header names into data */
2975 if( p->spec.bTitles>=QRF_Yes ){
2976 unsigned char saved_eText = p->spec.eText;
2977 p->spec.eText = p->spec.eTitle;
2978 memset(data.abNum, 0, nColumn);
2979 for(i=0; i<nColumn; i++){
2980 const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2866,13 +2995,14 @@
2995 data.n++;
2996 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2997 if( nNL ) data.bMultiRow = 1;
2998 }
2999 p->spec.eText = saved_eText;
 
3000 }
3001
3002 /* Load query results into data */
3003 while( rc==SQLITE_ROW && p->iErr==SQLITE_OK ){
3004 if( data.n+nColumn > data.nAlloc ){
3005 if( qrfColDataEnlarge(&data) ) return;
3006 }
3007 for(i=0; i<nColumn; i++){
3008 char *z;
@@ -2889,11 +3019,12 @@
3019 data.n++;
3020 if( w>data.a[i].mxW ) data.a[i].mxW = w;
3021 if( nNL ) data.bMultiRow = 1;
3022 }
3023 p->nRow++;
3024 rc = sqlite3_step(p->pStmt);
3025 }
3026 if( p->iErr ){
3027 qrfColDataFree(&data);
3028 return;
3029 }
3030
@@ -3097,11 +3228,11 @@
3228 /* Draw either (1) the separator between the title line and the body
3229 ** of the table, or (2) separators between individual rows of the table
3230 ** body. isTitleDataSeparator will be true if we are doing (1).
3231 */
3232 if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3233 int isTitleDataSeparator = (i==0 && p->spec.bTitles>=QRF_Yes);
3234 if( isTitleDataSeparator ){
3235 qrfLoadAlignment(&data, p);
3236 }
3237 switch( p->spec.eStyle ){
3238 case QRF_STYLE_Table: {
@@ -3124,19 +3255,12 @@
3255 }
3256 break;
3257 }
3258 case QRF_STYLE_Column: {
3259 if( isTitleDataSeparator ){
3260 qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3261 rowSep, szRowSep);
 
 
 
 
 
 
 
3262 }else if( data.bMultiRow ){
3263 qrfRTrim(p->pOut);
3264 sqlite3_str_append(p->pOut, "\n", 1);
3265 }
3266 break;
@@ -3144,20 +3268,39 @@
3268 }
3269 }
3270 }
3271
3272 /* Draw the line across the bottom of the table */
3273 if( p->spec.bBorder!=QRF_No || p->nRow==0 ){
3274 switch( p->spec.eStyle ){
3275 case QRF_STYLE_Box:
3276 if( p->nRow>0 ){
3277 qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3278 }else{
3279 qrfBoxSeparator(p->pOut, &data, DBL_12, DBL_124, DBL_14, 1);
3280 }
3281 break;
3282 case QRF_STYLE_Table:
3283 qrfRowSeparator(p->pOut, &data, '+');
3284 break;
3285 case QRF_STYLE_Markdown:
3286 if( p->nRow==0 ){
3287 qrfRowSeparator(p->pOut, &data, '|');
3288 }
3289 break;
3290 case QRF_STYLE_Column:
3291 if( p->nRow==0 ){
3292 qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3293 rowSep, szRowSep);
3294 }
3295 break;
3296 }
3297 }
3298 if( p->spec.bRowCount==QRF_Yes ){
3299 sqlite3_int64 n = p->nRow;
3300 sqlite3_str_appendf(p->pOut, "(%lld row%s)\n", n, n==1 ? "" : "s");
3301 }
3302 qrfWrite(p);
3303
3304 qrfColDataFree(&data);
3305 return;
3306 }
@@ -3404,10 +3547,49 @@
3547 sqlite3_str_append(p->pOut, ":", 1);
3548 qrfRenderValue(p, p->pOut, i);
3549 }
3550 qrfWrite(p);
3551 }
3552
3553 /*
3554 ** Render a title row (a row containing column names) if the spec
3555 ** calls for one and if it makes sense for the eStyle. Title rows
3556 ** do not make sense for some eStyles, such as QRF_STYLE_Off,
3557 ** QRF_STYLE_Count, QRF_STYLE_Json, and similar.
3558 */
3559 static void qrfSimpleTitle(Qrf *p){
3560 assert( p->nRow==0 );
3561 assert( p->spec.bTitles>=QRF_Yes );
3562 switch( p->spec.eStyle ){
3563 case QRF_STYLE_Html: {
3564 int i;
3565 sqlite3_str_append(p->pOut, "<tr>", 4);
3566 for(i=0; i<p->nCol; i++){
3567 const char *zCName = sqlite3_column_name(p->pStmt, i);
3568 sqlite3_str_append(p->pOut, "\n<th>", 5);
3569 qrfEncodeText(p, p->pOut, zCName);
3570 }
3571 sqlite3_str_append(p->pOut, "\n</tr>\n", 7);
3572 break;
3573 }
3574 case QRF_STYLE_Quote:
3575 case QRF_STYLE_List: {
3576 int i;
3577 int saved_eText = p->spec.eText;
3578 p->spec.eText = p->spec.eTitle;
3579 for(i=0; i<p->nCol; i++){
3580 const char *zCName = sqlite3_column_name(p->pStmt, i);
3581 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3582 qrfEncodeText(p, p->pOut, zCName);
3583 }
3584 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3585 qrfWrite(p);
3586 p->spec.eText = saved_eText;
3587 break;
3588 }
3589 }
3590 }
3591
3592 /*
3593 ** Render a single row of output for non-columnar styles - any
3594 ** style that lets us render row by row as the content is received
3595 ** from the query.
@@ -3437,25 +3619,19 @@
3619 }
3620 qrfOneJsonRow(p);
3621 break;
3622 }
3623 case QRF_STYLE_Html: {
3624 if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3625 qrfSimpleTitle(p);
3626 }
3627 sqlite3_str_append(p->pOut, "<tr>", 4);
3628 for(i=0; i<p->nCol; i++){
3629 sqlite3_str_append(p->pOut, "\n<td>", 5);
 
 
 
 
 
 
3630 qrfRenderValue(p, p->pOut, i);
3631 }
3632 sqlite3_str_append(p->pOut, "\n</tr>\n", 7);
3633 qrfWrite(p);
3634 break;
3635 }
3636 case QRF_STYLE_Insert: {
3637 unsigned int mxIns = p->spec.nMultiInsert;
@@ -3468,11 +3644,11 @@
3644 if( qrf_need_quote(p->spec.zTableName) ){
3645 sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
3646 }else{
3647 sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
3648 }
3649 if( p->spec.bTitles>=QRF_Yes ){
3650 for(i=0; i<p->nCol; i++){
3651 const char *zCName = sqlite3_column_name(p->pStmt, i);
3652 if( qrf_need_quote(zCName) ){
3653 sqlite3_str_appendf(p->pOut, "%c\"%w\"",
3654 i==0 ? '(' : ',', zCName);
@@ -3568,21 +3744,12 @@
3744 if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3745 qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3746 break;
3747 }
3748 default: { /* QRF_STYLE_List */
3749 if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3750 qrfSimpleTitle(p);
 
 
 
 
 
 
 
 
 
3751 }
3752 for(i=0; i<p->nCol; i++){
3753 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3754 qrfRenderValue(p, p->pOut, i);
3755 }
@@ -3604,11 +3771,11 @@
3771 char **pzErr /* Write errors here */
3772 ){
3773 size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3774 memset(p, 0, sizeof(*p));
3775 p->pzErr = pzErr;
3776 if( pSpec->iVersion>2 ){
3777 qrfError(p, SQLITE_ERROR,
3778 "unusable sqlite3_qrf_spec.iVersion (%d)",
3779 pSpec->iVersion);
3780 return;
3781 }
@@ -3620,15 +3787,19 @@
3787 return;
3788 }
3789 p->iErr = SQLITE_OK;
3790 p->nCol = sqlite3_column_count(p->pStmt);
3791 p->nRow = 0;
3792 switch( pSpec->iVersion ){
3793 case 0: sz = offsetof(sqlite3_qrf_spec, bRowCount); break;
3794 case 1: sz = offsetof(sqlite3_qrf_spec, bRowCount); break;
3795 default: sz = sizeof(sqlite3_qrf_spec); break;
3796 }
3797 memcpy(&p->spec, pSpec, sz);
3798 if( p->spec.zNull==0 ) p->spec.zNull = "";
3799 p->mxWidth = p->spec.nScreenWidth;
3800 if( p->mxWidth<=0 ) p->mxWidth = 2147483647;
3801 p->mxHeight = p->spec.nLineLimit;
3802 if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3803 if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3804 if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3805 if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
@@ -3756,10 +3927,24 @@
3927 if( p->spec.bTextJsonb==QRF_Auto ){
3928 p->spec.bTextJsonb = QRF_No;
3929 }
3930 if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = ",";
3931 if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3932 if( p->spec.zIFmt==0 || sqlite3_qrf_ckformat(p->spec.zIFmt)!=1 ){
3933 p->spec.zIFmt = "%lld";
3934 }else{
3935 size_t n = strlen(p->spec.zIFmt);
3936 memcpy(p->zFmt, p->spec.zIFmt, n-1);
3937 p->zFmt[n-1] = 'l';
3938 p->zFmt[n] = 'l';
3939 p->zFmt[n+1] = p->spec.zIFmt[n-1];
3940 p->zFmt[n+2] = 0;
3941 p->spec.zIFmt = p->zFmt;
3942 }
3943 if( p->spec.zFpFmt && sqlite3_qrf_ckformat(p->spec.zFpFmt)!=2 ){
3944 p->spec.zFpFmt = 0;
3945 }
3946 }
3947
3948 /*
3949 ** Finish rendering the results
3950 */
@@ -3890,10 +4075,34 @@
4075 default: {
4076 /* Non-columnar modes where the output can occur after each row
4077 ** of result is received */
4078 while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
4079 qrfOneSimpleRow(&qrf);
4080 }
4081 if( qrf.nCol>0 && qrf.nRow==0 && qrf.spec.bTitles==QRF_Always ){
4082 qrfSimpleTitle(&qrf);
4083 }
4084 if( qrf.nCol>0 && qrf.spec.bRowCount==QRF_Yes ){
4085 const char *zPlural = qrf.nRow==1 ? "" : "s";
4086 switch( qrf.spec.eStyle ){
4087 case QRF_STYLE_Line:
4088 if( qrf.nRow>0 ) sqlite3_str_append(qrf.pOut, "\n", 1);
4089 /* Fall through */
4090 case QRF_STYLE_Csv:
4091 case QRF_STYLE_List:
4092 case QRF_STYLE_Quote:
4093 sqlite3_str_appendf(qrf.pOut,"(%lld row%s)\n",qrf.nRow,zPlural);
4094 break;
4095 case QRF_STYLE_Html:
4096 sqlite3_str_appendf(qrf.pOut,"<!-- %lld row%s -->\n",
4097 qrf.nRow, zPlural);
4098 break;
4099 case QRF_STYLE_Insert:
4100 sqlite3_str_appendf(qrf.pOut,"/* %lld row%s inserted */\n",
4101 qrf.nRow, zPlural);
4102 break;
4103 }
4104 }
4105 break;
4106 }
4107 }
4108 qrfResetStmt(&qrf);
@@ -5106,10 +5315,12 @@
5315 int rc;
5316 int n;
5317 const char *z;
5318 SHA3Context cx;
5319 int iSize;
5320 int isRecursive = 0;
5321 int *pIsRecursive;
5322
5323 if( argc==1 ){
5324 iSize = 256;
5325 }else{
5326 iSize = sqlite3_value_int(argv[1]);
@@ -5119,10 +5330,15 @@
5330 return;
5331 }
5332 }
5333 if( zSql==0 ) return;
5334 SHA3Init(&cx, iSize);
5335 pIsRecursive = (int*)sqlite3_get_clientdata(db,"sha3_query()");
5336 if( pIsRecursive ){
5337 *pIsRecursive = 1;
5338 return;
5339 }
5340 while( zSql[0] ){
5341 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5342 if( rc ){
5343 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
5344 zSql, sqlite3_errmsg(db));
@@ -5145,19 +5361,25 @@
5361 sha3_step_vformat(&cx,"S%d:",n);
5362 SHA3Update(&cx,(unsigned char*)z,n);
5363 }
5364
5365 /* Compute a hash over the result of the query */
5366 sqlite3_set_clientdata(db, "sha3_query()", &isRecursive, 0);
5367 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5368 SHA3Update(&cx,(const unsigned char*)"R",1);
5369 for(i=0; i<nCol; i++){
5370 sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
5371 }
5372 }
5373 sqlite3_finalize(pStmt);
5374 sqlite3_set_clientdata(db, "sha3_query()", 0, 0);
5375 }
5376 if( isRecursive ){
5377 sqlite3_result_error(context, "recursive use of sha3_query()", -1);
5378 }else{
5379 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5380 }
5381 }
5382
5383 /*
5384 ** xStep function for sha3_agg().
5385 */
@@ -5272,10 +5494,14 @@
5494 #include <stdarg.h>
5495
5496 /******************************************************************************
5497 ** The Hash Engine
5498 */
5499 #if defined(__GNUC__) && __GNUC__>=11
5500 # pragma GCC diagnostic push
5501 # pragma GCC diagnostic ignored "-Wstringop-overread"
5502 #endif
5503 /* Context for the SHA1 hash */
5504 typedef struct SHA1Context SHA1Context;
5505 struct SHA1Context {
5506 unsigned int state[5];
5507 unsigned int count[2];
@@ -5412,11 +5638,11 @@
5638 }
5639 j = 0;
5640 }else{
5641 i = 0;
5642 }
5643 if( len-i>0 ) (void)memcpy(&p->buffer[j], &data[i], len - i);
5644 }
5645
5646 /* Compute a string using sqlite3_vsnprintf() and hash it */
5647 static void hash_step_vformat(
5648 SHA1Context *p, /* Add content to this context */
@@ -5467,10 +5693,13 @@
5693 zOut[i*2+1] = zEncode[digest[i] & 0xf];
5694 }
5695 zOut[i*2]= 0;
5696 }
5697 }
5698 #if defined(__GNUC__) && __GNUC__>=11
5699 # pragma GCC diagnostic pop
5700 #endif
5701 /* End of the hashing logic
5702 *****************************************************************************/
5703
5704 /*
5705 ** Two SQL functions: sha1(X) and sha1b(X).
@@ -5501,11 +5730,14 @@
5730 if( eType==SQLITE_BLOB ){
5731 pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
5732 }else{
5733 pData = (const unsigned char*)sqlite3_value_text(argv[0]);
5734 }
5735 if( pData==0 ){
5736 if( nByte ) return;
5737 pData = (const unsigned char*)"";
5738 }
5739 hash_step(&cx, pData, nByte);
5740 if( sqlite3_user_data(context)!=0 ){
5741 /* sha1b() - binary result */
5742 hash_finish(&cx, zOut, 1);
5743 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5541,13 +5773,20 @@
5773 int rc;
5774 int n;
5775 const char *z;
5776 SHA1Context cx;
5777 char zOut[44];
5778 int isRecursive = 0;
5779 int *pIsRecursive;
5780
5781 assert( argc==1 );
5782 if( zSql==0 ) return;
5783 pIsRecursive = sqlite3_get_clientdata(db, "sha1_query()");
5784 if( pIsRecursive ){
5785 *pIsRecursive = 1;
5786 return;
5787 }
5788 hash_init(&cx);
5789 while( zSql[0] ){
5790 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5791 if( rc ){
5792 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5570,10 +5809,11 @@
5809 n = (int)strlen(z);
5810 hash_step_vformat(&cx,"S%d:",n);
5811 hash_step(&cx,(unsigned char*)z,n);
5812
5813 /* Compute a hash over the result of the query */
5814 sqlite3_set_clientdata(db, "sha1_query()", &isRecursive, 0);
5815 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5816 hash_step(&cx,(const unsigned char*)"R",1);
5817 for(i=0; i<nCol; i++){
5818 switch( sqlite3_column_type(pStmt,i) ){
5819 case SQLITE_NULL: {
@@ -5624,13 +5864,18 @@
5864 }
5865 }
5866 }
5867 }
5868 sqlite3_finalize(pStmt);
5869 sqlite3_set_clientdata(db, "sha1_query()", 0, 0);
5870 }
5871 hash_finish(&cx, zOut, 0);
5872 if( isRecursive ){
5873 sqlite3_result_error(context, "recursive use of sha1_query()", -1);
5874 }else{
5875 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5876 }
5877 }
5878
5879
5880 #ifdef _WIN32
5881
@@ -5824,10 +6069,13 @@
6069 }
6070
6071 /*
6072 ** Allocate a new Decimal object initialized to the text in zIn[].
6073 ** Return NULL if any kind of error occurs.
6074 **
6075 ** Note that zIn[] is not necessarily zero-terminated. Always
6076 ** respect the boundary imposed by the n argument.
6077 */
6078 static Decimal *decimalNewFromText(const char *zIn, int n){
6079 Decimal *p = 0;
6080 int i;
6081 int iExp = 0;
@@ -5841,15 +6089,15 @@
6089 p->isNull = 0;
6090 p->nDigit = 0;
6091 p->nFrac = 0;
6092 p->a = sqlite3_malloc64( n+1 );
6093 if( p->a==0 ) goto new_from_text_failed;
6094 for(i=0; i<n && IsSpace(zIn[i]); i++){}
6095 if( i<n && zIn[i]=='-' ){
6096 p->sign = 1;
6097 i++;
6098 }else if( i<n && zIn[i]=='+' ){
6099 i++;
6100 }
6101 while( i<n && zIn[i]=='0' ) i++;
6102 while( i<n ){
6103 char c = zIn[i];
@@ -6056,32 +6304,41 @@
6304 }
6305 z[i] = 0;
6306 sqlite3_result_text(pCtx, z, i, sqlite3_free);
6307 }
6308
6309 /* Forward declaration */
6310 static void decimal_expand(Decimal *p, int nDigit, int nFrac);
6311
6312 /*
6313 ** Round a decimal value to N significant digits. N must be positive.
6314 */
6315 static void decimal_round(Decimal *p, int N){
6316 int i;
6317 int nZero; /* Number of leading zeros */
6318 if( N<1 ) return;
6319 if( p==0 ) return;
6320 if( p->nDigit<=N ) return;
6321 for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
6322 N += nZero;
6323 if( p->nDigit<=N ) return;
6324 if( p->a[N]>=5 ){
6325 /* If all leading digits are 9, increase the number of digits
6326 ** by adding a new 0 to the front */
6327 for(i=0; i<N && p->a[i]==9; i++){}
6328 if( i==N ){
6329 decimal_expand(p, p->nDigit+1, p->nFrac);
6330 if( p->oom ) return;
6331 }
6332
6333 /* Do the rounding */
6334 p->a[N-1]++;
6335 for(i=N-1; i>0 && p->a[i]>9; i--){
6336 p->a[i] = 0;
6337 p->a[i-1]++;
6338 }
6339 assert( p->a[0]<=9 );
 
 
 
6340 }
6341 memset(&p->a[N], 0, p->nDigit - N);
6342 }
6343
6344 /*
@@ -6225,10 +6482,11 @@
6482 int nAddSig;
6483 int nAddFrac;
6484 signed char *a;
6485 if( p==0 ) return;
6486 nAddFrac = nFrac - p->nFrac;
6487 assert( nAddFrac>=0 );
6488 nAddSig = (nDigit - p->nDigit) - nAddFrac;
6489 if( nAddFrac==0 && nAddSig==0 ) return;
6490 if( nDigit+1>SQLITE_DECIMAL_MAX_DIGIT ){ p->oom = 1; return; }
6491 a = sqlite3_realloc64(p->a, nDigit+1);
6492 if( a==0 ){
@@ -8232,10 +8490,20 @@
8490 if( r==(double)x ) return r;
8491 if( r<(double)x ) x--;
8492 return (double)x;
8493 }
8494 #endif
8495
8496 /* Convert a floating point value to its closest integer. Do so in
8497 ** a way that avoids 'outside the range of representable values' warnings
8498 ** from UBSAN.
8499 */
8500 static sqlite3_int64 seriesRealToI64(double r){
8501 if( r<-9223372036854774784.0 ) return SMALLEST_INT64;
8502 if( r>+9223372036854774784.0 ) return LARGEST_INT64;
8503 return (sqlite3_int64)r;
8504 }
8505
8506 /*
8507 ** This method is called to "rewind" the series_cursor object back
8508 ** to the first row of output. This method is always called at least
8509 ** once prior to any call to seriesColumn() or seriesRowid() or
@@ -8355,27 +8623,31 @@
8623 double r = sqlite3_value_double(argv[iArg++]);
8624 if( r==seriesCeil(r)
8625 && r>=(double)SMALLEST_INT64
8626 && r<=(double)LARGEST_INT64
8627 ){
8628 iMin = iMax = seriesRealToI64(r);
8629 }else{
8630 goto series_no_rows;
8631 }
8632 }else{
8633 iMin = iMax = sqlite3_value_int64(argv[iArg++]);
8634 }
8635 }else{
8636 if( idxNum & 0x0300 ){ /* value>X (0x200) or value>=X (0x100) */
8637 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
8638 double r = sqlite3_value_double(argv[iArg++]);
8639 if( r<=(double)SMALLEST_INT64 ){
8640 iMin = SMALLEST_INT64;
8641 }else if( r>(double)LARGEST_INT64 ){
8642 goto series_no_rows;
8643 }else{
8644 iMin = seriesRealToI64(seriesCeil(r));
8645 if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
8646 if( iMin==LARGEST_INT64 ) goto series_no_rows;
8647 iMin++;
8648 }
8649 }
8650 }else{
8651 iMin = sqlite3_value_int64(argv[iArg++]);
8652 if( (idxNum & 0x0200)!=0 ){
8653 if( iMin==LARGEST_INT64 ){
@@ -8384,19 +8656,23 @@
8656 iMin++;
8657 }
8658 }
8659 }
8660 }
8661 if( idxNum & 0x3000 ){ /* value<X (0x2000) or value<=X (0x1000) */
8662 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
8663 double r = sqlite3_value_double(argv[iArg++]);
8664 if( r>=(double)LARGEST_INT64 ){
8665 iMax = LARGEST_INT64;
8666 }else if( r<=(double)SMALLEST_INT64 ){
8667 goto series_no_rows;
8668 }else{
8669 iMax = seriesRealToI64(seriesFloor(r));
8670 if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
8671 if( iMax==SMALLEST_INT64 ) goto series_no_rows;
8672 iMax--;
8673 }
8674 }
8675 }else{
8676 iMax = sqlite3_value_int64(argv[iArg++]);
8677 if( idxNum & 0x2000 ){
8678 if( iMax==SMALLEST_INT64 ){
@@ -9638,11 +9914,10 @@
9914 if( pRe==0 ){
9915 sqlite3_result_error_nomem(context);
9916 return;
9917 }
9918 pStr = sqlite3_str_new(0);
 
9919 if( pRe->nInit>0 ){
9920 sqlite3_str_appendf(pStr, "INIT ");
9921 for(i=0; i<pRe->nInit; i++){
9922 sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]);
9923 }
@@ -9649,20 +9924,20 @@
9924 sqlite3_str_appendf(pStr, "\n");
9925 }
9926 for(i=0; (unsigned)i<pRe->nState; i++){
9927 sqlite3_str_appendf(pStr, "%-8s %4d\n",
9928 ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
9929 }
9930 if( sqlite3_str_errcode(pStr)==SQLITE_NOMEM ){
9931 sqlite3_str_finish(pStr);
9932 re_free(pRe);
9933 sqlite3_result_error_nomem(context);
9934 return;
9935 }
9936 n = sqlite3_str_length(pStr);
9937 z = sqlite3_str_finish(pStr);
9938 sqlite3_result_text(context, z, n-1, sqlite3_free);
 
 
 
 
 
 
9939 re_free(pRe);
9940 }
9941
9942 #endif /* SQLITE_DEBUG */
9943
@@ -10557,11 +10832,15 @@
10832 sqlite3_result_error_nomem(ctx);
10833 return SQLITE_NOMEM;
10834 }
10835 }
10836
10837 if( n>0 ){
10838 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10839 }else{
10840 sqlite3_result_null(ctx);
10841 }
10842 if( aBuf!=aStatic ) sqlite3_free(aBuf);
10843 #endif
10844 }else{
10845 readFileContents(ctx, pCur->zPath);
10846 }
@@ -10870,10 +11149,13 @@
11149 ** Return NULL if unable.
11150 **
11151 ** The file or directory X is not required to exist. The answer is formed
11152 ** by calling system realpath() on the prefix of X that does exist and
11153 ** appending the tail of X that does not (yet) exist.
11154 **
11155 ** FIXME: This routine sometimes returns NULL rather than raising
11156 ** an SQLITE_NOMEM error if an OOM is encountered.
11157 */
11158 static void realpathFunc(
11159 sqlite3_context *context,
11160 int argc,
11161 sqlite3_value **argv
@@ -10892,10 +11174,11 @@
11174 (void)argc;
11175 zPath = (const char*)sqlite3_value_text(argv[0]);
11176 if( zPath==0 ) return;
11177 if( zPath[0]==0 ) zPath = ".";
11178 zCopy = sqlite3_mprintf("%s",zPath);
11179 if( zCopy==0 ) return;
11180 len = strlen(zCopy);
11181 while( len>1 && (zCopy[len-1]=='/' || (isWin && zCopy[len-1]=='\\')) ){
11182 len--;
11183 }
11184 zCopy[len] = 0;
@@ -11802,11 +12085,13 @@
12085 int iAmt,
12086 sqlite_int64 iOfst
12087 ){
12088 ApndFile *paf = (ApndFile *)pFile;
12089 sqlite_int64 iWriteEnd = iOfst + iAmt;
12090 if( iWriteEnd + paf->iPgOne >= APND_MAX_SIZE-APND_MARK_SIZE ){
12091 return SQLITE_FULL;
12092 }
12093 pFile = ORIGFILE(pFile);
12094 /* If append-mark is absent or will be overwritten, write it. */
12095 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
12096 int rc = apndWriteMark(paf, pFile, iWriteEnd);
12097 if( SQLITE_OK!=rc ) return rc;
@@ -12220,10 +12505,12 @@
12505 **
12506 ** * No support for encryption
12507 ** * No support for ZIP archives spanning multiple files
12508 ** * No support for zip64 extensions
12509 ** * Only the "inflate/deflate" (zlib) compression method is supported
12510 ** * No support for transactions. ROLLBACK is the same as COMMIT.
12511 ** A crash mid-transaction can leave the ZIP archive in a corrupt state.
12512 */
12513 /* #include "sqlite3ext.h" */
12514 SQLITE_EXTENSION_INIT1
12515 #include <stdio.h>
12516 #include <string.h>
@@ -12685,10 +12972,11 @@
12972
12973 for(p=pCsr->pFreeEntry; p; p=pNext){
12974 pNext = p->pNext;
12975 zipfileEntryFree(p);
12976 }
12977 pCsr->pFreeEntry = 0;
12978 }
12979
12980 /*
12981 ** Destructor for an ZipfileCsr.
12982 */
@@ -13087,11 +13375,17 @@
13375 }
13376 }
13377
13378 if( rc==SQLITE_OK ){
13379 u32 *pt = &pNew->mUnixTime;
13380 /* aRead[0..nFile-1] might contain embedded \000 characters
13381 ** See Bug 2026-05-31T11:43:05Z */
13382 pNew->cds.zFile = sqlite3_malloc64(nFile+1);
13383 if( pNew->cds.zFile!=0 ){
13384 memcpy(pNew->cds.zFile, aRead, nFile);
13385 pNew->cds.zFile[nFile] = 0;
13386 }
13387 pNew->aExtra = (u8*)&pNew[1];
13388 memcpy(pNew->aExtra, &aRead[nFile], nExtra);
13389 if( pNew->cds.zFile==0 ){
13390 rc = SQLITE_NOMEM;
13391 }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
@@ -13844,14 +14138,14 @@
14138 if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
14139 bUpdate = 1;
14140 }
14141 }
14142 for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
14143 if( pOld==0 ) return SQLITE_OK;
14144 if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
14145 break;
14146 }
 
14147 }
14148 }
14149
14150 if( nVal>1 ){
14151 /* Check that "sz" and "rawdata" are both NULL: */
@@ -14191,14 +14485,14 @@
14485 ZipfileBuffer body;
14486 ZipfileBuffer cds;
14487 };
14488
14489 static int zipfileBufferGrow(ZipfileBuffer *pBuf, i64 nByte){
14490 if( (pBuf->nAlloc-pBuf->n)<nByte ){
14491 u8 *aNew;
14492 i64 nNew = pBuf->n ? (i64)pBuf->n*2 : 512;
14493 i64 nReq = pBuf->n + nByte;
14494
14495 while( nNew<nReq ) nNew = nNew*2;
14496 aNew = sqlite3_realloc64(pBuf->a, nNew);
14497 if( aNew==0 ) return SQLITE_NOMEM;
14498 pBuf->a = aNew;
@@ -14410,11 +14704,11 @@
14704 eocd.nEntry = (u16)p->nEntry;
14705 eocd.nEntryTotal = (u16)p->nEntry;
14706 eocd.nSize = p->cds.n;
14707 eocd.iOffset = p->body.n;
14708
14709 nZip = (i64)p->body.n + (i64)p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
14710 aZip = (u8*)sqlite3_malloc64(nZip);
14711 if( aZip==0 ){
14712 sqlite3_result_error_nomem(pCtx);
14713 }else{
14714 memcpy(aZip, p->body.a, p->body.n);
@@ -16296,11 +16590,11 @@
16590 p->pTable = pTab;
16591
16592 /* The statement the vtab will pass to sqlite3_declare_vtab() */
16593 zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
16594 for(i=0; i<pTab->nCol; i++){
16595 zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %Q",
16596 (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
16597 );
16598 }
16599 zInner = idxAppendText(&rc, zInner, ")");
16600
@@ -16496,11 +16790,11 @@
16790 sqlite3_free(zCols);
16791 sqlite3_free(zOrder);
16792 return sqlite3_reset(pIndexXInfo);
16793 }
16794 zCols = idxAppendText(&rc, zCols,
16795 "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %Q",
16796 zComma, zName, nCol, zName, zColl
16797 );
16798 zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
16799 }
16800 sqlite3_reset(pIndexXInfo);
@@ -17537,16 +17831,19 @@
17831 }
17832 iRet++;
17833 }
17834 }
17835 else if( c=='[' ){
17836 while( z[iRet] && z[iRet++]!=']' ){}
17837 }
17838 else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
17839 while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
17840 iRet++;
17841 }
17842 }
17843 else if( c==0 ){
17844 iRet = 0;
17845 }
17846
17847 return iRet;
17848 }
17849
@@ -17983,10 +18280,27 @@
18280 intckFinalize(p, pStmt);
18281
18282 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
18283 return zRet;
18284 }
18285
18286 /*
18287 ** Register or unregister special SQL functions implemented by intck.
18288 **
18289 ** Normally the custom SQL functions used by intck are only available
18290 ** in between sqlite3_intck_open() and sqlite3_intck_close(). However,
18291 ** for testing and debugging, it is sometimes useful to make those
18292 ** functions available generally. This routine provides as a separate
18293 ** interface in order to provide that capability.
18294 */
18295 int sqlite3_intck_register(sqlite3 *db, int bCreate){
18296 int rc;
18297 rc = sqlite3_create_function(db, "parse_create_index",
18298 2, SQLITE_UTF8, 0, bCreate ? intckParseCreateIndexFunc : 0, 0, 0
18299 );
18300 return rc;
18301 }
18302
18303 /*
18304 ** Open a new integrity-check object.
18305 */
18306 int sqlite3_intck_open(
@@ -18005,13 +18319,11 @@
18319 }else{
18320 memset(pNew, 0, sizeof(*pNew));
18321 pNew->db = db;
18322 pNew->zDb = (const char*)&pNew[1];
18323 memcpy(&pNew[1], zDb, nDb+1);
18324 rc = sqlite3_intck_register(db, 1);
 
 
18325 if( rc!=SQLITE_OK ){
18326 sqlite3_intck_close(pNew);
18327 pNew = 0;
18328 }
18329 }
@@ -18024,13 +18336,11 @@
18336 ** Free the integrity-check object.
18337 */
18338 void sqlite3_intck_close(sqlite3_intck *p){
18339 if( p ){
18340 sqlite3_finalize(p->pCheck);
18341 sqlite3_intck_register(p->db, 0);
 
 
18342 sqlite3_free(p->zObj);
18343 sqlite3_free(p->zKey);
18344 sqlite3_free(p->zTestSql);
18345 sqlite3_free(p->zErr);
18346 sqlite3_free(p->zMessage);
@@ -19464,11 +19774,11 @@
19774 sqlite3_vfs_unregister(pVfs);
19775 sqlite3_free(pVfs);
19776 }
19777
19778 /************************* End ext/misc/vfstrace.c ********************/
19779 /************************* Begin ext/misc/diskused.c ******************/
19780 /*
19781 ** 2026-04-13
19782 **
19783 ** The author disclaims copyright to this source code. In place of
19784 ** a legal notice, here is a blessing:
@@ -19477,12 +19787,21 @@
19787 ** May you find forgiveness for yourself and forgive others.
19788 ** May you share freely, never taking more than you give.
19789 **
19790 ******************************************************************************
19791 **
19792 ** This extension implements an SQL function:
19793 **
19794 ** diskused(X)
19795 **
19796 ** Where X is the schema name (typically 'main'). The output is text
19797 ** that describes how much filesystem space the various tables and indexes
19798 ** of the database consume.
19799 **
19800 ** This function is a replacement for the (now deprecated)
19801 ** "sqlite3_analyzer" utility program. This function is built
19802 ** into the CLI and is used to implement the ".diskused" command there.
19803 */
19804 /* #include "sqlite3ext.h" */
19805 SQLITE_EXTENSION_INIT1
19806 #include <assert.h>
19807 #include <string.h>
@@ -19490,28 +19809,28 @@
19809 #include <math.h>
19810
19811 /*
19812 ** State information for the analysis
19813 */
19814 typedef struct DiskUsed DiskUsed;
19815 struct DiskUsed {
19816 sqlite3 *db; /* Database connection */
19817 sqlite3_context *context; /* SQL function context */
19818 sqlite3_str *pOut; /* Write output here */
19819 char *zSU; /* Name of the temp.space_used table */
19820 const char *zSchema; /* Schema to be analyzed */
19821 };
19822
19823 /*
19824 ** Free all resources that the DiskUsed object references and
19825 ** reset the DiskUsed object.
19826 **
19827 ** Call this routine multiple times on the same DiskUsed object
19828 ** is a harmless no-op, as long as the memory for the object itself
19829 ** has not been freed.
19830 */
19831 static void diskusedReset(DiskUsed *p){
19832 if( p->zSU ){
19833 char *zSql = sqlite3_mprintf("DROP TABLE temp.%s;", p->zSU);
19834 if( zSql ){
19835 sqlite3_exec(p->db, zSql, 0, 0, 0);
19836 sqlite3_free(zSql);
@@ -19524,11 +19843,11 @@
19843
19844 /*
19845 ** Report an error using formatted text. If zFormat==NULL then report
19846 ** an OOM error.
19847 */
19848 static void diskusedError(DiskUsed *p, const char *zFormat, ...){
19849 char *zErr;
19850 if( zFormat ){
19851 va_list ap;
19852 va_start(ap, zFormat);
19853 zErr = sqlite3_vmprintf(zFormat, ap);
@@ -19540,38 +19859,38 @@
19859 sqlite3_result_error_nomem(p->context);
19860 }else{
19861 sqlite3_result_error(p->context, zErr, -1);
19862 sqlite3_free(zErr);
19863 }
19864 diskusedReset(p);
19865 }
19866
19867 /*
19868 ** Prepare and return an SQL statement.
19869 */
19870 static sqlite3_stmt *diskusedVPrep(DiskUsed *p, const char *zFmt, va_list ap){
19871 char *zSql;
19872 int rc;
19873 sqlite3_stmt *pStmt = 0;
19874 zSql = sqlite3_vmprintf(zFmt, ap);
19875 if( zSql==0 ){ diskusedError(p,0); return 0; }
19876 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19877 if( rc ){
19878 diskusedError(p, "SQL parse error: %s\nOriginal SQL: %s",
19879 sqlite3_errmsg(p->db), zSql);
19880 sqlite3_finalize(pStmt);
19881 diskusedReset(p);
19882 pStmt = 0;
19883 }
19884 sqlite3_free(zSql);
19885 return pStmt;
19886 }
19887 static sqlite3_stmt *diskusedPrepare(DiskUsed *p, const char *zFormat, ...){
19888 va_list ap;
19889 sqlite3_stmt *pStmt = 0;
19890 va_start(ap, zFormat);
19891 pStmt = diskusedVPrep(p,zFormat,ap);
19892 va_end(ap);
19893 return pStmt;
19894 }
19895
19896 /*
@@ -19580,60 +19899,60 @@
19899 **
19900 ** If rc is SQLITE_DONE or SQLITE_OK, then return false.
19901 **
19902 ** The prepared statement is closed in either case.
19903 */
19904 static int diskusedStmtFinish(DiskUsed *p, int rc, sqlite3_stmt *pStmt){
19905 if( rc==SQLITE_DONE ){
19906 rc = SQLITE_OK;
19907 }
19908 if( rc!=SQLITE_OK || (rc = sqlite3_reset(pStmt))!=SQLITE_OK ){
19909 diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19910 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19911 diskusedReset(p);
19912 }
19913 sqlite3_finalize(pStmt);
19914 return rc;
19915 }
19916
19917 /*
19918 ** Run SQL. Return the number of errors.
19919 */
19920 static int diskusedSql(DiskUsed *p, const char *zFormat, ...){
19921 va_list ap;
19922 int rc;
19923 sqlite3_stmt *pStmt = 0;
19924 va_start(ap, zFormat);
19925 pStmt = diskusedVPrep(p,zFormat,ap);
19926 va_end(ap);
19927 if( pStmt==0 ) return 1;
19928 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
19929 if( rc==SQLITE_DONE ){
19930 rc = SQLITE_OK;
19931 }else{
19932 diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19933 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19934 diskusedReset(p);
19935 }
19936 sqlite3_finalize(pStmt);
19937 return rc;
19938 }
19939
19940 /*
19941 ** Run an SQL query that returns an integer. Write that integer
19942 ** into *piRes. Return the number of errors.
19943 */
19944 static int diskusedSqlInt(
19945 DiskUsed *p,
19946 sqlite3_int64 *piRes,
19947 const char *zFormat, ...
19948 ){
19949 va_list ap;
19950 int rc;
19951 sqlite3_stmt *pStmt = 0;
19952 va_start(ap, zFormat);
19953 pStmt = diskusedVPrep(p,zFormat,ap);
19954 va_end(ap);
19955 if( pStmt==0 ) return 1;
19956 rc = sqlite3_step(pStmt);
19957 if( rc==SQLITE_ROW ){
19958 *piRes = sqlite3_column_int64(pStmt, 0);
@@ -19641,14 +19960,14 @@
19960 }else if( rc==SQLITE_DONE ){
19961 rc = SQLITE_OK;
19962 }else{
19963 if( p->db ){
19964 /* p->db is NULL if there was some prior error */
19965 diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
19966 sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
19967 }
19968 diskusedReset(p);
19969 }
19970 sqlite3_finalize(pStmt);
19971 return rc;
19972 }
19973
@@ -19657,20 +19976,20 @@
19976 ** by the format string. If the output is initially empty, begin
19977 ** the title line with "/" so that it forms the beginning of a C-style
19978 ** comment. Otherwise begin with a new-line. Always finish with a
19979 ** newline.
19980 */
19981 static void diskusedTitle(DiskUsed *p, const char *zFormat, ...){
19982 char *zFirst;
19983 char *zTitle;
19984 size_t nTitle;
19985 va_list ap;
19986 va_start(ap, zFormat);
19987 zTitle = sqlite3_vmprintf(zFormat, ap);
19988 va_end(ap);
19989 if( zTitle==0 ){
19990 diskusedError(p, 0);
19991 return;
19992 }
19993 zFirst = sqlite3_str_length(p->pOut)==0 ? "/" : "\n*";
19994 nTitle = strlen(zTitle);
19995 if( nTitle>=75 ){
@@ -19685,12 +20004,12 @@
20004 /*
20005 ** Add an output line that begins with the zDesc text extended out to
20006 ** 50 columns with "." characters, and followed by whatever text is
20007 ** described by zFormat.
20008 */
20009 static void diskusedLine(
20010 DiskUsed *p, /* DiskUsed context */
20011 const char *zDesc, /* Description */
20012 const char *zFormat, /* Argument to the description */
20013 ...
20014 ){
20015 char *zTxt;
@@ -19698,14 +20017,14 @@
20017 va_list ap;
20018 va_start(ap, zFormat);
20019 zTxt = sqlite3_vmprintf(zFormat, ap);
20020 va_end(ap);
20021 if( zTxt==0 ){
20022 diskusedError(p, 0);
20023 return;
20024 }
20025 nDesc = zDesc ? strlen(zDesc) : 0;
20026 if( nDesc>=50 ){
20027 sqlite3_str_appendf(p->pOut, "%s %z", zDesc, zTxt);
20028 }else{
20029 int nExtra = 50 - (int)nDesc;
20030 sqlite3_str_appendf(p->pOut, "%s%.*c %z", zDesc, nExtra, '.', zTxt);
@@ -19715,15 +20034,28 @@
20034 /*
20035 ** Write a percentage into the output. The number written should show
20036 ** two or three significant digits, with the decimal point being the fourth
20037 ** character.
20038 */
20039 static void diskusedPercent(
20040 DiskUsed *p, /* Context of the disk-usage analysis */
20041 sqlite3_int64 num, /* Numerator of the fraction */
20042 sqlite3_int64 denom /* Denominator of the fraction. Might be zero! */
20043 ){
20044 char zNum[100];
20045 char *zDP;
20046 int nLeadingDigit;
20047 int sz;
20048 double r;
20049 if( num==0 ){
20050 r = 0.0;
20051 }else if( denom==0 ){
20052 sqlite3_str_appendchar(p->pOut, 1, '\n');
20053 return;
20054 }else{
20055 r = num*100.0/(double)denom;
20056 }
20057 sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
20058 sz = (int)strlen(zNum);
20059 zDP = strchr(zNum, '.');
20060 if( zDP==0 ){
20061 memcpy(zNum+sz,".0",3);
@@ -19744,12 +20076,12 @@
20076 **
20077 ** The title if the subreport is given by zTitle. zWhere is
20078 ** a boolean expression that can go in the WHERE clause to select
20079 ** the relevant rows of the s.zSU table.
20080 */
20081 static int diskusedSubreport(
20082 DiskUsed *p, /* DiskUsed context */
20083 char *zTitle, /* Title for this subreport */
20084 char *zWhere, /* WHERE clause for this subreport */
20085 sqlite3_int64 pgsz, /* Database page size */
20086 sqlite3_int64 nPage /* Number of pages in entire database */
20087 ){
@@ -19773,14 +20105,14 @@
20105 sqlite3_int64 total_unused; /* Total unused bytes */
20106 sqlite3_int64 total_meta; /* Total metadata */
20107 int rc;
20108
20109 if( zTitle==0 || zWhere==0 ){
20110 diskusedError(p, 0);
20111 return SQLITE_NOMEM;
20112 }
20113 pStmt = diskusedPrepare(p,
20114 "SELECT\n"
20115 " sum(if(is_without_rowid OR is_index,nentry,leaf_entries)),\n" /* 0 */
20116 " sum(payload),\n" /* 1 */
20117 " sum(ovfl_payload),\n" /* 2 */
20118 " max(mx_payload),\n" /* 3 */
@@ -19797,11 +20129,11 @@
20129 " FROM temp.%s WHERE %s",
20130 p->zSU, zWhere);
20131 if( pStmt==0 ) return 1;
20132 rc = sqlite3_step(pStmt);
20133 if( rc==SQLITE_ROW ){
20134 diskusedTitle(p, "%s", zTitle);
20135
20136 nentry = sqlite3_column_int64(pStmt, 0);
20137 payload = sqlite3_column_int64(pStmt, 1);
20138 ovfl_payload = sqlite3_column_int64(pStmt, 2);
20139 mx_payload = sqlite3_column_int64(pStmt, 3);
@@ -19816,73 +20148,73 @@
20148 cnt = sqlite3_column_int64(pStmt, 12);
20149 int_cell = sqlite3_column_int64(pStmt, 13);
20150 rc = SQLITE_DONE;
20151
20152 total_pages = leaf_pages + int_pages + ovfl_pages;
20153 diskusedLine(p, "Percentage of total database", "%.3g%%\n",
20154 (total_pages*100.0)/(double)nPage);
20155 diskusedLine(p, "Number of entries", "%lld\n", nentry);
20156 storage = total_pages*pgsz;
20157 diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
20158 diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
20159 diskusedPercent(p, payload, storage);
20160 if( ovfl_cnt>0 ){
20161 diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
20162 diskusedPercent(p, ovfl_payload, payload);
20163 }
20164 total_unused = leaf_unused + int_unused + ovfl_unused;
20165 total_meta = storage - payload - total_unused;
20166 diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
20167 diskusedPercent(p, total_meta, storage);
20168 if( cnt==1 ){
20169 diskusedLine(p, "B-tree depth", "%lld\n", depth);
20170 if( int_cell>1 ){
20171 diskusedLine(p, "Average fanout", "%.1f\n",
20172 (double)(int_cell+int_pages)/(double)int_pages);
20173 }
20174 }
20175 if( nentry>0 ){
20176 diskusedLine(p, "Average payload per entry", "%.1f\n",
20177 (double)payload/(double)nentry);
20178 diskusedLine(p, "Average unused bytes per entry", "%.1f\n",
20179 (double)total_unused/(double)nentry);
20180 diskusedLine(p, "Average metadata per entry", "%.1f\n",
20181 (double)total_meta/(double)nentry);
20182 }
20183 diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
20184 if( nentry>0 ){
20185 diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
20186 diskusedPercent(p, ovfl_cnt, nentry);
20187 }
20188 if( int_pages>0 ){
20189 diskusedLine(p, "Index pages used", "%lld\n", int_pages);
20190 }
20191 diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
20192 if( ovfl_cnt ){
20193 diskusedLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
20194 }
20195 diskusedLine(p, "Total pages used", "%lld\n", total_pages);
20196 if( int_pages>0 ){
20197 diskusedLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
20198 }
20199 diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
20200 if( ovfl_cnt ){
20201 diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
20202 }
20203 diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
20204 diskusedPercent(p, total_unused, storage);
20205 }
20206 return diskusedStmtFinish(p, rc, pStmt);
20207 }
20208
20209 /*
20210 ** SQL Function: diskused(SCHEMA)
20211 **
20212 ** Analyze the database schema named in the argument. Return text
20213 ** containing the space utilization stats.
20214 */
20215 static void diskusedFunc(
20216 sqlite3_context *context,
20217 int argc,
20218 sqlite3_value **argv
20219 ){
20220 int rc;
@@ -19893,47 +20225,47 @@
20225 sqlite3_int64 nPage;
20226 sqlite3_int64 nPageInUse;
20227 sqlite3_int64 nFreeList;
20228 sqlite3_int64 nIndex;
20229 sqlite3_int64 nWORowid;
20230 DiskUsed s;
20231 sqlite3_uint64 r[2];
20232
20233 (void)argc;
20234 memset(&s, 0, sizeof(s));
20235 s.db = sqlite3_context_db_handle(context);
20236 s.context = context;
20237 s.pOut = sqlite3_str_new(0);
20238 if( sqlite3_str_errcode(s.pOut) ){
20239 diskusedError(&s, 0);
20240 return;
20241 }
20242 s.zSchema = (const char*)sqlite3_value_text(argv[0]);
20243 if( s.zSchema==0 ){
20244 s.zSchema = "main";
20245 }else if( sqlite3_strlike("temp",s.zSchema,0)==0 ){
20246 diskusedReset(&s);
20247 sqlite3_result_text(context, "cannot analyze \"temp\"",-1,SQLITE_STATIC);
20248 return;
20249 }
20250 ii = 0;
20251 rc = diskusedSqlInt(&s,&ii,"SELECT 1 FROM pragma_database_list"
20252 " WHERE name=%Q COLLATE nocase",s.zSchema);
20253 if( rc || ii==0 ){
20254 diskusedReset(&s);
20255 sqlite3_result_text(context,"no such database",-1,SQLITE_STATIC);
20256 return;
20257 }
20258 sqlite3_randomness(sizeof(r), &r);
20259 s.zSU = sqlite3_mprintf("diskused%016llx%016llx", r[0], r[1]);
20260 if( s.zSU==0 ){ diskusedError(&s, 0); return; }
20261
20262 /* The s.zSU table contains the data used for the analysis.
20263 ** The table name contains 128-bits of randomness to avoid
20264 ** collisions with preexisting tables in temp.
20265 */
20266 rc = diskusedSql(&s,
20267 "CREATE TABLE temp.%s(\n"
20268 " name text, -- A table or index\n"
20269 " tblname text, -- Table that owns name\n"
20270 " is_index boolean, -- TRUE if it is an index\n"
20271 " is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n"
@@ -19956,11 +20288,11 @@
20288 );
20289 if( rc ) return;
20290
20291 /* Populate the s.zSU table
20292 */
20293 rc = diskusedSql(&s,
20294 "WITH\n"
20295 " allidx(idxname) AS (\n"
20296 " SELECT name FROM \"%w\".sqlite_schema WHERE type='index'\n"
20297 " ),\n"
20298 " allobj(allname,tblname,isidx,isworowid) AS (\n"
@@ -20008,141 +20340,143 @@
20340 s.zSchema /* JOIN dbstat(%Q) */
20341 );
20342 if( rc ) return;
20343
20344 nPage = 0;
20345 rc = diskusedSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
20346 if( rc ) return;
20347 if( nPage<=0 ){
20348 /* Very brief reply for an empty database */
20349 diskusedReset(&s);
20350 sqlite3_result_text(context, "empty database", -1, SQLITE_STATIC);
20351 return;
20352 }
20353
20354 /* Begin generating the report */
20355 diskusedTitle(&s, "Database storage utilization report");
20356 pgsz = 0;
20357 rc = diskusedSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
20358 if( rc ) return;
20359 diskusedLine(&s, "Page size in bytes","%lld\n",pgsz);
20360 diskusedLine(&s, "Pages in the database", "%lld\n", nPage);
20361
20362 nPageInUse = 0;
20363 rc = diskusedSqlInt(&s, &nPageInUse,
20364 "SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
20365 if( rc ) return;
20366 diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20367 diskusedPercent(&s, nPageInUse, nPage);
20368
20369 nFreeList = 0;
20370 rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
20371 if( rc ) return;
20372 diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20373 diskusedPercent(&s, nFreeList, nPage);
20374
20375 ii = 0;
20376 rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
20377 if( rc ) return;
20378 if( ii==0 || nPage<=1 ){
20379 ii = 0;
20380 }else{
20381 double rPtrsPerPage = pgsz/5;
20382 double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
20383 ii = (sqlite3_int64)ceil(rAvPage);
20384 }
20385 diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20386 diskusedPercent(&s, ii, nPage);
20387
20388 ii = 0;
20389 rc = diskusedSqlInt(&s, &ii,
20390 "SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
20391 s.zSchema);
20392 if( rc ) return;
20393 diskusedLine(&s, "Number of tables", "%lld\n", ii);
20394 nWORowid = 0;
20395 rc = diskusedSqlInt(&s, &nWORowid,
20396 "SELECT count(*) FROM \"%w\".pragma_table_list WHERE wr",
20397 s.zSchema);
20398 if( rc ) return;
20399 if( nWORowid>0 ){
20400 diskusedLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
20401 diskusedLine(&s, "Number of rowid tables", "%lld\n", ii - nWORowid);
20402 }
20403 nIndex = 0;
20404 rc = diskusedSqlInt(&s, &nIndex,
20405 "SELECT count(*) FROM \"%w\".sqlite_schema WHERE type='index'",
20406 s.zSchema);
20407 if( rc ) return;
20408 diskusedLine(&s, "Number of indexes", "%lld\n", nIndex);
20409 ii = 0;
20410 rc = diskusedSqlInt(&s, &ii,
20411 "SELECT count(*) FROM \"%w\".sqlite_schema"
20412 " WHERE name GLOB 'sqlite_autoindex_*' AND type='index'",
20413 s.zSchema);
20414 if( rc ) return;
20415 diskusedLine(&s, "Number of defined indexes", "%lld\n", nIndex - ii);
20416 diskusedLine(&s, "Number of implied indexes", "%lld\n", ii);
20417 diskusedLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
20418 ii = 0;
20419 rc = diskusedSqlInt(&s, &ii,
20420 "SELECT sum(payload) FROM temp.%s"
20421 " WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
20422 s.zSU);
20423 if( rc ) return;
20424 diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
20425 diskusedPercent(&s, ii, pgsz*nPage);
20426
20427 diskusedTitle(&s, "Page counts for all tables with their indexes");
20428 pStmt = diskusedPrepare(&s,
20429 "SELECT upper(tblname),\n"
20430 " sum(int_pages+leaf_pages+ovfl_pages)\n"
20431 " FROM temp.%s\n"
20432 " WHERE tblname IS NOT NULL\n"
20433 " GROUP BY 1\n"
20434 " ORDER BY 2 DESC, 1;",
20435 s.zSU);
20436 if( pStmt==0 ) return;
20437 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20438 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20439 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20440 diskusedPercent(&s, nn, nPage);
20441 }
20442 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20443
20444 diskusedTitle(&s, "Page counts for all tables and indexes separately");
20445 pStmt = diskusedPrepare(&s,
20446 "SELECT upper(name),\n"
20447 " sum(int_pages+leaf_pages+ovfl_pages)\n"
20448 " FROM temp.%s\n"
20449 " WHERE name IS NOT NULL\n"
20450 " GROUP BY 1\n"
20451 " ORDER BY 2 DESC, 1;",
20452 s.zSU);
20453 if( pStmt==0 ) return;
20454 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20455 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20456 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20457 diskusedPercent(&s, nn, nPage);
20458 }
20459 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20460
20461 rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20462 if( rc ) return;
20463 rc = diskusedSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
20464 if( rc ) return;
20465 if( nWORowid>0 ){
20466 rc = diskusedSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
20467 pgsz, nPage);
20468 if( rc ) return;
20469 rc = diskusedSubreport(&s, "All rowid tables",
20470 "NOT is_without_rowid AND NOT is_index",
20471 pgsz, nPage);
20472 if( rc ) return;
20473 }
20474 rc = diskusedSubreport(&s, "All indexes", "is_index", pgsz, nPage);
20475 if( rc ) return;
20476
20477 pStmt = diskusedPrepare(&s,
20478 "SELECT upper(tblname), tblname, sum(is_index) FROM temp.%s"
20479 " GROUP BY 1 ORDER BY 1",
20480 s.zSU);
20481 if( pStmt==0 ) return;
20482 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
@@ -20150,37 +20484,37 @@
20484 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
20485 int nSubIndex = sqlite3_column_int(pStmt, 2);
20486 if( nSubIndex==0 ){
20487 char *zTitle = sqlite3_mprintf("Table %s", zUpper);
20488 char *zWhere = sqlite3_mprintf("name=%Q", zName);
20489 rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
20490 sqlite3_free(zTitle);
20491 sqlite3_free(zWhere);
20492 if( rc ) break;
20493 }else{
20494 sqlite3_stmt *pS2;
20495 char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper);
20496 char *zWhere = sqlite3_mprintf("tblname=%Q", zName);
20497 rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
20498 sqlite3_free(zTitle);
20499 sqlite3_free(zWhere);
20500 if( rc ) break;
20501 zTitle = sqlite3_mprintf("Table %s w/o any indexes", zUpper);
20502 zWhere = sqlite3_mprintf("name=%Q", zName);
20503 rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
20504 sqlite3_free(zTitle);
20505 sqlite3_free(zWhere);
20506 if( rc ) break;
20507 if( nSubIndex>1 ){
20508 zTitle = sqlite3_mprintf("All indexes of table %s", zUpper);
20509 zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName);
20510 rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
20511 sqlite3_free(zTitle);
20512 sqlite3_free(zWhere);
20513 if( rc ) break;
20514 }
20515 pS2 = diskusedPrepare(&s,
20516 "SELECT name, upper(name) FROM temp.%s"
20517 " WHERE is_index AND tblname=%Q",
20518 s.zSU, zName);
20519 if( pS2==0 ){
20520 rc = SQLITE_NOMEM;
@@ -20189,25 +20523,25 @@
20523 while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){
20524 const char *zU = (const char*)sqlite3_column_text(pS2, 1);
20525 const char *zN = (const char*)sqlite3_column_text(pS2, 0);
20526 zTitle = sqlite3_mprintf("Index %s", zU);
20527 zWhere = sqlite3_mprintf("name=%Q", zN);
20528 rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
20529 sqlite3_free(zTitle);
20530 sqlite3_free(zWhere);
20531 if( rc ) break;
20532 }
20533 rc = diskusedStmtFinish(&s, rc, pS2);
20534 if( rc ) break;
20535 }
20536 }
20537 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20538
20539 /* Append SQL statements that will recreate the raw data used for
20540 ** the analysis.
20541 */
20542 diskusedTitle(&s, "Raw data used to generate this report");
20543 sqlite3_str_appendf(s.pOut,
20544 "The following SQL will create a table named \"space_used\" which\n"
20545 "contains most of the information used to generate the report above.\n"
20546 "*/\n"
20547 );
@@ -20233,11 +20567,11 @@
20567 " ovfl_unused int, -- Unused bytes on overflow pages\n" /* 16 */
20568 " int_entries int -- B-tree entries on internal pages\n"/* 17 */
20569 ");\n"
20570 "INSERT INTO space_used VALUES\n"
20571 );
20572 pStmt = diskusedPrepare(&s,
20573 "SELECT quote(name), quote(tblname),\n" /* 0..1 */
20574 " is_index, is_without_rowid, nentry, leaf_entries,\n" /* 2..5 */
20575 " depth, payload, ovfl_payload, ovfl_cnt, mx_payload,\n" /* 6..10 */
20576 " int_pages, leaf_pages, ovfl_pages, int_unused,\n" /* 11..14 */
20577 " leaf_unused, ovfl_unused, int_entries\n" /* 15..17 */
@@ -20268,11 +20602,11 @@
20602 sqlite3_column_int64(pStmt, 15),
20603 sqlite3_column_int64(pStmt, 16),
20604 sqlite3_column_int64(pStmt, 17));
20605 }
20606 if( rc!=SQLITE_DONE ){
20607 diskusedError(&s, "SQL run-time error: %s\nSQL: %s",
20608 sqlite3_errmsg(s.db), sqlite3_sql(pStmt));
20609 sqlite3_finalize(pStmt);
20610 return;
20611 }
20612 sqlite3_str_appendf(s.pOut,";\nCOMMIT;");
@@ -20281,32 +20615,144 @@
20615 if( sqlite3_str_length(s.pOut) ){
20616 sqlite3_result_text(context, sqlite3_str_finish(s.pOut), -1,
20617 sqlite3_free);
20618 s.pOut = 0;
20619 }
20620 diskusedReset(&s);
20621 }
20622
20623
20624 #ifdef _WIN32
20625
20626 #endif
20627 int sqlite3_diskused_init(
20628 sqlite3 *db,
20629 char **pzErrMsg,
20630 const sqlite3_api_routines *pApi
20631 ){
20632 int rc = SQLITE_OK;
20633 SQLITE_EXTENSION_INIT2(pApi);
20634 (void)pzErrMsg; /* Unused parameter */
20635 rc = sqlite3_create_function(db, "diskused", 1,
20636 SQLITE_UTF8|SQLITE_DIRECTONLY,
20637 0, diskusedFunc, 0, 0);
20638 return rc;
20639 }
20640
20641 /************************* End ext/misc/diskused.c ********************/
20642 /************************* Begin ext/misc/strdup.c ******************/
20643 /*
20644 ** 2026-07-04
20645 **
20646 ** The author disclaims copyright to this source code. In place of
20647 ** a legal notice, here is a blessing:
20648 **
20649 ** May you do good and not evil.
20650 ** May you find forgiveness for yourself and forgive others.
20651 ** May you share freely, never taking more than you give.
20652 **
20653 ******************************************************************************
20654 **
20655 ** Since this module was written (coincidentally) on the 250th anniversary
20656 ** of the signing of the Declaration of Independence of The United States,
20657 ** it seems fitting to quote from that document:
20658 **
20659 ** We hold these truths to be self-evident, that all men are created
20660 ** equal, that they are endowed by their Creator with certain unalienable
20661 ** Rights, that among these are Life, Liberty and the pursuit of Happiness
20662 ** - That to secure these rights, Governments are instituted among Men,
20663 ** deriving their just powers from the consent of the governed,....
20664 **
20665 ** Two core ideas that (1) rights come from God and not from government,
20666 ** and that (2) there should not be special privileged classes of people
20667 ** were radical thoughts then, and are indeed disputed even today. Many
20668 ** people still hold that human rights derive from the beneficence of
20669 ** government and that certain classes of people have special rights and
20670 ** privileges not available to all. Yet, were it not for the crazy ideas
20671 ** espoused in the original Declaration of Independence, this software
20672 ** project, and indeed most of modern technology, would not exist.
20673 **
20674 ** Therefore let us give thanks for the bold leadership and vision
20675 ** demonstrated by the authors of the American Revolution, 250 years ago
20676 ** this day.
20677 **
20678 ******************************************************************************
20679 **
20680 ** Implementation of the strdup() SQL function. strdup() makes a copy
20681 ** of its argument (a string or a BLOB) into memory obtained directly
20682 ** from system malloc() (not from sqlite3_malloc()) and sized exactly
20683 ** to hold the string or BLOB. This is intended for testing purposes,
20684 ** particularly testing with ASAN. This function serves no practical
20685 ** purpose beyond testing and not not intended for production use.
20686 **
20687 ** NULL, BLOB, and TEXT values come through as NULL, BLOB, and TEXT,
20688 ** respectively. Numeric values are rendered as strings and come out
20689 ** as text.
20690 */
20691 /* #include "sqlite3ext.h" */
20692 SQLITE_EXTENSION_INIT1
20693 #include <assert.h>
20694 #include <string.h>
20695 #include <stdlib.h>
20696
20697 /*
20698 ** Make a copy of a string or BLOB in memory obtained from malloc().
20699 */
20700 static void strdupfunc(
20701 sqlite3_context *context,
20702 int argc,
20703 sqlite3_value **argv
20704 ){
20705 const unsigned char *zIn;
20706 int nIn;
20707 unsigned char *zOut;
20708
20709 assert( argc==1 );
20710 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
20711 if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
20712 zIn = (const unsigned char*)sqlite3_value_blob(argv[0]);
20713 nIn = sqlite3_value_bytes(argv[0]);
20714 zOut = malloc( nIn==0 ? 1 : nIn );
20715 if( zOut==0 ){
20716 sqlite3_result_error_nomem(context);
20717 return;
20718 }
20719 if( nIn>0 ) memcpy(zOut, zIn, nIn);
20720 sqlite3_result_blob(context, zOut, nIn, free);
20721 }else{
20722 zIn = (const unsigned char*)sqlite3_value_text(argv[0]);
20723 if( zIn==0 ) return;
20724 nIn = (int)strlen((char*)zIn);
20725 zOut = malloc( nIn+1 );
20726 if( zOut==0 ){
20727 sqlite3_result_error_nomem(context);
20728 return;
20729 }
20730 memcpy(zOut, zIn, nIn);
20731 zOut[nIn] = 0;
20732 sqlite3_result_text64(context, (char*)zOut, nIn, free,
20733 SQLITE_UTF8_ZT);
20734 }
20735 }
20736
20737 #ifdef _WIN32
20738
20739 #endif
20740 int sqlite3_strdup_init(
20741 sqlite3 *db,
20742 char **pzErrMsg,
20743 const sqlite3_api_routines *pApi
20744 ){
20745 int rc = SQLITE_OK;
20746 SQLITE_EXTENSION_INIT2(pApi);
20747 (void)pzErrMsg; /* Unused parameter */
20748 rc = sqlite3_create_function(db, "strdup", 1, SQLITE_UTF8,
20749 0, strdupfunc, 0, 0);
 
20750 return rc;
20751 }
20752
20753 /************************* End ext/misc/strdup.c ********************/
20754
20755 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
20756 #define SQLITE_SHELL_HAVE_RECOVER 1
20757 #else
20758 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -22123,23 +22569,44 @@
22569 int rc = sqlite3_finalize(pStmt);
22570 if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){
22571 recoverDbError(p, db);
22572 }
22573 }
22574
22575 /*
22576 ** Run a single SQL statement in zSql. If zSql contains two or more
22577 ** SQL statements separated by ';', only the first is run.
22578 **
22579 ** Return the sqlite3_finalizer() or sqlite3_prepare() result code
22580 ** from running the zSql statement.
22581 */
22582 static int recoverOneStmt(sqlite3 *db, const char *zSql){
22583 sqlite3_stmt *pStmt = 0;
22584 int rc;
22585 if( zSql==0 ) return SQLITE_OK;
22586 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
22587 if( rc ){
22588 sqlite3_finalize(pStmt);
22589 return rc;
22590 }
22591 while( SQLITE_ROW==sqlite3_step(pStmt) ){}
22592 return sqlite3_finalize(pStmt);
22593 }
22594
22595 /*
22596 ** This function is a no-op if recover handle p already contains an error
22597 ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this
22598 ** case.
22599 **
22600 ** Otherwise, execute a single SQL statment in zSql. Even if zSql contains
22601 ** two or more SQL statements separated by ';', only execute the first one.
22602 ** If successful, return SQLITE_OK. Or, if an error occurs, leave an error
22603 ** code and message in the recover handle and return a copy of the error code.
22604 */
22605 static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){
22606 if( p->errCode==SQLITE_OK ){
22607 int rc = recoverOneStmt(db, zSql);
22608 if( rc ){
22609 recoverDbError(p, db);
22610 }
22611 }
22612 return p->errCode;
@@ -22535,11 +23002,12 @@
23002 recoverError(p, SQLITE_NOMEM, 0);
23003 }
23004 }
23005 recoverFinalize(p, p1);
23006 }
23007 recoverExec(p, db2, "CREATE TABLE t1(a)");
23008 recoverExec(p, db2, "DROP TABLE t1");
23009
23010 if( p->errCode==SQLITE_OK ){
23011 sqlite3 *db = p->dbOut;
23012 sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main");
23013 if( pBackup ){
@@ -22617,16 +23085,16 @@
23085 ** discarded.
23086 */
23087 static void recoverOpenRecovery(sqlite3_recover *p){
23088 char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb);
23089 recoverExec(p, p->dbOut, zSql);
23090 sqlite3_free(zSql);
23091 recoverExec(p, p->dbOut, "PRAGMA writable_schema = 1");
23092 recoverExec(p, p->dbOut,
23093 "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT)");
23094 recoverExec(p, p->dbOut,
23095 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql)");
 
 
 
 
23096 }
23097
23098
23099 /*
23100 ** This function is a no-op if recover handle p already contains an error
@@ -22762,11 +23230,11 @@
23230 " (type='index' AND (sql LIKE '%unique%' OR ?1))"
23231 " FROM recovery.schema"
23232 ")"
23233 "SELECT rootpage, tbl, isVirtual, name, sql"
23234 " FROM dbschema "
23235 " WHERE (tbl OR isIndex) AND sql GLOB 'CREATE *'"
23236 " ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
23237 );
23238
23239 pTblname = recoverPrepare(p, p->dbOut,
23240 "SELECT name FROM sqlite_schema "
@@ -22788,11 +23256,11 @@
23256 zSql = (const char*)(zFree = recoverMPrintf(p,
23257 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
23258 zName, zName, zSql
23259 ));
23260 }
23261 rc = recoverOneStmt(p->dbOut, zSql);
23262 if( rc==SQLITE_OK ){
23263 recoverSqlCallback(p, zSql);
23264 if( bTable && !bVirtual ){
23265 if( SQLITE_ROW==sqlite3_step(pTblname) ){
23266 const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
@@ -22830,19 +23298,21 @@
23298
23299 pSelect = recoverPrepare(p, p->dbOut,
23300 p->bSlowIndexes ?
23301 "SELECT rootpage, sql FROM recovery.schema "
23302 " WHERE type!='table' AND type!='index'"
23303 " AND sql GLOB 'CREATE *'"
23304 :
23305 "SELECT rootpage, sql FROM recovery.schema "
23306 " WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
23307 " AND sql GLOB 'CREATE *'"
23308 );
23309
23310 if( pSelect ){
23311 while( sqlite3_step(pSelect)==SQLITE_ROW ){
23312 const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
23313 int rc = recoverOneStmt(p->dbOut, zSql);
23314 if( rc==SQLITE_OK ){
23315 recoverSqlCallback(p, zSql);
23316 }else if( rc!=SQLITE_ERROR ){
23317 recoverDbError(p, p->dbOut);
23318 }
@@ -24216,11 +24686,11 @@
24686 recoverCacheSchema(p);
24687
24688 if( bUseWrapper ) recoverUninstallWrapper(p);
24689 }while( p->errCode==SQLITE_NOTADB
24690 && (bUseWrapper--)
24691 && SQLITE_OK==recoverOneStmt(p->dbIn, "ROLLBACK")
24692 );
24693 }
24694
24695 recoverLeaveMutex();
24696 recoverExec(p, p->dbOut, "BEGIN");
@@ -24281,11 +24751,11 @@
24751
24752 /* If no error has occurred, commit the write transaction on the output
24753 ** database. Regardless of whether or not an error has occurred, make
24754 ** an attempt to end the read transaction on the input database. */
24755 recoverExec(p, p->dbOut, "COMMIT");
24756 rc = recoverOneStmt(p->dbIn, "END");
24757 if( p->errCode==SQLITE_OK ) p->errCode = rc;
24758
24759 recoverSqlCallback(p, "PRAGMA writable_schema = off");
24760 recoverSqlCallback(p, "COMMIT");
24761 p->eState = RECOVER_STATE_DONE;
@@ -24477,11 +24947,11 @@
24947 if( p==0 ){
24948 rc = SQLITE_NOMEM;
24949 }else{
24950 recoverFinalCleanup(p);
24951 if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){
24952 rc = recoverOneStmt(p->dbIn, "END");
24953 if( p->errCode==SQLITE_OK ) p->errCode = rc;
24954 }
24955 rc = p->errCode;
24956 sqlite3_free(p->zErrMsg);
24957 sqlite3_free(p->zStateDb);
@@ -24499,10 +24969,20 @@
24969 #endif
24970 #ifdef SQLITE_SHELL_EXTSRC
24971 # include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
24972 #endif
24973
24974 /*
24975 ** Set the SQLITE_SHELL_EDITION to a YYYYMMDD date string and the
24976 ** code will attempt to use defaults for the prompt and for the
24977 ** initial output mode (and maybe other feature) that were for
24978 ** the most recent version not newer than the specified date.
24979 */
24980 #ifndef SQLITE_SHELL_EDITION
24981 # define SQLITE_SHELL_EDITION 99991231 /* Use the latest if unspecified */
24982 #endif
24983
24984 #if defined(SQLITE_ENABLE_SESSION)
24985 /*
24986 ** State information for a single open session
24987 */
24988 typedef struct OpenSession OpenSession;
@@ -24530,10 +25010,12 @@
25010 u8 autoEQPtrace; /* autoEQP is in trace mode */
25011 u8 scanstatsOn; /* True to display scan stats before each finalize */
25012 u8 bAutoScreenWidth; /* Using the TTY to determine screen width */
25013 u8 mFlags; /* MFLG_ECHO, MFLG_CRLF, etc. */
25014 u8 eMode; /* One of the MODE_ values */
25015 char zIFmt[24]; /* Space to hold the --ifmt value */
25016 char zFpFmt[24]; /* Space to hold the --fpfmt value */
25017 sqlite3_qrf_spec spec; /* Spec to be passed into QRF */
25018 } Mode;
25019
25020 /* Flags for Mode.mFlags */
25021 #define MFLG_ECHO 0x01 /* Echo inputs to output */
@@ -24564,10 +25046,11 @@
25046 unsigned statsOn; /* True to display memory stats before each finalize */
25047 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
25048 u8 nPopOutput; /* Revert .output settings when reaching zero */
25049 u8 nPopMode; /* Revert .mode settings when reaching zero */
25050 u8 enableTimer; /* Enable the timer. 2: permanently 1: only once */
25051 u8 bDelimitNonprint; /* Add \001...\002 around non-printing in prompts */
25052 int inputNesting; /* Track nesting level of .read and other redirects */
25053 double prevTimer; /* Last reported timer value */
25054 double tmProgress; /* --timeout option for .progress */
25055 i64 lineno; /* Line number of last line read from in */
25056 const char *zInFile; /* Name of the input file */
@@ -24745,11 +25228,11 @@
25228 unsigned char eHdr; /* Default header encoding. */
25229 unsigned char eBlob; /* Default blob encoding. */
25230 unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
25231 unsigned char eStyle; /* Underlying QRF style */
25232 unsigned char eCx; /* 0: other, 1: line, 2: columnar */
25233 unsigned char mFlg; /* Flags. 1=border-off 2=split-column 4=rowcount */
25234 };
25235
25236 /* String constants used by built-in modes */
25237 static const char *aModeStr[] =
25238 /* 0 1 2 3 4 5 6 7 8 */
@@ -24758,45 +25241,45 @@
25241 /* 9 10 11 12 13 */
25242
25243 static const ModeInfo aModeInfo[] = {
25244 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
25245 { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
25246 { "box", 0, 0, 9, 1, 1, 0, 3, 1, 2, 0 },
25247 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
25248 { "column", 0, 0, 9, 1, 1, 0, 3, 2, 2, 0 },
25249 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
25250 { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
25251 { "html", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 },
25252 { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
25253 { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
25254 { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
25255 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
25256 { "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
25257 { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
25258 { "markdown", 0, 0, 9, 1, 1, 0, 3, 13, 2, 0 },
25259 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
25260 { "psql", 0, 0, 9, 1, 1, 0, 3, 19, 2, 5 },
25261 { "qbox", 0, 0, 10, 2, 1, 0, 3, 1, 2, 0 },
25262 { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
25263 { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
25264 { "table", 0, 0, 9, 1, 1, 0, 3, 19, 2, 0 },
25265 { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
25266 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
25267 { "www", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 }
25268 }; /* | / / | / / | | / \____
25269 ** | / / | / / | | / |
25270 ** Index into aModeStr[] | / / | | 2: columnar |
25271 ** | / / | | 1: line |
25272 ** | / / | | 0: other |
25273 ** text encoding |/ | show | | |
25274 ** v-------------------' | hdrs? | The QRF style |
25275 ** 0: n/a blob | v-----' /
25276 ** 1: plain v----------' 0: n/a _________/
25277 ** 2: sql 0: auto 1: no |
25278 ** 3: csv 1: as-text 2: yes 1: border-off
25279 ** 4: html 2: sql 3: always 2: split-column
25280 ** 5: c 3: hex 4: rowcount
25281 ** 6: json 4: c
25282 ** 5: json
25283 ** 6: size
25284 ******************************************************************/
25285
@@ -25079,11 +25562,11 @@
25562 */
25563 static char *local_getline(char *zLine, FILE *in){
25564 int nLine = zLine==0 ? 0 : 100;
25565 int n = 0;
25566
25567 while( seenInterrupt<2 ){
25568 if( n+100>nLine ){
25569 if( nLine>=1073741773 ){
25570 free(zLine);
25571 return 0;
25572 }
@@ -25107,10 +25590,22 @@
25590 break;
25591 }
25592 }
25593 return zLine;
25594 }
25595
25596 /*
25597 ** Return true if either the SQLITE_NO_COLOR compile-time option is used
25598 ** or if the NO_COLOR environment variable exists
25599 */
25600 static int shellNoColor(void){
25601 #if defined(SQLITE_NO_COLOR) || defined(SQLITE_SHELL_FIDDLE)
25602 return 1;
25603 #else
25604 return getenv("NO_COLOR")!=0;
25605 #endif
25606 }
25607
25608 /*
25609 ** The SQLITE_PS_APPDEF macro should be set to the name of a function
25610 ** that accepts a single "int" argument and returns a "const char *"
25611 ** that is guaranteed to be non-NULL. The value returned depends on the
@@ -25131,35 +25626,47 @@
25626 # define SQLITE_PS_APPDEF shellPromptAppDef
25627 static const char *shellPromptAppDef(int c){
25628 switch( c ){
25629 /* The default main prompt string */
25630 case 1:
25631 #if SQLITE_SHELL_EDITION<20260423
25632 return "sqlite> "; /* Legacy prompt for backwards compatibility */
25633 #elif defined(SQLITE_PS1)
25634 return SQLITE_PS1;
 
 
25635 #else
25636 if( shellNoColor() ){
25637 return "/A-/v /f-> ";
25638 }else{
25639 return "/e[1;32m/A-/v /e[1;/x33/:36/;m/m/e[3m/;/f/;/e[0m-> ";
25640 }
25641 #endif
25642
25643 /* The default continuation prompt string */
25644 case 2:
25645 #if SQLITE_SHELL_EDITION<20260423
25646 return " ...> "; /* Legacy continuation prompt */
25647 #elif defined(SQLITE_PS2)
25648 return SQLITE_PS2;
 
 
25649 #else
25650 if( shellNoColor() ){
25651 return "/B/C-> ";
25652 }else{
25653 return "/B/e[1;/x33/:36/;m/C/e[0m-> ";
25654 }
25655 #endif
25656
25657 /* Name of environment variables that override the prompt strings
25658 ** of cases 1 and 2 */
25659 case 3: return "SQLITE_PS1";
25660 case 4: return "SQLITE_PS2";
25661
25662 /* Name of the application */
25663 #ifndef SQLITE_CLI_APPNAME
25664 case 'A': return "SQLite";
25665 #else
25666 case 'A': return SHELL_STRINGIFY(SQLITE_CLI_APPNAME);
25667 #endif
25668
25669 /* Full version number of the application, including patch level */
25670 case 'V': return sqlite3_libversion();
25671
25672 /* Version number without the patch level */
@@ -25218,13 +25725,13 @@
25725 }else if( p->db && (pFN = sqlite3_db_filename(p->db,0))!=0 ){
25726 zFN = sqlite3_filename_database(pFN);
25727 }
25728 if( zFN==0 || zFN[0]==0 ){
25729 zFN = p->pAuxDb->zDbFilename;
25730 }
25731 if( zFN==0 || zFN[0]==0 || cli_strcmp(zFN,":memory:")==0 ){
25732 zFN = zMemoryName;
25733 }
25734 return zFN;
25735 }
25736
25737 /*
@@ -25263,10 +25770,26 @@
25770 if( z==0 || z[0]==0 ) z = getenv("LOGNAME");
25771 if( z==0 || z[0]==0 ) z = "?";
25772 #endif
25773 return z;
25774 }
25775
25776 /* If z[] begins with one or more ANSI X3.64 (VT100) escape sequences
25777 ** return the number of bytes in all such escape sequences. Return
25778 ** zero if there are no valid escape sequences.
25779 */
25780 static int nAnsiEscape(const char *z){
25781 int i = 0;
25782 while( z[i]=='\033' && z[i+1]=='[' ){
25783 int k = i+2;
25784 while( z[k]>=0x30 && z[k]<=0x3f ){ k++; }
25785 while( z[k]>=0x20 && z[k]<=0x2f ){ k++; }
25786 if( z[k]<0x40 || z[k]>0x7e ) break;
25787 i = k+1;
25788 }
25789 return i;
25790 }
25791
25792 /*
25793 ** Expand escapes in the given input prompt string. Return the
25794 ** expanded prompt in memory obtained from sqlite3_malloc(). The
25795 ** caller is responsible for freeing the memory.
@@ -25311,10 +25834,11 @@
25834 continue;
25835 }
25836 if( c>='0' && c<='7' ){
25837 /* /nnn becomes a single byte given by octal nnn */
25838 int v = c - '0';
25839 i++;
25840 while( i<=2 && zPrompt[i+1]>='0' && zPrompt[i+1]<='7' ){
25841 v = v*8 + zPrompt[++i] - '0';
25842 }
25843 if( !mOff ) sqlite3_str_appendchar(pOut, 1, v);
25844 zPrompt += i+1;
@@ -25533,15 +26057,36 @@
26057 memmove(z+idxSpace+nNew, z+idxSpace, len-nNew-idxSpace);
26058 memset(z+idxSpace, ' ', nNew);
26059 }
26060 }
26061 }
 
26062 if( 0==sqlite3_str_length(pOut) ){
26063 /* Avoid a bogus OOM */
26064 sqlite3_str_appendchar(pOut, 1, '\0');
26065 }
26066
26067 /* Editline does not recognize ANSI X3.64 escape sequences. So we have
26068 ** to find them all and enclose them inside '\001'...'\002' delimiters.
26069 ** Some versions of readline also require this, but others do not.
26070 */
26071 if( p->bDelimitNonprint && strstr(sqlite3_str_value(pOut),"\033[")!=0 ){
26072 char *zOrig = sqlite3_str_finish(pOut);
26073 int n;
26074 pOut = sqlite3_str_new(0);
26075 for(i=0; zOrig[i]; i++){
26076 if( zOrig[i]=='\033' && (n = nAnsiEscape(zOrig+i))>0 ){
26077 sqlite3_str_appendchar(pOut, 1, 1);
26078 sqlite3_str_append(pOut, &zOrig[i], n);
26079 sqlite3_str_appendchar(pOut, 1, 2);
26080 i += n-1;
26081 }else{
26082 sqlite3_str_appendchar(pOut, 1, zOrig[i]);
26083 }
26084 }
26085 sqlite3_free(zOrig);
26086 }
26087
26088 return sqlite3_str_finish(pOut);
26089 }
26090
26091 /*
26092 ** Retrieve a single line of input text.
@@ -25570,30 +26115,33 @@
26115 zResult = local_getline(zPrior, in);
26116 }else{
26117 const char *zBase = prompt_string(p, bContinue!=0);
26118 char *zPrompt = expand_prompt(p, zAll, zBase);
26119 shell_check_oom(zPrompt);
26120 #if SHELL_CMDLINE_EDIT_AVAILABLE
26121 if( shellCmdLineEdit ){
26122 free(zPrior);
26123 zResult = shell_readline(zPrompt);
26124 while( zResult==0 ){
26125 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
26126 sqlite3_sleep(50);
26127 if( seenInterrupt==0 ) break;
26128 zResult = shell_readline("");
26129 }
26130 if( zResult && *zResult ) shell_add_history(zResult);
26131 }else
26132 #endif
26133 {
26134 sputz(stdout, zPrompt);
26135 fflush(stdout);
26136 do{
26137 zResult = local_getline(zPrior, stdin);
26138 zPrior = 0;
26139 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
26140 if( zResult==0 ) sqlite3_sleep(50);
26141 }while( zResult==0 && seenInterrupt>0 );
26142 }
26143 sqlite3_free(zPrompt);
26144 }
26145 return zResult;
26146 }
26147 #endif /* !SQLITE_SHELL_FIDDLE */
@@ -25834,11 +26382,12 @@
26382 double r = sqlite3_value_double(apVal[0]);
26383 int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
26384 char z[400];
26385 if( n<1 ) n = 1;
26386 if( n>350 ) n = 350;
26387 z[sizeof(z)-1] = 0;
26388 snprintf(z, sizeof(z)-1, "%#+.*e", n, r);
26389 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
26390 }
26391
26392 /*
26393 ** SQL function: shell_add_schema(S,X)
@@ -25912,21 +26461,27 @@
26461 }
26462 sqlite3_result_value(pCtx, apVal[0]);
26463 }
26464
26465 /*
26466 ** SQL function: shell_prompt_test(PROMPT,PRIOR,FILENAME,FLAGS)
 
 
26467 **
26468 ** Return the shell prompt, with escapes expanded, for testing purposes.
26469 ** The first argument is the raw (unexpanded) prompt string. Or if the
26470 ** first argument is NULL, then use whatever prompt string is currently
26471 ** configured. If the second argument exists and is not NULL, then the
26472 ** second argument is understood to be prior incomplete text and a
26473 ** continuation prompt is generated. If a third argument is provided,
26474 ** it is assumed to be the full pathname of the database file. The
26475 ** fourth argument, if provided, is an integer of flags:
26476 **
26477 ** 0x0001 Always insert \001..\002 delimiters around ANSI escapes
26478 ** 0x0002 Never insert \001..\002 delimiters
26479 **
26480 ** This function is for testing purposes only. The interface may change.
26481 ** The function itself might be renamed or removed in future releases. Do
26482 ** not use this function in applications.
26483 */
26484 static void shellExpandPrompt(
26485 sqlite3_context *pCtx,
26486 int nVal,
26487 sqlite3_value **apVal
@@ -25936,11 +26491,14 @@
26491 const char *zPrior;
26492 const char *zSavedDbFile;
26493 int mSavedFlgs;
26494 const char *zFName;
26495 char *zRes;
26496 int mFlags;
26497 char bSavedDelimit = p->bDelimitNonprint;
26498
26499 if( nVal<1 ) return;
26500 if( nVal<2
26501 || (zPrior = (const char*)sqlite3_value_text(apVal[1]))==0
26502 || zPrior[0]==0
26503 ){
26504 zPrior = 0;
@@ -25952,12 +26510,19 @@
26510 zSavedDbFile = p->pAuxDb->zDbFilename;
26511 mSavedFlgs = p->pAuxDb->mFlgs;
26512 if( nVal>=3 && (zFName = (const char*)sqlite3_value_text(apVal[2]))!=0 ){
26513 p->pAuxDb->zDbFilename = zFName;
26514 p->pAuxDb->mFlgs |= 0x001;
26515 }
26516 mFlags = nVal>=4 ? sqlite3_value_int(apVal[3]) : 0;
26517 if( mFlags & 0x0001 ){
26518 p->bDelimitNonprint = 1;
26519 }else if( mFlags & 0x0002 ){
26520 p->bDelimitNonprint = 0;
26521 }
26522 zRes = expand_prompt(p, zPrior, zPrompt);
26523 p->bDelimitNonprint = bSavedDelimit;
26524 p->pAuxDb->zDbFilename = zSavedDbFile;
26525 p->pAuxDb->mFlgs = mSavedFlgs;
26526 sqlite3_result_text(pCtx, zRes, -1, SQLITE_TRANSIENT);
26527 sqlite3_free(zRes);
26528 }
@@ -26150,11 +26715,11 @@
26715 free(p->spec.zColumnSep);
26716 free(p->spec.zRowSep);
26717 free(p->spec.zTableName);
26718 free(p->spec.zNull);
26719 memset(p, 0, sizeof(*p));
26720 p->spec.iVersion = 2;
26721 p->autoExplain = autoExplain;
26722 }
26723
26724 /*
26725 ** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26190,10 +26755,18 @@
26755 pDest->spec.zTableName = strdup(pSrc->spec.zTableName);
26756 }
26757 if( pDest->spec.zNull ){
26758 pDest->spec.zNull = strdup(pSrc->spec.zNull);
26759 }
26760 if( pDest->spec.zFpFmt ){
26761 assert( pDest->spec.zFpFmt==pSrc->zFpFmt );
26762 pDest->spec.zFpFmt = pDest->zFpFmt;
26763 }
26764 if( pDest->spec.zIFmt ){
26765 assert( pDest->spec.zIFmt==pSrc->zIFmt );
26766 pDest->spec.zIFmt = pDest->zIFmt;
26767 }
26768 }
26769
26770 /*
26771 ** Set a string value to a copy of the zNew string in memory
26772 ** obtained from system malloc().
@@ -26208,10 +26781,47 @@
26781 if( *az ){
26782 memcpy(*az, zNew, n+1 );
26783 }
26784 }
26785 }
26786
26787 /* Forward reference */
26788 static int pickStr(const char *zArg, char **pzErr, ...);
26789
26790 /*
26791 ** Change the limits on the display mode. Return 0 on
26792 ** success. Return non-zero if zArg is mis-formatted.
26793 **
26794 ** Valid arguments:
26795 **
26796 ** "on" Default limits
26797 ** "off" All limits turned off
26798 ** L,C Line and Characters limits set
26799 ** L,C,T Line, Character, and Title limits set
26800 **
26801 ** Anything else returns non-zero
26802 */
26803 static int modeSetLimit(ShellState *p, const char *zArg){
26804 int k = zArg==0 ? 1 : pickStr(zArg,0,"on","off","");
26805 if( k==0 ){
26806 p->mode.spec.nLineLimit = DFLT_LINE_LIMIT;
26807 p->mode.spec.nCharLimit = DFLT_CHAR_LIMIT;
26808 p->mode.spec.nTitleLimit = DFLT_TITLE_LIMIT;
26809 }else if( k==1 ){
26810 p->mode.spec.nLineLimit = 0;
26811 p->mode.spec.nCharLimit = 0;
26812 p->mode.spec.nTitleLimit = 0;
26813 }else{
26814 int L, C, T = 0;
26815 int nNum = sscanf(zArg, "%d,%d,%d", &L, &C, &T);
26816 if( nNum<2 || L<0 || C<0 || T<0) return 1;
26817 p->mode.spec.nLineLimit = L;
26818 p->mode.spec.nCharLimit = C;
26819 if( nNum==3 ) p->mode.spec.nTitleLimit = T;
26820 }
26821 return 0;
26822 }
26823
26824 /*
26825 ** Change the mode to eMode
26826 */
26827 static void modeChange(ShellState *p, unsigned char eMode){
@@ -26238,17 +26848,23 @@
26848 pM->spec.bSplitColumn = QRF_Yes;
26849 pM->bAutoScreenWidth = 1;
26850 }else{
26851 pM->spec.bSplitColumn = QRF_No;
26852 }
26853 if( pI->mFlg & 0x04 ){
26854 pM->spec.bRowCount = QRF_Yes;
26855 }else{
26856 pM->spec.bRowCount = QRF_No;
26857 }
26858 }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
26859 modeFree(&p->mode);
26860 modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
26861 }else if( eMode==MODE_BATCH ){
26862 u8 mFlags = p->mode.mFlags;
26863 modeFree(&p->mode);
26864 modeChange(p, MODE_List);
26865 modeSetLimit(p, "off");
26866 p->mode.mFlags = mFlags;
26867 }else if( eMode==MODE_TTY ){
26868 u8 mFlags = p->mode.mFlags;
26869 modeFree(&p->mode);
26870 modeChange(p, MODE_QBox);
@@ -26266,13 +26882,15 @@
26882 /*
26883 ** Set the mode to the default. It assumed that the mode has
26884 ** already been freed and zeroed prior to calling this routine.
26885 */
26886 static void modeDefault(ShellState *p){
26887 p->mode.spec.iVersion = 2;
26888 p->mode.autoExplain = 1;
26889 if( (stdin_is_interactive || stdout_is_console)
26890 && SQLITE_SHELL_EDITION>=20260409
26891 ){
26892 modeChange(p, MODE_TTY);
26893 }else{
26894 modeChange(p, MODE_BATCH);
26895 }
26896 }
@@ -26881,11 +27499,11 @@
27499 return SQLITE_OK;
27500 }
27501 #endif
27502
27503 /*
27504 ** Print a schema statement. This is a helper routine to dump_callback().
27505 **
27506 ** This routine converts some CREATE TABLE statements for shadow tables
27507 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
27508 **
27509 ** If the schema statement in z[] contains a start-of-comment and if
@@ -28333,12 +28951,12 @@
28951 ".databases List names and files of attached databases",
28952 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
28953 #if SQLITE_SHELL_HAVE_RECOVER
28954 ".dbinfo ?DB? Show status information about the database",
28955 #endif
 
28956 ".dbtotxt Hex dump of the database file",
28957 ".diskused ?SCHEMA? Report database space and size stats",
28958 ".dump ?OBJECTS? Render database content as SQL",
28959 " Options:",
28960 " --data-only Output only INSERT statements",
28961 " --newlines Allow unescaped newline characters in output",
28962 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -28445,10 +29063,13 @@
29063 " --reset Reset the count for each input and interrupt",
29064 " --timeout S Halt after running for S seconds",
29065 #endif
29066 ".prompt MAIN CONTINUE Replace the standard prompts",
29067 " --hard-reset Unset SQLITE_PS1/2 and then --reset",
29068 #ifndef SQLITE_NO_COLOR
29069 " --no-color Disable color prompts. Use --color to re-enable",
29070 #endif
29071 " --reset Revert to default prompts",
29072 " --show Show the current prompt strings",
29073 " -- No more options. Subsequent args are prompts",
29074 #ifndef SQLITE_SHELL_FIDDLE
29075 ".quit Stop interpreting input stream, exit if primary.",
@@ -28609,10 +29230,14 @@
29230 " truncated. Zero means \"no limit\".\n"
29231 " --colsep STRING Use STRING as the column separator\n"
29232 " --escape ESC Enable/disable escaping of control characters\n"
29233 " found in the output. ESC can be \"off\", \"ascii\",\n"
29234 " or \"symbol\".\n"
29235 " --fpfmt STRING String is a printf-style format string used to\n"
29236 " render floating-point values.\n"
29237 " --ifmt STRING String is a printf-style format string used to\n"
29238 " render integer values.\n"
29239 " --linelimit N Set the maximum number of output lines to show for\n"
29240 " any single SQL value to N. Longer values are\n"
29241 " truncated. Zero means \"no limit\". Only works\n"
29242 " in \"line\" mode and in columnar modes.\n"
29243 " --limits L,C,T Shorthand for \"--linelimit L --charlimit C\n"
@@ -28629,10 +29254,11 @@
29254 " --quote ARG Enable/disable quoting of text. ARG can be\n"
29255 " \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
29256 " \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
29257 " \"on\" is an alias for \"sql\".\n"
29258 " --reset Changes all mode settings back to their default.\n"
29259 " --rowcount BOOLEAN Show \"(N rows)\" at the end of query results.\n"
29260 " --rowsep STRING Use STRING as the row separator\n"
29261 " --sw|--screenwidth N Declare the screen width of the output device\n"
29262 " to be N characters. An attempt may be made to\n"
29263 " wrap output text to fit within this limit. Zero\n"
29264 " means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28640,11 +29266,11 @@
29266 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
29267 " --tag NAME Save mode to the left as NAME.\n"
29268 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
29269 " --title ARG Whether or not to show column headers, and if so\n"
29270 " how to encode them. ARG can be \"off\", \"on\",\n"
29271 " \"always\", \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
29272 " --titlelimit N Limit the length of column titles to N characters.\n"
29273 " -v|--verbose Verbose output\n"
29274 " --widths LIST Set the columns widths for columnar modes. The\n"
29275 " argument is a list of integers, one for each\n"
29276 " column. A \"0\" width means use a dynamic width\n"
@@ -29345,11 +29971,12 @@
29971 sqlite3_base64_init(p->db, 0, 0);
29972 sqlite3_base85_init(p->db, 0, 0);
29973 sqlite3_regexp_init(p->db, 0, 0);
29974 sqlite3_ieee_init(p->db, 0, 0);
29975 sqlite3_series_init(p->db, 0, 0);
29976 sqlite3_diskused_init(p->db, 0, 0);
29977 sqlite3_strdup_init(p->db, 0, 0);
29978 #ifndef SQLITE_SHELL_FIDDLE
29979 sqlite3_fileio_init(p->db, 0, 0);
29980 sqlite3_completion_init(p->db, 0, 0);
29981 #endif
29982 #ifdef SQLITE_HAVE_ZLIB
@@ -29406,15 +30033,11 @@
30033 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
30034 editFunc, 0, 0);
30035 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
30036 editFunc, 0, 0);
30037 #endif
30038 sqlite3_create_function(p->db, "shell_prompt_test", -1, SQLITE_UTF8,
 
 
 
 
30039 p, shellExpandPrompt, 0, 0);
30040 sqlite3_create_function(p->db, "shell_temp_filename", 1, SQLITE_UTF8,
30041 p, shellTempFilenameFunc, 0, 0);
30042
30043
@@ -31155,11 +31778,11 @@
31778 typedef struct ArCommand ArCommand;
31779 struct ArCommand {
31780 u8 eCmd; /* An AR_CMD_* value */
31781 u8 bVerbose; /* True if --verbose */
31782 u8 bZip; /* True if the archive is a ZIP */
31783 u8 bDryRun; /* 1 for --dry-run, 2 for --debug */
31784 u8 bAppend; /* True if --append */
31785 u8 bGlob; /* True if --glob */
31786 u8 fromCmdLine; /* Run from -A instead of .archive */
31787 int nArg; /* Number of command arguments */
31788 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
@@ -31217,10 +31840,11 @@
31840 #define AR_SWITCH_FILE 9
31841 #define AR_SWITCH_DIRECTORY 10
31842 #define AR_SWITCH_APPEND 11
31843 #define AR_SWITCH_DRYRUN 12
31844 #define AR_SWITCH_GLOB 13
31845 #define AR_SWITCH_DEBUG 14
31846
31847 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
31848 switch( eSwitch ){
31849 case AR_CMD_CREATE:
31850 case AR_CMD_EXTRACT:
@@ -31234,11 +31858,14 @@
31858 }
31859 pAr->eCmd = eSwitch;
31860 break;
31861
31862 case AR_SWITCH_DRYRUN:
31863 if( pAr->bDryRun<2 ) pAr->bDryRun = 1;
31864 break;
31865 case AR_SWITCH_DEBUG:
31866 pAr->bDryRun = 2;
31867 break;
31868 case AR_SWITCH_GLOB:
31869 pAr->bGlob = 1;
31870 break;
31871 case AR_SWITCH_VERBOSE:
@@ -31285,10 +31912,11 @@
31912 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
31913 { "file", 'f', AR_SWITCH_FILE, 1 },
31914 { "append", 'a', AR_SWITCH_APPEND, 1 },
31915 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
31916 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
31917 { "debug", 0, AR_SWITCH_DEBUG, 0 },
31918 { "glob", 'g', AR_SWITCH_GLOB, 0 },
31919 };
31920 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
31921 struct ArSwitch *pEnd = &aSwitch[nSwitch];
31922
@@ -31585,18 +32213,41 @@
32213
32214 /*
32215 ** Implementation of .ar "eXtract" command.
32216 */
32217 static int arExtractCommand(ArCommand *pAr){
32218 /* The zSql1[] string is a template for the query that does the
32219 ** extraction. Notes:
32220 **
32221 ** * $dir is the directory into which the archive is to be extracted
32222 ** * $pass is the integer pass number: 0, 1, or 2
32223 ** * The dest CTE is created so that realpath($dir) only needs
32224 ** to be called once.
32225 */
32226 const char *zSql1 =
32227 "WITH dest(dpath,dlen) AS (\n"
32228 #ifdef _WIN32
32229 " SELECT realpath($dir) || '\\',\n"
32230 #else
32231 " SELECT realpath($dir) || '/',\n"
32232 #endif
32233 " 1+length(realpath($dir))\n"
32234 ")\n"
32235 "SELECT\n"
32236 " ($dir || name),\n"
32237 " CASE $dryrun\n" /* vv--- azExtraArg */
32238 " WHEN 0 THEN writefile($dir||name, %s, mode, mtime)\n"
32239 " WHEN 1 THEN 0\n"
32240 " ELSE shell_putsnl(format('writefile(%%Q,%%s,%%0o,%%d)',"
32241 "$dir||name,quote(%s),mode,mtime)) IS NULL\n"
32242 " END\n" /* ^^--- azExtraArg */
32243 " FROM dest CROSS JOIN %s\n"
32244 " WHERE (%s)\n" /* ^^-- pAr->zSrcTable */
32245 /* ^^--- zWhere */
32246 " AND (CASE $pass WHEN 0 THEN (mode&0xf000)<>0xa000\n"
32247 " WHEN 1 THEN (mode&0xf000)=0xa000\n"
32248 " ELSE data IS NULL END)\n"
32249 " AND dpath=substr(realpath($dir||name),1,dlen)\n" /* No escapes */
32250 " AND name NOT GLOB '*..[/\\]*'\n"; /* No /../ in paths */
32251
32252 const char *azExtraArg[] = {
32253 "sqlar_uncompress(data, sz)",
@@ -31623,39 +32274,48 @@
32274 }
32275 if( zDir==0 ) rc = SQLITE_NOMEM;
32276 }
32277
32278 shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
32279 azExtraArg[pAr->bZip],
32280 azExtraArg[pAr->bZip],
32281 pAr->zSrcTable,
32282 zWhere
32283 );
32284
32285 if( rc==SQLITE_OK ){
32286 j = sqlite3_bind_parameter_index(pSql, "$dir");
32287 sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
32288 j = sqlite3_bind_parameter_index(pSql, "$dryrun");
32289 sqlite3_bind_int(pSql, j, pAr->bDryRun);
32290
32291 /* Run the SELECT statement twice
32292 ** (0) writefile() files and directories
32293 ** (1) writefile() symlinks
32294 ** (2) writefile() for directory again
32295 ** The third pass is so that the timestamps for extracted directories
32296 ** will be reset to the value in the archive, since populating them
32297 ** in the first pass will have changed the timestamp. */
32298 for(i=0; i<3; i++){
32299 if( pAr->bDryRun>=2 ){
32300 cli_printf(pAr->out, "*** BEGIN PASS %d ***\n", i+1);
32301 }
32302 j = sqlite3_bind_parameter_index(pSql, "$pass");
32303 sqlite3_bind_int(pSql, j, i);
32304 if( pAr->bDryRun && i==0 ){
32305 cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
 
32306 }
32307 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
32308 if( i==0 && pAr->bVerbose ){
32309 cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
32310 }
32311 }
32312 if( pAr->bDryRun==1 ) break;
32313 shellReset(&rc, pSql);
32314 if( pAr->bDryRun>=2 ){
32315 cli_printf(pAr->out, "*** END PASS %d ***\n", i+1);
32316 }
32317 }
32318 shellFinalize(&rc, pSql);
32319 }
32320
32321 sqlite3_free(zDir);
@@ -32166,11 +32826,11 @@
32826 ;
32827 static const char * const zCollectVar = "\
32828 SELECT\
32829 '('||x'0a'\
32830 || group_concat(\
32831 cname,\
32832 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
32833 ||')' AS ColsSpec \
32834 FROM (\
32835 SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \
32836 FROM ColNames ORDER BY cpos\
@@ -32767,14 +33427,16 @@
33427 /*
33428 ** This function computes what to show the user about the configured
33429 ** titles (or column-names). Output is an integer between 0 and 3:
33430 **
33431 ** 0: The titles do not matter. Never show anything.
33432 ** 1: Show "--title off"
33433 ** 2: Show "--title on"
33434 ** 3: Show "--title always"
33435 ** 4: Show "--title VALUE" where VALUE is an encoding method
33436 ** to use, one of: plain sql csv html tcl json
33437 ** 5: Show "--title VALUE" as in 3, followed by "--title always"
33438 **
33439 ** Inputs are:
33440 **
33441 ** spec.bTitles (bT) Whether or not to show the titles
33442 ** spec.eTitle (eT) The actual encoding to be used for titles
@@ -32807,11 +33469,27 @@
33469 if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
33470 if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
33471 if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
33472 if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
33473
33474 v &= 3;
33475 /* At this point v means:
33476 ** 0: The titles do not matter. Never show anything.
33477 ** 1: Show "--title off"
33478 ** 2: Show "--title on"
33479 ** 3: Show "--title VALUE" where VALUE is an encoding method
33480 ** to use, one of: plain sql csv html tcl json
33481 ** If bTitles is QRF_Always, convert 2->3, 3->5. If bTitles is not
33482 ** QRF_Always, convert 3->4.
33483 */
33484 if( p->mode.spec.bTitles==QRF_Always ){
33485 if( v==3 ) v = 5;
33486 if( v==2 ) v = 3;
33487 }else{
33488 if( v==3 ) v = 4;
33489 }
33490 return v;
33491 }
33492
33493 /*
33494 ** DOT-COMMAND: .mode
33495 **
@@ -32835,10 +33513,14 @@
33513 ** truncated. Zero means "no limit".
33514 ** --colsep STRING Use STRING as the column separator
33515 ** --escape ESC Enable/disable escaping of control characters
33516 ** found in the output. ESC can be "off", "ascii",
33517 ** or "symbol".
33518 ** --fpfmt STRING String is a printf-style format string used to
33519 ** render floating-point values.
33520 ** --ifmt STRING String is a printf-style format string used to
33521 ** render integer values.
33522 ** --linelimit N Set the maximum number of output lines to show for
33523 ** any single SQL value to N. Longer values are
33524 ** truncated. Zero means "no limit". Only works
33525 ** in "line" mode and in columnar modes.
33526 ** --limits L,C,T Shorthand for "--linelimit L --charlimit C
@@ -32855,10 +33537,11 @@
33537 ** --quote ARG Enable/disable quoting of text. ARG can be
33538 ** "off", "on", "sql", "relaxed", "csv", "html",
33539 ** "tcl", or "json". "off" means show the text as-is.
33540 ** "on" is an alias for "sql".
33541 ** --reset Changes all mode settings back to their default.
33542 ** --rowcount BOOLEAN Show "(N rows)" at the end of query results.
33543 ** --rowsep STRING Use STRING as the row separator
33544 ** --sw|--screenwidth N Declare the screen width of the output device
33545 ** to be N characters. An attempt may be made to
33546 ** wrap output text to fit within this limit. Zero
33547 ** means "no limit". Or N can be "auto" to set the
@@ -32866,11 +33549,11 @@
33549 ** --tablename NAME Set the name of the table for "insert" mode.
33550 ** --tag NAME Save mode to the left as NAME.
33551 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
33552 ** --title ARG Whether or not to show column headers, and if so
33553 ** how to encode them. ARG can be "off", "on",
33554 ** "always", "sql", "csv", "html", "tcl", or "json".
33555 ** --titlelimit N Limit the length of column titles to N characters.
33556 ** -v|--verbose Verbose output
33557 ** --widths LIST Set the columns widths for columnar modes. The
33558 ** argument is a list of integers, one for each
33559 ** column. A "0" width means use a dynamic width
@@ -33011,30 +33694,14 @@
33694 }else if( optionMatch(z,"limits") ){
33695 if( (++i)>=nArg ){
33696 dotCmdError(p, i-1, "missing argument", 0);
33697 return 1;
33698 }
33699 if( modeSetLimit(p, azArg[i]) ){
33700 dotCmdError(p, i, "bad argument", "Should be \"on\" or \"off\" or "
33701 "\"L,C,T\" where L, C, and T are unsigned integers");
33702 return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33703 }
33704 chng = 1;
33705 }else if( optionMatch(z,"list") ){
33706 int ii;
33707 cli_puts("available modes:", p->out);
@@ -33105,15 +33772,56 @@
33772 break;
33773 default: /* off */
33774 p->mode.spec.eText = QRF_TEXT_Plain;
33775 break;
33776 }
33777 chng = 1;
33778 }else if( optionMatch(z,"ifmt") ){
33779 if( i+1>=nArg ){
33780 dotCmdError(p, i, "missing argument", 0);
33781 return 1;
33782 }
33783 i++;
33784 if( azArg[i][0]==0 || cli_strcmp(azArg[i],"auto")==0 ){
33785 p->mode.spec.zIFmt = 0;
33786 }else if( sqlite3_qrf_ckformat(azArg[i])!=1 ){
33787 dotCmdError(p, i, "not a valid integer format", 0);
33788 return 1;
33789 }else{
33790 assert( strlen(azArg[i])<sizeof(p->mode.zIFmt)-1 );
33791 memcpy(p->mode.zIFmt, azArg[i], strlen(azArg[i])+1);
33792 p->mode.spec.zIFmt = p->mode.zIFmt;
33793 }
33794 chng = 1;
33795 }else if( optionMatch(z,"fpfmt") ){
33796 if( i+1>=nArg ){
33797 dotCmdError(p, i, "missing argument", 0);
33798 return 1;
33799 }
33800 i++;
33801 if( azArg[i][0]==0 || cli_strcmp(azArg[i],"auto")==0 ){
33802 p->mode.spec.zFpFmt = 0;
33803 }else if( sqlite3_qrf_ckformat(azArg[i])!=2 ){
33804 dotCmdError(p, i, "not a valid floating-point format", 0);
33805 return 1;
33806 }else{
33807 assert( strlen(azArg[i])<sizeof(p->mode.zFpFmt)-1 );
33808 memcpy(p->mode.zFpFmt, azArg[i], strlen(azArg[i])+1);
33809 p->mode.spec.zFpFmt = p->mode.zFpFmt;
33810 }
33811 chng = 1;
33812 }else if( optionMatch(z,"reset") ){
33813 int saved_eMode = p->mode.eMode;
33814 modeFree(&p->mode);
33815 modeChange(p, saved_eMode);
33816 }else if( optionMatch(z,"rowcount") ){
33817 if( i+1>=nArg ){
33818 dotCmdError(p, i, "missing argument", 0);
33819 return 1;
33820 }
33821 p->mode.spec.bRowCount = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33822 chng = 1;
33823 }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
33824 if( (++i)>=nArg ){
33825 dotCmdError(p, i-1, "missing argument", 0);
33826 return 1;
33827 }
@@ -33163,25 +33871,63 @@
33871 return 1;
33872 }
33873 p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33874 chng = 1;
33875 }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
33876 /* The --titles option controls two fields of the
33877 ** sqlite3_qrf_spec object: eTitle and bTitles.
33878 **
33879 ** --titles eTitle bTitles
33880 ** -------- --------------- ---------------------
33881 ** "off" (unchanged) QRF_Off
33882 ** "on" (unchanged) QRF_On
33883 ** "always" (unchanged) QRF_Always
33884 ** "auto", (default) (default)
33885 ** "plain" QRF_TEXT_Plain QRF_Always or QRF_On
33886 ** "sql" QRF_TEXT_Sql QRF_Always or QRF_On
33887 ** "csv" QRF_TEXT_Csv QRF_Always or QRF_On
33888 ** "html" QRF_TEXT_Html QRF_Always or QRF_On
33889 ** "tcl" QRF_TEXT_Tcl QRF_Always or QRF_On
33890 ** "json" QRF_TEXT_Json QRF_Always or QRF_On
33891 **
33892 ** This mapping is different from the -title option to the "format"
33893 ** method of the TCL interface. In this mapping:
33894 **
33895 ** * "off", "on", and "always" affect only bTitles and leave
33896 ** eTitle unchanged
33897 **
33898 ** * "auto" sets both bTitles and eTitle to the default value
33899 ** in aModeInfo[] according to the current --style.
33900 **
33901 ** * "plain" through "json" set eTitle but leave bTitles
33902 ** unchanged if it is not QRF_Off. If bTitles is QRF_Off,
33903 ** then it is changed QRF_Always.
33904 */
33905 char *zErr = 0;
33906 if( i+1>=nArg ){
33907 dotCmdError(p, i, "missing argument", 0);
33908 return 1;
33909 }
33910 k = pickStr(azArg[++i],&zErr,
33911 "off","on","always","auto","plain","sql","csv","html","tcl","json","");
33912 /* 0 1 2 3 4 5 6 7 8 9 */
33913 if( k<0 ){
33914 dotCmdError(p, i, "bad --titles value","%z", zErr);
33915 return 1;
33916 }
 
33917 p->mode.mFlags &= ~MFLG_HDR;
33918 if( k<=2 ){
33919 p->mode.spec.bTitles = QRF_No+k;
33920 }else if( k==3 ){
33921 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
33922 p->mode.spec.bTitles = aModeInfo[p->mode.eMode].bHdr;
33923 }else{
33924 p->mode.spec.eTitle = (k-4)+QRF_TEXT_Plain;
33925 if( p->mode.spec.bTitles==QRF_No ){
33926 p->mode.spec.bTitles = QRF_Always;
33927 }
33928 }
33929 chng = 1;
33930 }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
33931 int nWidth = 0;
33932 short int *aWidth;
33933 const char *zW;
@@ -33295,10 +34041,18 @@
34041 append_c_string(pDesc, p->mode.spec.zColumnSep);
34042 }
34043 if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
34044 sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
34045 }
34046 if( bAll || p->mode.spec.zFpFmt!=0 ){
34047 const char *z = p->mode.spec.zFpFmt;
34048 sqlite3_str_appendf(pDesc, " --fpfmt %s", z ? z : "auto");
34049 }
34050 if( bAll || p->mode.spec.zIFmt!=0 ){
34051 const char *z = p->mode.spec.zIFmt;
34052 sqlite3_str_appendf(pDesc, " --ifmt %s", z ? z : "auto");
34053 }
34054 if( bAll
34055 || (p->mode.spec.nLineLimit>0 && pI->eCx>0)
34056 || p->mode.spec.nCharLimit>0
34057 || (p->mode.spec.nTitleLimit>0 && pI->eCx>0)
34058 ){
@@ -33332,10 +34086,16 @@
34086 if( bAll
34087 || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
34088 ){
34089 sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
34090 }
34091 if( bAll
34092 || ((p->mode.spec.bRowCount==QRF_Yes) != ((pI->mFlg&4)!=0))
34093 ){
34094 sqlite3_str_appendf(pDesc," --rowcount %s",
34095 p->mode.spec.bRowCount==QRF_Yes ? "on" : "off");
34096 }
34097 zSetting = aModeStr[pI->eRSep];
34098 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
34099 sqlite3_str_appendf(pDesc, " --rowsep ");
34100 append_c_string(pDesc, p->mode.spec.zRowSep);
34101 }
@@ -33361,14 +34121,19 @@
34121 if( k==1 ){
34122 sqlite3_str_appendall(pDesc, " --titles off");
34123 }else if( k==2 ){
34124 sqlite3_str_appendall(pDesc, " --titles on");
34125 }else if( k==3 ){
34126 sqlite3_str_appendall(pDesc, " --titles always");
34127 }else if( k>=4 ){
34128 static const char *azTitle[] =
34129 { "plain", "sql", "csv", "html", "tcl", "json"};
34130 sqlite3_str_appendf(pDesc, " --titles %s",
34131 azTitle[p->mode.spec.eTitle-1]);
34132 if( k==5 ){
34133 sqlite3_str_appendf(pDesc, " --titles always");
34134 }
34135 }
34136 if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
34137 int ii;
34138 const char *zSep = " --widths ";
34139 for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34248,11 +35013,16 @@
35013 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
35014 rc = shell_dbinfo_command(p, nArg, azArg);
35015 }else
35016 #endif /* SQLITE_SHELL_HAVE_RECOVER */
35017
35018 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
35019 open_db(p, 0);
35020 rc = shell_dbtotxt_command(p, nArg, azArg);
35021 }else
35022
35023 if( c=='d' && n==8 && cli_strncmp(azArg[0], "diskused", n)==0 ){
35024 const char *zSchema = 0;
35025 int ii;
35026 char *zSql;
35027 open_db(p, 0);
35028 for(ii=1; ii<nArg; ii++){
@@ -34267,27 +35037,19 @@
35037 rc = 1;
35038 goto meta_command_exit;
35039 }
35040 zSchema = z;
35041 }
35042 zSql = sqlite3_mprintf("SELECT diskused(%Q)", zSchema);
35043 shell_check_oom(zSql);
35044 modePush(p);
35045 modeChange(p, MODE_BATCH);
 
 
 
35046 shell_exec(p, zSql, 0);
35047 modePop(p);
35048 sqlite3_free(zSql);
35049 }else
35050
 
 
 
 
 
35051 if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
35052 char *zLike = 0;
35053 char *zSql;
35054 int i;
35055 int savedShellFlags = p->shellFlgs;
@@ -34689,15 +35451,19 @@
35451 }
35452 }else
35453
35454 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
35455 if( nArg==2 ){
35456 if( cli_strcmp(azArg[1],"always")==0 ){
35457 p->mode.spec.bTitles = QRF_Always;
35458 }else{
35459 p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35460 }
35461 p->mode.mFlags |= MFLG_HDR;
35462 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
35463 }else{
35464 eputz("Usage: .headers off|on|always\n");
35465 rc = 1;
35466 }
35467 }else
35468
35469 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -34901,13 +35667,21 @@
35667 sqlite3_str_free(pSql);
35668 }else
35669
35670 if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
35671 i64 iArg = 0;
35672 open_db(p, 0);
35673 if( nArg==2 ){
35674 iArg = integerValue(azArg[1]);
35675 if( iArg==0 ){
35676 if( cli_strcmp(azArg[1],"register")==0 ){
35677 sqlite3_intck_register(p->db, 1);
35678 rc = 0;
35679 goto meta_command_exit;
35680 }
35681 iArg = -1;
35682 }
35683 }
35684 if( (nArg!=1 && nArg!=2) || iArg<0 ){
35685 cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
35686 rc = 1;
35687 goto meta_command_exit;
@@ -34955,10 +35729,12 @@
35729 { "attached", SQLITE_LIMIT_ATTACHED },
35730 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
35731 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
35732 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
35733 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
35734 { "schema", SQLITE_LIMIT_SCHEMA },
35735 { "trigger_steps", SQLITE_LIMIT_TRIGGER_STEPS },
35736 };
35737 int i, n2;
35738 open_db(p, 0);
35739 if( nArg==1 ){
35740 for(i=0; i<ArraySize(aLimit); i++){
@@ -35400,10 +36176,26 @@
36176 }else
36177 if( strcmp(z,"-show")==0 ){
36178 cli_printf(stdout,"Main prompt: '%s'\n", prompt_string(p, 0));
36179 cli_printf(stdout,"Continuation: '%s'\n", prompt_string(p, 1));
36180 }else
36181 #ifndef SQLITE_NO_COLOR
36182 if( strcmp(z,"-color")==0 ){
36183 #ifdef _WIN32
36184 _putenv("NO_COLOR=");
36185 #else
36186 unsetenv("NO_COLOR");
36187 #endif
36188 }else
36189 if( strcmp(z,"-no-color")==0 ){
36190 #ifdef _WIN32
36191 _putenv("NO_COLOR=1");
36192 #else
36193 setenv("NO_COLOR","1",1);
36194 #endif
36195 }else
36196 #endif
36197 if( strcmp(z,"-")==0 ){
36198 noOpt = 1;
36199 }else
36200 {
36201 dotCmdError(p, i, "unknown option", 0);
@@ -35414,10 +36206,11 @@
36206 dotCmdError(p, i, "extra argument", 0);
36207 rc = 1;
36208 goto meta_command_exit;
36209 }else if( !p->dot.abQuot[i] && sqlite3_strglob("*[^a-z]*",z)!=0 ){
36210 dotCmdError(p, i, "use quotes around the prompt string", 0);
36211 rc = 1;
36212 }else{
36213 free(p->azPrompt[cnt]);
36214 p->azPrompt[cnt] = strdup(z);
36215 cnt++;
36216 }
@@ -36264,11 +37057,12 @@
37057 azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
37058 cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
37059 cli_printf(p->out, "%12.12s: %s\n","explain",
37060 p->mode.autoExplain ? "auto" : "off");
37061 cli_printf(p->out, "%12.12s: %s\n","headers",
37062 p->mode.spec.bTitles==QRF_Always ? "always" :
37063 azBool[p->mode.spec.bTitles==QRF_Yes]);
37064 if( p->mode.spec.eStyle==QRF_STYLE_Column
37065 || p->mode.spec.eStyle==QRF_STYLE_Box
37066 || p->mode.spec.eStyle==QRF_STYLE_Table
37067 || p->mode.spec.eStyle==QRF_STYLE_Markdown
37068 ){
@@ -37626,17 +38420,18 @@
38420 " -- treat no subsequent arguments as options\n"
38421 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
38422 " -A ARGS... run \".archive ARGS\" and exit\n"
38423 #endif
38424 " -append append the database to the end of the file\n"
38425 " -ascii set '.mode ascii'\n"
38426 " -bail stop after hitting an error\n"
38427 " -batch force batch I/O\n"
38428 " -box set '.mode box'\n"
38429 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
38430 " -cmdline-edit BOOL enable or disable command-line editing\n"
38431 " -column set '.mode column'\n"
38432 " -csv set '.mode csv -limits off'\n"
38433 #if !defined(SQLITE_OMIT_DESERIALIZE)
38434 " -deserialize open the database using sqlite3_deserialize()\n"
38435 #endif
38436 " -echo print inputs before execution\n"
38437 " -escape T ctrl-char escape; T is one of: symbol, ascii, off\n"
@@ -37644,18 +38439,18 @@
38439 " -[no]header turn headers on or off\n"
38440 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
38441 " -heap SIZE Size of heap for memsys3 or memsys5\n"
38442 #endif
38443 " -help show this message\n"
38444 " -html set '.mode html'\n"
38445 " -ifexists only open if database already exists\n"
38446 " -interactive force interactive I/O\n"
38447 " -json set '.mode json'\n"
38448 " -line set '.mode line'\n"
38449 " -list set '.mode list'\n"
38450 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
38451 " -markdown set '.mode markdown'\n"
38452 #if !defined(SQLITE_OMIT_DESERIALIZE)
38453 " -maxsize N maximum size for a --deserialize database\n"
38454 #endif
38455 " -memtrace trace all memory allocations and deallocations\n"
38456 " -mmap N default mmap size set to N\n"
@@ -37668,21 +38463,21 @@
38463 " -nonce STRING set the safe-mode escape nonce\n"
38464 " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
38465 " -nullvalue TEXT set text string for NULL values. Default ''\n"
38466 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
38467 " -pcachetrace trace all page cache operations\n"
38468 " -quote set '.mode quote'\n"
38469 " -readonly open the database read-only\n"
38470 " -safe enable safe-mode\n"
38471 " -screenwidth N use N as the default screenwidth \n"
38472 " -separator SEP set output column separator. Default: '|'\n"
38473 #ifdef SQLITE_ENABLE_SORTER_REFERENCES
38474 " -sorterref SIZE sorter references threshold size\n"
38475 #endif
38476 " -stats print memory stats before each finalize\n"
38477 " -table set '.mode table'\n"
38478 " -tabs set '.mode tabs'\n"
38479 " -unsafe-testing allow unsafe commands and modes for testing\n"
38480 " -version show SQLite version\n"
38481 " -vfs NAME use NAME as the default VFS\n"
38482 " -vfstrace enable tracing of all VFS calls\n"
38483 #ifdef SQLITE_HAVE_ZLIB
@@ -37710,10 +38505,23 @@
38505 sputz(stdout, "WARNING: attempt to configure SQLite after"
38506 " initialization.\n");
38507 }
38508 }
38509
38510 #if HAVE_EDITLINE
38511 /*
38512 ** https://sqlite.org/forum/forumpost/aad7a634916ff050:
38513 **
38514 ** Calling setlocale(LC_...,"") is required to get libedit to accept
38515 ** non-ASCII input.
38516 */
38517 #define DO_SET_LOCALE 1
38518 #include <locale.h>
38519 #else
38520 #define DO_SET_LOCALE 0
38521 #endif
38522
38523 /*
38524 ** Initialize the state information in data
38525 */
38526 static void main_init(ShellState *p) {
38527 memset(p, 0, sizeof(*p));
@@ -37724,31 +38532,36 @@
38532 verify_uninitialized();
38533 #endif
38534 sqlite3_config(SQLITE_CONFIG_URI, 1);
38535 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
38536 globalShellState = p;
38537 #if HAVE_EDITLINE || HAVE_READLINE
38538 /* Editline requires \001...\002 delimiters around ANSI x3.64 escapes in
38539 ** prompt strings. Readline does sometimes, depending on how it is
38540 ** compiled and installed. */
38541 p->bDelimitNonprint = 1;
38542 #else
38543 /* No \001...\002 escapes required for linenoise or when not using a
38544 ** command-line editing library */
38545 p->bDelimitNonprint = 0;
38546 #endif
38547 #if DO_SET_LOCALE
38548 setlocale(LC_CTYPE,"");
38549 #endif
38550 #undef DO_SET_LOCALE
38551 }
38552
38553 /*
38554 ** Output text to the console in a font that attracts extra attention.
38555 */
38556 static void printBold(const char *zText){
38557 if( shellNoColor() ){
38558 cli_printf(stdout, "%s", zText);
38559 }else{
38560 cli_printf(stdout, "\033[1;36m\033[3m%s\033[0m", zText);
38561 }
38562 }
 
 
 
 
 
 
 
 
 
38563
38564 /*
38565 ** Get the argument to an --option. Throw an error and die if no argument
38566 ** is available.
38567 */
@@ -37762,11 +38575,11 @@
38575 }
38576
38577 /*
38578 ** The callback from atexit().
38579 */
38580 static void SQLITE_CDECL abnormalExit(void){
38581 if( seenInterrupt ) eputz("Program interrupted.\n");
38582 if( globalShellState ){
38583 clearTempFile(globalShellState, 1, 1);
38584 }
38585 }
@@ -37837,10 +38650,11 @@
38650 }
38651 argv[argc] = 0;
38652 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
38653 GetConsoleMode(hOut, &mode);
38654 SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
38655 _setmode(_fileno(stdout),_O_BINARY); /* Bug 2026-08-03T08:52:42Z */
38656 rc = utf8_main(argc, argv);
38657 for(i=0; i<argc; i++) free(orig[i]);
38658 free(argv);
38659 return rc;
38660 }
@@ -37883,10 +38697,13 @@
38697 stdout_is_console = 1;
38698 data.wasm.zDefaultDbName = "/fiddle.sqlite3";
38699 #else
38700 stdin_is_interactive = isatty(0);
38701 stdout_is_console = isatty(1);
38702 if( !stdin_is_interactive || !stdout_is_console ){
38703 shellCmdLineEdit = 0;
38704 }
38705 #endif
38706 atexit(abnormalExit);
38707 #ifdef SQLITE_DEBUG
38708 mem_main_enter = sqlite3_memory_used();
38709 #endif
@@ -37973,11 +38790,11 @@
38790 stdin_is_interactive = 0;
38791 nCmd++;
38792 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
38793 shell_check_oom(azCmd);
38794 aiCmd = realloc(aiCmd, sizeof(aiCmd[0])*nCmd);
38795 shell_check_oom(aiCmd);
38796 azCmd[nCmd-1] = z;
38797 aiCmd[nCmd-1] = i;
38798 }
38799 continue;
38800 }
@@ -38130,10 +38947,12 @@
38947 }else if( cli_strcmp(z,"-safe")==0 ){
38948 /* no-op - catch this on the second pass */
38949 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
38950 /* skip over the argument */
38951 i++;
38952 }else if( cli_strcmp(z,"-cmdline-edit")==0 ){
38953 shellCmdLineEdit = booleanValue(cmdline_option_value(argc,argv,++i));
38954 }else if( cli_strcmp(z,"-test-argv")==0 ){
38955 /* Undocumented test option. Print the values in argv[] and exit.
38956 ** Use this to verify that any translation of the argv[], for example
38957 ** on Windows that receives wargv[] from the OS and must convert
38958 ** to UTF8 prior to calling this routine. */
@@ -38262,10 +39081,11 @@
39081 modeChange(&data, MODE_Psql);
39082 }else if( cli_strcmp(z,"-box")==0 ){
39083 modeChange(&data, MODE_Box);
39084 }else if( cli_strcmp(z,"-csv")==0 ){
39085 modeChange(&data, MODE_Csv);
39086 modeSetLimit(&data, "off");
39087 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
39088 /* See similar code at tag-20250224-1 */
39089 const char *zEsc = argv[++i];
39090 int k;
39091 for(k=0; k<ArraySize(qrfEscNames); k++){
@@ -38319,13 +39139,15 @@
39139 cmdline_option_value(argc,argv,++i));
39140 }else if( cli_strcmp(z,"-nullvalue")==0 ){
39141 modeSetStr(&data.mode.spec.zNull,
39142 cmdline_option_value(argc,argv,++i));
39143 }else if( cli_strcmp(z,"-header")==0 ){
39144 data.mode.spec.bTitles = QRF_Always;
39145 data.mode.mFlags |= MFLG_HDR;
39146 }else if( cli_strcmp(z,"-noheader")==0 ){
39147 data.mode.spec.bTitles = QRF_No;
39148 data.mode.mFlags |= MFLG_HDR;
39149 }else if( cli_strcmp(z,"-echo")==0 ){
39150 data.mode.mFlags |= MFLG_ECHO;
39151 }else if( cli_strcmp(z,"-eqp")==0 ){
39152 data.mode.autoEQP = AUTOEQP_on;
39153 }else if( cli_strcmp(z,"-eqpfull")==0 ){
@@ -38389,10 +39211,12 @@
39211 i++;
39212 #ifdef SQLITE_ENABLE_MULTIPLEX
39213 }else if( cli_strcmp(z,"-multiplex")==0 ){
39214 i++;
39215 #endif
39216 }else if( cli_strcmp(z,"-cmdline-edit")==0 ){
39217 i+=2;
39218 }else if( cli_strcmp(z,"-help")==0 ){
39219 usage(1);
39220 }else if( cli_strcmp(z,"-cmd")==0 ){
39221 /* Run commands that follow -cmd first and separately from commands
39222 ** that simply appear on the command-line. This seems goofy. It would
@@ -38418,12 +39242,14 @@
39242 rc = 1;
39243 goto shell_main_exit;
39244 }
39245 open_db(&data, OPEN_DB_ZIPFILE);
39246 if( z[2] ){
39247 char *zSaved = argv[i];
39248 argv[i] = &z[2];
39249 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
39250 argv[i] = zSaved;
39251 }else{
39252 arDotCommand(&data, 1, argv+i, argc-i);
39253 }
39254 readStdin = 0;
39255 stdin_is_interactive = 0;
39256
+4085 -1741
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 4aac1057eeaf6c29a4893e9c080497c780b0 with changes in files:
21
+** 3bd5456e50ef321f2cafcf67261d556a7606 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470470
#define SQLITE_VERSION "3.54.0"
471471
#define SQLITE_VERSION_NUMBER 3054000
472
-#define SQLITE_SOURCE_ID "2026-04-30 18:23:58 4aac1057eeaf6c29a4893e9c080497c780b0963e810c501532d79eba1b457f27"
472
+#define SQLITE_SOURCE_ID "2026-08-20 13:25:12 3bd5456e50ef321f2cafcf67261d556a760624ce0caab430ed9454cebec233e7"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2026-04-30T18:23:58.352Z"
475
+#define SQLITE_SCM_DATETIME "2026-08-20T13:25:12.207Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -3732,11 +3732,11 @@
37323732
** authorizer will fail with an error message explaining that
37333733
** access is denied.
37343734
**
37353735
** ^The first parameter to the authorizer callback is a copy of the third
37363736
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
3737
-** to the callback is an integer [SQLITE_COPY | action code] that specifies
3737
+** to the callback is an integer [SQLITE_READ | action code] that specifies
37383738
** the particular action to be authorized. ^The third through sixth parameters
37393739
** to the callback are either NULL pointers or zero-terminated strings
37403740
** that contain additional details about the action to be authorized.
37413741
** Applications must always be prepared to encounter a NULL pointer in any
37423742
** of the third through the sixth parameters of the authorization callback.
@@ -3775,25 +3775,37 @@
37753775
** ^(Only a single authorizer can be in place on a database connection
37763776
** at a time. Each call to sqlite3_set_authorizer overrides the
37773777
** previous call.)^ ^Disable the authorizer by installing a NULL callback.
37783778
** The authorizer is disabled by default.
37793779
**
3780
-** The authorizer callback must not do anything that will modify
3780
+** <h3>Limitations And Caveats</h3><ul>
3781
+**
3782
+** <li>The authorizer callback must not do anything that will modify
37813783
** the database connection that invoked the authorizer callback.
37823784
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
37833785
** database connections for the meaning of "modify" in this paragraph.
37843786
**
3785
-** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
3787
+** <li>^When [sqlite3_prepare_v2()] is used to prepare a statement, the
37863788
** statement might be re-prepared during [sqlite3_step()] due to a
37873789
** schema change. Hence, the application should ensure that the
37883790
** correct authorizer callback remains in place during the [sqlite3_step()].
37893791
**
3790
-** ^Note that the authorizer callback is invoked only during
3792
+** <li>^The authorizer callback is invoked only during
37913793
** [sqlite3_prepare()] or its variants. Authorization is not
37923794
** performed during statement evaluation in [sqlite3_step()], unless
37933795
** as stated in the previous paragraph, sqlite3_step() invokes
37943796
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
3797
+**
3798
+** <li>Authorizer callbacks for the expressions of a
3799
+** [generated column] are invoked when the schema is parsed (and specifically
3800
+** when the [CREATE TABLE] statement that contains the generated column is
3801
+** parsed) not when the generated column is used in a DML statement.
3802
+** This is deliberate, as one of the purposes of generated columns
3803
+** is to give schema designers the ability to provide gated access
3804
+** to privileged columns and/or functions.
3805
+**
3806
+** </ul>
37953807
*/
37963808
SQLITE_API int sqlite3_set_authorizer(
37973809
sqlite3*,
37983810
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
37993811
void *pUserData
@@ -3864,12 +3876,17 @@
38643876
#define SQLITE_ANALYZE 28 /* Table Name NULL */
38653877
#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
38663878
#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
38673879
#define SQLITE_FUNCTION 31 /* NULL Function Name */
38683880
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
3869
-#define SQLITE_COPY 0 /* No longer used */
38703881
#define SQLITE_RECURSIVE 33 /* NULL NULL */
3882
+
3883
+/*
3884
+** Note: The SQLITE_COPY macro (with value 0) used to be one of the
3885
+** action codes above. That macro has now been repurposed as a possible
3886
+** value to the 3rd argument to sqlite3_result_str().
3887
+*/
38713888
38723889
/*
38733890
** CAPI3REF: Deprecated Tracing And Profiling Functions
38743891
** DEPRECATED
38753892
**
@@ -4373,12 +4390,11 @@
43734390
** parameter on F or if the value of P does not match any of the
43744391
** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
43754392
**
43764393
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
43774394
** 64-bit signed integer and returns that integer, or D if P does not
4378
-** exist. If the value of P is something other than an integer, then
4379
-** zero is returned.
4395
+** exist or ff the value of P is something other than an integer.
43804396
**
43814397
** The sqlite3_uri_key(F,N) returns a pointer to the name (not
43824398
** the value) of the N-th query parameter for filename F, or a NULL
43834399
** pointer if N is less than zero or greater than the number of query
43844400
** parameters minus 1. The N value is zero-based so N should be 0 to obtain
@@ -4697,11 +4713,12 @@
46974713
** <dd>The maximum number of columns in a table definition or in the
46984714
** result set of a [SELECT] or the maximum number of columns in an index
46994715
** or in an ORDER BY or GROUP BY clause.</dd>)^
47004716
**
47014717
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
4702
-** <dd>The maximum depth of the parse tree on any expression.</dd>)^
4718
+** <dd>The maximum depth of the parse tree on any expression and
4719
+** the maximum nesting depth for subqueries and VIEWs</dd>)^
47034720
**
47044721
** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
47054722
** <dd>The maximum depth of the LALR(1) parser stack used to analyze
47064723
** input SQL statements.</dd>)^
47074724
**
@@ -4728,15 +4745,24 @@
47284745
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
47294746
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
47304747
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
47314748
**
47324749
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
4733
-** <dd>The maximum depth of recursion for triggers.</dd>)^
4750
+** <dd>The maximum depth of recursion for triggers, and the maximum
4751
+** nesting depth for separate triggers.</dd>)^
47344752
**
47354753
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
47364754
** <dd>The maximum number of auxiliary worker threads that a single
47374755
** [prepared statement] may start.</dd>)^
4756
+**
4757
+** [[SQLITE_LIMIT_SCHEMA]] ^(<dt>SQLITE_LIMIT_SCHEMA</dt>
4758
+** <dd>The maximum number of objects (tables, indexes, triggers, and views)
4759
+** defined by the database schema.</dd>)^
4760
+**
4761
+** [[SQLITE_LIMIT_TRIGGER_STEPS]] ^(<dt>SQLITE_LIMIT_TRIGGER_STEPS</dt>
4762
+** <dd>The maximum number of SQL statements that can be contained within
4763
+** a single trigger.</dd>)^
47384764
** </dl>
47394765
*/
47404766
#define SQLITE_LIMIT_LENGTH 0
47414767
#define SQLITE_LIMIT_SQL_LENGTH 1
47424768
#define SQLITE_LIMIT_COLUMN 2
@@ -4748,10 +4774,12 @@
47484774
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
47494775
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
47504776
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
47514777
#define SQLITE_LIMIT_WORKER_THREADS 11
47524778
#define SQLITE_LIMIT_PARSER_DEPTH 12
4779
+#define SQLITE_LIMIT_SCHEMA 13
4780
+#define SQLITE_LIMIT_TRIGGER_STEPS 14
47534781
47544782
/*
47554783
** CAPI3REF: Prepare Flags
47564784
**
47574785
** These constants define various flags that can be passed into the
@@ -4859,10 +4887,12 @@
48594887
** there is a small performance advantage to passing an nByte parameter that
48604888
** is the number of bytes in the input string <i>including</i>
48614889
** the nul-terminator.
48624890
** Note that nByte measures the length of the input in bytes, not
48634891
** characters, even for the UTF-16 interfaces.
4892
+** For the sqlite3_prepare16() and sqlite3_prepare16_v2() interfaces,
4893
+** the nByte value must be even or undefined behavior can result.
48644894
**
48654895
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
48664896
** past the end of the first SQL statement in zSql. These routines only
48674897
** compile the first statement in zSql, so *pzTail is left pointing to
48684898
** what remains uncompiled.
@@ -5605,11 +5635,11 @@
56055635
** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
56065636
** can be obtained by calling [sqlite3_reset()] on the
56075637
** [prepared statement]. ^In the "v2" interface,
56085638
** the more specific error code is returned directly by sqlite3_step().
56095639
**
5610
-** [SQLITE_MISUSE] means that the this routine was called inappropriately.
5640
+** [SQLITE_MISUSE] means that this routine was called inappropriately.
56115641
** Perhaps it was called on a [prepared statement] that has
56125642
** already been [sqlite3_finalize | finalized] or on one that had
56135643
** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
56145644
** be the case that the same database connection is being used by two or
56155645
** more threads at the same moment in time.
@@ -6778,11 +6808,15 @@
67786808
** to by the second parameter and which is N bytes long where N is the
67796809
** third parameter.
67806810
**
67816811
** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
67826812
** interfaces set the result of the application-defined function to be
6783
-** a BLOB containing all zero bytes and N bytes in size.
6813
+** a BLOB containing all zero bytes and N bytes in size. The
6814
+** zeroblob64(C,N) interface returns a [result code], which is normally
6815
+** [SQLITE_OK] but might be some other value if the requested operation
6816
+** could not be complete, for example if insufficient memory is available
6817
+** or if the value of N is out of range.
67846818
**
67856819
** ^The sqlite3_result_double() interface sets the result from
67866820
** an application-defined function to be a floating point value specified
67876821
** by its 2nd argument.
67886822
**
@@ -9116,12 +9150,12 @@
91169150
** The lifecycle of an sqlite3_str object is as follows:
91179151
** <ol>
91189152
** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
91199153
** <li> ^Text is appended to the sqlite3_str object using various
91209154
** methods, such as [sqlite3_str_appendf()].
9121
-** <li> ^The sqlite3_str object is destroyed and the string it created
9122
-** is returned using the [sqlite3_str_finish()] interface.
9155
+** <li> The sqlite3_str object is destroyed and the string it created
9156
+** is returned using [sqlite3_str_finish()] or [sqlite3_result_str()].
91239157
** </ol>
91249158
*/
91259159
typedef struct sqlite3_str sqlite3_str;
91269160
91279161
/*
@@ -9169,10 +9203,44 @@
91699203
** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
91709204
*/
91719205
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
91729206
SQLITE_API void sqlite3_str_free(sqlite3_str*);
91739207
9208
+/*
9209
+** CAPI3REF: Return A Dynamic String From an SQL Function
9210
+**
9211
+** The [sqlite3_result_str(C,S,F)] interface causes the
9212
+** [sqlite3_str|dynamic string] S to become the return value for the
9213
+** application-defined function or virtual table that uses
9214
+** [sqlite3_context] C. The F flag can be one of [SQLITE_COPY]
9215
+** or [SQLITE_XFER] or [SQLITE_FINISH].
9216
+**
9217
+** If the dynamic string is invalid or incomplete due to an out-of-memory
9218
+** or string-too-large error, then this routine transfers that error
9219
+** over to the SQL function.
9220
+**
9221
+** If the F argument is SQLITE_COPY, then a copy of the dynamic string
9222
+** content is made and the dynamic string object is unchanged.
9223
+** If the F argument is SQLITE_XFER, then ownership of the content
9224
+** in the dynamic is transferred to the SQL function (via a pointer copy
9225
+** rather than a string copy) and the dynamic string is reset to an
9226
+** empty string. The SQLITE_FINISH value for F works like SQLITE_RESET
9227
+** except that it also invokes the [sqlite3_str_free(S)] destructor
9228
+** on the dynamic string object.
9229
+*/
9230
+SQLITE_API void sqlite3_result_str(sqlite3_context*, sqlite3_str*, int);
9231
+
9232
+/*
9233
+** CAPI3REF: Control Flags For sqlite3_result_str()
9234
+**
9235
+** The following integers can be used as the third "F" argument
9236
+** to [sqlite3_result_str(C,S,F)].
9237
+*/
9238
+#define SQLITE_COPY 0 /* Results copied. Dynamic string unchanged */
9239
+#define SQLITE_XFER 1 /* Results transfered. Dynamic string reset */
9240
+#define SQLITE_FINISH 2 /* Like SQLITE_XFER, plus dynamic string freed */
9241
+
91749242
/*
91759243
** CAPI3REF: Add Content To A Dynamic String
91769244
** METHOD: sqlite3_str
91779245
**
91789246
** These interfaces add or remove content to an sqlite3_str object
@@ -11534,12 +11602,23 @@
1153411602
** reopen S as an in-memory database based on the serialization
1153511603
** contained in P. If S is a NULL pointer, the main database is
1153611604
** used. The serialized database P is N bytes in size. M is the size
1153711605
** of the buffer P, which might be larger than N. If M is larger than
1153811606
** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
11539
-** SQLite is permitted to add content to the in-memory database as
11540
-** long as the total size does not exceed M bytes.
11607
+** SQLite is permitted to add content to the in-memory database, in
11608
+** page-sized chunks, as long as the total size does not exceed M bytes.
11609
+**
11610
+** The parameter M must be greater than or equal to N. Ideally, M
11611
+** should have a value which is N+(512&times;K)+20 where K determines how
11612
+** must extra space is available to hold new content as the database
11613
+** grows. K can be 0 if the database is read-only.
11614
+**
11615
+** If the database content in P is malformed in a malicious way then
11616
+** it is possible that SQLite might try to read a few more than N bytes
11617
+** from P. If the veracity of the database content P is uncertain,
11618
+** then applications are advised to allocate about 20 extra bytes on
11619
+** the end of the P buffer to avoid a memory error.
1154111620
**
1154211621
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
1154311622
** invoke sqlite3_free() on the serialization buffer when the database
1154411623
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
1154511624
** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -13184,15 +13263,27 @@
1318413263
** <dt>SQLITE_CHANGESETAPPLY_FKNOACTION <dd>
1318513264
** If this flag it set, then all foreign key constraints in the target
1318613265
** database behave as if they were declared with "ON UPDATE NO ACTION ON
1318713266
** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL
1318813267
** or SET DEFAULT.
13268
+**
13269
+** <dt>SQLITE_CHANGESETAPPLY_NOUPDATELOOP <dd>
13270
+** Sometimes, a changeset contains two or more update statements such that
13271
+** although after applying all updates the database will contain no
13272
+** constraint violations, no single update can be applied before the others.
13273
+** The simplest example of this is a pair of UPDATEs that have "swapped"
13274
+** two column values with a UNIQUE constraint.
13275
+** <p>
13276
+** Usually, sqlite3changeset_apply() and similar functions work hard to try
13277
+** to find a way to apply such a changeset. However, if this flag is set,
13278
+** then all such updates are considered CONSTRAINT conflicts.
1318913279
*/
1319013280
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
1319113281
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
1319213282
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
1319313283
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
13284
+#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010
1319413285
1319513286
/*
1319613287
** CAPI3REF: Constants Passed To The Conflict Handler
1319713288
**
1319813289
** Values that may be passed as the second argument to a conflict-handler.
@@ -14954,10 +15045,45 @@
1495415045
*/
1495515046
#ifndef SQLITE_MAX_TRIGGER_DEPTH
1495615047
# define SQLITE_MAX_TRIGGER_DEPTH 1000
1495715048
#endif
1495815049
15050
+/*
15051
+** Maximum number of objects defined by a single database schema.
15052
+** Objects include:
15053
+**
15054
+** * tables (including the sqlite_schema table)
15055
+** * virtual tables
15056
+** * named indexes
15057
+** * indexes created automatically by UNIQUE and PRIMARY KEY constraints
15058
+** * triggers
15059
+** * views
15060
+**
15061
+** The total of all of the above is the number of objects in the schema,
15062
+** and that number may not exceed this value.
15063
+**
15064
+** The maximum number of objects is restricted to forestall theoretical
15065
+** signed integer overflow attacks using databases with billions of
15066
+** schema objects. Such attacks are "theoretical" because memory and
15067
+** disk space constraints would be reached long before billions of schema
15068
+** objects could be created. Even so, it seems good to have a well defined
15069
+** upper limit on the complexity of the schema, for defense in depth.
15070
+** No real-world application should ever get anywhere close to hitting
15071
+** this limit.
15072
+*/
15073
+#ifndef SQLITE_MAX_SCHEMA
15074
+# define SQLITE_MAX_SCHEMA 10000000
15075
+#endif
15076
+
15077
+/*
15078
+** Maximum number of SQL statements allowed in the body of a single
15079
+** trigger.
15080
+*/
15081
+#ifndef SQLITE_MAX_TRIGGER_STEPS
15082
+# define SQLITE_MAX_TRIGGER_STEPS 65000
15083
+#endif
15084
+
1495915085
/************** End of sqliteLimit.h *****************************************/
1496015086
/************** Continuing where we left off in sqliteInt.h ******************/
1496115087
1496215088
/* Disable nuisance warnings on Borland compilers */
1496315089
#if defined(__BORLANDC__)
@@ -15022,26 +15148,54 @@
1502215148
# define SQLITE_INT_TO_PTR(X) ((void*)(X))
1502315149
# define SQLITE_PTR_TO_INT(X) ((int)(X))
1502415150
#endif
1502515151
1502615152
/*
15027
-** Macros to hint to the compiler that a function should or should not be
15028
-** inlined.
15153
+** Hint to the compiler that a function should or should not be inlined:
15154
+**
15155
+** SQLITE_NOINLINE Never in-line this function
15156
+**
15157
+** SQLITE_INLINE Strive to in-line this function
15158
+**
15159
+** SQLITE_OPT_INLINE In-line this function if building the
15160
+** amalgamation.
15161
+**
15162
+** SQLITE_USES_INLINE Set to 1 or 0 according to whether or not
15163
+** inline functions are supported.
1502915164
*/
15030
-#if defined(__GNUC__)
15031
-# define SQLITE_NOINLINE __attribute__((noinline))
15032
-# define SQLITE_INLINE __attribute__((always_inline)) inline
15165
+#if defined(SQLITE_DISABLE_INLINE)
15166
+# define SQLITE_NOINLINE
15167
+# define SQLITE_INLINE
15168
+# define SQLITE_OPT_INLINE
15169
+# define SQLITE_USES_INLINE 0
15170
+#elif defined(__GNUC__)
15171
+# define SQLITE_NOINLINE __attribute__((noinline))
15172
+# define SQLITE_INLINE __attribute__((always_inline)) inline
15173
+# define SQLITE_OPT_INLINE __attribute__((always_inline)) inline
15174
+# define SQLITE_USES_INLINE 1
1503315175
#elif defined(_MSC_VER) && _MSC_VER>=1310
15034
-# define SQLITE_NOINLINE __declspec(noinline)
15035
-# define SQLITE_INLINE __forceinline
15176
+# define SQLITE_NOINLINE __declspec(noinline)
15177
+# define SQLITE_INLINE __forceinline
15178
+# define SQLITE_OPT_INLINE __forceinline
15179
+# define SQLITE_USES_INLINE 1
1503615180
#else
1503715181
# define SQLITE_NOINLINE
1503815182
# define SQLITE_INLINE
15183
+# define SQLITE_OPT_INLINE
15184
+# define SQLITE_USES_INLINE 0
1503915185
#endif
1504015186
#if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__)
1504115187
# undef SQLITE_INLINE
1504215188
# define SQLITE_INLINE
15189
+# undef SQLITE_OPT_INLINE
15190
+# define SQLITE_OPT_INLINE
15191
+# undef SQLITE_USES_INLINE
15192
+# define SQLITE_USES_INLINE 0
15193
+#endif
15194
+#if !defined(SQLITE_AMALGAMATION)
15195
+# undef SQLITE_OPT_INLINE
15196
+# define SQLITE_OPT_INLINE
1504315197
#endif
1504415198
1504515199
/*
1504615200
** Make sure that the compiler intrinsics we desire are enabled when
1504715201
** compiling with an appropriate version of MSVC unless prevented by
@@ -15212,11 +15366,13 @@
1521215366
** bitmask tests, testcase() can be used to make sure each bit
1521315367
** is significant and used at least once. On switch statements
1521415368
** where multiple cases go to the same block of code, testcase()
1521515369
** can insure that all cases are evaluated.
1521615370
*/
15217
-#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
15371
+#if defined(SQLITE_MUTATION_TEST)
15372
+# define testcase(X)
15373
+#elif defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
1521815374
# ifndef SQLITE_AMALGAMATION
1521915375
extern unsigned int sqlite3CoverageCounter;
1522015376
# endif
1522115377
# define testcase(X) if( X ){ sqlite3CoverageCounter += (unsigned)__LINE__; }
1522215378
#else
@@ -15798,10 +15954,17 @@
1579815954
*/
1579915955
#ifndef offsetof
1580015956
# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0))
1580115957
#endif
1580215958
15959
+/*
15960
+** sizeof64() is like sizeof(), but always returns a 64-bit value, even
15961
+** on 32-bit builds. This can help to avoid overflow by ensuring 64-bit
15962
+** arithmetic is used consistently in both 32-bit and 64-bit builds.
15963
+*/
15964
+#define sizeof64(X) ((sqlite3_int64)sizeof(X))
15965
+
1580315966
/*
1580415967
** Work around C99 "flex-array" syntax for pre-C99 compilers, so as
1580515968
** to avoid complaints from -fsanitize=strict-bounds.
1580615969
*/
1580715970
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
@@ -17159,11 +17322,11 @@
1715917322
SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
1716017323
#endif
1716117324
1716217325
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
1716317326
SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
17164
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
17327
+SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree*, Btree*);
1716517328
1716617329
SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
1716717330
1716817331
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
1716917332
** of the flags shown below.
@@ -17236,16 +17399,23 @@
1723617399
** The design of the _RANGE hint is aid b-tree implementations that try
1723717400
** to prefetch content from remote machines - to provide those
1723817401
** implementations with limits on what needs to be prefetched and thereby
1723917402
** reduce network bandwidth.
1724017403
**
17404
+** BTREE_HINT_TABLECURSOR (arguments: BtCursor*)
17405
+**
17406
+** This hint is invoked on a non-covering index cursor soon after it
17407
+** is opened. The only argument is a pointer to the table cursor used to
17408
+** obtain non-covered fields from the database.
17409
+**
1724117410
** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
1724217411
** standard SQLite. The other hints are provided for extensions that use
1724317412
** the SQLite parser and code generator but substitute their own storage
1724417413
** engine.
1724517414
*/
1724617415
#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
17416
+#define BTREE_HINT_TABLECURSOR 1 /* Table csr associated with this index csr */
1724717417
1724817418
/*
1724917419
** Values that may be OR'd together to form the argument to the
1725017420
** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
1725117421
**
@@ -17301,10 +17471,13 @@
1730117471
#endif
1730217472
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
1730317473
SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
1730417474
#ifdef SQLITE_ENABLE_CURSOR_HINTS
1730517475
SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...);
17476
+ #ifdef SQLITE_DEBUG
17477
+SQLITE_PRIVATE BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor*);
17478
+ #endif
1730617479
#endif
1730717480
1730817481
SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
1730917482
SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
1731017483
BtCursor*,
@@ -17547,12 +17720,10 @@
1754717720
int p3; /* The third parameter */
1754817721
union p4union { /* fourth parameter */
1754917722
int i; /* Integer value if p4type==P4_INT32 */
1755017723
void *p; /* Generic pointer */
1755117724
char *z; /* Pointer to data for string (char array) types */
17552
- i64 *pI64; /* Used when p4type is P4_INT64 */
17553
- double *pReal; /* Used when p4type is P4_REAL */
1755417725
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
1755517726
sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */
1755617727
CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
1755717728
Mem *pMem; /* Used when p4type is P4_MEM */
1755817729
VTable *pVtab; /* Used when p4type is P4_VTAB */
@@ -17603,10 +17774,23 @@
1760317774
signed char p1; /* First operand */
1760417775
signed char p2; /* Second parameter (often the jump destination) */
1760517776
signed char p3; /* Third parameter */
1760617777
};
1760717778
typedef struct VdbeOpList VdbeOpList;
17779
+
17780
+/*
17781
+** Combine two int32 values into a single int64. The least significant
17782
+** term comes first.
17783
+*/
17784
+#define INT32_TO_64(a,b) (i64)(((u64)(u32)(b)<<32)|(u32)(a))
17785
+
17786
+/*
17787
+** Return an int32 that is the lower or upper 32-bits of an int64.
17788
+*/
17789
+#define LOWER32(x) (int)(((u64)(x))&0xffffffff)
17790
+#define UPPER32(x) (int)(((u64)(x))>>32)
17791
+
1760817792
1760917793
/*
1761017794
** Allowed values of VdbeOp.p4type
1761117795
*/
1761217796
#define P4_NOTUSED 0 /* The P4 parameter is not used */
@@ -17623,16 +17807,14 @@
1762317807
#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
1762417808
#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
1762517809
#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
1762617810
#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
1762717811
#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
17628
-#define P4_REAL (-13) /* P4 is a 64-bit floating point value */
17629
-#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
17630
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
17631
-#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
17632
-#define P4_TABLEREF (-17) /* Like P4_TABLE, but reference counted */
17633
-#define P4_SUBRTNSIG (-18) /* P4 is a SubrtnSig pointer */
17812
+#define P4_INTARRAY (-13) /* P4 is a vector of 32-bit integers */
17813
+#define P4_FUNCCTX (-14) /* P4 is a pointer to an sqlite3_context object */
17814
+#define P4_TABLEREF (-15) /* Like P4_TABLE, but reference counted */
17815
+#define P4_SUBRTNSIG (-16) /* P4 is a SubrtnSig pointer */
1763417816
1763517817
/* Error message codes for OP_Halt */
17636