Fossil SCM

Bring in the latest SQLite upstream for beta testing.

drh 2025-11-18 18:15 trunk
Commit 4f7645916adf5c133ef9e4c83ca0d536d3e1802e91cd16b0109a3e8ddde23fbd
+5687 -3685
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1,23 +1,47 @@
1
-/* DO NOT EDIT!
2
-** This file is automatically generated by the script in the canonical
3
-** SQLite source tree at tool/mkshellc.tcl. That script combines source
4
-** code from various constituent source files of SQLite into this single
5
-** "shell.c" file used to implement the SQLite command-line shell.
6
-**
7
-** Most of the code found below comes from the "src/shell.c.in" file in
8
-** the canonical SQLite source tree. That main file contains "INCLUDE"
9
-** lines that specify other files in the canonical source tree that are
10
-** inserted to getnerate this complete program source file.
11
-**
12
-** The code from multiple files is combined into this single "shell.c"
13
-** source file to help make the command-line program easier to compile.
1
+/*
2
+** This is the amalgamated source code to the "sqlite3" or "sqlite3.exe"
3
+** command-line shell (CLI) for SQLite. This file is automatically
4
+** generated by the tool/mkshellc.tcl script from the following sources:
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/fileio.c
16
+** ext/misc/ieee754.c
17
+** ext/misc/memtrace.c
18
+** ext/misc/pcachetrace.c
19
+** ext/misc/regexp.c
20
+** ext/misc/series.c
21
+** ext/misc/sha1.c
22
+** ext/misc/shathree.c
23
+** ext/misc/sqlar.c
24
+** ext/misc/sqlite3_stdio.c
25
+** ext/misc/sqlite3_stdio.h
26
+** ext/misc/stmtrand.c
27
+** ext/misc/uint.c
28
+** ext/misc/vfstrace.c
29
+** ext/misc/windirent.h
30
+** ext/misc/zipfile.c
31
+** ext/qrf/qrf.c
32
+** ext/qrf/qrf.h
33
+** ext/recover/dbdata.c
34
+** ext/recover/sqlite3recover.c
35
+** ext/recover/sqlite3recover.h
36
+** src/shell.c.in
1437
**
1538
** To modify this program, get a copy of the canonical SQLite source tree,
16
-** edit the src/shell.c.in" and/or some of the other files that are included
17
-** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
39
+** edit the src/shell.c.in file and/or some of the other files that are
40
+** listed above, then rerun the rerun "make shell.c".
1841
*/
42
+/************************* Begin src/shell.c.in ******************/
1943
/*
2044
** 2001 September 15
2145
**
2246
** The author disclaims copyright to this source code. In place of
2347
** a legal notice, here is a blessing:
@@ -124,10 +148,11 @@
124148
typedef unsigned char u8;
125149
#include <ctype.h>
126150
#include <stdarg.h>
127151
#ifndef _WIN32
128152
# include <sys/time.h>
153
+# include <sys/ioctl.h>
129154
#endif
130155
131156
#if !defined(_WIN32) && !defined(WIN32)
132157
# include <signal.h>
133158
# if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
@@ -253,11 +278,11 @@
253278
/* string conversion routines only needed on Win32 */
254279
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
255280
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
256281
#endif
257282
258
-/************************* Begin ../ext/misc/sqlite3_stdio.h ******************/
283
+/************************* Begin ext/misc/sqlite3_stdio.h ******************/
259284
/*
260285
** 2024-09-24
261286
**
262287
** The author disclaims copyright to this source code. In place of
263288
** a legal notice, here is a blessing:
@@ -287,17 +312,19 @@
287312
#ifndef _SQLITE3_STDIO_H_
288313
#define _SQLITE3_STDIO_H_ 1
289314
#ifdef _WIN32
290315
/**** Definitions For Windows ****/
291316
#include <stdio.h>
317
+#include <stdarg.h>
292318
#include <windows.h>
293319
294320
FILE *sqlite3_fopen(const char *zFilename, const char *zMode);
295321
FILE *sqlite3_popen(const char *zCommand, const char *type);
296322
char *sqlite3_fgets(char *s, int size, FILE *stream);
297323
int sqlite3_fputs(const char *s, FILE *stream);
298324
int sqlite3_fprintf(FILE *stream, const char *format, ...);
325
+int sqlite3_vfprintf(FILE *stream, const char *format, va_list);
299326
void sqlite3_fsetmode(FILE *stream, int mode);
300327
301328
302329
#else
303330
/**** Definitions For All Other Platforms ****/
@@ -305,17 +332,18 @@
305332
#define sqlite3_fopen fopen
306333
#define sqlite3_popen popen
307334
#define sqlite3_fgets fgets
308335
#define sqlite3_fputs fputs
309336
#define sqlite3_fprintf fprintf
337
+#define sqlite3_vfprintf vfprintf
310338
#define sqlite3_fsetmode(F,X) /*no-op*/
311339
312340
#endif
313341
#endif /* _SQLITE3_STDIO_H_ */
314342
315
-/************************* End ../ext/misc/sqlite3_stdio.h ********************/
316
-/************************* Begin ../ext/misc/sqlite3_stdio.c ******************/
343
+/************************* End ext/misc/sqlite3_stdio.h ********************/
344
+/************************* Begin ext/misc/sqlite3_stdio.c ******************/
317345
/*
318346
** 2024-09-24
319347
**
320348
** The author disclaims copyright to this source code. In place of
321349
** a legal notice, here is a blessing:
@@ -572,11 +600,11 @@
572600
}
573601
}
574602
575603
576604
/*
577
-** Work-alike for fprintf() from the standard C library.
605
+** Work-alikes for fprintf() and vfprintf() from the standard C library.
578606
*/
579607
int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
580608
int rc;
581609
if( UseWtextForOutput(out) ){
582610
/* When writing to the command-prompt in Windows, it is necessary
@@ -599,10 +627,28 @@
599627
rc = vfprintf(out, zFormat, ap);
600628
va_end(ap);
601629
}
602630
return rc;
603631
}
632
+int sqlite3_vfprintf(FILE *out, const char *zFormat, va_list ap){
633
+ int rc;
634
+ if( UseWtextForOutput(out) ){
635
+ /* When writing to the command-prompt in Windows, it is necessary
636
+ ** to use _O_WTEXT input mode and write UTF-16 characters.
637
+ */
638
+ char *z;
639
+ z = sqlite3_vmprintf(zFormat, ap);
640
+ sqlite3_fputs(z, out);
641
+ rc = (int)strlen(z);
642
+ sqlite3_free(z);
643
+ }else{
644
+ /* Writing to a file or other destination, just write bytes without
645
+ ** any translation. */
646
+ rc = vfprintf(out, zFormat, ap);
647
+ }
648
+ return rc;
649
+}
604650
605651
/*
606652
** Set the mode for an output stream. mode argument is typically _O_BINARY or
607653
** _O_TEXT.
608654
*/
@@ -617,11 +663,2697 @@
617663
}
618664
}
619665
620666
#endif /* defined(_WIN32) */
621667
622
-/************************* End ../ext/misc/sqlite3_stdio.c ********************/
668
+/************************* End ext/misc/sqlite3_stdio.c ********************/
669
+/************************* Begin ext/qrf/qrf.h ******************/
670
+/*
671
+** 2025-10-20
672
+**
673
+** The author disclaims copyright to this source code. In place of
674
+** a legal notice, here is a blessing:
675
+**
676
+** May you do good and not evil.
677
+** May you find forgiveness for yourself and forgive others.
678
+** May you share freely, never taking more than you give.
679
+**
680
+*************************************************************************
681
+** Header file for the Result-Format or "resfmt" utility library for SQLite.
682
+** See the resfmt.md documentation for additional information.
683
+*/
684
+#ifndef SQLITE_QRF_H
685
+#define SQLITE_QRF_H
686
+#include <stdlib.h>
687
+/* #include "sqlite3.h" */
688
+
689
+/*
690
+** Specification used by clients to define the output format they want
691
+*/
692
+typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
693
+struct sqlite3_qrf_spec {
694
+ unsigned char iVersion; /* Version number of this structure */
695
+ unsigned char eStyle; /* Formatting style. "box", "csv", etc... */
696
+ unsigned char eEsc; /* How to escape control characters in text */
697
+ unsigned char eText; /* Quoting style for text */
698
+ unsigned char eTitle; /* Quating style for the text of column names */
699
+ unsigned char eBlob; /* Quoting style for BLOBs */
700
+ unsigned char bTitles; /* True to show column names */
701
+ unsigned char bWordWrap; /* Try to wrap on word boundaries */
702
+ unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
703
+ unsigned char bTextNull; /* Apply eText encoding to zNull[] */
704
+ unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
705
+ unsigned char eTitleAlign; /* Alignment for column headers */
706
+ short int nWrap; /* Wrap columns wider than this */
707
+ short int nScreenWidth; /* Maximum overall table width */
708
+ short int nLineLimit; /* Maximum number of lines for any row */
709
+ int nCharLimit; /* Maximum number of characters in a cell */
710
+ int nWidth; /* Number of entries in aWidth[] */
711
+ int nAlign; /* Number of entries in aAlignment[] */
712
+ short int *aWidth; /* Column widths */
713
+ unsigned char *aAlign; /* Column alignments */
714
+ char *zColumnSep; /* Alternative column separator */
715
+ char *zRowSep; /* Alternative row separator */
716
+ char *zTableName; /* Output table name */
717
+ char *zNull; /* Rendering of NULL */
718
+ char *(*xRender)(void*,sqlite3_value*); /* Render a value */
719
+ int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
720
+ void *pRenderArg; /* First argument to the xRender callback */
721
+ void *pWriteArg; /* First argument to the xWrite callback */
722
+ char **pzOutput; /* Storage location for output string */
723
+ /* Additional fields may be added in the future */
724
+};
725
+
726
+/*
727
+** Interfaces
728
+*/
729
+int sqlite3_format_query_result(
730
+ sqlite3_stmt *pStmt, /* SQL statement to run */
731
+ const sqlite3_qrf_spec *pSpec, /* Result format specification */
732
+ char **pzErr /* OUT: Write error message here */
733
+);
734
+
735
+/*
736
+** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
737
+** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
738
+*/
739
+#define QRF_MAX_WIDTH 10000
740
+#define QRF_MIN_WIDTH 0
741
+
742
+/*
743
+** Output styles:
744
+*/
745
+#define QRF_STYLE_Auto 0 /* Choose a style automatically */
746
+#define QRF_STYLE_Box 1 /* Unicode box-drawing characters */
747
+#define QRF_STYLE_Column 2 /* One record per line in neat columns */
748
+#define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
749
+#define QRF_STYLE_Csv 4 /* Comma-separated-value */
750
+#define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
751
+#define QRF_STYLE_Explain 6 /* EXPLAIN output */
752
+#define QRF_STYLE_Html 7 /* Generate an XHTML table */
753
+#define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
754
+#define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
755
+#define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
756
+#define QRF_STYLE_Line 11 /* One column per line. */
757
+#define QRF_STYLE_List 12 /* One record per line with a separator */
758
+#define QRF_STYLE_Markdown 13 /* Markdown formatting */
759
+#define QRF_STYLE_Off 14 /* No query output shown */
760
+#define QRF_STYLE_Quote 15 /* SQL-quoted, comma-separated */
761
+#define QRF_STYLE_Stats 16 /* EQP-like output but with performance stats */
762
+#define QRF_STYLE_StatsEst 17 /* EQP-like output with planner estimates */
763
+#define QRF_STYLE_StatsVm 18 /* EXPLAIN-like output with performance stats */
764
+#define QRF_STYLE_Table 19 /* MySQL-style table formatting */
765
+
766
+/*
767
+** Quoting styles for text.
768
+** Allowed values for sqlite3_qrf_spec.eText
769
+*/
770
+#define QRF_TEXT_Auto 0 /* Choose text encoding automatically */
771
+#define QRF_TEXT_Plain 1 /* Literal text */
772
+#define QRF_TEXT_Sql 2 /* Quote as an SQL literal */
773
+#define QRF_TEXT_Csv 3 /* CSV-style quoting */
774
+#define QRF_TEXT_Html 4 /* HTML-style quoting */
775
+#define QRF_TEXT_Tcl 5 /* C/Tcl quoting */
776
+#define QRF_TEXT_Json 6 /* JSON quoting */
777
+
778
+/*
779
+** Quoting styles for BLOBs
780
+** Allowed values for sqlite3_qrf_spec.eBlob
781
+*/
782
+#define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eText */
783
+#define QRF_BLOB_Text 1 /* Display content exactly as it is */
784
+#define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
785
+#define QRF_BLOB_Hex 3 /* Hexadecimal representation */
786
+#define QRF_BLOB_Tcl 4 /* "\000" notation */
787
+#define QRF_BLOB_Json 5 /* A JSON string */
788
+
789
+/*
790
+** Control-character escape modes.
791
+** Allowed values for sqlite3_qrf_spec.eEsc
792
+*/
793
+#define QRF_ESC_Auto 0 /* Choose the ctrl-char escape automatically */
794
+#define QRF_ESC_Off 1 /* Do not escape control characters */
795
+#define QRF_ESC_Ascii 2 /* Unix-style escapes. Ex: U+0007 shows ^G */
796
+#define QRF_ESC_Symbol 3 /* Unicode escapes. Ex: U+0007 shows U+2407 */
797
+
798
+/*
799
+** Allowed values for "boolean" fields, such as "bColumnNames", "bWordWrap",
800
+** and "bTextJsonb". There is an extra "auto" variants so these are actually
801
+** tri-state settings, not booleans.
802
+*/
803
+#define QRF_SW_Auto 0 /* Let QRF choose the best value */
804
+#define QRF_SW_Off 1 /* This setting is forced off */
805
+#define QRF_SW_On 2 /* This setting is forced on */
806
+#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
807
+#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
808
+#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
809
+
810
+/*
811
+** Possible alignment values alignment settings
812
+**
813
+** Horizontal Vertial
814
+** ---------- -------- */
815
+#define QRF_ALIGN_Auto 0 /* auto auto */
816
+#define QRF_ALIGN_Left 1 /* left auto */
817
+#define QRF_ALIGN_Center 2 /* center auto */
818
+#define QRF_ALIGN_Right 3 /* right auto */
819
+#define QRF_ALIGN_Top 4 /* auto top */
820
+#define QRF_ALIGN_NW 5 /* left top */
821
+#define QRF_ALIGN_N 6 /* center top */
822
+#define QRF_ALIGN_NE 7 /* right top */
823
+#define QRF_ALIGN_Middle 8 /* auto middle */
824
+#define QRF_ALIGN_W 9 /* left middle */
825
+#define QRF_ALIGN_C 10 /* center middle */
826
+#define QRF_ALIGN_E 11 /* right middle */
827
+#define QRF_ALIGN_Bottom 12 /* auto bottom */
828
+#define QRF_ALIGN_SW 13 /* left bottom */
829
+#define QRF_ALIGN_S 14 /* center bottom */
830
+#define QRF_ALIGN_SE 15 /* right bottom */
831
+#define QRF_ALIGN_HMASK 3 /* Horizontal alignment mask */
832
+#define QRF_ALIGN_VMASK 12 /* Vertical alignment mask */
833
+
834
+/*
835
+** Auxiliary routines contined within this module that might be useful
836
+** in other contexts, and which are therefore exported.
837
+*/
838
+/*
839
+** Return an estimate of the width, in columns, for the single Unicode
840
+** character c. For normal characters, the answer is always 1. But the
841
+** estimate might be 0 or 2 for zero-width and double-width characters.
842
+**
843
+** Different display devices display unicode using different widths. So
844
+** it is impossible to know that true display width with 100% accuracy.
845
+** Inaccuracies in the width estimates might cause columns to be misaligned.
846
+** Unfortunately, there is nothing we can do about that.
847
+*/
848
+int sqlite3_qrf_wcwidth(int c);
849
+
850
+
851
+
852
+
853
+#endif /* !defined(SQLITE_QRF_H) */
854
+
855
+/************************* End ext/qrf/qrf.h ********************/
856
+/************************* Begin ext/qrf/qrf.c ******************/
857
+/*
858
+** 2025-10-20
859
+**
860
+** The author disclaims copyright to this source code. In place of
861
+** a legal notice, here is a blessing:
862
+**
863
+** May you do good and not evil.
864
+** May you find forgiveness for yourself and forgive others.
865
+** May you share freely, never taking more than you give.
866
+**
867
+*************************************************************************
868
+** Implementation of the Result-Format or "qrf" utility library for SQLite.
869
+** See the qrf.md documentation for additional information.
870
+*/
871
+#ifndef SQLITE_QRF_H
872
+#include "qrf.h"
873
+#endif
874
+#include <string.h>
875
+#include <assert.h>
876
+
877
+/* typedef sqlite3_int64 i64; */
878
+
879
+/* A single line in the EQP output */
880
+typedef struct qrfEQPGraphRow qrfEQPGraphRow;
881
+struct qrfEQPGraphRow {
882
+ int iEqpId; /* ID for this row */
883
+ int iParentId; /* ID of the parent row */
884
+ qrfEQPGraphRow *pNext; /* Next row in sequence */
885
+ char zText[1]; /* Text to display for this row */
886
+};
887
+
888
+/* All EQP output is collected into an instance of the following */
889
+typedef struct qrfEQPGraph qrfEQPGraph;
890
+struct qrfEQPGraph {
891
+ qrfEQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
892
+ qrfEQPGraphRow *pLast; /* Last element of the pRow list */
893
+ char zPrefix[100]; /* Graph prefix */
894
+};
895
+
896
+/*
897
+** Private state information. Subject to change from one release to the
898
+** next.
899
+*/
900
+typedef struct Qrf Qrf;
901
+struct Qrf {
902
+ sqlite3_stmt *pStmt; /* The statement whose output is to be rendered */
903
+ sqlite3 *db; /* The corresponding database connection */
904
+ sqlite3_stmt *pJTrans; /* JSONB to JSON translator statement */
905
+ char **pzErr; /* Write error message here, if not NULL */
906
+ sqlite3_str *pOut; /* Accumulated output */
907
+ int iErr; /* Error code */
908
+ int nCol; /* Number of output columns */
909
+ int expMode; /* Original sqlite3_stmt_isexplain() plus 1 */
910
+ int mxWidth; /* Screen width */
911
+ int mxHeight; /* nLineLimit */
912
+ union {
913
+ struct { /* Content for QRF_STYLE_Line */
914
+ int mxColWth; /* Maximum display width of any column */
915
+ const char **azCol; /* Names of output columns (MODE_Line) */
916
+ } sLine;
917
+ qrfEQPGraph *pGraph; /* EQP graph (Eqp, Stats, and StatsEst) */
918
+ struct { /* Content for QRF_STYLE_Explain */
919
+ int nIndent; /* Slots allocated for aiIndent */
920
+ int iIndent; /* Current slot */
921
+ int *aiIndent; /* Indentation for each opcode */
922
+ } sExpln;
923
+ } u;
924
+ sqlite3_int64 nRow; /* Number of rows handled so far */
925
+ int *actualWidth; /* Actual width of each column */
926
+ sqlite3_qrf_spec spec; /* Copy of the original spec */
927
+};
928
+
929
+/*
930
+** Data for substitute ctype.h functions. Used for x-platform
931
+** consistency and so that '_' is counted as an alphabetic
932
+** character.
933
+**
934
+** 0x01 - space
935
+** 0x02 - digit
936
+** 0x04 - alphabetic, including '_'
937
+*/
938
+static const char qrfCType[] = {
939
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
940
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
942
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
943
+ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
944
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4,
945
+ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
946
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
947
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
952
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
953
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
954
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
955
+};
956
+#define qrfSpace(x) ((qrfCType[(unsigned char)x]&1)!=0)
957
+#define qrfDigit(x) ((qrfCType[(unsigned char)x]&2)!=0)
958
+#define qrfAlpha(x) ((qrfCType[(unsigned char)x]&4)!=0)
959
+#define qrfAlnum(x) ((qrfCType[(unsigned char)x]&6)!=0)
960
+
961
+/*
962
+** Set an error code and error message.
963
+*/
964
+static void qrfError(
965
+ Qrf *p, /* Query result state */
966
+ int iCode, /* Error code */
967
+ const char *zFormat, /* Message format (or NULL) */
968
+ ...
969
+){
970
+ p->iErr = iCode;
971
+ if( p->pzErr!=0 ){
972
+ sqlite3_free(*p->pzErr);
973
+ *p->pzErr = 0;
974
+ if( zFormat ){
975
+ va_list ap;
976
+ va_start(ap, zFormat);
977
+ *p->pzErr = sqlite3_vmprintf(zFormat, ap);
978
+ va_end(ap);
979
+ }
980
+ }
981
+}
982
+
983
+/*
984
+** Out-of-memory error.
985
+*/
986
+static void qrfOom(Qrf *p){
987
+ qrfError(p, SQLITE_NOMEM, "out of memory");
988
+}
989
+
990
+
991
+
992
+/*
993
+** Add a new entry to the EXPLAIN QUERY PLAN data
994
+*/
995
+static void qrfEqpAppend(Qrf *p, int iEqpId, int p2, const char *zText){
996
+ qrfEQPGraphRow *pNew;
997
+ sqlite3_int64 nText;
998
+ if( zText==0 ) return;
999
+ if( p->u.pGraph==0 ){
1000
+ p->u.pGraph = sqlite3_malloc64( sizeof(qrfEQPGraph) );
1001
+ if( p->u.pGraph==0 ){
1002
+ qrfOom(p);
1003
+ return;
1004
+ }
1005
+ memset(p->u.pGraph, 0, sizeof(qrfEQPGraph) );
1006
+ }
1007
+ nText = strlen(zText);
1008
+ pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
1009
+ if( pNew==0 ){
1010
+ qrfOom(p);
1011
+ return;
1012
+ }
1013
+ pNew->iEqpId = iEqpId;
1014
+ pNew->iParentId = p2;
1015
+ memcpy(pNew->zText, zText, nText+1);
1016
+ pNew->pNext = 0;
1017
+ if( p->u.pGraph->pLast ){
1018
+ p->u.pGraph->pLast->pNext = pNew;
1019
+ }else{
1020
+ p->u.pGraph->pRow = pNew;
1021
+ }
1022
+ p->u.pGraph->pLast = pNew;
1023
+}
1024
+
1025
+/*
1026
+** Free and reset the EXPLAIN QUERY PLAN data that has been collected
1027
+** in p->u.pGraph.
1028
+*/
1029
+static void qrfEqpReset(Qrf *p){
1030
+ qrfEQPGraphRow *pRow, *pNext;
1031
+ if( p->u.pGraph ){
1032
+ for(pRow = p->u.pGraph->pRow; pRow; pRow = pNext){
1033
+ pNext = pRow->pNext;
1034
+ sqlite3_free(pRow);
1035
+ }
1036
+ sqlite3_free(p->u.pGraph);
1037
+ p->u.pGraph = 0;
1038
+ }
1039
+}
1040
+
1041
+/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
1042
+** pOld, or return the first such line if pOld is NULL
1043
+*/
1044
+static qrfEQPGraphRow *qrfEqpNextRow(Qrf *p, int iEqpId, qrfEQPGraphRow *pOld){
1045
+ qrfEQPGraphRow *pRow = pOld ? pOld->pNext : p->u.pGraph->pRow;
1046
+ while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
1047
+ return pRow;
1048
+}
1049
+
1050
+/* Render a single level of the graph that has iEqpId as its parent. Called
1051
+** recursively to render sublevels.
1052
+*/
1053
+static void qrfEqpRenderLevel(Qrf *p, int iEqpId){
1054
+ qrfEQPGraphRow *pRow, *pNext;
1055
+ i64 n = strlen(p->u.pGraph->zPrefix);
1056
+ char *z;
1057
+ for(pRow = qrfEqpNextRow(p, iEqpId, 0); pRow; pRow = pNext){
1058
+ pNext = qrfEqpNextRow(p, iEqpId, pRow);
1059
+ z = pRow->zText;
1060
+ sqlite3_str_appendf(p->pOut, "%s%s%s\n", p->u.pGraph->zPrefix,
1061
+ pNext ? "|--" : "`--", z);
1062
+ if( n<(i64)sizeof(p->u.pGraph->zPrefix)-7 ){
1063
+ memcpy(&p->u.pGraph->zPrefix[n], pNext ? "| " : " ", 4);
1064
+ qrfEqpRenderLevel(p, pRow->iEqpId);
1065
+ p->u.pGraph->zPrefix[n] = 0;
1066
+ }
1067
+ }
1068
+}
1069
+
1070
+/*
1071
+** Display and reset the EXPLAIN QUERY PLAN data
1072
+*/
1073
+static void qrfEqpRender(Qrf *p, i64 nCycle){
1074
+ qrfEQPGraphRow *pRow;
1075
+ if( p->u.pGraph!=0 && (pRow = p->u.pGraph->pRow)!=0 ){
1076
+ if( pRow->zText[0]=='-' ){
1077
+ if( pRow->pNext==0 ){
1078
+ qrfEqpReset(p);
1079
+ return;
1080
+ }
1081
+ sqlite3_str_appendf(p->pOut, "%s\n", pRow->zText+3);
1082
+ p->u.pGraph->pRow = pRow->pNext;
1083
+ sqlite3_free(pRow);
1084
+ }else if( nCycle>0 ){
1085
+ sqlite3_str_appendf(p->pOut, "QUERY PLAN (cycles=%lld [100%%])\n",nCycle);
1086
+ }else{
1087
+ sqlite3_str_appendall(p->pOut, "QUERY PLAN\n");
1088
+ }
1089
+ p->u.pGraph->zPrefix[0] = 0;
1090
+ qrfEqpRenderLevel(p, 0);
1091
+ qrfEqpReset(p);
1092
+ }
1093
+}
1094
+
1095
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
1096
+/*
1097
+** Helper function for qrfExpStats().
1098
+**
1099
+*/
1100
+static int qrfStatsHeight(sqlite3_stmt *p, int iEntry){
1101
+ int iPid = 0;
1102
+ int ret = 1;
1103
+ sqlite3_stmt_scanstatus_v2(p, iEntry,
1104
+ SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
1105
+ );
1106
+ while( iPid!=0 ){
1107
+ int ii;
1108
+ for(ii=0; 1; ii++){
1109
+ int iId;
1110
+ int res;
1111
+ res = sqlite3_stmt_scanstatus_v2(p, ii,
1112
+ SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
1113
+ );
1114
+ if( res ) break;
1115
+ if( iId==iPid ){
1116
+ sqlite3_stmt_scanstatus_v2(p, ii,
1117
+ SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
1118
+ );
1119
+ }
1120
+ }
1121
+ ret++;
1122
+ }
1123
+ return ret;
1124
+}
1125
+#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
1126
+
1127
+
1128
+/*
1129
+** Generate ".scanstatus est" style of EQP output.
1130
+*/
1131
+static void qrfEqpStats(Qrf *p){
1132
+#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1133
+ qrfError(p, SQLITE_ERROR, "not available in this build");
1134
+#else
1135
+ static const int f = SQLITE_SCANSTAT_COMPLEX;
1136
+ sqlite3_stmt *pS = p->pStmt;
1137
+ int i = 0;
1138
+ i64 nTotal = 0;
1139
+ int nWidth = 0;
1140
+ sqlite3_str *pLine = sqlite3_str_new(p->db);
1141
+ sqlite3_str *pStats = sqlite3_str_new(p->db);
1142
+ qrfEqpReset(p);
1143
+
1144
+ for(i=0; 1; i++){
1145
+ const char *z = 0;
1146
+ int n = 0;
1147
+ if( sqlite3_stmt_scanstatus_v2(pS,i,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
1148
+ break;
1149
+ }
1150
+ n = (int)strlen(z) + qrfStatsHeight(pS,i)*3;
1151
+ if( n>nWidth ) nWidth = n;
1152
+ }
1153
+ nWidth += 4;
1154
+
1155
+ sqlite3_stmt_scanstatus_v2(pS,-1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal);
1156
+ for(i=0; 1; i++){
1157
+ i64 nLoop = 0;
1158
+ i64 nRow = 0;
1159
+ i64 nCycle = 0;
1160
+ int iId = 0;
1161
+ int iPid = 0;
1162
+ const char *zo = 0;
1163
+ const char *zName = 0;
1164
+ double rEst = 0.0;
1165
+
1166
+ if( sqlite3_stmt_scanstatus_v2(pS,i,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){
1167
+ break;
1168
+ }
1169
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_EST,f,(void*)&rEst);
1170
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop);
1171
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow);
1172
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle);
1173
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId);
1174
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid);
1175
+ sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NAME,f,(void*)&zName);
1176
+
1177
+ if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
1178
+ const char *zSp = "";
1179
+ double rpl;
1180
+ sqlite3_str_reset(pStats);
1181
+ if( nCycle>=0 && nTotal>0 ){
1182
+ sqlite3_str_appendf(pStats, "cycles=%lld [%d%%]",
1183
+ nCycle, ((nCycle*100)+nTotal/2) / nTotal
1184
+ );
1185
+ zSp = " ";
1186
+ }
1187
+ if( nLoop>=0 ){
1188
+ sqlite3_str_appendf(pStats, "%sloops=%lld", zSp, nLoop);
1189
+ zSp = " ";
1190
+ }
1191
+ if( nRow>=0 ){
1192
+ sqlite3_str_appendf(pStats, "%srows=%lld", zSp, nRow);
1193
+ zSp = " ";
1194
+ }
1195
+
1196
+ if( p->spec.eStyle==QRF_STYLE_StatsEst ){
1197
+ rpl = (double)nRow / (double)nLoop;
1198
+ sqlite3_str_appendf(pStats, "%srpl=%.1f est=%.1f", zSp, rpl, rEst);
1199
+ }
1200
+
1201
+ sqlite3_str_appendf(pLine,
1202
+ "% *s (%s)", -1*(nWidth-qrfStatsHeight(pS,i)*3), zo,
1203
+ sqlite3_str_value(pStats)
1204
+ );
1205
+ sqlite3_str_reset(pStats);
1206
+ qrfEqpAppend(p, iId, iPid, sqlite3_str_value(pLine));
1207
+ sqlite3_str_reset(pLine);
1208
+ }else{
1209
+ qrfEqpAppend(p, iId, iPid, zo);
1210
+ }
1211
+ }
1212
+ sqlite3_free(sqlite3_str_finish(pLine));
1213
+ sqlite3_free(sqlite3_str_finish(pStats));
1214
+#endif
1215
+}
1216
+
1217
+
1218
+/*
1219
+** Reset the prepared statement.
1220
+*/
1221
+static void qrfResetStmt(Qrf *p){
1222
+ int rc = sqlite3_reset(p->pStmt);
1223
+ if( rc!=SQLITE_OK && p->iErr==SQLITE_OK ){
1224
+ qrfError(p, rc, "%s", sqlite3_errmsg(p->db));
1225
+ }
1226
+}
1227
+
1228
+/*
1229
+** If xWrite is defined, send all content of pOut to xWrite and
1230
+** reset pOut.
1231
+*/
1232
+static void qrfWrite(Qrf *p){
1233
+ int n;
1234
+ if( p->spec.xWrite && (n = sqlite3_str_length(p->pOut))>0 ){
1235
+ int rc = p->spec.xWrite(p->spec.pWriteArg,
1236
+ sqlite3_str_value(p->pOut),
1237
+ (sqlite3_int64)n);
1238
+ sqlite3_str_reset(p->pOut);
1239
+ if( rc ){
1240
+ qrfError(p, rc, "Failed to write %d bytes of output", n);
1241
+ }
1242
+ }
1243
+}
1244
+
1245
+/* Lookup table to estimate the number of columns consumed by a Unicode
1246
+** character.
1247
+*/
1248
+static const struct {
1249
+ unsigned char w; /* Width of the character in columns */
1250
+ int iFirst; /* First character in a span having this width */
1251
+} aQrfUWidth[] = {
1252
+ /* {1, 0x00000}, */
1253
+ {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488},
1254
+ {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0},
1255
+ {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7},
1256
+ {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616},
1257
+ {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6},
1258
+ {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee},
1259
+ {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730},
1260
+ {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4},
1261
+ {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941},
1262
+ {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955},
1263
+ {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc},
1264
+ {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce},
1265
+ {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c},
1266
+ {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49},
1267
+ {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81},
1268
+ {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6},
1269
+ {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2},
1270
+ {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d},
1271
+ {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d},
1272
+ {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83},
1273
+ {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e},
1274
+ {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e},
1275
+ {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf},
1276
+ {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce},
1277
+ {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d},
1278
+ {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5},
1279
+ {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34},
1280
+ {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2},
1281
+ {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8},
1282
+ {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36},
1283
+ {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71},
1284
+ {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88},
1285
+ {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6},
1286
+ {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033},
1287
+ {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058},
1288
+ {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f},
1289
+ {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735},
1290
+ {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4},
1291
+ {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7},
1292
+ {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b},
1293
+ {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923},
1294
+ {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939},
1295
+ {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04},
1296
+ {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c},
1297
+ {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74},
1298
+ {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b},
1299
+ {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064},
1300
+ {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329},
1301
+ {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f},
1302
+ {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806},
1303
+ {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827},
1304
+ {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e},
1305
+ {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20},
1306
+ {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00},
1307
+ {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc},
1308
+ {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c},
1309
+ {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40},
1310
+ {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185},
1311
+ {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245},
1312
+ {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001},
1313
+ {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0}
1314
+};
1315
+
1316
+/*
1317
+** Return an estimate of the width, in columns, for the single Unicode
1318
+** character c. For normal characters, the answer is always 1. But the
1319
+** estimate might be 0 or 2 for zero-width and double-width characters.
1320
+**
1321
+** Different display devices display unicode using different widths. So
1322
+** it is impossible to know that true display width with 100% accuracy.
1323
+** Inaccuracies in the width estimates might cause columns to be misaligned.
1324
+** Unfortunately, there is nothing we can do about that.
1325
+*/
1326
+int sqlite3_qrf_wcwidth(int c){
1327
+ int iFirst, iLast;
1328
+
1329
+ /* Fast path for common characters */
1330
+ if( c<=0x300 ) return 1;
1331
+
1332
+ /* The general case */
1333
+ iFirst = 0;
1334
+ iLast = sizeof(aQrfUWidth)/sizeof(aQrfUWidth[0]) - 1;
1335
+ while( iFirst<iLast-1 ){
1336
+ int iMid = (iFirst+iLast)/2;
1337
+ int cMid = aQrfUWidth[iMid].iFirst;
1338
+ if( cMid < c ){
1339
+ iFirst = iMid;
1340
+ }else if( cMid > c ){
1341
+ iLast = iMid - 1;
1342
+ }else{
1343
+ return aQrfUWidth[iMid].w;
1344
+ }
1345
+ }
1346
+ if( aQrfUWidth[iLast].iFirst > c ) return aQrfUWidth[iFirst].w;
1347
+ return aQrfUWidth[iLast].w;
1348
+}
1349
+
1350
+/*
1351
+** Compute the value and length of a multi-byte UTF-8 character that
1352
+** begins at z[0]. Return the length. Write the Unicode value into *pU.
1353
+**
1354
+** This routine only works for *multi-byte* UTF-8 characters. It does
1355
+** not attempt to detect illegal characters.
1356
+*/
1357
+int sqlite3_qrf_decode_utf8(const unsigned char *z, int *pU){
1358
+ if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){
1359
+ *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f);
1360
+ return 2;
1361
+ }
1362
+ if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){
1363
+ *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f);
1364
+ return 3;
1365
+ }
1366
+ if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1367
+ && (z[3] & 0xc0)==0x80
1368
+ ){
1369
+ *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1370
+ | (z[3] & 0x3f);
1371
+ return 4;
1372
+ }
1373
+ *pU = 0;
1374
+ return 1;
1375
+}
1376
+
1377
+/*
1378
+** Check to see if z[] is a valid VT100 escape. If it is, then
1379
+** return the number of bytes in the escape sequence. Return 0 if
1380
+** z[] is not a VT100 escape.
1381
+**
1382
+** This routine assumes that z[0] is \033 (ESC).
1383
+*/
1384
+static int qrfIsVt100(const unsigned char *z){
1385
+ int i;
1386
+ if( z[1]!='[' ) return 0;
1387
+ i = 2;
1388
+ while( z[i]>=0x30 && z[i]<=0x3f ){ i++; }
1389
+ while( z[i]>=0x20 && z[i]<=0x2f ){ i++; }
1390
+ if( z[i]<0x40 || z[i]>0x7e ) return 0;
1391
+ return i+1;
1392
+}
1393
+
1394
+/*
1395
+** Return the length of a string in display characters.
1396
+** Multibyte UTF8 characters count as a single character
1397
+** for single-width characters, or as two characters for
1398
+** double-width characters.
1399
+*/
1400
+static int qrfDisplayLength(const char *zIn){
1401
+ const unsigned char *z = (const unsigned char*)zIn;
1402
+ int n = 0;
1403
+ while( *z ){
1404
+ if( z[0]<' ' ){
1405
+ int k;
1406
+ if( z[0]=='\033' && (k = qrfIsVt100(z))>0 ){
1407
+ z += k;
1408
+ }else{
1409
+ z++;
1410
+ }
1411
+ }else if( (0x80&z[0])==0 ){
1412
+ n++;
1413
+ z++;
1414
+ }else{
1415
+ int u = 0;
1416
+ int len = sqlite3_qrf_decode_utf8(z, &u);
1417
+ z += len;
1418
+ n += sqlite3_qrf_wcwidth(u);
1419
+ }
1420
+ }
1421
+ return n;
1422
+}
1423
+
1424
+/*
1425
+** Return the display width of the longest line of text
1426
+** in the (possibly) multi-line input string zIn[0..nByte].
1427
+** zIn[] is not necessarily zero-terminated. Take
1428
+** into account tab characters, zero- and double-width
1429
+** characters, CR and NL, and VT100 escape codes.
1430
+**
1431
+** Write the number of newlines into *pnNL. So, *pnNL will
1432
+** return 0 if everything fits on one line, or positive it
1433
+** it will need to be split.
1434
+*/
1435
+static int qrfDisplayWidth(const char *zIn, sqlite3_int64 nByte, int *pnNL){
1436
+ const unsigned char *z = (const unsigned char*)zIn;
1437
+ const unsigned char *zEnd = &z[nByte];
1438
+ int mx = 0;
1439
+ int n = 0;
1440
+ int nNL = 0;
1441
+ while( z<zEnd ){
1442
+ if( z[0]<' ' ){
1443
+ int k;
1444
+ if( z[0]=='\033' && (k = qrfIsVt100(z))>0 ){
1445
+ z += k;
1446
+ }else{
1447
+ if( z[0]=='\t' ){
1448
+ n = (n+8)&~7;
1449
+ }else if( z[0]=='\n' || z[0]=='\r' ){
1450
+ nNL++;
1451
+ if( n>mx ) mx = n;
1452
+ n = 0;
1453
+ }
1454
+ z++;
1455
+ }
1456
+ }else if( (0x80&z[0])==0 ){
1457
+ n++;
1458
+ z++;
1459
+ }else{
1460
+ int u = 0;
1461
+ int len = sqlite3_qrf_decode_utf8(z, &u);
1462
+ z += len;
1463
+ n += sqlite3_qrf_wcwidth(u);
1464
+ }
1465
+ }
1466
+ if( mx>n ) n = mx;
1467
+ if( pnNL ) *pnNL = nNL;
1468
+ return n;
1469
+}
1470
+
1471
+/*
1472
+** Escape the input string if it is needed and in accordance with
1473
+** eEsc, which is either QRF_ESC_Ascii or QRF_ESC_Symbol.
1474
+**
1475
+** Escaping is needed if the string contains any control characters
1476
+** other than \t, \n, and \r\n
1477
+**
1478
+** If no escaping is needed (the common case) then set *ppOut to NULL
1479
+** and return 0. If escaping is needed, write the escaped string into
1480
+** memory obtained from sqlite3_malloc64() and make *ppOut point to that
1481
+** memory and return 0. If an error occurs, return non-zero.
1482
+**
1483
+** The caller is responsible for freeing *ppFree if it is non-NULL in order
1484
+** to reclaim memory.
1485
+*/
1486
+static void qrfEscape(
1487
+ int eEsc, /* QRF_ESC_Ascii or QRF_ESC_Symbol */
1488
+ sqlite3_str *pStr, /* String to be escaped */
1489
+ int iStart /* Begin escapding on this byte of pStr */
1490
+){
1491
+ sqlite3_int64 i, j; /* Loop counters */
1492
+ sqlite3_int64 sz; /* Size of the string prior to escaping */
1493
+ sqlite3_int64 nCtrl = 0;/* Number of control characters to escape */
1494
+ unsigned char *zIn; /* Text to be escaped */
1495
+ unsigned char c; /* A single character of the text */
1496
+ unsigned char *zOut; /* Where to write the results */
1497
+
1498
+ /* Find the text to be escaped */
1499
+ zIn = (unsigned char*)sqlite3_str_value(pStr);
1500
+ if( zIn==0 ) return;
1501
+ zIn += iStart;
1502
+
1503
+ /* Count the control characters */
1504
+ for(i=0; (c = zIn[i])!=0; i++){
1505
+ if( c<=0x1f
1506
+ && c!='\t'
1507
+ && c!='\n'
1508
+ && (c!='\r' || zIn[i+1]!='\n')
1509
+ ){
1510
+ nCtrl++;
1511
+ }
1512
+ }
1513
+ if( nCtrl==0 ) return; /* Early out if no control characters */
1514
+
1515
+ /* Make space to hold the escapes. Copy the original text to the end
1516
+ ** of the available space. */
1517
+ sz = sqlite3_str_length(pStr) - iStart;
1518
+ if( eEsc==QRF_ESC_Symbol ) nCtrl *= 2;
1519
+ sqlite3_str_appendchar(pStr, nCtrl, ' ');
1520
+ zOut = (unsigned char*)sqlite3_str_value(pStr);
1521
+ if( zOut==0 ) return;
1522
+ zOut += iStart;
1523
+ zIn = zOut + nCtrl;
1524
+ memmove(zIn,zOut,sz);
1525
+
1526
+ /* Convert the control characters */
1527
+ for(i=j=0; (c = zIn[i])!=0; i++){
1528
+ if( c>0x1f
1529
+ || c=='\t'
1530
+ || c=='\n'
1531
+ || (c=='\r' && zIn[i+1]=='\n')
1532
+ ){
1533
+ continue;
1534
+ }
1535
+ if( i>0 ){
1536
+ memmove(&zOut[j], zIn, i);
1537
+ j += i;
1538
+ }
1539
+ zIn += i+1;
1540
+ i = -1;
1541
+ if( eEsc==QRF_ESC_Symbol ){
1542
+ zOut[j++] = 0xe2;
1543
+ zOut[j++] = 0x90;
1544
+ zOut[j++] = 0x80+c;
1545
+ }else{
1546
+ zOut[j++] = '^';
1547
+ zOut[j++] = 0x40+c;
1548
+ }
1549
+ }
1550
+}
1551
+
1552
+/*
1553
+** If a field contains any character identified by a 1 in the following
1554
+** array, then the string must be quoted for CSV.
1555
+*/
1556
+static const char qrfCsvQuote[] = {
1557
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1558
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1559
+ 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1560
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1561
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1562
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1563
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1564
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1565
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1566
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1567
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1568
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1569
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1570
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1571
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1572
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1573
+};
1574
+
1575
+/*
1576
+** Encode text appropriately and append it to pOut.
1577
+*/
1578
+static void qrfEncodeText(Qrf *p, sqlite3_str *pOut, const char *zTxt){
1579
+ int iStart = sqlite3_str_length(pOut);
1580
+ switch( p->spec.eText ){
1581
+ case QRF_TEXT_Sql: {
1582
+ if( p->spec.eEsc==QRF_ESC_Off ){
1583
+ sqlite3_str_appendf(pOut, "%Q", zTxt);
1584
+ }else{
1585
+ sqlite3_str_appendf(pOut, "%#Q", zTxt);
1586
+ }
1587
+ break;
1588
+ }
1589
+ case QRF_TEXT_Csv: {
1590
+ unsigned int i;
1591
+ for(i=0; zTxt[i]; i++){
1592
+ if( qrfCsvQuote[((const unsigned char*)zTxt)[i]] ){
1593
+ i = 0;
1594
+ break;
1595
+ }
1596
+ }
1597
+ if( i==0 || strstr(zTxt, p->spec.zColumnSep)!=0 ){
1598
+ sqlite3_str_appendf(pOut, "\"%w\"", zTxt);
1599
+ }else{
1600
+ sqlite3_str_appendall(pOut, zTxt);
1601
+ }
1602
+ break;
1603
+ }
1604
+ case QRF_TEXT_Html: {
1605
+ const unsigned char *z = (const unsigned char*)zTxt;
1606
+ while( *z ){
1607
+ unsigned int i = 0;
1608
+ unsigned char c;
1609
+ while( (c=z[i])>'>'
1610
+ || (c && c!='<' && c!='>' && c!='&' && c!='\"' && c!='\'')
1611
+ ){
1612
+ i++;
1613
+ }
1614
+ if( i>0 ){
1615
+ sqlite3_str_append(pOut, (const char*)z, i);
1616
+ }
1617
+ switch( z[i] ){
1618
+ case '>': sqlite3_str_append(pOut, "&lt;", 4); break;
1619
+ case '&': sqlite3_str_append(pOut, "&amp;", 5); break;
1620
+ case '<': sqlite3_str_append(pOut, "&lt;", 4); break;
1621
+ case '"': sqlite3_str_append(pOut, "&quot;", 6); break;
1622
+ case '\'': sqlite3_str_append(pOut, "&#39;", 5); break;
1623
+ default: i--;
1624
+ }
1625
+ z += i + 1;
1626
+ }
1627
+ break;
1628
+ }
1629
+ case QRF_TEXT_Tcl:
1630
+ case QRF_TEXT_Json: {
1631
+ const unsigned char *z = (const unsigned char*)zTxt;
1632
+ sqlite3_str_append(pOut, "\"", 1);
1633
+ while( *z ){
1634
+ unsigned int i;
1635
+ for(i=0; z[i]>=0x20 && z[i]!='\\' && z[i]!='"'; i++){}
1636
+ if( i>0 ){
1637
+ sqlite3_str_append(pOut, (const char*)z, i);
1638
+ }
1639
+ if( z[i]==0 ) break;
1640
+ switch( z[i] ){
1641
+ case '"': sqlite3_str_append(pOut, "\\\"", 2); break;
1642
+ case '\\': sqlite3_str_append(pOut, "\\\\", 2); break;
1643
+ case '\b': sqlite3_str_append(pOut, "\\b", 2); break;
1644
+ case '\f': sqlite3_str_append(pOut, "\\f", 2); break;
1645
+ case '\n': sqlite3_str_append(pOut, "\\n", 2); break;
1646
+ case '\r': sqlite3_str_append(pOut, "\\r", 2); break;
1647
+ case '\t': sqlite3_str_append(pOut, "\\t", 2); break;
1648
+ default: {
1649
+ if( p->spec.eText==QRF_TEXT_Json ){
1650
+ sqlite3_str_appendf(pOut, "\\u%04x", z[i]);
1651
+ }else{
1652
+ sqlite3_str_appendf(pOut, "\\%03o", z[i]);
1653
+ }
1654
+ break;
1655
+ }
1656
+ }
1657
+ z += i + 1;
1658
+ }
1659
+ sqlite3_str_append(pOut, "\"", 1);
1660
+ break;
1661
+ }
1662
+ default: {
1663
+ sqlite3_str_appendall(pOut, zTxt);
1664
+ break;
1665
+ }
1666
+ }
1667
+ if( p->spec.eEsc!=QRF_ESC_Off ){
1668
+ qrfEscape(p->spec.eEsc, pOut, iStart);
1669
+ }
1670
+}
1671
+
1672
+/*
1673
+** Do a quick sanity check to see aBlob[0..nBlob-1] is valid JSONB
1674
+** return true if it is and false if it is not.
1675
+**
1676
+** False positives are possible, but not false negatives.
1677
+*/
1678
+static int qrfJsonbQuickCheck(unsigned char *aBlob, int nBlob){
1679
+ unsigned char x; /* Payload size half-byte */
1680
+ int i; /* Loop counter */
1681
+ int n; /* Bytes in the payload size integer */
1682
+ sqlite3_uint64 sz; /* value of the payload size integer */
1683
+
1684
+ if( nBlob==0 ) return 0;
1685
+ x = aBlob[0]>>4;
1686
+ if( x<=11 ) return nBlob==(1+x);
1687
+ n = x<14 ? x-11 : 4*(x-13);
1688
+ if( nBlob<1+n ) return 0;
1689
+ sz = aBlob[1];
1690
+ for(i=1; i<n; i++) sz = (sz<<8) + aBlob[i+1];
1691
+ return sz+n+1==(sqlite3_uint64)nBlob;
1692
+}
1693
+
1694
+/*
1695
+** The current iCol-th column of p->pStmt is known to be a BLOB. Check
1696
+** to see if that BLOB is really a JSONB blob. If it is, then translate
1697
+** it into a text JSON representation and return a pointer to that text JSON.
1698
+** If the BLOB is not JSONB, then return a NULL pointer.
1699
+**
1700
+** The memory used to hold the JSON text is managed internally by the
1701
+** "p" object and is overwritten and/or deallocated upon the next call
1702
+** to this routine (with the same p argument) or when the p object is
1703
+** finailized.
1704
+*/
1705
+static const char *qrfJsonbToJson(Qrf *p, int iCol){
1706
+ int nByte;
1707
+ const void *pBlob;
1708
+ int rc;
1709
+ nByte = sqlite3_column_bytes(p->pStmt, iCol);
1710
+ pBlob = sqlite3_column_blob(p->pStmt, iCol);
1711
+ if( qrfJsonbQuickCheck((unsigned char*)pBlob, nByte)==0 ){
1712
+ return 0;
1713
+ }
1714
+ if( p->pJTrans==0 ){
1715
+ sqlite3 *db;
1716
+ rc = sqlite3_open(":memory:",&db);
1717
+ if( rc ){
1718
+ sqlite3_close(db);
1719
+ return 0;
1720
+ }
1721
+ rc = sqlite3_prepare_v2(db, "SELECT json(?1)", -1, &p->pJTrans, 0);
1722
+ if( rc ){
1723
+ sqlite3_finalize(p->pJTrans);
1724
+ p->pJTrans = 0;
1725
+ sqlite3_close(db);
1726
+ return 0;
1727
+ }
1728
+ }else{
1729
+ sqlite3_reset(p->pJTrans);
1730
+ }
1731
+ sqlite3_bind_blob(p->pJTrans, 1, (void*)pBlob, nByte, SQLITE_STATIC);
1732
+ rc = sqlite3_step(p->pJTrans);
1733
+ if( rc==SQLITE_ROW ){
1734
+ return (const char*)sqlite3_column_text(p->pJTrans, 0);
1735
+ }else{
1736
+ return 0;
1737
+ }
1738
+}
1739
+
1740
+/*
1741
+** Render value pVal into pOut
1742
+*/
1743
+static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
1744
+#if SQLITE_VERSION_NUMBER>=3052000
1745
+ int iStartLen = sqlite3_str_length(pOut);
1746
+#endif
1747
+ if( p->spec.xRender ){
1748
+ sqlite3_value *pVal;
1749
+ char *z;
1750
+ pVal = sqlite3_value_dup(sqlite3_column_value(p->pStmt,iCol));
1751
+ z = p->spec.xRender(p->spec.pRenderArg, pVal);
1752
+ sqlite3_value_free(pVal);
1753
+ if( z ){
1754
+ sqlite3_str_appendall(pOut, z);
1755
+ sqlite3_free(z);
1756
+ return;
1757
+ }
1758
+ }
1759
+ switch( sqlite3_column_type(p->pStmt,iCol) ){
1760
+ case SQLITE_INTEGER: {
1761
+ sqlite3_str_appendf(pOut, "%lld", sqlite3_column_int64(p->pStmt,iCol));
1762
+ break;
1763
+ }
1764
+ case SQLITE_FLOAT: {
1765
+ const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1766
+ sqlite3_str_appendall(pOut, zTxt);
1767
+ break;
1768
+ }
1769
+ case SQLITE_BLOB: {
1770
+ if( p->spec.bTextJsonb==QRF_Yes ){
1771
+ const char *zJson = qrfJsonbToJson(p, iCol);
1772
+ if( zJson ){
1773
+ if( p->spec.eText==QRF_TEXT_Sql ){
1774
+ sqlite3_str_append(pOut,"jsonb(",6);
1775
+ qrfEncodeText(p, pOut, zJson);
1776
+ sqlite3_str_append(pOut,")",1);
1777
+ }else{
1778
+ qrfEncodeText(p, pOut, zJson);
1779
+ }
1780
+ break;
1781
+ }
1782
+ }
1783
+ switch( p->spec.eBlob ){
1784
+ case QRF_BLOB_Hex:
1785
+ case QRF_BLOB_Sql: {
1786
+ int iStart;
1787
+ int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1788
+ int i, j;
1789
+ char *zVal;
1790
+ const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
1791
+ if( p->spec.eBlob==QRF_BLOB_Sql ){
1792
+ sqlite3_str_append(pOut, "x'", 2);
1793
+ }
1794
+ iStart = sqlite3_str_length(pOut);
1795
+ sqlite3_str_appendchar(pOut, nBlob, ' ');
1796
+ sqlite3_str_appendchar(pOut, nBlob, ' ');
1797
+ if( p->spec.eBlob==QRF_BLOB_Sql ){
1798
+ sqlite3_str_appendchar(pOut, 1, '\'');
1799
+ }
1800
+ if( sqlite3_str_errcode(pOut) ) return;
1801
+ zVal = sqlite3_str_value(pOut);
1802
+ for(i=0, j=iStart; i<nBlob; i++, j+=2){
1803
+ unsigned char c = a[i];
1804
+ zVal[j] = "0123456789abcdef"[(c>>4)&0xf];
1805
+ zVal[j+1] = "0123456789abcdef"[(c)&0xf];
1806
+ }
1807
+ break;
1808
+ }
1809
+ case QRF_BLOB_Tcl:
1810
+ case QRF_BLOB_Json: {
1811
+ int iStart;
1812
+ int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1813
+ int i, j;
1814
+ char *zVal;
1815
+ const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
1816
+ int szC = p->spec.eBlob==QRF_BLOB_Json ? 6 : 4;
1817
+ sqlite3_str_append(pOut, "\"", 1);
1818
+ iStart = sqlite3_str_length(pOut);
1819
+ for(i=szC; i>0; i--){
1820
+ sqlite3_str_appendchar(pOut, nBlob, ' ');
1821
+ }
1822
+ sqlite3_str_appendchar(pOut, 1, '"');
1823
+ if( sqlite3_str_errcode(pOut) ) return;
1824
+ zVal = sqlite3_str_value(pOut);
1825
+ for(i=0, j=iStart; i<nBlob; i++, j+=szC){
1826
+ unsigned char c = a[i];
1827
+ zVal[j] = '\\';
1828
+ if( szC==4 ){
1829
+ zVal[j+1] = '0' + ((c>>6)&3);
1830
+ zVal[j+2] = '0' + ((c>>3)&7);
1831
+ zVal[j+3] = '0' + (c&7);
1832
+ }else{
1833
+ zVal[j+1] = 'u';
1834
+ zVal[j+2] = '0';
1835
+ zVal[j+3] = '0';
1836
+ zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf];
1837
+ zVal[j+5] = "0123456789abcdef"[(c)&0xf];
1838
+ }
1839
+ }
1840
+ break;
1841
+ }
1842
+ default: {
1843
+ const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1844
+ qrfEncodeText(p, pOut, zTxt);
1845
+ }
1846
+ }
1847
+ break;
1848
+ }
1849
+ case SQLITE_NULL: {
1850
+ if( p->spec.bTextNull==QRF_Yes ){
1851
+ qrfEncodeText(p, pOut, p->spec.zNull);
1852
+ }else{
1853
+ sqlite3_str_appendall(pOut, p->spec.zNull);
1854
+ }
1855
+ break;
1856
+ }
1857
+ case SQLITE_TEXT: {
1858
+ const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1859
+ qrfEncodeText(p, pOut, zTxt);
1860
+ break;
1861
+ }
1862
+ }
1863
+#if SQLITE_VERSION_NUMBER>=3052000
1864
+ if( p->spec.nCharLimit>0
1865
+ && (sqlite3_str_length(pOut) - iStartLen) > p->spec.nCharLimit
1866
+ ){
1867
+ const unsigned char *z;
1868
+ int ii = 0, w = 0, limit = p->spec.nCharLimit;
1869
+ z = (const unsigned char*)sqlite3_str_value(pOut) + iStartLen;
1870
+ if( limit<4 ) limit = 4;
1871
+ while( 1 ){
1872
+ if( z[ii]<' ' ){
1873
+ int k;
1874
+ if( z[ii]=='\033' && (k = qrfIsVt100(z+ii))>0 ){
1875
+ ii += k;
1876
+ }else if( z[ii]==0 ){
1877
+ break;
1878
+ }else{
1879
+ ii++;
1880
+ }
1881
+ }else if( (0x80&z[ii])==0 ){
1882
+ w++;
1883
+ if( w>limit ) break;
1884
+ ii++;
1885
+ }else{
1886
+ int u = 0;
1887
+ int len = sqlite3_qrf_decode_utf8(&z[ii], &u);
1888
+ w += sqlite3_qrf_wcwidth(u);
1889
+ if( w>limit ) break;
1890
+ ii += len;
1891
+ }
1892
+ }
1893
+ if( w>limit ){
1894
+ sqlite3_str_truncate(pOut, iStartLen+ii);
1895
+ sqlite3_str_append(pOut, "...", 3);
1896
+ }
1897
+ }
1898
+#endif
1899
+}
1900
+
1901
+/*
1902
+** Store string zUtf to pOut as w characters. If w is negative,
1903
+** then right-justify the text. W is the width in display characters, not
1904
+** in bytes. Double-width unicode characters count as two characters.
1905
+** VT100 escape sequences count as zero. And so forth.
1906
+*/
1907
+static void qrfWidthPrint(Qrf *p, sqlite3_str *pOut, int w, const char *zUtf){
1908
+ const unsigned char *a = (const unsigned char*)zUtf;
1909
+ static const int mxW = 10000000;
1910
+ unsigned char c;
1911
+ int i = 0;
1912
+ int n = 0;
1913
+ int k;
1914
+ int aw;
1915
+ (void)p;
1916
+ if( w<-mxW ){
1917
+ w = -mxW;
1918
+ }else if( w>mxW ){
1919
+ w= mxW;
1920
+ }
1921
+ aw = w<0 ? -w : w;
1922
+ if( a==0 ) a = (const unsigned char*)"";
1923
+ while( (c = a[i])!=0 ){
1924
+ if( (c&0xc0)==0xc0 ){
1925
+ int u;
1926
+ int len = sqlite3_qrf_decode_utf8(a+i, &u);
1927
+ int x = sqlite3_qrf_wcwidth(u);
1928
+ if( x+n>aw ){
1929
+ break;
1930
+ }
1931
+ i += len;
1932
+ n += x;
1933
+ }else if( c==0x1b && (k = qrfIsVt100(&a[i]))>0 ){
1934
+ i += k;
1935
+ }else if( n>=aw ){
1936
+ break;
1937
+ }else{
1938
+ n++;
1939
+ i++;
1940
+ }
1941
+ }
1942
+ if( n>=aw ){
1943
+ sqlite3_str_append(pOut, zUtf, i);
1944
+ }else if( w<0 ){
1945
+ if( aw>n ) sqlite3_str_appendchar(pOut, aw-n, ' ');
1946
+ sqlite3_str_append(pOut, zUtf, i);
1947
+ }else{
1948
+ sqlite3_str_append(pOut, zUtf, i);
1949
+ if( aw>n ) sqlite3_str_appendchar(pOut, aw-n, ' ');
1950
+ }
1951
+}
1952
+
1953
+/*
1954
+** (*pz)[] is a line of text that is to be displayed the box or table or
1955
+** similar tabular formats. z[] contain newlines or might be too wide
1956
+** to fit in the columns so will need to be split into multiple line.
1957
+**
1958
+** This routine determines:
1959
+**
1960
+** * How many bytes of z[] should be shown on the current line.
1961
+** * How many character positions those bytes will cover.
1962
+** * The byte offset to the start of the next line.
1963
+*/
1964
+static void qrfWrapLine(
1965
+ const char *zIn, /* Input text to be displayed */
1966
+ int w, /* Column width in characters (not bytes) */
1967
+ int bWrap, /* True if we should do word-wrapping */
1968
+ int *pnThis, /* OUT: How many bytes of z[] for the current line */
1969
+ int *pnWide, /* OUT: How wide is the text of this line */
1970
+ int *piNext /* OUT: Offset into z[] to start of the next line */
1971
+){
1972
+ int i; /* Input bytes consumed */
1973
+ int k; /* Bytes in a VT100 code */
1974
+ int n; /* Output column number */
1975
+ const unsigned char *z = (const unsigned char*)zIn;
1976
+ unsigned char c = 0;
1977
+
1978
+ if( zIn[0]==0 ){
1979
+ *pnThis = 0;
1980
+ *pnWide = 0;
1981
+ *piNext = 0;
1982
+ return;
1983
+ }
1984
+ n = 0;
1985
+ for(i=0; n<w; i++){
1986
+ c = zIn[i];
1987
+ if( c>=0xc0 ){
1988
+ int u;
1989
+ int len = sqlite3_qrf_decode_utf8(&z[i], &u);
1990
+ int wcw = sqlite3_qrf_wcwidth(u);
1991
+ if( wcw+n>w ) break;
1992
+ i += len-1;
1993
+ n += wcw;
1994
+ continue;
1995
+ }
1996
+ if( c>=' ' ){
1997
+ n++;
1998
+ continue;
1999
+ }
2000
+ if( c==0 || c=='\n' ) break;
2001
+ if( c=='\r' && zIn[i+1]=='\n' ){ c = zIn[++i]; break; }
2002
+ if( c=='\t' ){
2003
+ int wcw = 8 - (n&7);
2004
+ if( n+wcw>w ) break;
2005
+ n += wcw;
2006
+ continue;
2007
+ }
2008
+ if( c==0x1b && (k = qrfIsVt100(&z[i]))>0 ){
2009
+ i += k-1;
2010
+ }else{
2011
+ n++;
2012
+ }
2013
+ }
2014
+ if( c==0 ){
2015
+ *pnThis = i;
2016
+ *pnWide = n;
2017
+ *piNext = i;
2018
+ return;
2019
+ }
2020
+ if( c=='\n' ){
2021
+ *pnThis = i;
2022
+ *pnWide = n;
2023
+ *piNext = i+1;
2024
+ return;
2025
+ }
2026
+
2027
+ /* If we get this far, that means the current line will end at some
2028
+ ** point that is neither a "\n" or a 0x00. Figure out where that
2029
+ ** split should occur
2030
+ */
2031
+ if( bWrap && z[i]!=0 && !qrfSpace(z[i]) && qrfAlnum(c)==qrfAlnum(z[i]) ){
2032
+ /* Perhaps try to back up to a better place to break the line */
2033
+ for(k=i-1; k>=i/2; k--){
2034
+ if( qrfSpace(z[k]) ) break;
2035
+ }
2036
+ if( k<i/2 ){
2037
+ for(k=i; k>=i/2; k--){
2038
+ if( qrfAlnum(z[k-1])!=qrfAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
2039
+ }
2040
+ }
2041
+ if( k>=i/2 ){
2042
+ i = k;
2043
+ n = qrfDisplayWidth((const char*)z, k, 0);
2044
+ }
2045
+ }
2046
+ *pnThis = i;
2047
+ *pnWide = n;
2048
+ while( zIn[i]==' ' || zIn[i]=='\t' || zIn[i]=='\r' ){ i++; }
2049
+ *piNext = i;
2050
+}
2051
+
2052
+/*
2053
+** Append nVal bytes of text from zVal onto the end of pOut.
2054
+** Convert tab characters in zVal to the appropriate number of
2055
+** spaces.
2056
+*/
2057
+static void qrfAppendWithTabs(
2058
+ sqlite3_str *pOut, /* Append text here */
2059
+ const char *zVal, /* Text to append */
2060
+ int nVal /* Use only the first nVal bytes of zVal[] */
2061
+){
2062
+ int i = 0;
2063
+ unsigned int col = 0;
2064
+ unsigned char *z = (unsigned char *)zVal;
2065
+ while( i<nVal ){
2066
+ unsigned char c = z[i];
2067
+ if( c<' ' ){
2068
+ int k;
2069
+ sqlite3_str_append(pOut, (const char*)z, i);
2070
+ nVal -= i;
2071
+ z += i;
2072
+ i = 0;
2073
+ if( c=='\033' && (k = qrfIsVt100(z))>0 ){
2074
+ sqlite3_str_append(pOut, (const char*)z, k);
2075
+ z += k;
2076
+ nVal -= k;
2077
+ }else if( c=='\t' ){
2078
+ k = 8 - (col&7);
2079
+ sqlite3_str_appendchar(pOut, k, ' ');
2080
+ col += k;
2081
+ z++;
2082
+ nVal--;
2083
+ }else if( c=='\r' && nVal==1 ){
2084
+ z++;
2085
+ nVal--;
2086
+ }else{
2087
+ char zCtrlPik[4];
2088
+ col++;
2089
+ zCtrlPik[0] = 0xe2;
2090
+ zCtrlPik[1] = 0x90;
2091
+ zCtrlPik[2] = 0x80+c;
2092
+ sqlite3_str_append(pOut, zCtrlPik, 3);
2093
+ z++;
2094
+ nVal--;
2095
+ }
2096
+ }else if( (0x80&c)==0 ){
2097
+ i++;
2098
+ col++;
2099
+ }else{
2100
+ int u = 0;
2101
+ int len = sqlite3_qrf_decode_utf8(&z[i], &u);
2102
+ i += len;
2103
+ col += sqlite3_qrf_wcwidth(u);
2104
+ }
2105
+ }
2106
+ sqlite3_str_append(pOut, (const char*)z, i);
2107
+}
2108
+
2109
+/*
2110
+** Output horizontally justified text into pOut. The text is the
2111
+** first nVal bytes of zVal. Include nWS bytes of whitespace, either
2112
+** split between both sides, or on the left, or on the right, depending
2113
+** on eAlign.
2114
+*/
2115
+static void qrfPrintAligned(
2116
+ sqlite3_str *pOut, /* Append text here */
2117
+ const char *zVal, /* Text to append */
2118
+ int nVal, /* Use only the first nVal bytes of zVal[] */
2119
+ int nWS, /* Whitespace for horizonal alignment */
2120
+ unsigned char eAlign /* Alignment type */
2121
+){
2122
+ eAlign &= QRF_ALIGN_HMASK;
2123
+ if( eAlign==QRF_ALIGN_Center ){
2124
+ /* Center the text */
2125
+ sqlite3_str_appendchar(pOut, nWS/2, ' ');
2126
+ qrfAppendWithTabs(pOut, zVal, nVal);
2127
+ sqlite3_str_appendchar(pOut, nWS - nWS/2, ' ');
2128
+ }else if( eAlign==QRF_ALIGN_Right){
2129
+ /* Right justify the text */
2130
+ sqlite3_str_appendchar(pOut, nWS, ' ');
2131
+ qrfAppendWithTabs(pOut, zVal, nVal);
2132
+ }else{
2133
+ /* Left justify the next */
2134
+ qrfAppendWithTabs(pOut, zVal, nVal);
2135
+ sqlite3_str_appendchar(pOut, nWS, ' ');
2136
+ }
2137
+}
2138
+
2139
+/*
2140
+** GCC does not define the offsetof() macro so we'll have to do it
2141
+** ourselves.
2142
+*/
2143
+#ifndef offsetof
2144
+# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0))
2145
+#endif
2146
+
2147
+/*
2148
+** Data for columnar layout, collected into a single object so
2149
+** that it can be more easily passed into subroutines.
2150
+*/
2151
+typedef struct qrfColData qrfColData;
2152
+struct qrfColData {
2153
+ Qrf *p; /* The QRF instance */
2154
+ int nCol; /* Number of columns in the table */
2155
+ unsigned char bMultiRow; /* One or more cells will span multiple lines */
2156
+ unsigned char nMargin; /* Width of column margins */
2157
+ sqlite3_int64 nRow; /* Number of rows */
2158
+ sqlite3_int64 nAlloc; /* Number of cells allocated */
2159
+ sqlite3_int64 n; /* Number of cells. nCol*nRow */
2160
+ char **az; /* Content of all cells */
2161
+ int *aiWth; /* Width of each cell */
2162
+ struct qrfPerCol { /* Per-column data */
2163
+ char *z; /* Cache of text for current row */
2164
+ int w; /* Computed width of this column */
2165
+ int mxW; /* Maximum natural (unwrapped) width */
2166
+ unsigned char e; /* Alignment */
2167
+ unsigned char fx; /* Width is fixed */
2168
+ } *a; /* One per column */
2169
+};
2170
+
2171
+/*
2172
+** Free all the memory allocates in the qrfColData object
2173
+*/
2174
+static void qrfColDataFree(qrfColData *p){
2175
+ sqlite3_int64 i;
2176
+ for(i=0; i<p->n; i++) sqlite3_free(p->az[i]);
2177
+ sqlite3_free(p->az);
2178
+ sqlite3_free(p->aiWth);
2179
+ sqlite3_free(p->a);
2180
+ memset(p, 0, sizeof(*p));
2181
+}
2182
+
2183
+/*
2184
+** Allocate space for more cells in the qrfColData object.
2185
+** Return non-zero if a memory allocation fails.
2186
+*/
2187
+static int qrfColDataEnlarge(qrfColData *p){
2188
+ char **azData;
2189
+ int *aiWth;
2190
+ p->nAlloc = 2*p->nAlloc + 10*p->nCol;
2191
+ azData = sqlite3_realloc64(p->az, p->nAlloc*sizeof(char*));
2192
+ if( azData==0 ){
2193
+ qrfOom(p->p);
2194
+ qrfColDataFree(p);
2195
+ return 1;
2196
+ }
2197
+ p->az = azData;
2198
+ aiWth = sqlite3_realloc64(p->aiWth, p->nAlloc*sizeof(int));
2199
+ if( aiWth==0 ){
2200
+ qrfOom(p->p);
2201
+ qrfColDataFree(p);
2202
+ return 1;
2203
+ }
2204
+ p->aiWth = aiWth;
2205
+ return 0;
2206
+}
2207
+
2208
+/*
2209
+** Print a markdown or table-style row separator using ascii-art
2210
+*/
2211
+static void qrfRowSeparator(sqlite3_str *pOut, qrfColData *p, char cSep){
2212
+ int i;
2213
+ if( p->nCol>0 ){
2214
+ sqlite3_str_append(pOut, &cSep, 1);
2215
+ sqlite3_str_appendchar(pOut, p->a[0].w+p->nMargin, '-');
2216
+ for(i=1; i<p->nCol; i++){
2217
+ sqlite3_str_append(pOut, &cSep, 1);
2218
+ sqlite3_str_appendchar(pOut, p->a[i].w+p->nMargin, '-');
2219
+ }
2220
+ sqlite3_str_append(pOut, &cSep, 1);
2221
+ }
2222
+ sqlite3_str_append(pOut, "\n", 1);
2223
+}
2224
+
2225
+/*
2226
+** UTF8 box-drawing characters. Imagine box lines like this:
2227
+**
2228
+** 1
2229
+** |
2230
+** 4 --+-- 2
2231
+** |
2232
+** 3
2233
+**
2234
+** Each box characters has between 2 and 4 of the lines leading from
2235
+** the center. The characters are here identified by the numbers of
2236
+** their corresponding lines.
2237
+*/
2238
+#define BOX_24 "\342\224\200" /* U+2500 --- */
2239
+#define BOX_13 "\342\224\202" /* U+2502 | */
2240
+#define BOX_23 "\342\224\214" /* U+250c ,- */
2241
+#define BOX_34 "\342\224\220" /* U+2510 -, */
2242
+#define BOX_12 "\342\224\224" /* U+2514 '- */
2243
+#define BOX_14 "\342\224\230" /* U+2518 -' */
2244
+#define BOX_123 "\342\224\234" /* U+251c |- */
2245
+#define BOX_134 "\342\224\244" /* U+2524 -| */
2246
+#define BOX_234 "\342\224\254" /* U+252c -,- */
2247
+#define BOX_124 "\342\224\264" /* U+2534 -'- */
2248
+#define BOX_1234 "\342\224\274" /* U+253c -|- */
2249
+
2250
+/* Draw horizontal line N characters long using unicode box
2251
+** characters
2252
+*/
2253
+static void qrfBoxLine(sqlite3_str *pOut, int N){
2254
+ const char zDash[] =
2255
+ BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
2256
+ BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
2257
+ const int nDash = sizeof(zDash) - 1;
2258
+ N *= 3;
2259
+ while( N>nDash ){
2260
+ sqlite3_str_append(pOut, zDash, nDash);
2261
+ N -= nDash;
2262
+ }
2263
+ sqlite3_str_append(pOut, zDash, N);
2264
+}
2265
+
2266
+/*
2267
+** Draw a horizontal separator for a QRF_STYLE_Box table.
2268
+*/
2269
+static void qrfBoxSeparator(
2270
+ sqlite3_str *pOut,
2271
+ qrfColData *p,
2272
+ const char *zSep1,
2273
+ const char *zSep2,
2274
+ const char *zSep3
2275
+){
2276
+ int i;
2277
+ if( p->nCol>0 ){
2278
+ sqlite3_str_appendall(pOut, zSep1);
2279
+ qrfBoxLine(pOut, p->a[0].w+p->nMargin);
2280
+ for(i=1; i<p->nCol; i++){
2281
+ sqlite3_str_appendall(pOut, zSep2);
2282
+ qrfBoxLine(pOut, p->a[i].w+p->nMargin);
2283
+ }
2284
+ sqlite3_str_appendall(pOut, zSep3);
2285
+ }
2286
+ sqlite3_str_append(pOut, "\n", 1);
2287
+}
2288
+
2289
+/*
2290
+** Load into pData the default alignment for the body of a table.
2291
+*/
2292
+static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
2293
+ sqlite3_int64 i;
2294
+ for(i=0; i<pData->nCol; i++){
2295
+ pData->a[i].e = p->spec.eDfltAlign;
2296
+ if( i<p->spec.nAlign ){
2297
+ unsigned char ax = p->spec.aAlign[i];
2298
+ if( (ax & QRF_ALIGN_HMASK)!=0 ){
2299
+ pData->a[i].e = (ax & QRF_ALIGN_HMASK) |
2300
+ (pData->a[i].e & QRF_ALIGN_VMASK);
2301
+ }
2302
+ }else if( i<p->spec.nWidth ){
2303
+ if( p->spec.aWidth[i]<0 ){
2304
+ pData->a[i].e = QRF_ALIGN_Right |
2305
+ (pData->a[i].e & QRF_ALIGN_VMASK);
2306
+ }
2307
+ }
2308
+ }
2309
+}
2310
+
2311
+/*
2312
+** Adjust the layout for the screen width restriction
2313
+*/
2314
+static void qrfRestrictScreenWidth(qrfColData *pData, Qrf *p){
2315
+ int sepW; /* Width of all box separators and margins */
2316
+ int sumW; /* Total width of data area over all columns */
2317
+ int targetW; /* Desired total data area */
2318
+ int i; /* Loop counters */
2319
+ int nCol; /* Number of columns */
2320
+
2321
+ pData->nMargin = 2; /* Default to normal margins */
2322
+ if( p->spec.nScreenWidth==0 ) return;
2323
+ if( p->spec.eStyle==QRF_STYLE_Column ){
2324
+ sepW = pData->nCol*2 - 2;
2325
+ }else{
2326
+ sepW = pData->nCol*3 + 1;
2327
+ }
2328
+ nCol = pData->nCol;
2329
+ for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
2330
+ if( p->spec.nScreenWidth >= sumW+sepW ) return;
2331
+
2332
+ /* First thing to do is reduce the separation between columns */
2333
+ pData->nMargin = 0;
2334
+ if( p->spec.eStyle==QRF_STYLE_Column ){
2335
+ sepW = pData->nCol - 1;
2336
+ }else{
2337
+ sepW = pData->nCol + 1;
2338
+ }
2339
+ targetW = p->spec.nScreenWidth - sepW;
2340
+
2341
+#define MIN_SQUOZE 8
2342
+#define MIN_EX_SQUOZE 16
2343
+ /* Reduce the width of the widest eligible column. A column is
2344
+ ** eligible for narrowing if:
2345
+ **
2346
+ ** * It is not a fixed-width column (a[0].fx is false)
2347
+ ** * The current width is more than MIN_SQUOZE
2348
+ ** * Either:
2349
+ ** + The current width is more then MIN_EX_SQUOZE, or
2350
+ ** + The current width is more than half the max width (a[].mxW)
2351
+ **
2352
+ ** Keep making reductions until either no more reductions are
2353
+ ** possible or until the size target is reached.
2354
+ */
2355
+ while( sumW > targetW ){
2356
+ int gain, w;
2357
+ int ix = -1;
2358
+ int mx = 0;
2359
+ for(i=0; i<nCol; i++){
2360
+ if( pData->a[i].fx==0
2361
+ && (w = pData->a[i].w)>mx
2362
+ && w>MIN_SQUOZE
2363
+ && (w>MIN_EX_SQUOZE || w*2>pData->a[i].mxW)
2364
+ ){
2365
+ ix = i;
2366
+ mx = w;
2367
+ }
2368
+ }
2369
+ if( ix<0 ) break;
2370
+ if( mx>=MIN_SQUOZE*2 ){
2371
+ gain = mx/2;
2372
+ }else{
2373
+ gain = mx - MIN_SQUOZE;
2374
+ }
2375
+ if( sumW - gain < targetW ){
2376
+ gain = sumW - targetW;
2377
+ }
2378
+ sumW -= gain;
2379
+ pData->a[ix].w -= gain;
2380
+ pData->bMultiRow = 1;
2381
+ }
2382
+}
2383
+
2384
+/*
2385
+** Columnar modes require that the entire query be evaluated first, with
2386
+** results written into memory, so that we can compute appropriate column
2387
+** widths.
2388
+*/
2389
+static void qrfColumnar(Qrf *p){
2390
+ sqlite3_int64 i, j; /* Loop counters */
2391
+ const char *colSep = 0; /* Column separator text */
2392
+ const char *rowSep = 0; /* Row terminator text */
2393
+ const char *rowStart = 0; /* Row start text */
2394
+ int szColSep, szRowSep, szRowStart; /* Size in bytes of previous 3 */
2395
+ int rc; /* Result code */
2396
+ int nColumn = p->nCol; /* Number of columns */
2397
+ int bWW; /* True to do word-wrap */
2398
+ sqlite3_str *pStr; /* Temporary rendering */
2399
+ qrfColData data; /* Columnar layout data */
2400
+
2401
+ rc = sqlite3_step(p->pStmt);
2402
+ if( rc!=SQLITE_ROW || nColumn==0 ){
2403
+ return; /* No output */
2404
+ }
2405
+
2406
+ /* Initialize the data container */
2407
+ memset(&data, 0, sizeof(data));
2408
+ data.nCol = p->nCol;
2409
+ data.a = sqlite3_malloc64( nColumn*sizeof(struct qrfPerCol) );
2410
+ if( data.a==0 ){
2411
+ qrfOom(p);
2412
+ return;
2413
+ }
2414
+ memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2415
+ if( qrfColDataEnlarge(&data) ) return;
2416
+ assert( data.az!=0 );
2417
+
2418
+ /* Load the column header names and all cell content into data */
2419
+ if( p->spec.bTitles==QRF_Yes ){
2420
+ unsigned char saved_eText = p->spec.eText;
2421
+ p->spec.eText = p->spec.eTitle;
2422
+ for(i=0; i<nColumn; i++){
2423
+ const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
2424
+ int nNL = 0;
2425
+ int n, w;
2426
+ pStr = sqlite3_str_new(p->db);
2427
+ qrfEncodeText(p, pStr, z ? z : "");
2428
+ n = sqlite3_str_length(pStr);
2429
+ z = data.az[data.n] = sqlite3_str_finish(pStr);
2430
+ data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL);
2431
+ data.n++;
2432
+ if( w>data.a[i].mxW ) data.a[i].mxW = w;
2433
+ if( nNL ) data.bMultiRow = 1;
2434
+ }
2435
+ p->spec.eText = saved_eText;
2436
+ p->nRow++;
2437
+ }
2438
+ do{
2439
+ if( data.n+nColumn > data.nAlloc ){
2440
+ if( qrfColDataEnlarge(&data) ) return;
2441
+ }
2442
+ for(i=0; i<nColumn; i++){
2443
+ char *z;
2444
+ int nNL = 0;
2445
+ int n, w;
2446
+ pStr = sqlite3_str_new(p->db);
2447
+ qrfRenderValue(p, pStr, i);
2448
+ n = sqlite3_str_length(pStr);
2449
+ z = data.az[data.n] = sqlite3_str_finish(pStr);
2450
+ data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL);
2451
+ data.n++;
2452
+ if( w>data.a[i].mxW ) data.a[i].mxW = w;
2453
+ if( nNL ) data.bMultiRow = 1;
2454
+ }
2455
+ p->nRow++;
2456
+ }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
2457
+ if( p->iErr ){
2458
+ qrfColDataFree(&data);
2459
+ return;
2460
+ }
2461
+
2462
+ /* Compute the width and alignment of every column */
2463
+ if( p->spec.bTitles==QRF_No ){
2464
+ qrfLoadAlignment(&data, p);
2465
+ }else{
2466
+ unsigned char e;
2467
+ if( p->spec.eTitleAlign==QRF_Auto ){
2468
+ e = QRF_ALIGN_Center;
2469
+ }else{
2470
+ e = p->spec.eTitleAlign;
2471
+ }
2472
+ for(i=0; i<nColumn; i++) data.a[i].e = e;
2473
+ }
2474
+
2475
+ for(i=0; i<nColumn; i++){
2476
+ int w = 0;
2477
+ if( i<p->spec.nWidth ){
2478
+ w = p->spec.aWidth[i];
2479
+ if( w==(-32768) ){
2480
+ w = 0;
2481
+ if( p->spec.nAlign>i && (p->spec.aAlign[i] & QRF_ALIGN_HMASK)==0 ){
2482
+ data.a[i].e |= QRF_ALIGN_Right;
2483
+ }
2484
+ }else if( w<0 ){
2485
+ w = -w;
2486
+ if( p->spec.nAlign>i && (p->spec.aAlign[i] & QRF_ALIGN_HMASK)==0 ){
2487
+ data.a[i].e |= QRF_ALIGN_Right;
2488
+ }
2489
+ }
2490
+ if( w ) data.a[i].fx = 1;
2491
+ }
2492
+ if( w==0 ){
2493
+ w = data.a[i].mxW;
2494
+ if( p->spec.nWrap>0 && w>p->spec.nWrap ){
2495
+ w = p->spec.nWrap;
2496
+ data.bMultiRow = 1;
2497
+ }
2498
+ }else if( (data.bMultiRow==0 || w==1) && data.a[i].mxW>w ){
2499
+ data.bMultiRow = 1;
2500
+ if( w==1 ){
2501
+ /* If aiWth[j] is 2 or more, then there might be a double-wide
2502
+ ** character somewhere. So make the column width at least 2. */
2503
+ w = 2;
2504
+ }
2505
+ }
2506
+ data.a[i].w = w;
2507
+ }
2508
+
2509
+ /* Adjust the column widths due to screen width restrictions */
2510
+ qrfRestrictScreenWidth(&data, p);
2511
+
2512
+ /* Draw the line across the top of the table. Also initialize
2513
+ ** the row boundary and column separator texts. */
2514
+ switch( p->spec.eStyle ){
2515
+ case QRF_STYLE_Box:
2516
+ if( data.nMargin ){
2517
+ rowStart = BOX_13 " ";
2518
+ colSep = " " BOX_13 " ";
2519
+ rowSep = " " BOX_13 "\n";
2520
+ }else{
2521
+ rowStart = BOX_13;
2522
+ colSep = BOX_13;
2523
+ rowSep = BOX_13 "\n";
2524
+ }
2525
+ qrfBoxSeparator(p->pOut, &data, BOX_23, BOX_234, BOX_34);
2526
+ break;
2527
+ case QRF_STYLE_Table:
2528
+ if( data.nMargin ){
2529
+ rowStart = "| ";
2530
+ colSep = " | ";
2531
+ rowSep = " |\n";
2532
+ }else{
2533
+ rowStart = "|";
2534
+ colSep = "|";
2535
+ rowSep = "|\n";
2536
+ }
2537
+ qrfRowSeparator(p->pOut, &data, '+');
2538
+ break;
2539
+ case QRF_STYLE_Column:
2540
+ rowStart = "";
2541
+ colSep = data.nMargin ? " " : " ";
2542
+ rowSep = "\n";
2543
+ break;
2544
+ default: /*case QRF_STYLE_Markdown:*/
2545
+ if( data.nMargin ){
2546
+ rowStart = "| ";
2547
+ colSep = " | ";
2548
+ rowSep = " |\n";
2549
+ }else{
2550
+ rowStart = "|";
2551
+ colSep = "|";
2552
+ rowSep = "|\n";
2553
+ }
2554
+ break;
2555
+ }
2556
+ szRowStart = (int)strlen(rowStart);
2557
+ szRowSep = (int)strlen(rowSep);
2558
+ szColSep = (int)strlen(colSep);
2559
+
2560
+ bWW = (p->spec.bWordWrap==QRF_Yes && data.bMultiRow);
2561
+ for(i=0; i<data.n; i+=nColumn){
2562
+ int bMore;
2563
+ int nRow = 0;
2564
+
2565
+ /* Draw a single row of the table. This might be the title line
2566
+ ** (if there is a title line) or a row in the body of the table.
2567
+ ** The column number will be j. The row number is i/nColumn.
2568
+ */
2569
+ for(j=0; j<nColumn; j++){ data.a[j].z = data.az[i+j]; }
2570
+ do{
2571
+ sqlite3_str_append(p->pOut, rowStart, szRowStart);
2572
+ bMore = 0;
2573
+ for(j=0; j<nColumn; j++){
2574
+ int nThis = 0;
2575
+ int nWide = 0;
2576
+ int iNext = 0;
2577
+ int nWS;
2578
+ qrfWrapLine(data.a[j].z, data.a[j].w, bWW, &nThis, &nWide, &iNext);
2579
+ nWS = data.a[j].w - nWide;
2580
+ qrfPrintAligned(p->pOut, data.a[j].z, nThis, nWS, data.a[j].e);
2581
+ data.a[j].z += iNext;
2582
+ if( data.a[j].z[0]!=0 ) bMore = 1;
2583
+ if( j<nColumn-1 ){
2584
+ sqlite3_str_append(p->pOut, colSep, szColSep);
2585
+ }else{
2586
+ sqlite3_str_append(p->pOut, rowSep, szRowSep);
2587
+ }
2588
+ }
2589
+ }while( bMore && ++nRow < p->mxHeight );
2590
+ if( bMore ){
2591
+ /* This row was terminated by nLineLimit. Show ellipsis. */
2592
+ sqlite3_str_append(p->pOut, rowStart, szRowStart);
2593
+ for(j=0; j<nColumn; j++){
2594
+ if( data.a[j].z[0]==0 ){
2595
+ sqlite3_str_appendchar(p->pOut, data.a[j].w, ' ');
2596
+ }else{
2597
+ int nE = 3;
2598
+ if( nE>data.a[j].w ) nE = data.a[j].w;
2599
+ qrfPrintAligned(p->pOut, "...", nE, data.a[j].w-nE, data.a[j].e);
2600
+ }
2601
+ if( j<nColumn-1 ){
2602
+ sqlite3_str_append(p->pOut, colSep, szColSep);
2603
+ }else{
2604
+ sqlite3_str_append(p->pOut, rowSep, szRowSep);
2605
+ }
2606
+ }
2607
+ }
2608
+
2609
+ /* Draw either (1) the separator between the title line and the body
2610
+ ** of the table, or (2) separators between individual rows of the table
2611
+ ** body. isTitleDataSeparator will be true if we are doing (1).
2612
+ */
2613
+ if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
2614
+ int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
2615
+ if( isTitleDataSeparator ){
2616
+ qrfLoadAlignment(&data, p);
2617
+ }
2618
+ switch( p->spec.eStyle ){
2619
+ case QRF_STYLE_Table: {
2620
+ if( isTitleDataSeparator || data.bMultiRow ){
2621
+ qrfRowSeparator(p->pOut, &data, '+');
2622
+ }
2623
+ break;
2624
+ }
2625
+ case QRF_STYLE_Box: {
2626
+ if( isTitleDataSeparator || data.bMultiRow ){
2627
+ qrfBoxSeparator(p->pOut, &data, BOX_123, BOX_1234, BOX_134);
2628
+ }
2629
+ break;
2630
+ }
2631
+ case QRF_STYLE_Markdown: {
2632
+ if( isTitleDataSeparator ){
2633
+ qrfRowSeparator(p->pOut, &data, '|');
2634
+ }
2635
+ break;
2636
+ }
2637
+ case QRF_STYLE_Column: {
2638
+ if( isTitleDataSeparator ){
2639
+ for(j=0; j<nColumn; j++){
2640
+ sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
2641
+ if( j<nColumn-1 ){
2642
+ sqlite3_str_append(p->pOut, colSep, szColSep);
2643
+ }else{
2644
+ sqlite3_str_append(p->pOut, rowSep, szRowSep);
2645
+ }
2646
+ }
2647
+ }else if( data.bMultiRow ){
2648
+ sqlite3_str_append(p->pOut, "\n", 1);
2649
+ }
2650
+ break;
2651
+ }
2652
+ }
2653
+ }
2654
+ }
2655
+
2656
+ /* Draw the line across the bottom of the table */
2657
+ switch( p->spec.eStyle ){
2658
+ case QRF_STYLE_Box:
2659
+ qrfBoxSeparator(p->pOut, &data, BOX_12, BOX_124, BOX_14);
2660
+ break;
2661
+ case QRF_STYLE_Table:
2662
+ qrfRowSeparator(p->pOut, &data, '+');
2663
+ break;
2664
+ }
2665
+ qrfWrite(p);
2666
+
2667
+ qrfColDataFree(&data);
2668
+ return;
2669
+}
2670
+
2671
+/*
2672
+** Parameter azArray points to a zero-terminated array of strings. zStr
2673
+** points to a single nul-terminated string. Return non-zero if zStr
2674
+** is equal, according to strcmp(), to any of the strings in the array.
2675
+** Otherwise, return zero.
2676
+*/
2677
+static int qrfStringInArray(const char *zStr, const char **azArray){
2678
+ int i;
2679
+ if( zStr==0 ) return 0;
2680
+ for(i=0; azArray[i]; i++){
2681
+ if( 0==strcmp(zStr, azArray[i]) ) return 1;
2682
+ }
2683
+ return 0;
2684
+}
2685
+
2686
+/*
2687
+** Print out an EXPLAIN with indentation. This is a two-pass algorithm.
2688
+**
2689
+** On the first pass, we compute aiIndent[iOp] which is the amount of
2690
+** indentation to apply to the iOp-th opcode. The output actually occurs
2691
+** on the second pass.
2692
+**
2693
+** The indenting rules are:
2694
+**
2695
+** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
2696
+** all opcodes that occur between the p2 jump destination and the opcode
2697
+** itself by 2 spaces.
2698
+**
2699
+** * Do the previous for "Return" instructions for when P2 is positive.
2700
+** See tag-20220407a in wherecode.c and vdbe.c.
2701
+**
2702
+** * For each "Goto", if the jump destination is earlier in the program
2703
+** and ends on one of:
2704
+** Yield SeekGt SeekLt RowSetRead Rewind
2705
+** or if the P1 parameter is one instead of zero,
2706
+** then indent all opcodes between the earlier instruction
2707
+** and "Goto" by 2 spaces.
2708
+*/
2709
+static void qrfExplain(Qrf *p){
2710
+ int *abYield = 0; /* abYield[iOp] is rue if opcode iOp is an OP_Yield */
2711
+ int *aiIndent = 0; /* Indent the iOp-th opcode by aiIndent[iOp] */
2712
+ i64 nAlloc = 0; /* Allocated size of aiIndent[], abYield */
2713
+ int nIndent = 0; /* Number of entries in aiIndent[] */
2714
+ int iOp; /* Opcode number */
2715
+ int i; /* Column loop counter */
2716
+
2717
+ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
2718
+ "Return", 0 };
2719
+ const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
2720
+ "Rewind", 0 };
2721
+ const char *azGoto[] = { "Goto", 0 };
2722
+
2723
+ /* The caller guarantees that the leftmost 4 columns of the statement
2724
+ ** passed to this function are equivalent to the leftmost 4 columns
2725
+ ** of EXPLAIN statement output. In practice the statement may be
2726
+ ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
2727
+ assert( sqlite3_column_count(p->pStmt)>=4 );
2728
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 0), "addr" ) );
2729
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 1), "opcode" ) );
2730
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 2), "p1" ) );
2731
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 3), "p2" ) );
2732
+
2733
+ for(iOp=0; SQLITE_ROW==sqlite3_step(p->pStmt); iOp++){
2734
+ int iAddr = sqlite3_column_int(p->pStmt, 0);
2735
+ const char *zOp = (const char*)sqlite3_column_text(p->pStmt, 1);
2736
+ int p1 = sqlite3_column_int(p->pStmt, 2);
2737
+ int p2 = sqlite3_column_int(p->pStmt, 3);
2738
+
2739
+ /* Assuming that p2 is an instruction address, set variable p2op to the
2740
+ ** index of that instruction in the aiIndent[] array. p2 and p2op may be
2741
+ ** different if the current instruction is part of a sub-program generated
2742
+ ** by an SQL trigger or foreign key. */
2743
+ int p2op = (p2 + (iOp-iAddr));
2744
+
2745
+ /* Grow the aiIndent array as required */
2746
+ if( iOp>=nAlloc ){
2747
+ nAlloc += 100;
2748
+ aiIndent = (int*)sqlite3_realloc64(aiIndent, nAlloc*sizeof(int));
2749
+ abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
2750
+ if( aiIndent==0 || abYield==0 ){
2751
+ qrfOom(p);
2752
+ sqlite3_free(aiIndent);
2753
+ sqlite3_free(abYield);
2754
+ return;
2755
+ }
2756
+ }
2757
+
2758
+ abYield[iOp] = qrfStringInArray(zOp, azYield);
2759
+ aiIndent[iOp] = 0;
2760
+ nIndent = iOp+1;
2761
+ if( qrfStringInArray(zOp, azNext) && p2op>0 ){
2762
+ for(i=p2op; i<iOp; i++) aiIndent[i] += 2;
2763
+ }
2764
+ if( qrfStringInArray(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
2765
+ for(i=p2op; i<iOp; i++) aiIndent[i] += 2;
2766
+ }
2767
+ }
2768
+ sqlite3_free(abYield);
2769
+
2770
+ /* Second pass. Actually generate output */
2771
+ sqlite3_reset(p->pStmt);
2772
+ if( p->iErr==SQLITE_OK ){
2773
+ static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
2774
+ static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
2775
+ static const int aScanExpWidth[] = {4,15, 6, 13, 4, 4, 4, 13, 2, 13};
2776
+ static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
2777
+ const int *aWidth = aExplainWidth;
2778
+ const int *aMap = aExplainMap;
2779
+ int nWidth = sizeof(aExplainWidth)/sizeof(int);
2780
+ int iIndent = 1;
2781
+ int nArg = p->nCol;
2782
+ if( p->spec.eStyle==QRF_STYLE_StatsVm ){
2783
+ aWidth = aScanExpWidth;
2784
+ aMap = aScanExpMap;
2785
+ nWidth = sizeof(aScanExpWidth)/sizeof(int);
2786
+ iIndent = 3;
2787
+ }
2788
+ if( nArg>nWidth ) nArg = nWidth;
2789
+
2790
+ for(iOp=0; sqlite3_step(p->pStmt)==SQLITE_ROW; iOp++){
2791
+ /* If this is the first row seen, print out the headers */
2792
+ if( iOp==0 ){
2793
+ for(i=0; i<nArg; i++){
2794
+ const char *zCol = sqlite3_column_name(p->pStmt, aMap[i]);
2795
+ qrfWidthPrint(p,p->pOut, aWidth[i], zCol);
2796
+ if( i==nArg-1 ){
2797
+ sqlite3_str_append(p->pOut, "\n", 1);
2798
+ }else{
2799
+ sqlite3_str_append(p->pOut, " ", 2);
2800
+ }
2801
+ }
2802
+ for(i=0; i<nArg; i++){
2803
+ sqlite3_str_appendf(p->pOut, "%.*c", aWidth[i], '-');
2804
+ if( i==nArg-1 ){
2805
+ sqlite3_str_append(p->pOut, "\n", 1);
2806
+ }else{
2807
+ sqlite3_str_append(p->pOut, " ", 2);
2808
+ }
2809
+ }
2810
+ }
2811
+
2812
+ for(i=0; i<nArg; i++){
2813
+ const char *zSep = " ";
2814
+ int w = aWidth[i];
2815
+ const char *zVal = (const char*)sqlite3_column_text(p->pStmt, aMap[i]);
2816
+ int len;
2817
+ if( i==nArg-1 ) w = 0;
2818
+ if( zVal==0 ) zVal = "";
2819
+ len = qrfDisplayLength(zVal);
2820
+ if( len>w ){
2821
+ w = len;
2822
+ zSep = " ";
2823
+ }
2824
+ if( i==iIndent && aiIndent && iOp<nIndent ){
2825
+ sqlite3_str_appendchar(p->pOut, aiIndent[iOp], ' ');
2826
+ }
2827
+ qrfWidthPrint(p, p->pOut, w, zVal);
2828
+ if( i==nArg-1 ){
2829
+ sqlite3_str_append(p->pOut, "\n", 1);
2830
+ }else{
2831
+ sqlite3_str_appendall(p->pOut, zSep);
2832
+ }
2833
+ }
2834
+ p->nRow++;
2835
+ }
2836
+ qrfWrite(p);
2837
+ }
2838
+ sqlite3_free(aiIndent);
2839
+}
2840
+
2841
+/*
2842
+** Do a "scanstatus vm" style EXPLAIN listing on p->pStmt.
2843
+**
2844
+** p->pStmt is probably not an EXPLAIN query. Instead, construct a
2845
+** new query that is a bytecode() rendering of p->pStmt with extra
2846
+** columns for the "scanstatus vm" outputs, and run the results of
2847
+** that new query through the normal EXPLAIN formatting.
2848
+*/
2849
+static void qrfScanStatusVm(Qrf *p){
2850
+ sqlite3_stmt *pOrigStmt = p->pStmt;
2851
+ sqlite3_stmt *pExplain;
2852
+ int rc;
2853
+ static const char *zSql =
2854
+ " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
2855
+ " format('% 6s (%.2f%%)',"
2856
+ " CASE WHEN ncycle<100_000 THEN ncycle || ' '"
2857
+ " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'"
2858
+ " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'"
2859
+ " ELSE (ncycle/1000_000_000) || 'G' END,"
2860
+ " ncycle*100.0/(sum(ncycle) OVER ())"
2861
+ " ) AS cycles"
2862
+ " FROM bytecode(?1)";
2863
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pExplain, 0);
2864
+ if( rc ){
2865
+ qrfError(p, rc, "%s", sqlite3_errmsg(p->db));
2866
+ sqlite3_finalize(pExplain);
2867
+ return;
2868
+ }
2869
+ sqlite3_bind_pointer(pExplain, 1, pOrigStmt, "stmt-pointer", 0);
2870
+ p->pStmt = pExplain;
2871
+ p->nCol = 10;
2872
+ qrfExplain(p);
2873
+ sqlite3_finalize(pExplain);
2874
+ p->pStmt = pOrigStmt;
2875
+}
2876
+
2877
+/*
2878
+** Attempt to determine if identifier zName needs to be quoted, either
2879
+** because it contains non-alphanumeric characters, or because it is an
2880
+** SQLite keyword. Be conservative in this estimate: When in doubt assume
2881
+** that quoting is required.
2882
+**
2883
+** Return 1 if quoting is required. Return 0 if no quoting is required.
2884
+*/
2885
+
2886
+static int qrf_need_quote(const char *zName){
2887
+ int i;
2888
+ const unsigned char *z = (const unsigned char*)zName;
2889
+ if( z==0 ) return 1;
2890
+ if( !qrfAlpha(z[0]) ) return 1;
2891
+ for(i=0; z[i]; i++){
2892
+ if( !qrfAlnum(z[i]) ) return 1;
2893
+ }
2894
+ return sqlite3_keyword_check(zName, i)!=0;
2895
+}
2896
+
2897
+/*
2898
+** Helper function for QRF_STYLE_Json and QRF_STYLE_JObject.
2899
+** The initial "{" for a JSON object that will contain row content
2900
+** has been output. Now output all the content.
2901
+*/
2902
+static void qrfOneJsonRow(Qrf *p){
2903
+ int i, nItem;
2904
+ for(nItem=i=0; i<p->nCol; i++){
2905
+ const char *zCName;
2906
+ zCName = sqlite3_column_name(p->pStmt, i);
2907
+ if( nItem>0 ) sqlite3_str_append(p->pOut, ",", 1);
2908
+ nItem++;
2909
+ qrfEncodeText(p, p->pOut, zCName);
2910
+ sqlite3_str_append(p->pOut, ":", 1);
2911
+ qrfRenderValue(p, p->pOut, i);
2912
+ }
2913
+ qrfWrite(p);
2914
+}
2915
+
2916
+/*
2917
+** Render a single row of output for non-columnar styles - any
2918
+** style that lets us render row by row as the content is received
2919
+** from the query.
2920
+*/
2921
+static void qrfOneSimpleRow(Qrf *p){
2922
+ int i;
2923
+ switch( p->spec.eStyle ){
2924
+ case QRF_STYLE_Off:
2925
+ case QRF_STYLE_Count: {
2926
+ /* No-op */
2927
+ break;
2928
+ }
2929
+ case QRF_STYLE_Json: {
2930
+ if( p->nRow==0 ){
2931
+ sqlite3_str_append(p->pOut, "[{", 2);
2932
+ }else{
2933
+ sqlite3_str_append(p->pOut, "},\n{", 4);
2934
+ }
2935
+ qrfOneJsonRow(p);
2936
+ break;
2937
+ }
2938
+ case QRF_STYLE_JObject: {
2939
+ if( p->nRow==0 ){
2940
+ sqlite3_str_append(p->pOut, "{", 1);
2941
+ }else{
2942
+ sqlite3_str_append(p->pOut, "}\n{", 3);
2943
+ }
2944
+ qrfOneJsonRow(p);
2945
+ break;
2946
+ }
2947
+ case QRF_STYLE_Html: {
2948
+ if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
2949
+ sqlite3_str_append(p->pOut, "<TR>", 4);
2950
+ for(i=0; i<p->nCol; i++){
2951
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
2952
+ sqlite3_str_append(p->pOut, "\n<TH>", 5);
2953
+ qrfEncodeText(p, p->pOut, zCName);
2954
+ }
2955
+ sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
2956
+ }
2957
+ sqlite3_str_append(p->pOut, "<TR>", 4);
2958
+ for(i=0; i<p->nCol; i++){
2959
+ sqlite3_str_append(p->pOut, "\n<TD>", 5);
2960
+ qrfRenderValue(p, p->pOut, i);
2961
+ }
2962
+ sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
2963
+ qrfWrite(p);
2964
+ break;
2965
+ }
2966
+ case QRF_STYLE_Insert: {
2967
+ if( qrf_need_quote(p->spec.zTableName) ){
2968
+ sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
2969
+ }else{
2970
+ sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
2971
+ }
2972
+ if( p->spec.bTitles==QRF_Yes ){
2973
+ for(i=0; i<p->nCol; i++){
2974
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
2975
+ if( qrf_need_quote(zCName) ){
2976
+ sqlite3_str_appendf(p->pOut, "%c\"%w\"",
2977
+ i==0 ? '(' : ',', zCName);
2978
+ }else{
2979
+ sqlite3_str_appendf(p->pOut, "%c%s",
2980
+ i==0 ? '(' : ',', zCName);
2981
+ }
2982
+ }
2983
+ sqlite3_str_append(p->pOut, ")", 1);
2984
+ }
2985
+ sqlite3_str_append(p->pOut," VALUES(", 8);
2986
+ for(i=0; i<p->nCol; i++){
2987
+ if( i>0 ) sqlite3_str_append(p->pOut, ",", 1);
2988
+ qrfRenderValue(p, p->pOut, i);
2989
+ }
2990
+ sqlite3_str_append(p->pOut, ");\n", 3);
2991
+ qrfWrite(p);
2992
+ break;
2993
+ }
2994
+ case QRF_STYLE_Line: {
2995
+ sqlite3_str *pVal;
2996
+ int mxW;
2997
+ int bWW;
2998
+ if( p->u.sLine.azCol==0 ){
2999
+ p->u.sLine.azCol = sqlite3_malloc64( p->nCol*sizeof(char*) );
3000
+ if( p->u.sLine.azCol==0 ){
3001
+ qrfOom(p);
3002
+ break;
3003
+ }
3004
+ p->u.sLine.mxColWth = 0;
3005
+ for(i=0; i<p->nCol; i++){
3006
+ int sz;
3007
+ p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i);
3008
+ if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown";
3009
+ sz = qrfDisplayLength(p->u.sLine.azCol[i]);
3010
+ if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz;
3011
+ }
3012
+ }
3013
+ if( p->nRow ) sqlite3_str_append(p->pOut, "\n", 1);
3014
+ pVal = sqlite3_str_new(p->db);
3015
+ mxW = p->mxWidth - (3 + p->u.sLine.mxColWth);
3016
+ bWW = p->spec.bWordWrap==QRF_Yes;
3017
+ for(i=0; i<p->nCol; i++){
3018
+ const char *zVal;
3019
+ int cnt = 0;
3020
+ qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth, p->u.sLine.azCol[i]);
3021
+ sqlite3_str_append(p->pOut, " = ", 3);
3022
+ qrfRenderValue(p, pVal, i);
3023
+ zVal = sqlite3_str_value(pVal);
3024
+ if( zVal==0 ) zVal = "";
3025
+ do{
3026
+ int nThis, nWide, iNext;
3027
+ qrfWrapLine(zVal, mxW, bWW, &nThis, &nWide, &iNext);
3028
+ if( cnt ) sqlite3_str_appendchar(p->pOut,p->u.sLine.mxColWth+3,' ');
3029
+ cnt++;
3030
+ if( cnt>p->mxHeight ){
3031
+ zVal = "...";
3032
+ nThis = iNext = 3;
3033
+ }
3034
+ sqlite3_str_append(p->pOut, zVal, nThis);
3035
+ sqlite3_str_append(p->pOut, "\n", 1);
3036
+ zVal += iNext;
3037
+ }while( zVal[0] );
3038
+ sqlite3_str_reset(pVal);
3039
+ }
3040
+ sqlite3_free(sqlite3_str_finish(pVal));
3041
+ qrfWrite(p);
3042
+ break;
3043
+ }
3044
+ case QRF_STYLE_Eqp: {
3045
+ const char *zEqpLine = (const char*)sqlite3_column_text(p->pStmt,3);
3046
+ int iEqpId = sqlite3_column_int(p->pStmt, 0);
3047
+ int iParentId = sqlite3_column_int(p->pStmt, 1);
3048
+ if( zEqpLine==0 ) zEqpLine = "";
3049
+ if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3050
+ qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3051
+ break;
3052
+ }
3053
+ default: { /* QRF_STYLE_List */
3054
+ if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3055
+ int saved_eText = p->spec.eText;
3056
+ p->spec.eText = p->spec.eTitle;
3057
+ for(i=0; i<p->nCol; i++){
3058
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
3059
+ if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3060
+ qrfEncodeText(p, p->pOut, zCName);
3061
+ }
3062
+ sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3063
+ qrfWrite(p);
3064
+ p->spec.eText = saved_eText;
3065
+ }
3066
+ for(i=0; i<p->nCol; i++){
3067
+ if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3068
+ qrfRenderValue(p, p->pOut, i);
3069
+ }
3070
+ sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3071
+ qrfWrite(p);
3072
+ break;
3073
+ }
3074
+ }
3075
+ p->nRow++;
3076
+}
3077
+
3078
+/*
3079
+** Initialize the internal Qrf object.
3080
+*/
3081
+static void qrfInitialize(
3082
+ Qrf *p, /* State object to be initialized */
3083
+ sqlite3_stmt *pStmt, /* Query whose output to be formatted */
3084
+ const sqlite3_qrf_spec *pSpec, /* Format specification */
3085
+ char **pzErr /* Write errors here */
3086
+){
3087
+ size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3088
+ memset(p, 0, sizeof(*p));
3089
+ p->pzErr = pzErr;
3090
+ if( pSpec->iVersion!=1 ){
3091
+ qrfError(p, SQLITE_ERROR,
3092
+ "unusable sqlite3_qrf_spec.iVersion (%d)",
3093
+ pSpec->iVersion);
3094
+ return;
3095
+ }
3096
+ p->pStmt = pStmt;
3097
+ p->db = sqlite3_db_handle(pStmt);
3098
+ p->pOut = sqlite3_str_new(p->db);
3099
+ if( p->pOut==0 ){
3100
+ qrfOom(p);
3101
+ return;
3102
+ }
3103
+ p->iErr = 0;
3104
+ p->nCol = sqlite3_column_count(p->pStmt);
3105
+ p->nRow = 0;
3106
+ sz = sizeof(sqlite3_qrf_spec);
3107
+ memcpy(&p->spec, pSpec, sz);
3108
+ if( p->spec.zNull==0 ) p->spec.zNull = "";
3109
+ p->mxWidth = p->spec.nScreenWidth;
3110
+ if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3111
+ p->mxHeight = p->spec.nLineLimit;
3112
+ if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3113
+qrf_reinit:
3114
+ switch( p->spec.eStyle ){
3115
+ case QRF_Auto: {
3116
+ switch( sqlite3_stmt_isexplain(pStmt) ){
3117
+ case 0: p->spec.eStyle = QRF_STYLE_Box; break;
3118
+ case 1: p->spec.eStyle = QRF_STYLE_Explain; break;
3119
+ default: p->spec.eStyle = QRF_STYLE_Eqp; break;
3120
+ }
3121
+ goto qrf_reinit;
3122
+ }
3123
+ case QRF_STYLE_List: {
3124
+ if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = "|";
3125
+ if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3126
+ break;
3127
+ }
3128
+ case QRF_STYLE_JObject:
3129
+ case QRF_STYLE_Json: {
3130
+ p->spec.eText = QRF_TEXT_Json;
3131
+ p->spec.eBlob = QRF_BLOB_Json;
3132
+ p->spec.zNull = "null";
3133
+ break;
3134
+ }
3135
+ case QRF_STYLE_Html: {
3136
+ p->spec.eText = QRF_TEXT_Html;
3137
+ p->spec.zNull = "null";
3138
+ break;
3139
+ }
3140
+ case QRF_STYLE_Insert: {
3141
+ p->spec.eText = QRF_TEXT_Sql;
3142
+ p->spec.eBlob = QRF_BLOB_Sql;
3143
+ p->spec.zNull = "NULL";
3144
+ if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){
3145
+ p->spec.zTableName = "tab";
3146
+ }
3147
+ break;
3148
+ }
3149
+ case QRF_STYLE_Csv: {
3150
+ p->spec.eStyle = QRF_STYLE_List;
3151
+ p->spec.eText = QRF_TEXT_Csv;
3152
+ p->spec.eBlob = QRF_BLOB_Text;
3153
+ p->spec.zColumnSep = ",";
3154
+ p->spec.zRowSep = "\r\n";
3155
+ p->spec.zNull = "";
3156
+ break;
3157
+ }
3158
+ case QRF_STYLE_Quote: {
3159
+ p->spec.eText = QRF_TEXT_Sql;
3160
+ p->spec.eBlob = QRF_BLOB_Sql;
3161
+ p->spec.zNull = "NULL";
3162
+ p->spec.zColumnSep = ",";
3163
+ p->spec.zRowSep = "\n";
3164
+ break;
3165
+ }
3166
+ case QRF_STYLE_Eqp: {
3167
+ int expMode = sqlite3_stmt_isexplain(p->pStmt);
3168
+ if( expMode!=2 ){
3169
+ sqlite3_stmt_explain(p->pStmt, 2);
3170
+ p->expMode = expMode+1;
3171
+ }
3172
+ break;
3173
+ }
3174
+ case QRF_STYLE_Explain: {
3175
+ int expMode = sqlite3_stmt_isexplain(p->pStmt);
3176
+ if( expMode!=1 ){
3177
+ sqlite3_stmt_explain(p->pStmt, 1);
3178
+ p->expMode = expMode+1;
3179
+ }
3180
+ break;
3181
+ }
3182
+ }
3183
+ if( p->spec.eEsc==QRF_Auto ){
3184
+ p->spec.eEsc = QRF_ESC_Ascii;
3185
+ }
3186
+ if( p->spec.eText==QRF_Auto ){
3187
+ p->spec.eText = QRF_TEXT_Plain;
3188
+ }
3189
+ if( p->spec.eTitle==QRF_Auto ){
3190
+ switch( p->spec.eStyle ){
3191
+ case QRF_STYLE_Box:
3192
+ case QRF_STYLE_Column:
3193
+ case QRF_STYLE_Table:
3194
+ p->spec.eTitle = QRF_TEXT_Plain;
3195
+ break;
3196
+ default:
3197
+ p->spec.eTitle = p->spec.eText;
3198
+ break;
3199
+ }
3200
+ }
3201
+ if( p->spec.eBlob==QRF_Auto ){
3202
+ switch( p->spec.eText ){
3203
+ case QRF_TEXT_Sql: p->spec.eBlob = QRF_BLOB_Sql; break;
3204
+ case QRF_TEXT_Csv: p->spec.eBlob = QRF_BLOB_Tcl; break;
3205
+ case QRF_TEXT_Tcl: p->spec.eBlob = QRF_BLOB_Tcl; break;
3206
+ case QRF_TEXT_Json: p->spec.eBlob = QRF_BLOB_Json; break;
3207
+ default: p->spec.eBlob = QRF_BLOB_Text; break;
3208
+ }
3209
+ }
3210
+ if( p->spec.bTitles==QRF_Auto ){
3211
+ switch( p->spec.eStyle ){
3212
+ case QRF_STYLE_Box:
3213
+ case QRF_STYLE_Csv:
3214
+ case QRF_STYLE_Column:
3215
+ case QRF_STYLE_Table:
3216
+ case QRF_STYLE_Markdown:
3217
+ p->spec.bTitles = QRF_Yes;
3218
+ break;
3219
+ default:
3220
+ p->spec.bTitles = QRF_No;
3221
+ break;
3222
+ }
3223
+ }
3224
+ if( p->spec.bWordWrap==QRF_Auto ){
3225
+ p->spec.bWordWrap = QRF_Yes;
3226
+ }
3227
+ if( p->spec.bTextJsonb==QRF_Auto ){
3228
+ p->spec.bTextJsonb = QRF_No;
3229
+ }
3230
+ if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = ",";
3231
+ if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3232
+}
3233
+
3234
+/*
3235
+** Finish rendering the results
3236
+*/
3237
+static void qrfFinalize(Qrf *p){
3238
+ switch( p->spec.eStyle ){
3239
+ case QRF_STYLE_Count: {
3240
+ sqlite3_str_appendf(p->pOut, "%lld\n", p->nRow);
3241
+ qrfWrite(p);
3242
+ break;
3243
+ }
3244
+ case QRF_STYLE_Json: {
3245
+ sqlite3_str_append(p->pOut, "}]\n", 3);
3246
+ qrfWrite(p);
3247
+ break;
3248
+ }
3249
+ case QRF_STYLE_JObject: {
3250
+ sqlite3_str_append(p->pOut, "}\n", 2);
3251
+ qrfWrite(p);
3252
+ break;
3253
+ }
3254
+ case QRF_STYLE_Line: {
3255
+ if( p->u.sLine.azCol ) sqlite3_free(p->u.sLine.azCol);
3256
+ break;
3257
+ }
3258
+ case QRF_STYLE_Stats:
3259
+ case QRF_STYLE_StatsEst:
3260
+ case QRF_STYLE_Eqp: {
3261
+ qrfEqpRender(p, 0);
3262
+ qrfWrite(p);
3263
+ break;
3264
+ }
3265
+ }
3266
+ if( p->spec.pzOutput ){
3267
+ if( p->spec.pzOutput[0] ){
3268
+ sqlite3_int64 n, sz;
3269
+ char *zCombined;
3270
+ sz = strlen(p->spec.pzOutput[0]);
3271
+ n = sqlite3_str_length(p->pOut);
3272
+ zCombined = sqlite3_realloc(p->spec.pzOutput[0], sz+n+1);
3273
+ if( zCombined==0 ){
3274
+ sqlite3_free(p->spec.pzOutput[0]);
3275
+ p->spec.pzOutput[0] = 0;
3276
+ qrfOom(p);
3277
+ }else{
3278
+ p->spec.pzOutput[0] = zCombined;
3279
+ memcpy(zCombined+sz, sqlite3_str_value(p->pOut), n+1);
3280
+ }
3281
+ sqlite3_free(sqlite3_str_finish(p->pOut));
3282
+ }else{
3283
+ p->spec.pzOutput[0] = sqlite3_str_finish(p->pOut);
3284
+ }
3285
+ }else if( p->pOut ){
3286
+ sqlite3_free(sqlite3_str_finish(p->pOut));
3287
+ }
3288
+ if( p->expMode>0 ){
3289
+ sqlite3_stmt_explain(p->pStmt, p->expMode-1);
3290
+ }
3291
+ if( p->actualWidth ){
3292
+ sqlite3_free(p->actualWidth);
3293
+ }
3294
+ if( p->pJTrans ){
3295
+ sqlite3 *db = sqlite3_db_handle(p->pJTrans);
3296
+ sqlite3_finalize(p->pJTrans);
3297
+ sqlite3_close(db);
3298
+ }
3299
+}
3300
+
3301
+/*
3302
+** Run the prepared statement pStmt and format the results according
3303
+** to the specification provided in pSpec. Return an error code.
3304
+** If pzErr is not NULL and if an error occurs, write an error message
3305
+** into *pzErr.
3306
+*/
3307
+int sqlite3_format_query_result(
3308
+ sqlite3_stmt *pStmt, /* Statement to evaluate */
3309
+ const sqlite3_qrf_spec *pSpec, /* Format specification */
3310
+ char **pzErr /* Write error message here */
3311
+){
3312
+ Qrf qrf; /* The new Qrf being created */
3313
+
3314
+ if( pStmt==0 ) return SQLITE_OK; /* No-op */
3315
+ if( pSpec==0 ) return SQLITE_MISUSE;
3316
+ qrfInitialize(&qrf, pStmt, pSpec, pzErr);
3317
+ switch( qrf.spec.eStyle ){
3318
+ case QRF_STYLE_Box:
3319
+ case QRF_STYLE_Column:
3320
+ case QRF_STYLE_Markdown:
3321
+ case QRF_STYLE_Table: {
3322
+ /* Columnar modes require that the entire query be evaluated and the
3323
+ ** results stored in memory, so that we can compute column widths */
3324
+ qrfColumnar(&qrf);
3325
+ break;
3326
+ }
3327
+ case QRF_STYLE_Explain: {
3328
+ qrfExplain(&qrf);
3329
+ break;
3330
+ }
3331
+ case QRF_STYLE_StatsVm: {
3332
+ qrfScanStatusVm(&qrf);
3333
+ break;
3334
+ }
3335
+ case QRF_STYLE_Stats:
3336
+ case QRF_STYLE_StatsEst: {
3337
+ qrfEqpStats(&qrf);
3338
+ break;
3339
+ }
3340
+ default: {
3341
+ /* Non-columnar modes where the output can occur after each row
3342
+ ** of result is received */
3343
+ while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
3344
+ qrfOneSimpleRow(&qrf);
3345
+ }
3346
+ break;
3347
+ }
3348
+ }
3349
+ qrfResetStmt(&qrf);
3350
+ qrfFinalize(&qrf);
3351
+ return qrf.iErr;
3352
+}
3353
+
3354
+/************************* End ext/qrf/qrf.c ********************/
6233355
6243356
/* Use console I/O package as a direct INCLUDE. */
6253357
#define SQLITE_INTERNAL_LINKAGE static
6263358
6273359
#ifdef SQLITE_SHELL_FIDDLE
@@ -631,12 +3363,71 @@
6313363
# define SQLITE_CIO_NO_TRANSLATE
6323364
# define SQLITE_CIO_NO_SETMODE
6333365
# define SQLITE_CIO_NO_FLUSH
6343366
#endif
6353367
636
-#define eputz(z) sqlite3_fputs(z,stderr)
637
-#define sputz(fp,z) sqlite3_fputs(z,fp)
3368
+/*
3369
+** Output routines that are able to redirect to memory rather than
3370
+** doing actually I/O.
3371
+** Works like.
3372
+** --------------
3373
+** cli_printf(FILE*, const char*, ...); fprintf()
3374
+** cli_puts(const char*, FILE*); fputs()
3375
+** cli_vprintf(FILE*, const char*, va_list); vfprintf()
3376
+**
3377
+** These are just thin wrappers with the following added semantics:
3378
+** If the file-scope variable cli_output_capture is not NULL, and
3379
+** if the FILE* argument is stdout or stderr, then rather than
3380
+** writing to stdout/stdout, append the text to the cli_output_capture
3381
+** variable.
3382
+**
3383
+** The cli_exit(int) routine works like exit() except that it
3384
+** first dumps any capture output to stdout.
3385
+*/
3386
+static sqlite3_str *cli_output_capture = 0;
3387
+static int cli_printf(FILE *out, const char *zFormat, ...){
3388
+ va_list ap;
3389
+ int rc;
3390
+ va_start(ap,zFormat);
3391
+ if( cli_output_capture && (out==stdout || out==stderr) ){
3392
+ sqlite3_str_vappendf(cli_output_capture, zFormat, ap);
3393
+ rc = 1;
3394
+ }else{
3395
+ rc = sqlite3_vfprintf(out, zFormat, ap);
3396
+ }
3397
+ va_end(ap);
3398
+ return rc;
3399
+}
3400
+static int cli_puts(const char *zText, FILE *out){
3401
+ if( cli_output_capture && (out==stdout || out==stderr) ){
3402
+ sqlite3_str_appendall(cli_output_capture, zText);
3403
+ return 1;
3404
+ }
3405
+ return sqlite3_fputs(zText, out);
3406
+}
3407
+#if 0 /* Not currently used - available if we need it later */
3408
+static int cli_vprintf(FILE *out, const char *zFormat, va_list ap){
3409
+ if( cli_output_capture && (out==stdout || out==stderr) ){
3410
+ sqlite3_str_vappendf(cli_output_capture, zFormat, ap);
3411
+ return 1;
3412
+ }else{
3413
+ return sqlite3_vfprintf(out, zFormat, ap);
3414
+ }
3415
+}
3416
+#endif
3417
+static void cli_exit(int rc){
3418
+ if( cli_output_capture ){
3419
+ char *z = sqlite3_str_finish(cli_output_capture);
3420
+ sqlite3_fputs(z, stdout);
3421
+ fflush(stdout);
3422
+ }
3423
+ exit(rc);
3424
+}
3425
+
3426
+
3427
+#define eputz(z) cli_puts(z,stderr)
3428
+#define sputz(fp,z) cli_puts(z,fp)
6383429
6393430
/* True if the timer is enabled */
6403431
static int enableTimer = 0;
6413432
6423433
/* A version of strcmp() that works with NULL values */
@@ -723,11 +3514,11 @@
7233514
static void endTimer(FILE *out){
7243515
if( enableTimer ){
7253516
sqlite3_int64 iEnd = timeOfDay();
7263517
struct rusage sEnd;
7273518
getrusage(RUSAGE_SELF, &sEnd);
728
- sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
3519
+ cli_printf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
7293520
(iEnd - iBegin)*0.000001,
7303521
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
7313522
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
7323523
}
7333524
}
@@ -804,17 +3595,17 @@
8043595
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
8053596
sqlite3_int64 ftWallEnd = timeOfDay();
8063597
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
8073598
#ifdef _WIN64
8083599
/* microsecond precision on 64-bit windows */
809
- sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
3600
+ cli_printf(out, "Run Time: real %.6f user %f sys %f\n",
8103601
(ftWallEnd - ftWallBegin)*0.000001,
8113602
timeDiff(&ftUserBegin, &ftUserEnd),
8123603
timeDiff(&ftKernelBegin, &ftKernelEnd));
8133604
#else
8143605
/* millisecond precisino on 32-bit windows */
815
- sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
3606
+ cli_printf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
8163607
(ftWallEnd - ftWallBegin)*0.000001,
8173608
timeDiff(&ftUserBegin, &ftUserEnd),
8183609
timeDiff(&ftKernelBegin, &ftKernelEnd));
8193610
#endif
8203611
}
@@ -851,16 +3642,21 @@
8513642
** is true. Otherwise, assume stdin is connected to a file or pipe.
8523643
*/
8533644
static int stdin_is_interactive = 1;
8543645
8553646
/*
856
-** On Windows systems we need to know if standard output is a console
857
-** in order to show that UTF-16 translation is done in the sign-on
858
-** banner. The following variable is true if it is the console.
3647
+** Treat stdout like a TTY if true.
8593648
*/
8603649
static int stdout_is_console = 1;
8613650
3651
+/*
3652
+** Use this value as the width of the output device. Or, figure it
3653
+** out at runtime if the value is negative. Or use a default width
3654
+** if this value is zero.
3655
+*/
3656
+static int stdout_tty_width = -1;
3657
+
8623658
/*
8633659
** The following is the open SQLite database. We make a pointer
8643660
** to this database a static variable so that it can be accessed
8653661
** by the SIGINT handler to interrupt database processing.
8663662
*/
@@ -994,11 +3790,11 @@
9943790
#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
9953791
9963792
/* Indicate out-of-memory and exit. */
9973793
static void shell_out_of_memory(void){
9983794
eputz("Error: out of memory\n");
999
- exit(1);
3795
+ cli_exit(1);
10003796
}
10013797
10023798
/* Check a pointer to see if it is NULL. If it is NULL, exit with an
10033799
** out-of-memory error.
10043800
*/
@@ -1025,306 +3821,24 @@
10253821
char *z;
10263822
if( iotrace==0 ) return;
10273823
va_start(ap, zFormat);
10283824
z = sqlite3_vmprintf(zFormat, ap);
10293825
va_end(ap);
1030
- sqlite3_fprintf(iotrace, "%s", z);
3826
+ cli_printf(iotrace, "%s", z);
10313827
sqlite3_free(z);
10323828
}
10333829
#endif
10343830
1035
-/* Lookup table to estimate the number of columns consumed by a Unicode
1036
-** character.
1037
-*/
1038
-static const struct {
1039
- unsigned char w; /* Width of the character in columns */
1040
- int iFirst; /* First character in a span having this width */
1041
-} aUWidth[] = {
1042
- /* {1, 0x00000}, */
1043
- {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488},
1044
- {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0},
1045
- {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7},
1046
- {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616},
1047
- {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6},
1048
- {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee},
1049
- {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730},
1050
- {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4},
1051
- {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941},
1052
- {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955},
1053
- {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc},
1054
- {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce},
1055
- {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c},
1056
- {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49},
1057
- {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81},
1058
- {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6},
1059
- {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2},
1060
- {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d},
1061
- {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d},
1062
- {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83},
1063
- {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e},
1064
- {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e},
1065
- {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf},
1066
- {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce},
1067
- {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d},
1068
- {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5},
1069
- {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34},
1070
- {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2},
1071
- {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8},
1072
- {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36},
1073
- {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71},
1074
- {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88},
1075
- {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6},
1076
- {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033},
1077
- {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058},
1078
- {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f},
1079
- {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735},
1080
- {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4},
1081
- {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7},
1082
- {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b},
1083
- {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923},
1084
- {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939},
1085
- {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04},
1086
- {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c},
1087
- {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74},
1088
- {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b},
1089
- {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064},
1090
- {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329},
1091
- {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f},
1092
- {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806},
1093
- {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827},
1094
- {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e},
1095
- {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20},
1096
- {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00},
1097
- {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc},
1098
- {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c},
1099
- {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40},
1100
- {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185},
1101
- {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245},
1102
- {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001},
1103
- {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0}
1104
-};
1105
-
1106
-/*
1107
-** Return an estimate of the width, in columns, for the single Unicode
1108
-** character c. For normal characters, the answer is always 1. But the
1109
-** estimate might be 0 or 2 for zero-width and double-width characters.
1110
-**
1111
-** Different display devices display unicode using different widths. So
1112
-** it is impossible to know that true display width with 100% accuracy.
1113
-** Inaccuracies in the width estimates might cause columns to be misaligned.
1114
-** Unfortunately, there is nothing we can do about that.
1115
-*/
1116
-int cli_wcwidth(int c){
1117
- int iFirst, iLast;
1118
-
1119
- /* Fast path for common characters */
1120
- if( c<=0x300 ) return 1;
1121
-
1122
- /* The general case */
1123
- iFirst = 0;
1124
- iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1;
1125
- while( iFirst<iLast-1 ){
1126
- int iMid = (iFirst+iLast)/2;
1127
- int cMid = aUWidth[iMid].iFirst;
1128
- if( cMid < c ){
1129
- iFirst = iMid;
1130
- }else if( cMid > c ){
1131
- iLast = iMid - 1;
1132
- }else{
1133
- return aUWidth[iMid].w;
1134
- }
1135
- }
1136
- if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w;
1137
- return aUWidth[iLast].w;
1138
-}
1139
-
1140
-/*
1141
-** Compute the value and length of a multi-byte UTF-8 character that
1142
-** begins at z[0]. Return the length. Write the Unicode value into *pU.
1143
-**
1144
-** This routine only works for *multi-byte* UTF-8 characters.
1145
-*/
1146
-static int decodeUtf8(const unsigned char *z, int *pU){
1147
- if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){
1148
- *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f);
1149
- return 2;
1150
- }
1151
- if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){
1152
- *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f);
1153
- return 3;
1154
- }
1155
- if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1156
- && (z[3] & 0xc0)==0x80
1157
- ){
1158
- *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1159
- | (z[3] & 0x3f);
1160
- return 4;
1161
- }
1162
- *pU = 0;
1163
- return 1;
1164
-}
1165
-
1166
-
1167
-#if 0 /* NOT USED */
1168
-/*
1169
-** Return the width, in display columns, of a UTF-8 string.
1170
-**
1171
-** Each normal character counts as 1. Zero-width characters count
1172
-** as zero, and double-width characters count as 2.
1173
-*/
1174
-int cli_wcswidth(const char *z){
1175
- const unsigned char *a = (const unsigned char*)z;
1176
- int n = 0;
1177
- int i = 0;
1178
- unsigned char c;
1179
- while( (c = a[i])!=0 ){
1180
- if( c>=0xc0 ){
1181
- int u;
1182
- int len = decodeUtf8(&a[i], &u);
1183
- i += len;
1184
- n += cli_wcwidth(u);
1185
- }else if( c>=' ' ){
1186
- n++;
1187
- i++;
1188
- }else{
1189
- i++;
1190
- }
1191
- }
1192
- return n;
1193
-}
1194
-#endif
1195
-
1196
-/*
1197
-** Check to see if z[] is a valid VT100 escape. If it is, then
1198
-** return the number of bytes in the escape sequence. Return 0 if
1199
-** z[] is not a VT100 escape.
1200
-**
1201
-** This routine assumes that z[0] is \033 (ESC).
1202
-*/
1203
-static int isVt100(const unsigned char *z){
1204
- int i;
1205
- if( z[1]!='[' ) return 0;
1206
- i = 2;
1207
- while( z[i]>=0x30 && z[i]<=0x3f ){ i++; }
1208
- while( z[i]>=0x20 && z[i]<=0x2f ){ i++; }
1209
- if( z[i]<0x40 || z[i]>0x7e ) return 0;
1210
- return i+1;
1211
-}
1212
-
1213
-/*
1214
-** Output string zUtf to stdout as w characters. If w is negative,
1215
-** then right-justify the text. W is the width in UTF-8 characters, not
1216
-** in bytes. This is different from the %*.*s specification in printf
1217
-** since with %*.*s the width is measured in bytes, not characters.
1218
-**
1219
-** Take into account zero-width and double-width Unicode characters.
1220
-** In other words, a zero-width character does not count toward the
1221
-** the w limit. A double-width character counts as two.
1222
-**
1223
-** w should normally be a small number. A couple hundred at most. This
1224
-** routine caps w at 100 million to avoid integer overflow issues.
1225
-*/
1226
-static void utf8_width_print(FILE *out, int w, const char *zUtf){
1227
- const unsigned char *a = (const unsigned char*)zUtf;
1228
- static const int mxW = 10000000;
1229
- unsigned char c;
1230
- int i = 0;
1231
- int n = 0;
1232
- int k;
1233
- int aw;
1234
- if( w<-mxW ){
1235
- w = -mxW;
1236
- }else if( w>mxW ){
1237
- w= mxW;
1238
- }
1239
- aw = w<0 ? -w : w;
1240
- if( zUtf==0 ) zUtf = "";
1241
- while( (c = a[i])!=0 ){
1242
- if( (c&0xc0)==0xc0 ){
1243
- int u;
1244
- int len = decodeUtf8(a+i, &u);
1245
- int x = cli_wcwidth(u);
1246
- if( x+n>aw ){
1247
- break;
1248
- }
1249
- i += len;
1250
- n += x;
1251
- }else if( c==0x1b && (k = isVt100(&a[i]))>0 ){
1252
- i += k;
1253
- }else if( n>=aw ){
1254
- break;
1255
- }else{
1256
- n++;
1257
- i++;
1258
- }
1259
- }
1260
- if( n>=aw ){
1261
- sqlite3_fprintf(out, "%.*s", i, zUtf);
1262
- }else if( w<0 ){
1263
- sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf);
1264
- }else{
1265
- sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, "");
1266
- }
1267
-}
1268
-
1269
-
1270
-/*
1271
-** Determines if a string is a number of not.
1272
-*/
1273
-static int isNumber(const char *z, int *realnum){
1274
- if( *z=='-' || *z=='+' ) z++;
1275
- if( !IsDigit(*z) ){
1276
- return 0;
1277
- }
1278
- z++;
1279
- if( realnum ) *realnum = 0;
1280
- while( IsDigit(*z) ){ z++; }
1281
- if( *z=='.' ){
1282
- z++;
1283
- if( !IsDigit(*z) ) return 0;
1284
- while( IsDigit(*z) ){ z++; }
1285
- if( realnum ) *realnum = 1;
1286
- }
1287
- if( *z=='e' || *z=='E' ){
1288
- z++;
1289
- if( *z=='+' || *z=='-' ) z++;
1290
- if( !IsDigit(*z) ) return 0;
1291
- while( IsDigit(*z) ){ z++; }
1292
- if( realnum ) *realnum = 1;
1293
- }
1294
- return *z==0;
1295
-}
1296
-
12973831
/*
12983832
** Compute a string length that is limited to what can be stored in
12993833
** lower 30 bits of a 32-bit signed integer.
13003834
*/
13013835
static int strlen30(const char *z){
1302
- const char *z2 = z;
1303
- while( *z2 ){ z2++; }
1304
- return 0x3fffffff & (int)(z2 - z);
1305
-}
1306
-
1307
-/*
1308
-** Return the length of a string in characters. Multibyte UTF8 characters
1309
-** count as a single character for single-width characters, or as two
1310
-** characters for double-width characters.
1311
-*/
1312
-static int strlenChar(const char *z){
1313
- int n = 0;
1314
- while( *z ){
1315
- if( (0x80&z[0])==0 ){
1316
- n++;
1317
- z++;
1318
- }else{
1319
- int u = 0;
1320
- int len = decodeUtf8((const u8*)z, &u);
1321
- z += len;
1322
- n += cli_wcwidth(u);
1323
- }
1324
- }
1325
- return n;
3836
+ size_t n;
3837
+ if( z==0 ) return 0;
3838
+ n = strlen(z);
3839
+ return n>0x3fffffff ? 0x3fffffff : (int)n;
13263840
}
13273841
13283842
/*
13293843
** Return open FILE * if zFile exists, can be opened for read
13303844
** and is an ordinary file or a character stream source.
@@ -1770,11 +4284,11 @@
17704284
** work here in the middle of this regular program.
17714285
*/
17724286
#define SQLITE_EXTENSION_INIT1
17734287
#define SQLITE_EXTENSION_INIT2(X) (void)(X)
17744288
1775
-/************************* Begin ../ext/misc/windirent.h ******************/
4289
+/************************* Begin ext/misc/windirent.h ******************/
17764290
/*
17774291
** 2025-06-05
17784292
**
17794293
** The author disclaims copyright to this source code. In place of
17804294
** a legal notice, here is a blessing:
@@ -1935,12 +4449,12 @@
19354449
return &pDir->cur;
19364450
}
19374451
19384452
#endif /* defined(_WIN32) && defined(_MSC_VER) */
19394453
1940
-/************************* End ../ext/misc/windirent.h ********************/
1941
-/************************* Begin ../ext/misc/memtrace.c ******************/
4454
+/************************* End ext/misc/windirent.h ********************/
4455
+/************************* Begin ext/misc/memtrace.c ******************/
19424456
/*
19434457
** 2019-01-21
19444458
**
19454459
** The author disclaims copyright to this source code. In place of
19464460
** a legal notice, here is a blessing:
@@ -2046,12 +4560,12 @@
20464560
}
20474561
memtraceOut = 0;
20484562
return rc;
20494563
}
20504564
2051
-/************************* End ../ext/misc/memtrace.c ********************/
2052
-/************************* Begin ../ext/misc/pcachetrace.c ******************/
4565
+/************************* End ext/misc/memtrace.c ********************/
4566
+/************************* Begin ext/misc/pcachetrace.c ******************/
20534567
/*
20544568
** 2023-06-21
20554569
**
20564570
** The author disclaims copyright to this source code. In place of
20574571
** a legal notice, here is a blessing:
@@ -2228,12 +4742,12 @@
22284742
}
22294743
pcachetraceOut = 0;
22304744
return rc;
22314745
}
22324746
2233
-/************************* End ../ext/misc/pcachetrace.c ********************/
2234
-/************************* Begin ../ext/misc/shathree.c ******************/
4747
+/************************* End ext/misc/pcachetrace.c ********************/
4748
+/************************* Begin ext/misc/shathree.c ******************/
22354749
/*
22364750
** 2017-03-08
22374751
**
22384752
** The author disclaims copyright to this source code. In place of
22394753
** a legal notice, here is a blessing:
@@ -3085,12 +5599,12 @@
30855599
0, sha3QueryFunc, 0, 0);
30865600
}
30875601
return rc;
30885602
}
30895603
3090
-/************************* End ../ext/misc/shathree.c ********************/
3091
-/************************* Begin ../ext/misc/sha1.c ******************/
5604
+/************************* End ext/misc/shathree.c ********************/
5605
+/************************* Begin ext/misc/sha1.c ******************/
30925606
/*
30935607
** 2017-01-27
30945608
**
30955609
** The author disclaims copyright to this source code. In place of
30965610
** a legal notice, here is a blessing:
@@ -3497,12 +6011,12 @@
34976011
sha1QueryFunc, 0, 0);
34986012
}
34996013
return rc;
35006014
}
35016015
3502
-/************************* End ../ext/misc/sha1.c ********************/
3503
-/************************* Begin ../ext/misc/uint.c ******************/
6016
+/************************* End ext/misc/sha1.c ********************/
6017
+/************************* Begin ext/misc/uint.c ******************/
35046018
/*
35056019
** 2020-04-14
35066020
**
35076021
** The author disclaims copyright to this source code. In place of
35086022
** a legal notice, here is a blessing:
@@ -3592,12 +6106,12 @@
35926106
SQLITE_EXTENSION_INIT2(pApi);
35936107
(void)pzErrMsg; /* Unused parameter */
35946108
return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
35956109
}
35966110
3597
-/************************* End ../ext/misc/uint.c ********************/
3598
-/************************* Begin ../ext/misc/decimal.c ******************/
6111
+/************************* End ext/misc/uint.c ********************/
6112
+/************************* Begin ext/misc/decimal.c ******************/
35996113
/*
36006114
** 2020-06-22
36016115
**
36026116
** The author disclaims copyright to this source code. In place of
36036117
** a legal notice, here is a blessing:
@@ -4497,14 +7011,14 @@
44977011
0, decimalCollFunc);
44987012
}
44997013
return rc;
45007014
}
45017015
4502
-/************************* End ../ext/misc/decimal.c ********************/
7016
+/************************* End ext/misc/decimal.c ********************/
45037017
#undef sqlite3_base_init
45047018
#define sqlite3_base_init sqlite3_base64_init
4505
-/************************* Begin ../ext/misc/base64.c ******************/
7019
+/************************* Begin ext/misc/base64.c ******************/
45067020
/*
45077021
** 2022-11-18
45087022
**
45097023
** The author disclaims copyright to this source code. In place of
45107024
** a legal notice, here is a blessing:
@@ -4799,15 +7313,15 @@
47997313
** allows shell.c, as distributed, to have this extension built in.
48007314
*/
48017315
#define BASE64_INIT(db) sqlite3_base64_init(db, 0, 0)
48027316
#define BASE64_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */
48037317
4804
-/************************* End ../ext/misc/base64.c ********************/
7318
+/************************* End ext/misc/base64.c ********************/
48057319
#undef sqlite3_base_init
48067320
#define sqlite3_base_init sqlite3_base85_init
48077321
#define OMIT_BASE85_CHECKER
4808
-/************************* Begin ../ext/misc/base85.c ******************/
7322
+/************************* Begin ext/misc/base85.c ******************/
48097323
/*
48107324
** 2022-11-16
48117325
**
48127326
** The author disclaims copyright to this source code. In place of
48137327
** a legal notice, here is a blessing:
@@ -5259,12 +7773,12 @@
52597773
return rc;
52607774
}
52617775
52627776
#endif
52637777
5264
-/************************* End ../ext/misc/base85.c ********************/
5265
-/************************* Begin ../ext/misc/ieee754.c ******************/
7778
+/************************* End ext/misc/base85.c ********************/
7779
+/************************* Begin ext/misc/ieee754.c ******************/
52667780
/*
52677781
** 2013-04-17
52687782
**
52697783
** The author disclaims copyright to this source code. In place of
52707784
** a legal notice, here is a blessing:
@@ -5589,12 +8103,12 @@
55898103
aFunc[i].xFunc, 0, 0);
55908104
}
55918105
return rc;
55928106
}
55938107
5594
-/************************* End ../ext/misc/ieee754.c ********************/
5595
-/************************* Begin ../ext/misc/series.c ******************/
8108
+/************************* End ext/misc/ieee754.c ********************/
8109
+/************************* Begin ext/misc/series.c ******************/
55968110
/*
55978111
** 2015-08-18, 2023-04-28
55988112
**
55998113
** The author disclaims copyright to this source code. In place of
56008114
** a legal notice, here is a blessing:
@@ -6529,12 +9043,12 @@
65299043
rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
65309044
#endif
65319045
return rc;
65329046
}
65339047
6534
-/************************* End ../ext/misc/series.c ********************/
6535
-/************************* Begin ../ext/misc/regexp.c ******************/
9048
+/************************* End ext/misc/series.c ********************/
9049
+/************************* Begin ext/misc/regexp.c ******************/
65369050
/*
65379051
** 2012-11-13
65389052
**
65399053
** The author disclaims copyright to this source code. In place of
65409054
** a legal notice, here is a blessing:
@@ -7446,13 +9960,13 @@
74469960
#endif /* SQLITE_DEBUG */
74479961
}
74489962
return rc;
74499963
}
74509964
7451
-/************************* End ../ext/misc/regexp.c ********************/
9965
+/************************* End ext/misc/regexp.c ********************/
74529966
#ifndef SQLITE_SHELL_FIDDLE
7453
-/************************* Begin ../ext/misc/fileio.c ******************/
9967
+/************************* Begin ext/misc/fileio.c ******************/
74549968
/*
74559969
** 2014-06-13
74569970
**
74579971
** The author disclaims copyright to this source code. In place of
74589972
** a legal notice, here is a blessing:
@@ -8574,20 +11088,12 @@
857411088
rc = fsdirRegister(db);
857511089
}
857611090
return rc;
857711091
}
857811092
8579
-#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
8580
-/* To allow a standalone DLL, make test_windirent.c use the same
8581
- * redefined SQLite API calls as the above extension code does.
8582
- * Just pull in this .c to accomplish this. As a beneficial side
8583
- * effect, this extension becomes a single translation unit. */
8584
-# include "test_windirent.c"
8585
-#endif
8586
-
8587
-/************************* End ../ext/misc/fileio.c ********************/
8588
-/************************* Begin ../ext/misc/completion.c ******************/
11093
+/************************* End ext/misc/fileio.c ********************/
11094
+/************************* Begin ext/misc/completion.c ******************/
858911095
/*
859011096
** 2017-07-10
859111097
**
859211098
** The author disclaims copyright to this source code. In place of
859311099
** a legal notice, here is a blessing:
@@ -9095,12 +11601,12 @@
909511601
rc = sqlite3CompletionVtabInit(db);
909611602
#endif
909711603
return rc;
909811604
}
909911605
9100
-/************************* End ../ext/misc/completion.c ********************/
9101
-/************************* Begin ../ext/misc/appendvfs.c ******************/
11606
+/************************* End ext/misc/completion.c ********************/
11607
+/************************* Begin ext/misc/appendvfs.c ******************/
910211608
/*
910311609
** 2017-10-20
910411610
**
910511611
** The author disclaims copyright to this source code. In place of
910611612
** a legal notice, here is a blessing:
@@ -9770,14 +12276,14 @@
977012276
#endif
977112277
if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
977212278
return rc;
977312279
}
977412280
9775
-/************************* End ../ext/misc/appendvfs.c ********************/
12281
+/************************* End ext/misc/appendvfs.c ********************/
977612282
#endif
977712283
#ifdef SQLITE_HAVE_ZLIB
9778
-/************************* Begin ../ext/misc/zipfile.c ******************/
12284
+/************************* Begin ext/misc/zipfile.c ******************/
977912285
/*
978012286
** 2017-12-26
978112287
**
978212288
** The author disclaims copyright to this source code. In place of
978312289
** a legal notice, here is a blessing:
@@ -12062,12 +14568,12 @@
1206214568
SQLITE_EXTENSION_INIT2(pApi);
1206314569
(void)pzErrMsg; /* Unused parameter */
1206414570
return zipfileRegister(db);
1206514571
}
1206614572
12067
-/************************* End ../ext/misc/zipfile.c ********************/
12068
-/************************* Begin ../ext/misc/sqlar.c ******************/
14573
+/************************* End ext/misc/zipfile.c ********************/
14574
+/************************* Begin ext/misc/sqlar.c ******************/
1206914575
/*
1207014576
** 2017-12-17
1207114577
**
1207214578
** The author disclaims copyright to this source code. In place of
1207314579
** a legal notice, here is a blessing:
@@ -12191,14 +14697,14 @@
1219114697
sqlarUncompressFunc, 0, 0);
1219214698
}
1219314699
return rc;
1219414700
}
1219514701
12196
-/************************* End ../ext/misc/sqlar.c ********************/
14702
+/************************* End ext/misc/sqlar.c ********************/
1219714703
#endif
1219814704
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
12199
-/************************* Begin ../ext/expert/sqlite3expert.h ******************/
14705
+/************************* Begin ext/expert/sqlite3expert.h ******************/
1220014706
/*
1220114707
** 2017 April 07
1220214708
**
1220314709
** The author disclaims copyright to this source code. In place of
1220414710
** a legal notice, here is a blessing:
@@ -12364,12 +14870,12 @@
1236414870
*/
1236514871
void sqlite3_expert_destroy(sqlite3expert*);
1236614872
1236714873
#endif /* !defined(SQLITEEXPERT_H) */
1236814874
12369
-/************************* End ../ext/expert/sqlite3expert.h ********************/
12370
-/************************* Begin ../ext/expert/sqlite3expert.c ******************/
14875
+/************************* End ext/expert/sqlite3expert.h ********************/
14876
+/************************* Begin ext/expert/sqlite3expert.c ******************/
1237114877
/*
1237214878
** 2017 April 09
1237314879
**
1237414880
** The author disclaims copyright to this source code. In place of
1237514881
** a legal notice, here is a blessing:
@@ -14603,13 +17109,13 @@
1460317109
}
1460417110
}
1460517111
1460617112
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
1460717113
14608
-/************************* End ../ext/expert/sqlite3expert.c ********************/
17114
+/************************* End ext/expert/sqlite3expert.c ********************/
1460917115
#endif
14610
-/************************* Begin ../ext/intck/sqlite3intck.h ******************/
17116
+/************************* Begin ext/intck/sqlite3intck.h ******************/
1461117117
/*
1461217118
** 2024-02-08
1461317119
**
1461417120
** The author disclaims copyright to this source code. In place of
1461517121
** a legal notice, here is a blessing:
@@ -14778,12 +17284,12 @@
1477817284
} /* end of the 'extern "C"' block */
1477917285
#endif
1478017286
1478117287
#endif /* ifndef _SQLITE_INTCK_H */
1478217288
14783
-/************************* End ../ext/intck/sqlite3intck.h ********************/
14784
-/************************* Begin ../ext/intck/sqlite3intck.c ******************/
17289
+/************************* End ext/intck/sqlite3intck.h ********************/
17290
+/************************* Begin ext/intck/sqlite3intck.c ******************/
1478517291
/*
1478617292
** 2024-02-08
1478717293
**
1478817294
** The author disclaims copyright to this source code. In place of
1478917295
** a legal notice, here is a blessing:
@@ -14942,10 +17448,11 @@
1494217448
}
1494317449
}else{
1494417450
sqlite3_free(zRet);
1494517451
zRet = 0;
1494617452
}
17453
+ va_end(ap);
1494717454
return zRet;
1494817455
}
1494917456
1495017457
/*
1495117458
** This is used by sqlite3_intck_unlock() to save the vector key value
@@ -15721,12 +18228,12 @@
1572118228
}
1572218229
}
1572318230
return p->zTestSql;
1572418231
}
1572518232
15726
-/************************* End ../ext/intck/sqlite3intck.c ********************/
15727
-/************************* Begin ../ext/misc/stmtrand.c ******************/
18233
+/************************* End ext/intck/sqlite3intck.c ********************/
18234
+/************************* Begin ext/misc/stmtrand.c ******************/
1572818235
/*
1572918236
** 2024-05-24
1573018237
**
1573118238
** The author disclaims copyright to this source code. In place of
1573218239
** a legal notice, here is a blessing:
@@ -15821,12 +18328,12 @@
1582118328
stmtrandFunc, 0, 0);
1582218329
}
1582318330
return rc;
1582418331
}
1582518332
15826
-/************************* End ../ext/misc/stmtrand.c ********************/
15827
-/************************* Begin ../ext/misc/vfstrace.c ******************/
18333
+/************************* End ext/misc/stmtrand.c ********************/
18334
+/************************* Begin ext/misc/vfstrace.c ******************/
1582818335
/*
1582918336
** 2011 March 16
1583018337
**
1583118338
** The author disclaims copyright to this source code. In place of
1583218339
** a legal notice, here is a blessing:
@@ -17035,19 +19542,19 @@
1703519542
if( pVfs->xOpen!=vfstraceOpen ) return;
1703619543
sqlite3_vfs_unregister(pVfs);
1703719544
sqlite3_free(pVfs);
1703819545
}
1703919546
17040
-/************************* End ../ext/misc/vfstrace.c ********************/
19547
+/************************* End ext/misc/vfstrace.c ********************/
1704119548
1704219549
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1704319550
#define SQLITE_SHELL_HAVE_RECOVER 1
1704419551
#else
1704519552
#define SQLITE_SHELL_HAVE_RECOVER 0
1704619553
#endif
1704719554
#if SQLITE_SHELL_HAVE_RECOVER
17048
-/************************* Begin ../ext/recover/sqlite3recover.h ******************/
19555
+/************************* Begin ext/recover/sqlite3recover.h ******************/
1704919556
/*
1705019557
** 2022-08-27
1705119558
**
1705219559
** The author disclaims copyright to this source code. In place of
1705319560
** a legal notice, here is a blessing:
@@ -17294,13 +19801,13 @@
1729419801
} /* end of the 'extern "C"' block */
1729519802
#endif
1729619803
1729719804
#endif /* ifndef _SQLITE_RECOVER_H */
1729819805
17299
-/************************* End ../ext/recover/sqlite3recover.h ********************/
19806
+/************************* End ext/recover/sqlite3recover.h ********************/
1730019807
# ifndef SQLITE_HAVE_SQLITE3R
17301
-/************************* Begin ../ext/recover/dbdata.c ******************/
19808
+/************************* Begin ext/recover/dbdata.c ******************/
1730219809
/*
1730319810
** 2019-04-17
1730419811
**
1730519812
** The author disclaims copyright to this source code. In place of
1730619813
** a legal notice, here is a blessing:
@@ -18321,12 +20828,12 @@
1832120828
return sqlite3DbdataRegister(db);
1832220829
}
1832320830
1832420831
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
1832520832
18326
-/************************* End ../ext/recover/dbdata.c ********************/
18327
-/************************* Begin ../ext/recover/sqlite3recover.c ******************/
20833
+/************************* End ext/recover/dbdata.c ********************/
20834
+/************************* Begin ext/recover/sqlite3recover.c ******************/
1832820835
/*
1832920836
** 2022-08-27
1833020837
**
1833120838
** The author disclaims copyright to this source code. In place of
1833220839
** a legal notice, here is a blessing:
@@ -21225,11 +23732,11 @@
2122523732
return rc;
2122623733
}
2122723734
2122823735
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
2122923736
21230
-/************************* End ../ext/recover/sqlite3recover.c ********************/
23737
+/************************* End ext/recover/sqlite3recover.c ********************/
2123123738
# endif /* SQLITE_HAVE_SQLITE3R */
2123223739
#endif
2123323740
#ifdef SQLITE_SHELL_EXTSRC
2123423741
# include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
2123523742
#endif
@@ -21253,97 +23760,78 @@
2125323760
sqlite3expert *pExpert;
2125423761
int bVerbose;
2125523762
};
2125623763
#endif
2125723764
21258
-/* A single line in the EQP output */
21259
-typedef struct EQPGraphRow EQPGraphRow;
21260
-struct EQPGraphRow {
21261
- int iEqpId; /* ID for this row */
21262
- int iParentId; /* ID of the parent row */
21263
- EQPGraphRow *pNext; /* Next row in sequence */
21264
- char zText[1]; /* Text to display for this row */
21265
-};
21266
-
21267
-/* All EQP output is collected into an instance of the following */
21268
-typedef struct EQPGraph EQPGraph;
21269
-struct EQPGraph {
21270
- EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
21271
- EQPGraphRow *pLast; /* Last element of the pRow list */
21272
- char zPrefix[100]; /* Graph prefix */
21273
-};
21274
-
21275
-/* Parameters affecting columnar mode result display (defaulting together) */
21276
-typedef struct ColModeOpts {
21277
- int iWrap; /* In columnar modes, wrap lines reaching this limit */
21278
- u8 bQuote; /* Quote results for .mode box and table */
21279
- u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
21280
-} ColModeOpts;
21281
-#define ColModeOpts_default { 60, 0, 0 }
21282
-#define ColModeOpts_default_qbox { 60, 1, 0 }
23765
+/* All the parameters that determine how to render query results.
23766
+*/
23767
+typedef struct Mode {
23768
+ u8 autoExplain; /* Automatically turn on .explain mode */
23769
+ u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */
23770
+ u8 autoEQPtrace; /* autoEQP is in trace mode */
23771
+ u8 scanstatsOn; /* True to display scan stats before each finalize */
23772
+ u8 bAutoScreenWidth; /* Using the TTY to determine screen width */
23773
+ u8 mFlags; /* MFLG_ECHO and/or MFLG_CRLF */
23774
+ u8 eMode; /* One of the MODE_ values */
23775
+ sqlite3_qrf_spec spec; /* Spec to be passed into QRF */
23776
+} Mode;
23777
+
23778
+/* Flags for Mode.mFlags */
23779
+#define MFLG_ECHO 0x01 /* Echo inputs to output */
23780
+#define MFLG_CRLF 0x02 /* Use CR/LF output line endings */
23781
+
2128323782
2128423783
/*
2128523784
** State information about the database connection is contained in an
2128623785
** instance of the following structure.
2128723786
*/
2128823787
typedef struct ShellState ShellState;
2128923788
struct ShellState {
2129023789
sqlite3 *db; /* The database */
21291
- u8 autoExplain; /* Automatically turn on .explain mode */
21292
- u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */
21293
- u8 autoEQPtest; /* autoEQP is in test mode */
21294
- u8 autoEQPtrace; /* autoEQP is in trace mode */
21295
- u8 scanstatsOn; /* True to display scan stats before each finalize */
23790
+ int iCompat; /* Compatibility date YYYYMMDD */
2129623791
u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
2129723792
u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
2129823793
u8 nEqpLevel; /* Depth of the EQP output graph */
2129923794
u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
2130023795
u8 bSafeMode; /* True to prohibit unsafe operations */
2130123796
u8 bSafeModePersist; /* The long-term value of bSafeMode */
2130223797
u8 eRestoreState; /* See comments above doAutoDetectRestore() */
21303
- u8 crlfMode; /* Do NL-to-CRLF translations when enabled (maybe) */
21304
- u8 eEscMode; /* Escape mode for text output */
21305
- ColModeOpts cmOpts; /* Option values affecting columnar mode output */
2130623798
unsigned statsOn; /* True to display memory stats before each finalize */
2130723799
unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
23800
+ u8 nPopOutput; /* Revert .output settings when reaching zero */
23801
+ u8 nPopMode; /* Revert .mode settings when reaching zero */
2130823802
int inputNesting; /* Track nesting level of .read and other redirects */
21309
- int outCount; /* Revert to stdout when reaching zero */
21310
- int cnt; /* Number of records displayed so far */
2131123803
i64 lineno; /* Line number of last line read from in */
23804
+ const char *zInFile; /* Name of the input file */
2131223805
int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
2131323806
FILE *in; /* Read commands from this stream */
2131423807
FILE *out; /* Write results here */
2131523808
FILE *traceOut; /* Output for sqlite3_trace() */
2131623809
int nErr; /* Number of errors seen */
21317
- int mode; /* An output mode setting */
21318
- int modePrior; /* Saved mode */
21319
- int cMode; /* temporary output mode for the current query */
21320
- int normalMode; /* Output mode before ".explain on" */
2132123810
int writableSchema; /* True if PRAGMA writable_schema=ON */
21322
- int showHeader; /* True to show column names in List or Column mode */
2132323811
int nCheck; /* Number of ".check" commands run */
2132423812
unsigned nProgress; /* Number of progress callbacks encountered */
2132523813
unsigned mxProgress; /* Maximum progress callbacks before failing */
2132623814
unsigned flgProgress; /* Flags for the progress callback */
2132723815
unsigned shellFlgs; /* Various flags */
21328
- unsigned priorShFlgs; /* Saved copy of flags */
23816
+ unsigned nTestRun; /* Number of test cases run */
23817
+ unsigned nTestErr; /* Number of test cases that failed */
2132923818
sqlite3_int64 szMax; /* --maxsize argument to .open */
2133023819
char *zDestTable; /* Name of destination table when MODE_Insert */
2133123820
char *zTempFile; /* Temporary file that might need deleting */
23821
+ char *zErrPrefix; /* Alternative error message prefix */
2133223822
char zTestcase[30]; /* Name of current test case */
21333
- char colSeparator[20]; /* Column separator character for several modes */
21334
- char rowSeparator[20]; /* Row separator character for MODE_Ascii */
21335
- char colSepPrior[20]; /* Saved column separator */
21336
- char rowSepPrior[20]; /* Saved row separator */
21337
- int *colWidth; /* Requested width of each column in columnar modes */
21338
- int *actualWidth; /* Actual width of each column */
21339
- int nWidth; /* Number of slots in colWidth[] and actualWidth[] */
21340
- char nullValue[20]; /* The text to print when a NULL comes back from
21341
- ** the database */
2134223823
char outfile[FILENAME_MAX]; /* Filename for *out */
2134323824
sqlite3_stmt *pStmt; /* Current statement if any. */
2134423825
FILE *pLog; /* Write log output here */
23826
+ Mode mode; /* Current display mode */
23827
+ Mode modePrior; /* Backup */
23828
+ struct SavedMode { /* Ability to define custom mode configurations */
23829
+ char *zTag; /* Name of this saved mode */
23830
+ Mode mode; /* The saved mode */
23831
+ } *aSavedModes; /* Array of saved .mode settings. system malloc() */
23832
+ int nSavedModes; /* Number of saved .mode settings */
2134523833
struct AuxDb { /* Storage space for auxiliary database connections */
2134623834
sqlite3 *db; /* Connection pointer */
2134723835
const char *zDbFilename; /* Filename used to open the connection */
2134823836
char *zFreeOnClose; /* Free this memory allocation on close */
2134923837
#if defined(SQLITE_ENABLE_SESSION)
@@ -21350,18 +23838,23 @@
2135023838
int nSession; /* Number of active sessions */
2135123839
OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
2135223840
#endif
2135323841
} aAuxDb[5], /* Array of all database connections */
2135423842
*pAuxDb; /* Currently active database connection */
21355
- int *aiIndent; /* Array of indents used in MODE_Explain */
21356
- int nIndent; /* Size of array aiIndent[] */
21357
- int iIndent; /* Index of current op in aiIndent[] */
2135823843
char *zNonce; /* Nonce for temporary safe-mode escapes */
21359
- EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
2136023844
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2136123845
ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
2136223846
#endif
23847
+ struct DotCmdLine { /* Info about arguments to a dot-command */
23848
+ const char *zOrig; /* Original text of the dot-command */
23849
+ char *zCopy; /* Copy of zOrig, from malloc() */
23850
+ int nAlloc; /* Size of allocates for arrays below */
23851
+ int nArg; /* Number of argument slots actually used */
23852
+ char **azArg; /* Pointer to each argument, dequoted */
23853
+ int *aiOfst; /* Offset into zOrig[] for start of each arg */
23854
+ char *abQuot; /* True if the argment was originally quoted */
23855
+ } dot;
2136323856
#ifdef SQLITE_SHELL_FIDDLE
2136423857
struct {
2136523858
const char * zInput; /* Input string from wasm/JS proxy */
2136623859
const char * zPos; /* Cursor pos into zInput */
2136723860
const char * zDefaultDbName; /* Default name for db file */
@@ -21372,11 +23865,11 @@
2137223865
#ifdef SQLITE_SHELL_FIDDLE
2137323866
static ShellState shellState;
2137423867
#endif
2137523868
2137623869
21377
-/* Allowed values for ShellState.autoEQP
23870
+/* Allowed values for ShellState.mode.autoEQP
2137823871
*/
2137923872
#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
2138023873
#define AUTOEQP_on 1 /* Automatic EQP is on */
2138123874
#define AUTOEQP_trigger 2 /* On and also show plans for triggers */
2138223875
#define AUTOEQP_full 3 /* Show full EXPLAIN */
@@ -21401,30 +23894,25 @@
2140123894
#define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progress
2140223895
** callback limit is reached, and for each
2140323896
** top-level SQL statement */
2140423897
#define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
2140523898
21406
-/* Allowed values for ShellState.eEscMode. The default value should
21407
-** be 0, so to change the default, reorder the names.
23899
+/* Names of values for Mode.spec.eEsc and Mode.spec.eText
2140823900
*/
21409
-#define SHELL_ESC_ASCII 0 /* Substitute ^Y for X where Y=X+0x40 */
21410
-#define SHELL_ESC_SYMBOL 1 /* Substitute U+2400 graphics */
21411
-#define SHELL_ESC_OFF 2 /* Send characters verbatim */
21412
-
21413
-static const char *shell_EscModeNames[] = { "ascii", "symbol", "off" };
23901
+static const char *qrfEscNames[] = { "auto", "off", "ascii", "symbol" };
23902
+static const char *qrfQuoteNames[] =
23903
+ { "off","off","sql","hex","csv","tcl","json"};
2141423904
2141523905
/*
2141623906
** These are the allowed shellFlgs values
2141723907
*/
2141823908
#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
2141923909
#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
2142023910
#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
2142123911
#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
21422
-#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
23912
+#define SHFLG_NoErrLineno 0x00000010 /* Omit line numbers from error msgs */
2142323913
#define SHFLG_CountChanges 0x00000020 /* .changes setting */
21424
-#define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */
21425
-#define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */
2142623914
#define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
2142723915
#define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
2142823916
#define SHFLG_TestingMode 0x00000400 /* allow unsafe testing features */
2142923917
2143023918
/*
@@ -21433,58 +23921,105 @@
2143323921
#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
2143423922
#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
2143523923
#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
2143623924
2143723925
/*
21438
-** These are the allowed modes.
23926
+** These are the allowed values for Mode.eMode. There is a lot of overlap
23927
+** between these values and the Mode.spec.eStyle values, but they are not
23928
+** one-to-one, and thus need to be tracked separately.
2143923929
*/
21440
-#define MODE_Line 0 /* One column per line. Blank line between records */
21441
-#define MODE_Column 1 /* One record per line in neat columns */
21442
-#define MODE_List 2 /* One record per line with a separator */
21443
-#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
21444
-#define MODE_Html 4 /* Generate an XHTML table */
21445
-#define MODE_Insert 5 /* Generate SQL "insert" statements */
21446
-#define MODE_Quote 6 /* Quote values as for SQL */
21447
-#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
21448
-#define MODE_Csv 8 /* Quote strings, numbers are plain */
21449
-#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
21450
-#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
21451
-#define MODE_Pretty 11 /* Pretty-print schemas */
21452
-#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
21453
-#define MODE_Json 13 /* Output JSON */
21454
-#define MODE_Markdown 14 /* Markdown formatting */
21455
-#define MODE_Table 15 /* MySQL-style table formatting */
21456
-#define MODE_Box 16 /* Unicode box-drawing characters */
21457
-#define MODE_Count 17 /* Output only a count of the rows of output */
21458
-#define MODE_Off 18 /* No query output shown */
21459
-#define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */
21460
-#define MODE_Www 20 /* Full web-page output */
21461
-
21462
-static const char *modeDescr[] = {
21463
- "line",
21464
- "column",
21465
- "list",
21466
- "semi",
21467
- "html",
21468
- "insert",
21469
- "quote",
21470
- "tcl",
21471
- "csv",
21472
- "explain",
21473
- "ascii",
21474
- "prettyprint",
21475
- "eqp",
21476
- "json",
21477
- "markdown",
21478
- "table",
21479
- "box",
21480
- "count",
21481
- "off",
21482
- "scanexp",
21483
- "www",
23930
+#define MODE_Ascii 0 /* Use ASCII unit and record separators (0x1F/0x1E) */
23931
+#define MODE_Box 1 /* Unicode box-drawing characters */
23932
+#define MODE_C 2 /* Comma-separated list of C-strings */
23933
+#define MODE_Column 3 /* One record per line in neat columns */
23934
+#define MODE_Count 4 /* Output only a count of the rows of output */
23935
+#define MODE_Csv 5 /* Quote strings, numbers are plain */
23936
+#define MODE_Html 6 /* Generate an XHTML table */
23937
+#define MODE_Insert 7 /* Generate SQL "insert" statements */
23938
+#define MODE_JAtom 8 /* Comma-separated list of JSON atoms */
23939
+#define MODE_JObject 9 /* One JSON object per row */
23940
+#define MODE_Json 10 /* Output JSON */
23941
+#define MODE_Line 11 /* One column per line. Blank line between records */
23942
+#define MODE_List 12 /* One record per line with a separator */
23943
+#define MODE_Markdown 13 /* Markdown formatting */
23944
+#define MODE_Off 14 /* No query output shown */
23945
+#define MODE_QBox 15 /* BOX with SQL-quoted content */
23946
+#define MODE_Quote 16 /* Quote values as for SQL */
23947
+#define MODE_Table 17 /* MySQL-style table formatting */
23948
+#define MODE_Tabs 18 /* Tab-separated values */
23949
+#define MODE_Tcl 19 /* Space-separated list of TCL strings */
23950
+#define MODE_Www 20 /* Full web-page output */
23951
+
23952
+#define MODE_BUILTIN 20 /* Maximum built-in mode */
23953
+#define MODE_BATCH 50 /* Default mode for batch processing */
23954
+#define MODE_TTY 51 /* Default mode for interactive processing */
23955
+#define MODE_USER 75 /* First user-defined mode */
23956
+#define MODE_N_USER 25 /* Maximum number of user-defined modes */
23957
+
23958
+/*
23959
+** Information about built-in display modes
23960
+*/
23961
+typedef struct ModeInfo ModeInfo;
23962
+struct ModeInfo {
23963
+ char zName[9]; /* Symbolic name of the mode */
23964
+ unsigned char eCSep; /* Column separator */
23965
+ unsigned char eRSep; /* Row separator */
23966
+ unsigned char eNull; /* Null representation */
23967
+ unsigned char eText; /* Default text encoding */
23968
+ unsigned char eHdr; /* Default header encoding. */
23969
+ unsigned char eBlob; /* Default blob encoding. */
23970
+ unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
23971
+ unsigned char eStyle; /* Underlying QRF style */
23972
+ unsigned char eCx; /* 0: other, 1: line, 2: columnar */
2148423973
};
2148523974
23975
+/* String constants used by built-in modes */
23976
+static const char *aModeStr[] =
23977
+ /* 0 1 2 3 4 5 6 7 8 */
23978
+ { 0, "\n", "|", " ", ",", "\r\n", "\036", "\037", "\t",
23979
+ "", "NULL", "null", "\"\"" };
23980
+ /* 9 10 11 12 */
23981
+
23982
+static const ModeInfo aModeInfo[] = {
23983
+/* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
23984
+ { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 },
23985
+ { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 },
23986
+ { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 },
23987
+ { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 },
23988
+ { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 },
23989
+ { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 },
23990
+ { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 },
23991
+ { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 },
23992
+ { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 },
23993
+ { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 },
23994
+ { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 },
23995
+ { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 },
23996
+ { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 },
23997
+ { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 },
23998
+ { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 },
23999
+ { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 },
24000
+ { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 },
24001
+ { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 },
24002
+ { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 },
24003
+ { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 },
24004
+ { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 }
24005
+}; /* | / / | / / | | \
24006
+ ** | / / | / / | | \_ 2: columnar
24007
+ ** Index into aModeStr[] | / / | | 1: line
24008
+ ** | / / | | 0: other
24009
+ ** | / / | \
24010
+ ** text encoding |/ | show | \
24011
+ ** v-------------------' | hdrs? | The QRF style
24012
+ ** 0: n/a blob | v-----'
24013
+ ** 1: plain v_---------' 0: n/a
24014
+ ** 2: sql 0: n/a 1: no
24015
+ ** 3: csv 1: as-text 2: yes
24016
+ ** 4: html 2: sql
24017
+ ** 5: c 3: hex
24018
+ ** 6: json 4: c
24019
+ ** 5: json
24020
+ ******************************************************************/
2148624021
/*
2148724022
** These are the column/row/line separators used by the various
2148824023
** import/export modes.
2148924024
*/
2149024025
#define SEP_Column "|"
@@ -21499,18 +24034,183 @@
2149924034
/*
2150024035
** Limit input nesting via .read or any other input redirect.
2150124036
** It's not too expensive, so a generous allowance can be made.
2150224037
*/
2150324038
#define MAX_INPUT_NESTING 25
24039
+
24040
+
24041
+/*
24042
+** Clear a display mode, freeing any allocated memory that it
24043
+** contains.
24044
+*/
24045
+static void modeFree(Mode *p){
24046
+ free(p->spec.aWidth);
24047
+ free(p->spec.aAlign);
24048
+ free(p->spec.zColumnSep);
24049
+ free(p->spec.zRowSep);
24050
+ free(p->spec.zTableName);
24051
+ free(p->spec.zNull);
24052
+ memset(p, 0, sizeof(*p));
24053
+ p->spec.iVersion = 1;
24054
+}
24055
+
24056
+/*
24057
+** Duplicate Mode pSrc into pDest. pDest is assumed to be
24058
+** uninitialized prior to invoking this routine.
24059
+*/
24060
+static void modeDup(Mode *pDest, Mode *pSrc){
24061
+ memcpy(pDest, pSrc, sizeof(*pDest));
24062
+ if( pDest->spec.aWidth ){
24063
+ size_t sz = sizeof(pSrc->spec.aWidth[0]) * pSrc->spec.nWidth;
24064
+ pDest->spec.aWidth = malloc( sz );
24065
+ if( pDest->spec.aWidth ){
24066
+ memcpy(pDest->spec.aWidth, pSrc->spec.aWidth, sz);
24067
+ }else{
24068
+ pDest->spec.nWidth = 0;
24069
+ }
24070
+ }
24071
+ if( pDest->spec.aAlign ){
24072
+ size_t sz = sizeof(pSrc->spec.aAlign[0]) * pSrc->spec.nAlign;
24073
+ pDest->spec.aAlign = malloc( sz );
24074
+ if( pDest->spec.aAlign ){
24075
+ memcpy(pDest->spec.aAlign, pSrc->spec.aAlign, sz);
24076
+ }else{
24077
+ pDest->spec.nAlign = 0;
24078
+ }
24079
+ }
24080
+ if( pDest->spec.zColumnSep ){
24081
+ pDest->spec.zColumnSep = strdup(pSrc->spec.zColumnSep);
24082
+ }
24083
+ if( pDest->spec.zRowSep ){
24084
+ pDest->spec.zRowSep = strdup(pSrc->spec.zRowSep);
24085
+ }
24086
+ if( pDest->spec.zTableName ){
24087
+ pDest->spec.zTableName = strdup(pSrc->spec.zTableName);
24088
+ }
24089
+ if( pDest->spec.zNull ){
24090
+ pDest->spec.zNull = strdup(pSrc->spec.zNull);
24091
+ }
24092
+}
24093
+
24094
+/*
24095
+** Set a string value to a copy of the zNew string in memory
24096
+** obtained from system malloc().
24097
+*/
24098
+static void modeSetStr(char **az, const char *zNew){
24099
+ free(*az);
24100
+ if( zNew==0 ){
24101
+ *az = 0;
24102
+ }else{
24103
+ size_t n = strlen(zNew);
24104
+ *az = malloc( n+1 );
24105
+ if( *az ){
24106
+ memcpy(*az, zNew, n+1 );
24107
+ }
24108
+ }
24109
+}
24110
+
24111
+/*
24112
+** Change the mode to eMode
24113
+*/
24114
+static void modeChange(ShellState *p, unsigned char eMode){
24115
+ const ModeInfo *pI;
24116
+ if( eMode<ArraySize(aModeInfo) ){
24117
+ pI = &aModeInfo[eMode];
24118
+ Mode *pM = &p->mode;
24119
+ pM->eMode = eMode;
24120
+ if( pI->eCSep ) modeSetStr(&pM->spec.zColumnSep, aModeStr[pI->eCSep]);
24121
+ if( pI->eRSep ) modeSetStr(&pM->spec.zRowSep, aModeStr[pI->eRSep]);
24122
+ if( pI->eNull ) modeSetStr(&pM->spec.zNull, aModeStr[pI->eNull]);
24123
+ pM->spec.eText = pI->eText;
24124
+ pM->spec.eBlob = pI->eBlob;
24125
+ pM->spec.bTitles = pI->bHdr;
24126
+ pM->spec.eTitle = pI->eHdr;
24127
+ }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
24128
+ modeFree(&p->mode);
24129
+ modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
24130
+ }else if( eMode==MODE_BATCH ){
24131
+ u8 mFlags = p->mode.mFlags;
24132
+ modeFree(&p->mode);
24133
+ modeChange(p, MODE_List);
24134
+ p->mode.mFlags = mFlags;
24135
+ }else if( eMode==MODE_TTY ){
24136
+ u8 mFlags = p->mode.mFlags;
24137
+ modeFree(&p->mode);
24138
+ modeChange(p, MODE_QBox);
24139
+ p->mode.bAutoScreenWidth = 1;
24140
+ p->mode.spec.nCharLimit = 300;
24141
+ p->mode.spec.nLineLimit = 5;
24142
+ p->mode.spec.bTextJsonb = QRF_Yes;
24143
+ p->mode.mFlags = mFlags;
24144
+ }
24145
+}
24146
+
24147
+/*
24148
+** Set the mode to the default according to p->iCompat. It assumed
24149
+** that the mode has already been freed and zeroed prior to calling
24150
+** this routine.
24151
+*/
24152
+static void modeDefault(ShellState *p){
24153
+ p->mode.spec.iVersion = 1;
24154
+ p->mode.autoExplain = 1;
24155
+ if( p->iCompat>=20251115 && (stdin_is_interactive || stdout_is_console) ){
24156
+ modeChange(p, MODE_TTY);
24157
+ }else{
24158
+ modeChange(p, MODE_BATCH);
24159
+ }
24160
+}
24161
+
24162
+/*
24163
+** Find the number of a display mode given its name. Return -1 if
24164
+** the name does not match any mode.
24165
+**
24166
+** Saved modes are also searched if p!=NULL. The number returned
24167
+** for a saved mode is the index into the p->aSavedModes[] array
24168
+** plus MODE_USER.
24169
+**
24170
+** Two special mode names are also available: "batch" and "tty".
24171
+** evaluate to the default mode for batch operation and interactive
24172
+** operation on a TTY, respectively.
24173
+*/
24174
+static int modeFind(ShellState *p, const char *zName){
24175
+ int i;
24176
+ for(i=0; i<ArraySize(aModeInfo); i++){
24177
+ if( cli_strcmp(aModeInfo[i].zName,zName)==0 ) return i;
24178
+ }
24179
+ for(i=0; i<p->nSavedModes; i++){
24180
+ if( cli_strcmp(p->aSavedModes[i].zTag,zName)==0 ) return i+MODE_USER;
24181
+ }
24182
+ if( strcmp(zName,"batch")==0 ) return MODE_BATCH;
24183
+ if( strcmp(zName,"tty")==0 ) return MODE_TTY;
24184
+ return -1;
24185
+}
24186
+
24187
+/*
24188
+** Save or restore the current output mode
24189
+*/
24190
+static void modePush(ShellState *p){
24191
+ if( p->nPopMode==0 ){
24192
+ modeFree(&p->modePrior);
24193
+ modeDup(&p->modePrior,&p->mode);
24194
+ }
24195
+}
24196
+static void modePop(ShellState *p){
24197
+ if( p->modePrior.spec.iVersion>0 ){
24198
+ modeFree(&p->mode);
24199
+ p->mode = p->modePrior;
24200
+ memset(&p->modePrior, 0, sizeof(p->modePrior));
24201
+ }
24202
+}
24203
+
2150424204
2150524205
/*
2150624206
** A callback for the sqlite3_log() interface.
2150724207
*/
2150824208
static void shellLog(void *pArg, int iErrCode, const char *zMsg){
2150924209
ShellState *p = (ShellState*)pArg;
2151024210
if( p->pLog==0 ) return;
21511
- sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
24211
+ cli_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
2151224212
fflush(p->pLog);
2151324213
}
2151424214
2151524215
/*
2151624216
** SQL function: shell_putsnl(X)
@@ -21523,13 +24223,29 @@
2152324223
int nVal,
2152424224
sqlite3_value **apVal
2152524225
){
2152624226
ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
2152724227
(void)nVal;
21528
- sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
24228
+ cli_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
2152924229
sqlite3_result_value(pCtx, apVal[0]);
2153024230
}
24231
+
24232
+/*
24233
+** Compute the name of the location of an input error in memory
24234
+** obtained from sqlite3_malloc().
24235
+*/
24236
+static char *shellErrorLocation(ShellState *p){
24237
+ char *zLoc;
24238
+ if( p->zErrPrefix ){
24239
+ zLoc = sqlite3_mprintf("%s", p->zErrPrefix);
24240
+ }else if( p->zInFile==0 || strcmp(p->zInFile,"<stdin>")==0){
24241
+ zLoc = sqlite3_mprintf("line %lld:", p->lineno);
24242
+ }else{
24243
+ zLoc = sqlite3_mprintf("%s:%lld:", p->zInFile, p->lineno);
24244
+ }
24245
+ return zLoc;
24246
+}
2153124247
2153224248
/*
2153324249
** If in safe mode, print an error message described by the arguments
2153424250
** and exit immediately.
2153524251
*/
@@ -21539,17 +24255,53 @@
2153924255
...
2154024256
){
2154124257
if( p->bSafeMode ){
2154224258
va_list ap;
2154324259
char *zMsg;
24260
+ char *zLoc = shellErrorLocation(p);
2154424261
va_start(ap, zErrMsg);
2154524262
zMsg = sqlite3_vmprintf(zErrMsg, ap);
2154624263
va_end(ap);
21547
- sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg);
21548
- exit(1);
24264
+ cli_printf(stderr, "%s %s\n", zLoc, zMsg);
24265
+ cli_exit(1);
2154924266
}
2155024267
}
24268
+
24269
+/*
24270
+** Issue an error message from a dot-command.
24271
+*/
24272
+static void dotCmdError(
24273
+ ShellState *p, /* Shell state */
24274
+ int iArg, /* Index of argument on which error occurred */
24275
+ const char *zBrief, /* Brief (<20 character) error description */
24276
+ const char *zDetail, /* Error details */
24277
+ ...
24278
+){
24279
+ FILE *out = stderr;
24280
+ char *zLoc = shellErrorLocation(p);
24281
+ if( zBrief!=0 && iArg>=0 && iArg<p->dot.nArg ){
24282
+ int i = p->dot.aiOfst[iArg];
24283
+ int nPrompt = strlen30(zBrief) + 5;
24284
+ cli_printf(out, "%s %s\n", zLoc, p->dot.zOrig);
24285
+ if( i > nPrompt ){
24286
+ cli_printf(out, "%s %*s%s ---^\n", zLoc, 1+i-nPrompt, "", zBrief);
24287
+ }else{
24288
+ cli_printf(out, "%s %*s^--- %s\n", zLoc, i, "", zBrief);
24289
+ }
24290
+ }
24291
+ if( zDetail ){
24292
+ char *zMsg;
24293
+ va_list ap;
24294
+ va_start(ap, zDetail);
24295
+ zMsg = sqlite3_vmprintf(zDetail,ap);
24296
+ va_end(ap);
24297
+ cli_printf(out,"%s %s\n", zLoc, zMsg);
24298
+ sqlite3_free(zMsg);
24299
+ }
24300
+ sqlite3_free(zLoc);
24301
+}
24302
+
2155124303
2155224304
/*
2155324305
** SQL function: edit(VALUE)
2155424306
** edit(VALUE,EDITOR)
2155524307
**
@@ -21691,161 +24443,25 @@
2169124443
sqlite3_free(zTempFile);
2169224444
sqlite3_free(p);
2169324445
}
2169424446
#endif /* SQLITE_NOHAVE_SYSTEM */
2169524447
21696
-/*
21697
-** Save or restore the current output mode
21698
-*/
21699
-static void outputModePush(ShellState *p){
21700
- p->modePrior = p->mode;
21701
- p->priorShFlgs = p->shellFlgs;
21702
- memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
21703
- memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
21704
-}
21705
-static void outputModePop(ShellState *p){
21706
- p->mode = p->modePrior;
21707
- p->shellFlgs = p->priorShFlgs;
21708
- memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
21709
- memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
21710
-}
21711
-
2171224448
/*
2171324449
** Set output mode to text or binary for Windows.
2171424450
*/
2171524451
static void setCrlfMode(ShellState *p){
2171624452
#ifdef _WIN32
21717
- if( p->crlfMode ){
24453
+ if( p->mode.mFlags & MFLG_CRLF ){
2171824454
sqlite3_fsetmode(p->out, _O_TEXT);
2171924455
}else{
2172024456
sqlite3_fsetmode(p->out, _O_BINARY);
2172124457
}
2172224458
#else
2172324459
UNUSED_PARAMETER(p);
2172424460
#endif
2172524461
}
2172624462
21727
-/*
21728
-** Output the given string as a hex-encoded blob (eg. X'1234' )
21729
-*/
21730
-static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
21731
- int i;
21732
- unsigned char *aBlob = (unsigned char*)pBlob;
21733
-
21734
- char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
21735
- shell_check_oom(zStr);
21736
-
21737
- for(i=0; i<nBlob; i++){
21738
- static const char aHex[] = {
21739
- '0', '1', '2', '3', '4', '5', '6', '7',
21740
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
21741
- };
21742
- zStr[i*2] = aHex[ (aBlob[i] >> 4) ];
21743
- zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ];
21744
- }
21745
- zStr[i*2] = '\0';
21746
-
21747
- sqlite3_fprintf(out, "X'%s'", zStr);
21748
- sqlite3_free(zStr);
21749
-}
21750
-
21751
-/*
21752
-** Output the given string as a quoted string using SQL quoting conventions:
21753
-**
21754
-** (1) Single quotes (') within the string are doubled
21755
-** (2) The while string is enclosed in '...'
21756
-** (3) Control characters other than \n, \t, and \r\n are escaped
21757
-** using \u00XX notation and if such substitutions occur,
21758
-** the whole string is enclosed in unistr('...') instead of '...'.
21759
-**
21760
-** Step (3) is omitted if the control-character escape mode is OFF.
21761
-**
21762
-** See also: output_quoted_escaped_string() which does the same except
21763
-** that it does not make exceptions for \n, \t, and \r\n in step (3).
21764
-*/
21765
-static void output_quoted_string(ShellState *p, const char *zInX){
21766
- int i;
21767
- int needUnistr = 0;
21768
- int needDblQuote = 0;
21769
- const unsigned char *z = (const unsigned char*)zInX;
21770
- unsigned char c;
21771
- FILE *out = p->out;
21772
- sqlite3_fsetmode(out, _O_BINARY);
21773
- if( z==0 ) return;
21774
- for(i=0; (c = z[i])!=0; i++){
21775
- if( c=='\'' ){ needDblQuote = 1; }
21776
- if( c>0x1f ) continue;
21777
- if( c=='\t' || c=='\n' ) continue;
21778
- if( c=='\r' && z[i+1]=='\n' ) continue;
21779
- needUnistr = 1;
21780
- break;
21781
- }
21782
- if( (needDblQuote==0 && needUnistr==0)
21783
- || (needDblQuote==0 && p->eEscMode==SHELL_ESC_OFF)
21784
- ){
21785
- sqlite3_fprintf(out, "'%s'",z);
21786
- }else if( p->eEscMode==SHELL_ESC_OFF ){
21787
- char *zEncoded = sqlite3_mprintf("%Q", z);
21788
- sqlite3_fputs(zEncoded, out);
21789
- sqlite3_free(zEncoded);
21790
- }else{
21791
- if( needUnistr ){
21792
- sqlite3_fputs("unistr('", out);
21793
- }else{
21794
- sqlite3_fputs("'", out);
21795
- }
21796
- while( *z ){
21797
- for(i=0; (c = z[i])!=0; i++){
21798
- if( c=='\'' ) break;
21799
- if( c>0x1f ) continue;
21800
- if( c=='\t' || c=='\n' ) continue;
21801
- if( c=='\r' && z[i+1]=='\n' ) continue;
21802
- break;
21803
- }
21804
- if( i ){
21805
- sqlite3_fprintf(out, "%.*s", i, z);
21806
- z += i;
21807
- }
21808
- if( c==0 ) break;
21809
- if( c=='\'' ){
21810
- sqlite3_fputs("''", out);
21811
- }else{
21812
- sqlite3_fprintf(out, "\\u%04x", c);
21813
- }
21814
- z++;
21815
- }
21816
- if( needUnistr ){
21817
- sqlite3_fputs("')", out);
21818
- }else{
21819
- sqlite3_fputs("'", out);
21820
- }
21821
- }
21822
- setCrlfMode(p);
21823
-}
21824
-
21825
-/*
21826
-** Output the given string as a quoted string using SQL quoting conventions.
21827
-** Additionallly , escape the "\n" and "\r" characters so that they do not
21828
-** get corrupted by end-of-line translation facilities in some operating
21829
-** systems.
21830
-**
21831
-** This is like output_quoted_string() but with the addition of the \r\n
21832
-** escape mechanism.
21833
-*/
21834
-static void output_quoted_escaped_string(ShellState *p, const char *z){
21835
- char *zEscaped;
21836
- sqlite3_fsetmode(p->out, _O_BINARY);
21837
- if( p->eEscMode==SHELL_ESC_OFF ){
21838
- zEscaped = sqlite3_mprintf("%Q", z);
21839
- }else{
21840
- zEscaped = sqlite3_mprintf("%#Q", z);
21841
- }
21842
- sqlite3_fputs(zEscaped, p->out);
21843
- sqlite3_free(zEscaped);
21844
- setCrlfMode(p);
21845
-}
21846
-
2184724463
/*
2184824464
** Find earliest of chars within s specified in zAny.
2184924465
** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated.
2185024466
*/
2185124467
static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){
@@ -21905,17 +24521,63 @@
2190524521
static const char *zq = "\"";
2190624522
static long ctrlMask = ~0L;
2190724523
static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
2190824524
char ace[3] = "\\?";
2190924525
char cbsSay;
21910
- sqlite3_fputs(zq, out);
24526
+ cli_puts(zq, out);
24527
+ if( z==0 ) z = "";
24528
+ while( *z!=0 ){
24529
+ const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
24530
+ const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
24531
+ const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
24532
+ if( pcEnd > z ){
24533
+ cli_printf(out, "%.*s", (int)(pcEnd-z), z);
24534
+ }
24535
+ if( (c = *pcEnd)==0 ) break;
24536
+ ++pcEnd;
24537
+ switch( c ){
24538
+ case '\\': case '"':
24539
+ cbsSay = (char)c;
24540
+ break;
24541
+ case '\t': cbsSay = 't'; break;
24542
+ case '\n': cbsSay = 'n'; break;
24543
+ case '\r': cbsSay = 'r'; break;
24544
+ case '\f': cbsSay = 'f'; break;
24545
+ default: cbsSay = 0; break;
24546
+ }
24547
+ if( cbsSay ){
24548
+ ace[1] = cbsSay;
24549
+ cli_puts(ace, out);
24550
+ }else if( !isprint(c&0xff) ){
24551
+ cli_printf(out, "\\%03o", c&0xff);
24552
+ }else{
24553
+ ace[1] = (char)c;
24554
+ cli_puts(ace+1, out);
24555
+ }
24556
+ z = pcEnd;
24557
+ }
24558
+ cli_puts(zq, out);
24559
+}
24560
+
24561
+/* Encode input string z[] as a C-language string literal and
24562
+** append it to the sqlite3_str. If z is NULL render and empty string.
24563
+*/
24564
+static void append_c_string(sqlite3_str *out, const char *z){
24565
+ char c;
24566
+ static const char *zq = "\"";
24567
+ static long ctrlMask = ~0L;
24568
+ static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
24569
+ char ace[3] = "\\?";
24570
+ char cbsSay;
24571
+ if( z==0 ) z = "";
24572
+ sqlite3_str_appendall(out,zq);
2191124573
while( *z!=0 ){
2191224574
const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
2191324575
const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
2191424576
const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
2191524577
if( pcEnd > z ){
21916
- sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
24578
+ sqlite3_str_appendf(out, "%.*s", (int)(pcEnd-z), z);
2191724579
}
2191824580
if( (c = *pcEnd)==0 ) break;
2191924581
++pcEnd;
2192024582
switch( c ){
2192124583
case '\\': case '"':
@@ -21927,255 +24589,63 @@
2192724589
case '\f': cbsSay = 'f'; break;
2192824590
default: cbsSay = 0; break;
2192924591
}
2193024592
if( cbsSay ){
2193124593
ace[1] = cbsSay;
21932
- sqlite3_fputs(ace, out);
21933
- }else if( !isprint(c&0xff) ){
21934
- sqlite3_fprintf(out, "\\%03o", c&0xff);
21935
- }else{
21936
- ace[1] = (char)c;
21937
- sqlite3_fputs(ace+1, out);
21938
- }
21939
- z = pcEnd;
21940
- }
21941
- sqlite3_fputs(zq, out);
21942
-}
21943
-
21944
-/*
21945
-** Output the given string as quoted according to JSON quoting rules.
21946
-*/
21947
-static void output_json_string(FILE *out, const char *z, i64 n){
21948
- unsigned char c;
21949
- static const char *zq = "\"";
21950
- static long ctrlMask = ~0L;
21951
- static const char *zDQBS = "\"\\";
21952
- const char *pcLimit;
21953
- char ace[3] = "\\?";
21954
- char cbsSay;
21955
-
21956
- if( z==0 ) z = "";
21957
- pcLimit = z + ((n<0)? strlen(z) : (size_t)n);
21958
- sqlite3_fputs(zq, out);
21959
- while( z < pcLimit ){
21960
- const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z);
21961
- const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask);
21962
- const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast;
21963
- if( pcEnd > z ){
21964
- sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
21965
- z = pcEnd;
21966
- }
21967
- if( z >= pcLimit ) break;
21968
- c = (unsigned char)*(z++);
21969
- switch( c ){
21970
- case '"': case '\\':
21971
- cbsSay = (char)c;
21972
- break;
21973
- case '\b': cbsSay = 'b'; break;
21974
- case '\f': cbsSay = 'f'; break;
21975
- case '\n': cbsSay = 'n'; break;
21976
- case '\r': cbsSay = 'r'; break;
21977
- case '\t': cbsSay = 't'; break;
21978
- default: cbsSay = 0; break;
21979
- }
21980
- if( cbsSay ){
21981
- ace[1] = cbsSay;
21982
- sqlite3_fputs(ace, out);
21983
- }else if( c<=0x1f || c>=0x7f ){
21984
- sqlite3_fprintf(out, "\\u%04x", c);
21985
- }else{
21986
- ace[1] = (char)c;
21987
- sqlite3_fputs(ace+1, out);
21988
- }
21989
- }
21990
- sqlite3_fputs(zq, out);
21991
-}
21992
-
21993
-/*
21994
-** Escape the input string if it is needed and in accordance with
21995
-** eEscMode.
21996
-**
21997
-** Escaping is needed if the string contains any control characters
21998
-** other than \t, \n, and \r\n
21999
-**
22000
-** If no escaping is needed (the common case) then set *ppFree to NULL
22001
-** and return the original string. If escaping is needed, write the
22002
-** escaped string into memory obtained from sqlite3_malloc64() or the
22003
-** equivalent, and return the new string and set *ppFree to the new string
22004
-** as well.
22005
-**
22006
-** The caller is responsible for freeing *ppFree if it is non-NULL in order
22007
-** to reclaim memory.
22008
-*/
22009
-static const char *escapeOutput(
22010
- ShellState *p,
22011
- const char *zInX,
22012
- char **ppFree
22013
-){
22014
- i64 i, j;
22015
- i64 nCtrl = 0;
22016
- unsigned char *zIn;
22017
- unsigned char c;
22018
- unsigned char *zOut;
22019
-
22020
-
22021
- /* No escaping if disabled */
22022
- if( p->eEscMode==SHELL_ESC_OFF ){
22023
- *ppFree = 0;
22024
- return zInX;
22025
- }
22026
-
22027
- /* Count the number of control characters in the string. */
22028
- zIn = (unsigned char*)zInX;
22029
- for(i=0; (c = zIn[i])!=0; i++){
22030
- if( c<=0x1f
22031
- && c!='\t'
22032
- && c!='\n'
22033
- && (c!='\r' || zIn[i+1]!='\n')
22034
- ){
22035
- nCtrl++;
22036
- }
22037
- }
22038
- if( nCtrl==0 ){
22039
- *ppFree = 0;
22040
- return zInX;
22041
- }
22042
- if( p->eEscMode==SHELL_ESC_SYMBOL ) nCtrl *= 2;
22043
- zOut = sqlite3_malloc64( i + nCtrl + 1 );
22044
- shell_check_oom(zOut);
22045
- for(i=j=0; (c = zIn[i])!=0; i++){
22046
- if( c>0x1f
22047
- || c=='\t'
22048
- || c=='\n'
22049
- || (c=='\r' && zIn[i+1]=='\n')
22050
- ){
22051
- continue;
22052
- }
22053
- if( i>0 ){
22054
- memcpy(&zOut[j], zIn, i);
22055
- j += i;
22056
- }
22057
- zIn += i+1;
22058
- i = -1;
22059
- switch( p->eEscMode ){
22060
- case SHELL_ESC_SYMBOL:
22061
- zOut[j++] = 0xe2;
22062
- zOut[j++] = 0x90;
22063
- zOut[j++] = 0x80+c;
22064
- break;
22065
- case SHELL_ESC_ASCII:
22066
- zOut[j++] = '^';
22067
- zOut[j++] = 0x40+c;
22068
- break;
22069
- }
22070
- }
22071
- if( i>0 ){
22072
- memcpy(&zOut[j], zIn, i);
22073
- j += i;
22074
- }
22075
- zOut[j] = 0;
22076
- *ppFree = (char*)zOut;
22077
- return (char*)zOut;
22078
-}
22079
-
22080
-/*
22081
-** Output the given string with characters that are special to
22082
-** HTML escaped.
22083
-*/
22084
-static void output_html_string(FILE *out, const char *z){
22085
- int i;
22086
- if( z==0 ) z = "";
22087
- while( *z ){
22088
- for(i=0; z[i]
22089
- && z[i]!='<'
22090
- && z[i]!='&'
22091
- && z[i]!='>'
22092
- && z[i]!='\"'
22093
- && z[i]!='\'';
22094
- i++){}
22095
- if( i>0 ){
22096
- sqlite3_fprintf(out, "%.*s",i,z);
22097
- }
22098
- if( z[i]=='<' ){
22099
- sqlite3_fputs("&lt;", out);
22100
- }else if( z[i]=='&' ){
22101
- sqlite3_fputs("&amp;", out);
22102
- }else if( z[i]=='>' ){
22103
- sqlite3_fputs("&gt;", out);
22104
- }else if( z[i]=='\"' ){
22105
- sqlite3_fputs("&quot;", out);
22106
- }else if( z[i]=='\'' ){
22107
- sqlite3_fputs("&#39;", out);
22108
- }else{
22109
- break;
22110
- }
22111
- z += i + 1;
22112
- }
22113
-}
22114
-
22115
-/*
22116
-** If a field contains any character identified by a 1 in the following
22117
-** array, then the string must be quoted for CSV.
22118
-*/
22119
-static const char needCsvQuote[] = {
22120
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22121
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22122
- 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
22123
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22124
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22125
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22126
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22127
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
22128
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22129
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22130
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22131
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22132
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22133
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22134
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22135
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22136
-};
22137
-
22138
-/*
22139
-** Output a single term of CSV. Actually, p->colSeparator is used for
22140
-** the separator, which may or may not be a comma. p->nullValue is
22141
-** the null value. Strings are quoted if necessary. The separator
22142
-** is only issued if bSep is true.
22143
-*/
22144
-static void output_csv(ShellState *p, const char *z, int bSep){
22145
- if( z==0 ){
22146
- sqlite3_fprintf(p->out, "%s",p->nullValue);
22147
- }else{
22148
- unsigned i;
22149
- for(i=0; z[i]; i++){
22150
- if( needCsvQuote[((unsigned char*)z)[i]] ){
22151
- i = 0;
22152
- break;
22153
- }
22154
- }
22155
- if( i==0 || strstr(z, p->colSeparator)!=0 ){
22156
- char *zQuoted = sqlite3_mprintf("\"%w\"", z);
22157
- shell_check_oom(zQuoted);
22158
- sqlite3_fputs(zQuoted, p->out);
22159
- sqlite3_free(zQuoted);
22160
- }else{
22161
- sqlite3_fputs(z, p->out);
22162
- }
22163
- }
22164
- if( bSep ){
22165
- sqlite3_fputs(p->colSeparator, p->out);
22166
- }
24594
+ sqlite3_str_appendall(out,ace);
24595
+ }else if( !isprint(c&0xff) ){
24596
+ sqlite3_str_appendf(out, "\\%03o", c&0xff);
24597
+ }else{
24598
+ ace[1] = (char)c;
24599
+ sqlite3_str_appendall(out, ace+1);
24600
+ }
24601
+ z = pcEnd;
24602
+ }
24603
+ sqlite3_str_appendall(out, zq);
2216724604
}
2216824605
2216924606
/*
2217024607
** This routine runs when the user presses Ctrl-C
2217124608
*/
2217224609
static void interrupt_handler(int NotUsed){
2217324610
UNUSED_PARAMETER(NotUsed);
22174
- if( ++seenInterrupt>1 ) exit(1);
24611
+ if( ++seenInterrupt>1 ) cli_exit(1);
2217524612
if( globalDb ) sqlite3_interrupt(globalDb);
2217624613
}
24614
+
24615
+/* Try to determine the screen width. Use the default if unable.
24616
+*/
24617
+int shellScreenWidth(void){
24618
+ if( stdout_tty_width>0 ) return stdout_tty_width;
24619
+#if defined(TIOCGSIZE)
24620
+ struct ttysize ts;
24621
+ if( ioctl(STDIN_FILENO, TIOCGSIZE, &ts)>=0
24622
+ || ioctl(STDOUT_FILENO, TIOCGSIZE, &ts)>=0
24623
+ || ioctl(STDERR_FILENO, TIOCGSIZE, &ts)>=0
24624
+ ){
24625
+ return ts.ts_cols;
24626
+ }
24627
+#elif defined(TIOCGWINSZ)
24628
+ struct winsize ws;
24629
+ if( ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)>=0
24630
+ || ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)>=0
24631
+ || ioctl(STDERR_FILENO, TIOCGWINSZ, &ws)>=0
24632
+ ){
24633
+ return ws.ws_col;
24634
+ }
24635
+#elif defined(_WIN32)
24636
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
24637
+ if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)
24638
+ || GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi)
24639
+ || GetConsoleScreenBufferInfo(GetStdHandle(STD_INPUT_HANDLE), &csbi)
24640
+ ){
24641
+ return csbi.srWindow.Right - csbi.srWindow.Left + 1;
24642
+ }
24643
+#endif
24644
+#define DEFAULT_SCREEN_WIDTH 80
24645
+ return DEFAULT_SCREEN_WIDTH;
24646
+}
2217724647
2217824648
#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
2217924649
/*
2218024650
** This routine runs for console events (e.g. Ctrl-C) on Win32
2218124651
*/
@@ -22268,27 +24738,27 @@
2226824738
const char *az[4];
2226924739
az[0] = zA1;
2227024740
az[1] = zA2;
2227124741
az[2] = zA3;
2227224742
az[3] = zA4;
22273
- sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]);
24743
+ cli_printf(p->out, "authorizer: %s", azAction[op]);
2227424744
for(i=0; i<4; i++){
22275
- sqlite3_fputs(" ", p->out);
24745
+ cli_puts(" ", p->out);
2227624746
if( az[i] ){
2227724747
output_c_string(p->out, az[i]);
2227824748
}else{
22279
- sqlite3_fputs("NULL", p->out);
24749
+ cli_puts("NULL", p->out);
2228024750
}
2228124751
}
22282
- sqlite3_fputs("\n", p->out);
24752
+ cli_puts("\n", p->out);
2228324753
if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
2228424754
return SQLITE_OK;
2228524755
}
2228624756
#endif
2228724757
2228824758
/*
22289
-** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
24759
+** Print a schema statement. This is helper routine to dump_callbac().
2229024760
**
2229124761
** This routine converts some CREATE TABLE statements for shadow tables
2229224762
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
2229324763
**
2229424764
** If the schema statement in z[] contains a start-of-comment and if
@@ -22315,22 +24785,16 @@
2231524785
}
2231624786
sqlite3_free(zNew);
2231724787
}
2231824788
}
2231924789
if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
22320
- sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
24790
+ cli_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
2232124791
}else{
22322
- sqlite3_fprintf(out, "%s%s", z, zTail);
24792
+ cli_printf(out, "%s%s", z, zTail);
2232324793
}
2232424794
sqlite3_free(zToFree);
2232524795
}
22326
-static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
22327
- char c = z[n];
22328
- z[n] = 0;
22329
- printSchemaLine(out, z, zTail);
22330
- z[n] = c;
22331
-}
2233224796
2233324797
/*
2233424798
** Return true if string z[] has nothing but whitespace and comments to the
2233524799
** end of the first line.
2233624800
*/
@@ -22344,99 +24808,132 @@
2234424808
}
2234524809
return 1;
2234624810
}
2234724811
2234824812
/*
22349
-** Add a new entry to the EXPLAIN QUERY PLAN data
22350
-*/
22351
-static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
22352
- EQPGraphRow *pNew;
22353
- i64 nText;
22354
- if( zText==0 ) return;
22355
- nText = strlen(zText);
22356
- if( p->autoEQPtest ){
22357
- sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
22358
- }
22359
- pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
22360
- shell_check_oom(pNew);
22361
- pNew->iEqpId = iEqpId;
22362
- pNew->iParentId = p2;
22363
- memcpy(pNew->zText, zText, nText+1);
22364
- pNew->pNext = 0;
22365
- if( p->sGraph.pLast ){
22366
- p->sGraph.pLast->pNext = pNew;
22367
- }else{
22368
- p->sGraph.pRow = pNew;
22369
- }
22370
- p->sGraph.pLast = pNew;
22371
-}
22372
-
22373
-/*
22374
-** Free and reset the EXPLAIN QUERY PLAN data that has been collected
22375
-** in p->sGraph.
22376
-*/
22377
-static void eqp_reset(ShellState *p){
22378
- EQPGraphRow *pRow, *pNext;
22379
- for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
22380
- pNext = pRow->pNext;
22381
- sqlite3_free(pRow);
22382
- }
22383
- memset(&p->sGraph, 0, sizeof(p->sGraph));
22384
-}
22385
-
22386
-/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
22387
-** pOld, or return the first such line if pOld is NULL
22388
-*/
22389
-static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
22390
- EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
22391
- while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
22392
- return pRow;
22393
-}
22394
-
22395
-/* Render a single level of the graph that has iEqpId as its parent. Called
22396
-** recursively to render sublevels.
22397
-*/
22398
-static void eqp_render_level(ShellState *p, int iEqpId){
22399
- EQPGraphRow *pRow, *pNext;
22400
- i64 n = strlen(p->sGraph.zPrefix);
22401
- char *z;
22402
- for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
22403
- pNext = eqp_next_row(p, iEqpId, pRow);
22404
- z = pRow->zText;
22405
- sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
22406
- pNext ? "|--" : "`--", z);
22407
- if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){
22408
- memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
22409
- eqp_render_level(p, pRow->iEqpId);
22410
- p->sGraph.zPrefix[n] = 0;
22411
- }
22412
- }
22413
-}
22414
-
22415
-/*
22416
-** Display and reset the EXPLAIN QUERY PLAN data
22417
-*/
22418
-static void eqp_render(ShellState *p, i64 nCycle){
22419
- EQPGraphRow *pRow = p->sGraph.pRow;
22420
- if( pRow ){
22421
- if( pRow->zText[0]=='-' ){
22422
- if( pRow->pNext==0 ){
22423
- eqp_reset(p);
22424
- return;
22425
- }
22426
- sqlite3_fprintf(p->out, "%s\n", pRow->zText+3);
22427
- p->sGraph.pRow = pRow->pNext;
22428
- sqlite3_free(pRow);
22429
- }else if( nCycle>0 ){
22430
- sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle);
22431
- }else{
22432
- sqlite3_fputs("QUERY PLAN\n", p->out);
22433
- }
22434
- p->sGraph.zPrefix[0] = 0;
22435
- eqp_render_level(p, 0);
22436
- eqp_reset(p);
22437
- }
24813
+** SQL Function: shell_format_schema(SQL,FLAGS)
24814
+**
24815
+** This function is internally by the CLI to assist with the
24816
+** ".schema", ".fullschema", and ".dump" commands. The first
24817
+** argument is the value from sqlite_schema.sql. The value returned
24818
+** is a modification of the input that can actually be run as SQL
24819
+** to recreate the schema object.
24820
+**
24821
+** When FLAGS is zero, the only changes is to append ";". If the
24822
+** 0x01 bit of FLAGS is set, then transformations are made to implement
24823
+** ".schema --indent".
24824
+*/
24825
+static void shellFormatSchema(
24826
+ sqlite3_context *pCtx,
24827
+ int nVal,
24828
+ sqlite3_value **apVal
24829
+){
24830
+ int flags; /* Value of 2nd parameter */
24831
+ const char *zSql; /* Value of 1st parameter */
24832
+ int nSql; /* Bytes of text in zSql[] */
24833
+ sqlite3_str *pOut; /* Output buffer */
24834
+ char *z; /* Writable copy of zSql */
24835
+ int i, j; /* Loop counters */
24836
+ int nParen = 0;
24837
+ char cEnd = 0;
24838
+ char c;
24839
+ int nLine = 0;
24840
+ int isIndex;
24841
+ int isWhere = 0;
24842
+
24843
+ assert( nVal==2 );
24844
+ pOut = sqlite3_str_new(sqlite3_context_db_handle(pCtx));
24845
+ nSql = sqlite3_value_bytes(apVal[0]);
24846
+ zSql = (const char*)sqlite3_value_text(apVal[0]);
24847
+ if( zSql==0 || zSql[0]==0 ) goto shellFormatSchema_finish;
24848
+ flags = sqlite3_value_int(apVal[1]);
24849
+ if( (flags & 0x01)==0 ){
24850
+ sqlite3_str_append(pOut, zSql, nSql);
24851
+ sqlite3_str_append(pOut, ";", 1);
24852
+ goto shellFormatSchema_finish;
24853
+ }
24854
+ if( sqlite3_strlike("CREATE VIEW%", zSql, 0)==0
24855
+ || sqlite3_strlike("CREATE TRIG%", zSql, 0)==0
24856
+ ){
24857
+ sqlite3_str_append(pOut, zSql, nSql);
24858
+ sqlite3_str_append(pOut, ";", 1);
24859
+ goto shellFormatSchema_finish;
24860
+ }
24861
+ isIndex = sqlite3_strlike("CREATE INDEX%", zSql, 0)==0
24862
+ || sqlite3_strlike("CREATE UNIQUE INDEX%", zSql, 0)==0;
24863
+ z = sqlite3_mprintf("%s", zSql);
24864
+ if( z==0 ){
24865
+ sqlite3_str_free(pOut);
24866
+ sqlite3_result_error_nomem(pCtx);
24867
+ return;
24868
+ }
24869
+ j = 0;
24870
+ for(i=0; IsSpace(z[i]); i++){}
24871
+ for(; (c = z[i])!=0; i++){
24872
+ if( IsSpace(c) ){
24873
+ if( z[j-1]=='\r' ) z[j-1] = '\n';
24874
+ if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
24875
+ }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
24876
+ j--;
24877
+ }
24878
+ z[j++] = c;
24879
+ }
24880
+ while( j>0 && IsSpace(z[j-1]) ){ j--; }
24881
+ z[j] = 0;
24882
+ if( strlen30(z)>=79 ){
24883
+ for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
24884
+ if( c==cEnd ){
24885
+ cEnd = 0;
24886
+ }else if( c=='"' || c=='\'' || c=='`' ){
24887
+ cEnd = c;
24888
+ }else if( c=='[' ){
24889
+ cEnd = ']';
24890
+ }else if( c=='-' && z[i+1]=='-' ){
24891
+ cEnd = '\n';
24892
+ }else if( c=='(' ){
24893
+ nParen++;
24894
+ }else if( c==')' ){
24895
+ nParen--;
24896
+ if( nLine>0 && nParen==0 && j>0 && !isWhere ){
24897
+ sqlite3_str_append(pOut, z, j);
24898
+ sqlite3_str_append(pOut, "\n", 1);
24899
+ j = 0;
24900
+ }
24901
+ }else if( (c=='w' || c=='W')
24902
+ && nParen==0 && isIndex
24903
+ && sqlite3_strnicmp("WHERE",&z[i],5)==0
24904
+ && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
24905
+ isWhere = 1;
24906
+ }else if( isWhere && (c=='A' || c=='a')
24907
+ && nParen==0
24908
+ && sqlite3_strnicmp("AND",&z[i],3)==0
24909
+ && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
24910
+ sqlite3_str_append(pOut, z, j);
24911
+ sqlite3_str_append(pOut, "\n ", 5);
24912
+ j = 0;
24913
+ }
24914
+ z[j++] = c;
24915
+ if( nParen==1 && cEnd==0
24916
+ && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
24917
+ && !isWhere
24918
+ ){
24919
+ if( c=='\n' ) j--;
24920
+ sqlite3_str_append(pOut, z, j);
24921
+ sqlite3_str_append(pOut, "\n ", 3);
24922
+ j = 0;
24923
+ nLine++;
24924
+ while( IsSpace(z[i+1]) ){ i++; }
24925
+ }
24926
+ }
24927
+ z[j] = 0;
24928
+ }
24929
+ sqlite3_str_appendall(pOut, z);
24930
+ sqlite3_str_append(pOut, ";", 1);
24931
+ sqlite3_free(z);
24932
+
24933
+shellFormatSchema_finish:
24934
+ sqlite3_result_text(pCtx, sqlite3_str_finish(pOut), -1, sqlite3_free);
2243824935
}
2243924936
2244024937
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
2244124938
/*
2244224939
** Progress handler callback.
@@ -22443,496 +24940,22 @@
2244324940
*/
2244424941
static int progress_handler(void *pClientData) {
2244524942
ShellState *p = (ShellState*)pClientData;
2244624943
p->nProgress++;
2244724944
if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
22448
- sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress);
24945
+ cli_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
2244924946
if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
2245024947
if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
2245124948
return 1;
2245224949
}
2245324950
if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
22454
- sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress);
24951
+ cli_printf(p->out, "Progress %u\n", p->nProgress);
2245524952
}
2245624953
return 0;
2245724954
}
2245824955
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
2245924956
22460
-/*
22461
-** Print N dashes
22462
-*/
22463
-static void print_dashes(FILE *out, int N){
22464
- const char zDash[] = "--------------------------------------------------";
22465
- const int nDash = sizeof(zDash) - 1;
22466
- while( N>nDash ){
22467
- sqlite3_fputs(zDash, out);
22468
- N -= nDash;
22469
- }
22470
- sqlite3_fprintf(out, "%.*s", N, zDash);
22471
-}
22472
-
22473
-/*
22474
-** Print a markdown or table-style row separator using ascii-art
22475
-*/
22476
-static void print_row_separator(
22477
- ShellState *p,
22478
- int nArg,
22479
- const char *zSep
22480
-){
22481
- int i;
22482
- if( nArg>0 ){
22483
- sqlite3_fputs(zSep, p->out);
22484
- print_dashes(p->out, p->actualWidth[0]+2);
22485
- for(i=1; i<nArg; i++){
22486
- sqlite3_fputs(zSep, p->out);
22487
- print_dashes(p->out, p->actualWidth[i]+2);
22488
- }
22489
- sqlite3_fputs(zSep, p->out);
22490
- }
22491
- sqlite3_fputs("\n", p->out);
22492
-}
22493
-
22494
-/*
22495
-** This is the callback routine that the shell
22496
-** invokes for each row of a query result.
22497
-*/
22498
-static int shell_callback(
22499
- void *pArg,
22500
- int nArg, /* Number of result columns */
22501
- char **azArg, /* Text of each result column */
22502
- char **azCol, /* Column names */
22503
- int *aiType /* Column types. Might be NULL */
22504
-){
22505
- int i;
22506
- ShellState *p = (ShellState*)pArg;
22507
-
22508
- if( azArg==0 ) return 0;
22509
- switch( p->cMode ){
22510
- case MODE_Count:
22511
- case MODE_Off: {
22512
- break;
22513
- }
22514
- case MODE_Line: {
22515
- int w = 5;
22516
- if( azArg==0 ) break;
22517
- for(i=0; i<nArg; i++){
22518
- int len = strlen30(azCol[i] ? azCol[i] : "");
22519
- if( len>w ) w = len;
22520
- }
22521
- if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out);
22522
- for(i=0; i<nArg; i++){
22523
- char *pFree = 0;
22524
- const char *pDisplay;
22525
- pDisplay = escapeOutput(p, azArg[i] ? azArg[i] : p->nullValue, &pFree);
22526
- sqlite3_fprintf(p->out, "%*s = %s%s", w, azCol[i],
22527
- pDisplay, p->rowSeparator);
22528
- if( pFree ) sqlite3_free(pFree);
22529
- }
22530
- break;
22531
- }
22532
- case MODE_ScanExp:
22533
- case MODE_Explain: {
22534
- static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
22535
- static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
22536
- static const int aScanExpWidth[] = {4, 15, 6, 13, 4, 4, 4, 13, 2, 13};
22537
- static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
22538
-
22539
- const int *aWidth = aExplainWidth;
22540
- const int *aMap = aExplainMap;
22541
- int nWidth = ArraySize(aExplainWidth);
22542
- int iIndent = 1;
22543
-
22544
- if( p->cMode==MODE_ScanExp ){
22545
- aWidth = aScanExpWidth;
22546
- aMap = aScanExpMap;
22547
- nWidth = ArraySize(aScanExpWidth);
22548
- iIndent = 3;
22549
- }
22550
- if( nArg>nWidth ) nArg = nWidth;
22551
-
22552
- /* If this is the first row seen, print out the headers */
22553
- if( p->cnt++==0 ){
22554
- for(i=0; i<nArg; i++){
22555
- utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]);
22556
- sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out);
22557
- }
22558
- for(i=0; i<nArg; i++){
22559
- print_dashes(p->out, aWidth[i]);
22560
- sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out);
22561
- }
22562
- }
22563
-
22564
- /* If there is no data, exit early. */
22565
- if( azArg==0 ) break;
22566
-
22567
- for(i=0; i<nArg; i++){
22568
- const char *zSep = " ";
22569
- int w = aWidth[i];
22570
- const char *zVal = azArg[ aMap[i] ];
22571
- if( i==nArg-1 ) w = 0;
22572
- if( zVal && strlenChar(zVal)>w ){
22573
- w = strlenChar(zVal);
22574
- zSep = " ";
22575
- }
22576
- if( i==iIndent && p->aiIndent && p->pStmt ){
22577
- if( p->iIndent<p->nIndent ){
22578
- sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
22579
- }
22580
- p->iIndent++;
22581
- }
22582
- utf8_width_print(p->out, w, zVal ? zVal : p->nullValue);
22583
- sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out);
22584
- }
22585
- break;
22586
- }
22587
- case MODE_Semi: { /* .schema and .fullschema output */
22588
- printSchemaLine(p->out, azArg[0], ";\n");
22589
- break;
22590
- }
22591
- case MODE_Pretty: { /* .schema and .fullschema with --indent */
22592
- char *z;
22593
- int j;
22594
- int nParen = 0;
22595
- char cEnd = 0;
22596
- char c;
22597
- int nLine = 0;
22598
- int isIndex;
22599
- int isWhere = 0;
22600
- assert( nArg==1 );
22601
- if( azArg[0]==0 ) break;
22602
- if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
22603
- || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
22604
- ){
22605
- sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
22606
- break;
22607
- }
22608
- isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0
22609
- || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0;
22610
- z = sqlite3_mprintf("%s", azArg[0]);
22611
- shell_check_oom(z);
22612
- j = 0;
22613
- for(i=0; IsSpace(z[i]); i++){}
22614
- for(; (c = z[i])!=0; i++){
22615
- if( IsSpace(c) ){
22616
- if( z[j-1]=='\r' ) z[j-1] = '\n';
22617
- if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
22618
- }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
22619
- j--;
22620
- }
22621
- z[j++] = c;
22622
- }
22623
- while( j>0 && IsSpace(z[j-1]) ){ j--; }
22624
- z[j] = 0;
22625
- if( strlen30(z)>=79 ){
22626
- for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
22627
- if( c==cEnd ){
22628
- cEnd = 0;
22629
- }else if( c=='"' || c=='\'' || c=='`' ){
22630
- cEnd = c;
22631
- }else if( c=='[' ){
22632
- cEnd = ']';
22633
- }else if( c=='-' && z[i+1]=='-' ){
22634
- cEnd = '\n';
22635
- }else if( c=='(' ){
22636
- nParen++;
22637
- }else if( c==')' ){
22638
- nParen--;
22639
- if( nLine>0 && nParen==0 && j>0 && !isWhere ){
22640
- printSchemaLineN(p->out, z, j, "\n");
22641
- j = 0;
22642
- }
22643
- }else if( (c=='w' || c=='W')
22644
- && nParen==0 && isIndex
22645
- && sqlite3_strnicmp("WHERE",&z[i],5)==0
22646
- && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
22647
- isWhere = 1;
22648
- }else if( isWhere && (c=='A' || c=='a')
22649
- && nParen==0
22650
- && sqlite3_strnicmp("AND",&z[i],3)==0
22651
- && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
22652
- printSchemaLineN(p->out, z, j, "\n ");
22653
- j = 0;
22654
- }
22655
- z[j++] = c;
22656
- if( nParen==1 && cEnd==0
22657
- && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
22658
- && !isWhere
22659
- ){
22660
- if( c=='\n' ) j--;
22661
- printSchemaLineN(p->out, z, j, "\n ");
22662
- j = 0;
22663
- nLine++;
22664
- while( IsSpace(z[i+1]) ){ i++; }
22665
- }
22666
- }
22667
- z[j] = 0;
22668
- }
22669
- printSchemaLine(p->out, z, ";\n");
22670
- sqlite3_free(z);
22671
- break;
22672
- }
22673
- case MODE_List: {
22674
- if( p->cnt++==0 && p->showHeader ){
22675
- for(i=0; i<nArg; i++){
22676
- char *z = azCol[i];
22677
- char *pFree;
22678
- const char *zOut = escapeOutput(p, z, &pFree);
22679
- sqlite3_fprintf(p->out, "%s%s", zOut,
22680
- i==nArg-1 ? p->rowSeparator : p->colSeparator);
22681
- if( pFree ) sqlite3_free(pFree);
22682
- }
22683
- }
22684
- if( azArg==0 ) break;
22685
- for(i=0; i<nArg; i++){
22686
- char *z = azArg[i];
22687
- char *pFree;
22688
- const char *zOut;
22689
- if( z==0 ) z = p->nullValue;
22690
- zOut = escapeOutput(p, z, &pFree);
22691
- sqlite3_fputs(zOut, p->out);
22692
- if( pFree ) sqlite3_free(pFree);
22693
- sqlite3_fputs((i<nArg-1)? p->colSeparator : p->rowSeparator, p->out);
22694
- }
22695
- break;
22696
- }
22697
- case MODE_Www:
22698
- case MODE_Html: {
22699
- if( p->cnt==0 && p->cMode==MODE_Www ){
22700
- sqlite3_fputs(
22701
- "</PRE>\n"
22702
- "<TABLE border='1' cellspacing='0' cellpadding='2'>\n"
22703
- ,p->out
22704
- );
22705
- }
22706
- if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){
22707
- sqlite3_fputs("<TR>", p->out);
22708
- for(i=0; i<nArg; i++){
22709
- sqlite3_fputs("<TH>", p->out);
22710
- output_html_string(p->out, azCol[i]);
22711
- sqlite3_fputs("</TH>\n", p->out);
22712
- }
22713
- sqlite3_fputs("</TR>\n", p->out);
22714
- }
22715
- p->cnt++;
22716
- if( azArg==0 ) break;
22717
- sqlite3_fputs("<TR>", p->out);
22718
- for(i=0; i<nArg; i++){
22719
- sqlite3_fputs("<TD>", p->out);
22720
- output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
22721
- sqlite3_fputs("</TD>\n", p->out);
22722
- }
22723
- sqlite3_fputs("</TR>\n", p->out);
22724
- break;
22725
- }
22726
- case MODE_Tcl: {
22727
- if( p->cnt++==0 && p->showHeader ){
22728
- for(i=0; i<nArg; i++){
22729
- output_c_string(p->out, azCol[i] ? azCol[i] : "");
22730
- if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out);
22731
- }
22732
- sqlite3_fputs(p->rowSeparator, p->out);
22733
- }
22734
- if( azArg==0 ) break;
22735
- for(i=0; i<nArg; i++){
22736
- output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
22737
- if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out);
22738
- }
22739
- sqlite3_fputs(p->rowSeparator, p->out);
22740
- break;
22741
- }
22742
- case MODE_Csv: {
22743
- sqlite3_fsetmode(p->out, _O_BINARY);
22744
- if( p->cnt++==0 && p->showHeader ){
22745
- for(i=0; i<nArg; i++){
22746
- output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
22747
- }
22748
- sqlite3_fputs(p->rowSeparator, p->out);
22749
- }
22750
- if( nArg>0 ){
22751
- for(i=0; i<nArg; i++){
22752
- output_csv(p, azArg[i], i<nArg-1);
22753
- }
22754
- sqlite3_fputs(p->rowSeparator, p->out);
22755
- }
22756
- setCrlfMode(p);
22757
- break;
22758
- }
22759
- case MODE_Insert: {
22760
- if( azArg==0 ) break;
22761
- sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable);
22762
- if( p->showHeader ){
22763
- sqlite3_fputs("(", p->out);
22764
- for(i=0; i<nArg; i++){
22765
- if( i>0 ) sqlite3_fputs(",", p->out);
22766
- if( quoteChar(azCol[i]) ){
22767
- char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
22768
- shell_check_oom(z);
22769
- sqlite3_fputs(z, p->out);
22770
- sqlite3_free(z);
22771
- }else{
22772
- sqlite3_fprintf(p->out, "%s", azCol[i]);
22773
- }
22774
- }
22775
- sqlite3_fputs(")", p->out);
22776
- }
22777
- p->cnt++;
22778
- for(i=0; i<nArg; i++){
22779
- sqlite3_fputs(i>0 ? "," : " VALUES(", p->out);
22780
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22781
- sqlite3_fputs("NULL", p->out);
22782
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
22783
- if( ShellHasFlag(p, SHFLG_Newlines) ){
22784
- output_quoted_string(p, azArg[i]);
22785
- }else{
22786
- output_quoted_escaped_string(p, azArg[i]);
22787
- }
22788
- }else if( aiType && aiType[i]==SQLITE_INTEGER ){
22789
- sqlite3_fputs(azArg[i], p->out);
22790
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22791
- char z[50];
22792
- double r = sqlite3_column_double(p->pStmt, i);
22793
- sqlite3_uint64 ur;
22794
- memcpy(&ur,&r,sizeof(r));
22795
- if( ur==0x7ff0000000000000LL ){
22796
- sqlite3_fputs("9.0e+999", p->out);
22797
- }else if( ur==0xfff0000000000000LL ){
22798
- sqlite3_fputs("-9.0e+999", p->out);
22799
- }else{
22800
- sqlite3_int64 ir = (sqlite3_int64)r;
22801
- if( r==(double)ir ){
22802
- sqlite3_snprintf(50,z,"%lld.0", ir);
22803
- }else{
22804
- sqlite3_snprintf(50,z,"%!.20g", r);
22805
- }
22806
- sqlite3_fputs(z, p->out);
22807
- }
22808
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22809
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22810
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
22811
- output_hex_blob(p->out, pBlob, nBlob);
22812
- }else if( isNumber(azArg[i], 0) ){
22813
- sqlite3_fputs(azArg[i], p->out);
22814
- }else if( ShellHasFlag(p, SHFLG_Newlines) ){
22815
- output_quoted_string(p, azArg[i]);
22816
- }else{
22817
- output_quoted_escaped_string(p, azArg[i]);
22818
- }
22819
- }
22820
- sqlite3_fputs(");\n", p->out);
22821
- break;
22822
- }
22823
- case MODE_Json: {
22824
- if( azArg==0 ) break;
22825
- if( p->cnt==0 ){
22826
- sqlite3_fputs("[{", p->out);
22827
- }else{
22828
- sqlite3_fputs(",\n{", p->out);
22829
- }
22830
- p->cnt++;
22831
- for(i=0; i<nArg; i++){
22832
- output_json_string(p->out, azCol[i], -1);
22833
- sqlite3_fputs(":", p->out);
22834
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22835
- sqlite3_fputs("null", p->out);
22836
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22837
- char z[50];
22838
- double r = sqlite3_column_double(p->pStmt, i);
22839
- sqlite3_uint64 ur;
22840
- memcpy(&ur,&r,sizeof(r));
22841
- if( ur==0x7ff0000000000000LL ){
22842
- sqlite3_fputs("9.0e+999", p->out);
22843
- }else if( ur==0xfff0000000000000LL ){
22844
- sqlite3_fputs("-9.0e+999", p->out);
22845
- }else{
22846
- sqlite3_snprintf(50,z,"%!.20g", r);
22847
- sqlite3_fputs(z, p->out);
22848
- }
22849
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22850
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22851
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
22852
- output_json_string(p->out, pBlob, nBlob);
22853
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
22854
- output_json_string(p->out, azArg[i], -1);
22855
- }else{
22856
- sqlite3_fputs(azArg[i], p->out);
22857
- }
22858
- if( i<nArg-1 ){
22859
- sqlite3_fputs(",", p->out);
22860
- }
22861
- }
22862
- sqlite3_fputs("}", p->out);
22863
- break;
22864
- }
22865
- case MODE_Quote: {
22866
- if( azArg==0 ) break;
22867
- if( p->cnt==0 && p->showHeader ){
22868
- for(i=0; i<nArg; i++){
22869
- if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22870
- output_quoted_string(p, azCol[i]);
22871
- }
22872
- sqlite3_fputs(p->rowSeparator, p->out);
22873
- }
22874
- p->cnt++;
22875
- for(i=0; i<nArg; i++){
22876
- if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22877
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22878
- sqlite3_fputs("NULL", p->out);
22879
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
22880
- output_quoted_string(p, azArg[i]);
22881
- }else if( aiType && aiType[i]==SQLITE_INTEGER ){
22882
- sqlite3_fputs(azArg[i], p->out);
22883
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22884
- char z[50];
22885
- double r = sqlite3_column_double(p->pStmt, i);
22886
- sqlite3_snprintf(50,z,"%!.20g", r);
22887
- sqlite3_fputs(z, p->out);
22888
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22889
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22890
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
22891
- output_hex_blob(p->out, pBlob, nBlob);
22892
- }else if( isNumber(azArg[i], 0) ){
22893
- sqlite3_fputs(azArg[i], p->out);
22894
- }else{
22895
- output_quoted_string(p, azArg[i]);
22896
- }
22897
- }
22898
- sqlite3_fputs(p->rowSeparator, p->out);
22899
- break;
22900
- }
22901
- case MODE_Ascii: {
22902
- if( p->cnt++==0 && p->showHeader ){
22903
- for(i=0; i<nArg; i++){
22904
- if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22905
- sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out);
22906
- }
22907
- sqlite3_fputs(p->rowSeparator, p->out);
22908
- }
22909
- if( azArg==0 ) break;
22910
- for(i=0; i<nArg; i++){
22911
- if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22912
- sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out);
22913
- }
22914
- sqlite3_fputs(p->rowSeparator, p->out);
22915
- break;
22916
- }
22917
- case MODE_EQP: {
22918
- eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
22919
- break;
22920
- }
22921
- }
22922
- return 0;
22923
-}
22924
-
22925
-/*
22926
-** This is the callback routine that the SQLite library
22927
-** invokes for each row of a query result.
22928
-*/
22929
-static int callback(void *pArg, int nArg, char **azArg, char **azCol){
22930
- /* since we don't have type info, call the shell_callback with a NULL value */
22931
- return shell_callback(pArg, nArg, azArg, azCol, NULL);
22932
-}
22933
-
2293424957
/*
2293524958
** This is the callback routine from sqlite3_exec() that appends all
2293624959
** output onto the end of a ShellText object.
2293724960
*/
2293824961
static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
@@ -22988,11 +25011,11 @@
2298825011
"INSERT INTO selftest(tno,op,cmd,ans)"
2298925012
" SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
2299025013
"DROP TABLE [_shell$self];"
2299125014
,0,0,&zErrMsg);
2299225015
if( zErrMsg ){
22993
- sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
25016
+ cli_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
2299425017
sqlite3_free(zErrMsg);
2299525018
}
2299625019
sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
2299725020
}
2299825021
@@ -23006,15 +25029,11 @@
2300625029
if( p->zDestTable ){
2300725030
sqlite3_free(p->zDestTable);
2300825031
p->zDestTable = 0;
2300925032
}
2301025033
if( zName==0 ) return;
23011
- if( quoteChar(zName) ){
23012
- p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
23013
- }else{
23014
- p->zDestTable = sqlite3_mprintf("%s", zName);
23015
- }
25034
+ p->zDestTable = sqlite3_mprintf("%s", zName);
2301625035
shell_check_oom(p->zDestTable);
2301725036
}
2301825037
2301925038
/*
2302025039
** Maybe construct two lines of text that point out the position of a
@@ -23080,36 +25099,36 @@
2308025099
int i;
2308125100
const char *z;
2308225101
rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
2308325102
if( rc!=SQLITE_OK || !pSelect ){
2308425103
char *zContext = shell_error_context(zSelect, p->db);
23085
- sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s",
25104
+ cli_printf(p->out, "/**** ERROR: (%d) %s *****/\n%s",
2308625105
rc, sqlite3_errmsg(p->db), zContext);
2308725106
sqlite3_free(zContext);
2308825107
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2308925108
return rc;
2309025109
}
2309125110
rc = sqlite3_step(pSelect);
2309225111
nResult = sqlite3_column_count(pSelect);
2309325112
while( rc==SQLITE_ROW ){
2309425113
z = (const char*)sqlite3_column_text(pSelect, 0);
23095
- sqlite3_fprintf(p->out, "%s", z);
25114
+ cli_printf(p->out, "%s", z);
2309625115
for(i=1; i<nResult; i++){
23097
- sqlite3_fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
25116
+ cli_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
2309825117
}
2309925118
if( z==0 ) z = "";
2310025119
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
2310125120
if( z[0] ){
23102
- sqlite3_fputs("\n;\n", p->out);
25121
+ cli_puts("\n;\n", p->out);
2310325122
}else{
23104
- sqlite3_fputs(";\n", p->out);
25123
+ cli_puts(";\n", p->out);
2310525124
}
2310625125
rc = sqlite3_step(pSelect);
2310725126
}
2310825127
rc = sqlite3_finalize(pSelect);
2310925128
if( rc!=SQLITE_OK ){
23110
- sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n",
25129
+ cli_printf(p->out, "/**** ERROR: (%d) %s *****/\n",
2311125130
rc, sqlite3_errmsg(p->db));
2311225131
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2311325132
}
2311425133
return rc;
2311525134
}
@@ -23165,11 +25184,11 @@
2316525184
};
2316625185
int i;
2316725186
for(i=0; i<ArraySize(aTrans); i++){
2316825187
int n = strlen30(aTrans[i].zPattern);
2316925188
if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){
23170
- sqlite3_fprintf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
25189
+ cli_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
2317125190
break;
2317225191
}
2317325192
}
2317425193
}
2317525194
fclose(in);
@@ -23197,11 +25216,11 @@
2319725216
if( nPercent>1 ){
2319825217
sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
2319925218
}else{
2320025219
sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
2320125220
}
23202
- sqlite3_fprintf(out, "%-36s %s\n", zLabel, zLine);
25221
+ cli_printf(out, "%-36s %s\n", zLabel, zLine);
2320325222
}
2320425223
2320525224
/*
2320625225
** Display memory stats.
2320725226
*/
@@ -23219,34 +25238,34 @@
2321925238
if( pArg->pStmt && pArg->statsOn==2 ){
2322025239
int nCol, i, x;
2322125240
sqlite3_stmt *pStmt = pArg->pStmt;
2322225241
char z[100];
2322325242
nCol = sqlite3_column_count(pStmt);
23224
- sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol);
25243
+ cli_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
2322525244
for(i=0; i<nCol; i++){
2322625245
sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
23227
- sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
25246
+ cli_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
2322825247
#ifndef SQLITE_OMIT_DECLTYPE
2322925248
sqlite3_snprintf(30, z+x, "declared type:");
23230
- sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
25249
+ cli_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
2323125250
#endif
2323225251
#ifdef SQLITE_ENABLE_COLUMN_METADATA
2323325252
sqlite3_snprintf(30, z+x, "database name:");
23234
- sqlite3_fprintf(out, "%-36s %s\n", z,
25253
+ cli_printf(out, "%-36s %s\n", z,
2323525254
sqlite3_column_database_name(pStmt,i));
2323625255
sqlite3_snprintf(30, z+x, "table name:");
23237
- sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
25256
+ cli_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
2323825257
sqlite3_snprintf(30, z+x, "origin name:");
23239
- sqlite3_fprintf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i));
25258
+ cli_printf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i));
2324025259
#endif
2324125260
}
2324225261
}
2324325262
2324425263
if( pArg->statsOn==3 ){
2324525264
if( pArg->pStmt ){
2324625265
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
23247
- sqlite3_fprintf(out, "VM-steps: %d\n", iCur);
25266
+ cli_printf(out, "VM-steps: %d\n", iCur);
2324825267
}
2324925268
return 0;
2325025269
}
2325125270
2325225271
displayStatLine(out, "Memory Used:",
@@ -23271,93 +25290,93 @@
2327125290
if( db ){
2327225291
if( pArg->shellFlgs & SHFLG_Lookaside ){
2327325292
iHiwtr = iCur = -1;
2327425293
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
2327525294
&iCur, &iHiwtr, bReset);
23276
- sqlite3_fprintf(out,
25295
+ cli_printf(out,
2327725296
"Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
2327825297
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
2327925298
&iCur, &iHiwtr, bReset);
23280
- sqlite3_fprintf(out,
25299
+ cli_printf(out,
2328125300
"Successful lookaside attempts: %d\n", iHiwtr);
2328225301
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
2328325302
&iCur, &iHiwtr, bReset);
23284
- sqlite3_fprintf(out,
25303
+ cli_printf(out,
2328525304
"Lookaside failures due to size: %d\n", iHiwtr);
2328625305
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
2328725306
&iCur, &iHiwtr, bReset);
23288
- sqlite3_fprintf(out,
25307
+ cli_printf(out,
2328925308
"Lookaside failures due to OOM: %d\n", iHiwtr);
2329025309
}
2329125310
iHiwtr = iCur = -1;
2329225311
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
23293
- sqlite3_fprintf(out,
25312
+ cli_printf(out,
2329425313
"Pager Heap Usage: %d bytes\n", iCur);
2329525314
iHiwtr = iCur = -1;
2329625315
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
23297
- sqlite3_fprintf(out,
25316
+ cli_printf(out,
2329825317
"Page cache hits: %d\n", iCur);
2329925318
iHiwtr = iCur = -1;
2330025319
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
23301
- sqlite3_fprintf(out,
25320
+ cli_printf(out,
2330225321
"Page cache misses: %d\n", iCur);
2330325322
iHiwtr64 = iCur64 = -1;
2330425323
sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
2330525324
0);
2330625325
iHiwtr = iCur = -1;
2330725326
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
23308
- sqlite3_fprintf(out,
25327
+ cli_printf(out,
2330925328
"Page cache writes: %d\n", iCur);
2331025329
iHiwtr = iCur = -1;
2331125330
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
23312
- sqlite3_fprintf(out,
25331
+ cli_printf(out,
2331325332
"Page cache spills: %d\n", iCur);
23314
- sqlite3_fprintf(out,
25333
+ cli_printf(out,
2331525334
"Temporary data spilled to disk: %lld\n", iCur64);
2331625335
sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
2331725336
1);
2331825337
iHiwtr = iCur = -1;
2331925338
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
23320
- sqlite3_fprintf(out,
25339
+ cli_printf(out,
2332125340
"Schema Heap Usage: %d bytes\n", iCur);
2332225341
iHiwtr = iCur = -1;
2332325342
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
23324
- sqlite3_fprintf(out,
25343
+ cli_printf(out,
2332525344
"Statement Heap/Lookaside Usage: %d bytes\n", iCur);
2332625345
}
2332725346
2332825347
if( pArg->pStmt ){
2332925348
int iHit, iMiss;
2333025349
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
2333125350
bReset);
23332
- sqlite3_fprintf(out,
25351
+ cli_printf(out,
2333325352
"Fullscan Steps: %d\n", iCur);
2333425353
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
23335
- sqlite3_fprintf(out,
25354
+ cli_printf(out,
2333625355
"Sort Operations: %d\n", iCur);
2333725356
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
23338
- sqlite3_fprintf(out,
25357
+ cli_printf(out,
2333925358
"Autoindex Inserts: %d\n", iCur);
2334025359
iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
2334125360
bReset);
2334225361
iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
2334325362
bReset);
2334425363
if( iHit || iMiss ){
23345
- sqlite3_fprintf(out,
25364
+ cli_printf(out,
2334625365
"Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss);
2334725366
}
2334825367
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
23349
- sqlite3_fprintf(out,
25368
+ cli_printf(out,
2335025369
"Virtual Machine Steps: %d\n", iCur);
2335125370
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
23352
- sqlite3_fprintf(out,
25371
+ cli_printf(out,
2335325372
"Reprepare operations: %d\n", iCur);
2335425373
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
23355
- sqlite3_fprintf(out,
25374
+ cli_printf(out,
2335625375
"Number of times run: %d\n", iCur);
2335725376
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
23358
- sqlite3_fprintf(out,
25377
+ cli_printf(out,
2335925378
"Memory used by prepared stmt: %d\n", iCur);
2336025379
}
2336125380
2336225381
#ifdef __linux__
2336325382
displayLinuxIoStats(pArg->out);
@@ -23366,271 +25385,10 @@
2336625385
/* Do not remove this machine readable comment: extra-stats-output-here */
2336725386
2336825387
return 0;
2336925388
}
2337025389
23371
-
23372
-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
23373
-static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
23374
- int iPid = 0;
23375
- int ret = 1;
23376
- sqlite3_stmt_scanstatus_v2(p, iEntry,
23377
- SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
23378
- );
23379
- while( iPid!=0 ){
23380
- int ii;
23381
- for(ii=0; 1; ii++){
23382
- int iId;
23383
- int res;
23384
- res = sqlite3_stmt_scanstatus_v2(p, ii,
23385
- SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
23386
- );
23387
- if( res ) break;
23388
- if( iId==iPid ){
23389
- sqlite3_stmt_scanstatus_v2(p, ii,
23390
- SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
23391
- );
23392
- }
23393
- }
23394
- ret++;
23395
- }
23396
- return ret;
23397
-}
23398
-#endif
23399
-
23400
-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
23401
-static void display_explain_scanstats(
23402
- sqlite3 *db, /* Database to query */
23403
- ShellState *pArg /* Pointer to ShellState */
23404
-){
23405
- static const int f = SQLITE_SCANSTAT_COMPLEX;
23406
- sqlite3_stmt *p = pArg->pStmt;
23407
- int ii = 0;
23408
- i64 nTotal = 0;
23409
- int nWidth = 0;
23410
- eqp_reset(pArg);
23411
-
23412
- for(ii=0; 1; ii++){
23413
- const char *z = 0;
23414
- int n = 0;
23415
- if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
23416
- break;
23417
- }
23418
- n = (int)strlen(z) + scanStatsHeight(p, ii)*3;
23419
- if( n>nWidth ) nWidth = n;
23420
- }
23421
- nWidth += 4;
23422
-
23423
- sqlite3_stmt_scanstatus_v2(p, -1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal);
23424
- for(ii=0; 1; ii++){
23425
- i64 nLoop = 0;
23426
- i64 nRow = 0;
23427
- i64 nCycle = 0;
23428
- int iId = 0;
23429
- int iPid = 0;
23430
- const char *zo = 0;
23431
- const char *zName = 0;
23432
- char *zText = 0;
23433
- double rEst = 0.0;
23434
-
23435
- if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){
23436
- break;
23437
- }
23438
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_EST,f,(void*)&rEst);
23439
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop);
23440
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow);
23441
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle);
23442
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId);
23443
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid);
23444
- sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NAME,f,(void*)&zName);
23445
-
23446
- zText = sqlite3_mprintf("%s", zo);
23447
- if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
23448
- char *z = 0;
23449
- if( nCycle>=0 && nTotal>0 ){
23450
- z = sqlite3_mprintf("%zcycles=%lld [%d%%]", z,
23451
- nCycle, ((nCycle*100)+nTotal/2) / nTotal
23452
- );
23453
- }
23454
- if( nLoop>=0 ){
23455
- z = sqlite3_mprintf("%z%sloops=%lld", z, z ? " " : "", nLoop);
23456
- }
23457
- if( nRow>=0 ){
23458
- z = sqlite3_mprintf("%z%srows=%lld", z, z ? " " : "", nRow);
23459
- }
23460
-
23461
- if( zName && pArg->scanstatsOn>1 ){
23462
- double rpl = (double)nRow / (double)nLoop;
23463
- z = sqlite3_mprintf("%z rpl=%.1f est=%.1f", z, rpl, rEst);
23464
- }
23465
-
23466
- zText = sqlite3_mprintf(
23467
- "% *z (%z)", -1*(nWidth-scanStatsHeight(p, ii)*3), zText, z
23468
- );
23469
- }
23470
-
23471
- eqp_append(pArg, iId, iPid, zText);
23472
- sqlite3_free(zText);
23473
- }
23474
-
23475
- eqp_render(pArg, nTotal);
23476
-}
23477
-#endif
23478
-
23479
-
23480
-/*
23481
-** Parameter azArray points to a zero-terminated array of strings. zStr
23482
-** points to a single nul-terminated string. Return non-zero if zStr
23483
-** is equal, according to strcmp(), to any of the strings in the array.
23484
-** Otherwise, return zero.
23485
-*/
23486
-static int str_in_array(const char *zStr, const char **azArray){
23487
- int i;
23488
- for(i=0; azArray[i]; i++){
23489
- if( 0==cli_strcmp(zStr, azArray[i]) ) return 1;
23490
- }
23491
- return 0;
23492
-}
23493
-
23494
-/*
23495
-** If compiled statement pSql appears to be an EXPLAIN statement, allocate
23496
-** and populate the ShellState.aiIndent[] array with the number of
23497
-** spaces each opcode should be indented before it is output.
23498
-**
23499
-** The indenting rules are:
23500
-**
23501
-** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
23502
-** all opcodes that occur between the p2 jump destination and the opcode
23503
-** itself by 2 spaces.
23504
-**
23505
-** * Do the previous for "Return" instructions for when P2 is positive.
23506
-** See tag-20220407a in wherecode.c and vdbe.c.
23507
-**
23508
-** * For each "Goto", if the jump destination is earlier in the program
23509
-** and ends on one of:
23510
-** Yield SeekGt SeekLt RowSetRead Rewind
23511
-** or if the P1 parameter is one instead of zero,
23512
-** then indent all opcodes between the earlier instruction
23513
-** and "Goto" by 2 spaces.
23514
-*/
23515
-static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
23516
- int *abYield = 0; /* True if op is an OP_Yield */
23517
- int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
23518
- int iOp; /* Index of operation in p->aiIndent[] */
23519
-
23520
- const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
23521
- "Return", 0 };
23522
- const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
23523
- "Rewind", 0 };
23524
- const char *azGoto[] = { "Goto", 0 };
23525
-
23526
- /* The caller guarantees that the leftmost 4 columns of the statement
23527
- ** passed to this function are equivalent to the leftmost 4 columns
23528
- ** of EXPLAIN statement output. In practice the statement may be
23529
- ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
23530
- assert( sqlite3_column_count(pSql)>=4 );
23531
- assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) );
23532
- assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) );
23533
- assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) );
23534
- assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) );
23535
-
23536
- for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
23537
- int i;
23538
- int iAddr = sqlite3_column_int(pSql, 0);
23539
- const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
23540
- int p1 = sqlite3_column_int(pSql, 2);
23541
- int p2 = sqlite3_column_int(pSql, 3);
23542
-
23543
- /* Assuming that p2 is an instruction address, set variable p2op to the
23544
- ** index of that instruction in the aiIndent[] array. p2 and p2op may be
23545
- ** different if the current instruction is part of a sub-program generated
23546
- ** by an SQL trigger or foreign key. */
23547
- int p2op = (p2 + (iOp-iAddr));
23548
-
23549
- /* Grow the p->aiIndent array as required */
23550
- if( iOp>=nAlloc ){
23551
- nAlloc += 100;
23552
- p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
23553
- shell_check_oom(p->aiIndent);
23554
- abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
23555
- shell_check_oom(abYield);
23556
- }
23557
-
23558
- abYield[iOp] = str_in_array(zOp, azYield);
23559
- p->aiIndent[iOp] = 0;
23560
- p->nIndent = iOp+1;
23561
- if( str_in_array(zOp, azNext) && p2op>0 ){
23562
- for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
23563
- }
23564
- if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
23565
- for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
23566
- }
23567
- }
23568
-
23569
- p->iIndent = 0;
23570
- sqlite3_free(abYield);
23571
- sqlite3_reset(pSql);
23572
-}
23573
-
23574
-/*
23575
-** Free the array allocated by explain_data_prepare().
23576
-*/
23577
-static void explain_data_delete(ShellState *p){
23578
- sqlite3_free(p->aiIndent);
23579
- p->aiIndent = 0;
23580
- p->nIndent = 0;
23581
- p->iIndent = 0;
23582
-}
23583
-
23584
-static void exec_prepared_stmt(ShellState*, sqlite3_stmt*);
23585
-
23586
-/*
23587
-** Display scan stats.
23588
-*/
23589
-static void display_scanstats(
23590
- sqlite3 *db, /* Database to query */
23591
- ShellState *pArg /* Pointer to ShellState */
23592
-){
23593
-#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
23594
- UNUSED_PARAMETER(db);
23595
- UNUSED_PARAMETER(pArg);
23596
-#else
23597
- if( pArg->scanstatsOn==3 ){
23598
- const char *zSql =
23599
- " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
23600
- " format('% 6s (%.2f%%)',"
23601
- " CASE WHEN ncycle<100_000 THEN ncycle || ' '"
23602
- " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'"
23603
- " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'"
23604
- " ELSE (ncycle/1000_000_000) || 'G' END,"
23605
- " ncycle*100.0/(sum(ncycle) OVER ())"
23606
- " ) AS cycles"
23607
- " FROM bytecode(?)";
23608
-
23609
- int rc = SQLITE_OK;
23610
- sqlite3_stmt *pStmt = 0;
23611
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
23612
- if( rc==SQLITE_OK ){
23613
- sqlite3_stmt *pSave = pArg->pStmt;
23614
- pArg->pStmt = pStmt;
23615
- sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0);
23616
-
23617
- pArg->cnt = 0;
23618
- pArg->cMode = MODE_ScanExp;
23619
- explain_data_prepare(pArg, pStmt);
23620
- exec_prepared_stmt(pArg, pStmt);
23621
- explain_data_delete(pArg);
23622
-
23623
- sqlite3_finalize(pStmt);
23624
- pArg->pStmt = pSave;
23625
- }
23626
- }else{
23627
- display_explain_scanstats(db, pArg);
23628
- }
23629
-#endif
23630
-}
23631
-
2363225390
/*
2363325391
** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
2363425392
*/
2363525393
static unsigned int savedSelectTrace;
2363625394
static unsigned int savedWhereTrace;
@@ -23756,584 +25514,10 @@
2375625514
sqlite3_reset(pQ);
2375725515
}
2375825516
sqlite3_finalize(pQ);
2375925517
}
2376025518
23761
-/*
23762
-** UTF8 box-drawing characters. Imagine box lines like this:
23763
-**
23764
-** 1
23765
-** |
23766
-** 4 --+-- 2
23767
-** |
23768
-** 3
23769
-**
23770
-** Each box characters has between 2 and 4 of the lines leading from
23771
-** the center. The characters are here identified by the numbers of
23772
-** their corresponding lines.
23773
-*/
23774
-#define BOX_24 "\342\224\200" /* U+2500 --- */
23775
-#define BOX_13 "\342\224\202" /* U+2502 | */
23776
-#define BOX_23 "\342\224\214" /* U+250c ,- */
23777
-#define BOX_34 "\342\224\220" /* U+2510 -, */
23778
-#define BOX_12 "\342\224\224" /* U+2514 '- */
23779
-#define BOX_14 "\342\224\230" /* U+2518 -' */
23780
-#define BOX_123 "\342\224\234" /* U+251c |- */
23781
-#define BOX_134 "\342\224\244" /* U+2524 -| */
23782
-#define BOX_234 "\342\224\254" /* U+252c -,- */
23783
-#define BOX_124 "\342\224\264" /* U+2534 -'- */
23784
-#define BOX_1234 "\342\224\274" /* U+253c -|- */
23785
-
23786
-/* Draw horizontal line N characters long using unicode box
23787
-** characters
23788
-*/
23789
-static void print_box_line(FILE *out, int N){
23790
- const char zDash[] =
23791
- BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
23792
- BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
23793
- const int nDash = sizeof(zDash) - 1;
23794
- N *= 3;
23795
- while( N>nDash ){
23796
- sqlite3_fputs(zDash, out);
23797
- N -= nDash;
23798
- }
23799
- sqlite3_fprintf(out, "%.*s", N, zDash);
23800
-}
23801
-
23802
-/*
23803
-** Draw a horizontal separator for a MODE_Box table.
23804
-*/
23805
-static void print_box_row_separator(
23806
- ShellState *p,
23807
- int nArg,
23808
- const char *zSep1,
23809
- const char *zSep2,
23810
- const char *zSep3
23811
-){
23812
- int i;
23813
- if( nArg>0 ){
23814
- sqlite3_fputs(zSep1, p->out);
23815
- print_box_line(p->out, p->actualWidth[0]+2);
23816
- for(i=1; i<nArg; i++){
23817
- sqlite3_fputs(zSep2, p->out);
23818
- print_box_line(p->out, p->actualWidth[i]+2);
23819
- }
23820
- sqlite3_fputs(zSep3, p->out);
23821
- }
23822
- sqlite3_fputs("\n", p->out);
23823
-}
23824
-
23825
-/*
23826
-** z[] is a line of text that is to be displayed the .mode box or table or
23827
-** similar tabular formats. z[] might contain control characters such
23828
-** as \n, \t, \f, or \r.
23829
-**
23830
-** Compute characters to display on the first line of z[]. Stop at the
23831
-** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
23832
-** from malloc()) of that first line, which caller should free sometime.
23833
-** Write anything to display on the next line into *pzTail. If this is
23834
-** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
23835
-*/
23836
-static char *translateForDisplayAndDup(
23837
- ShellState *p, /* To access current settings */
23838
- const unsigned char *z, /* Input text to be transformed */
23839
- const unsigned char **pzTail, /* OUT: Tail of the input for next line */
23840
- int mxWidth, /* Max width. 0 means no limit */
23841
- u8 bWordWrap /* If true, avoid breaking mid-word */
23842
-){
23843
- int i; /* Input bytes consumed */
23844
- int j; /* Output bytes generated */
23845
- int k; /* Input bytes to be displayed */
23846
- int n; /* Output column number */
23847
- unsigned char *zOut; /* Output text */
23848
-
23849
- if( z==0 ){
23850
- *pzTail = 0;
23851
- return 0;
23852
- }
23853
- if( mxWidth<0 ) mxWidth = -mxWidth;
23854
- if( mxWidth==0 ) mxWidth = 1000000;
23855
- i = j = n = 0;
23856
- while( n<mxWidth ){
23857
- unsigned char c = z[i];
23858
- if( c>=0xc0 ){
23859
- int u;
23860
- int len = decodeUtf8(&z[i], &u);
23861
- i += len;
23862
- j += len;
23863
- n += cli_wcwidth(u);
23864
- continue;
23865
- }
23866
- if( c>=' ' ){
23867
- n++;
23868
- i++;
23869
- j++;
23870
- continue;
23871
- }
23872
- if( c==0 || c=='\n' || (c=='\r' && z[i+1]=='\n') ) break;
23873
- if( c=='\t' ){
23874
- do{
23875
- n++;
23876
- j++;
23877
- }while( (n&7)!=0 && n<mxWidth );
23878
- i++;
23879
- continue;
23880
- }
23881
- if( c==0x1b && p->eEscMode==SHELL_ESC_OFF && (k = isVt100(&z[i]))>0 ){
23882
- i += k;
23883
- j += k;
23884
- }else{
23885
- n++;
23886
- j += 3;
23887
- i++;
23888
- }
23889
- }
23890
- if( n>=mxWidth && bWordWrap ){
23891
- /* Perhaps try to back up to a better place to break the line */
23892
- for(k=i; k>i/2; k--){
23893
- if( IsSpace(z[k-1]) ) break;
23894
- }
23895
- if( k<=i/2 ){
23896
- for(k=i; k>i/2; k--){
23897
- if( IsAlnum(z[k-1])!=IsAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
23898
- }
23899
- }
23900
- if( k<=i/2 ){
23901
- k = i;
23902
- }else{
23903
- i = k;
23904
- while( z[i]==' ' ) i++;
23905
- }
23906
- }else{
23907
- k = i;
23908
- }
23909
- if( n>=mxWidth && z[i]>=' ' ){
23910
- *pzTail = &z[i];
23911
- }else if( z[i]=='\r' && z[i+1]=='\n' ){
23912
- *pzTail = z[i+2] ? &z[i+2] : 0;
23913
- }else if( z[i]==0 || z[i+1]==0 ){
23914
- *pzTail = 0;
23915
- }else{
23916
- *pzTail = &z[i+1];
23917
- }
23918
- zOut = malloc( j+1 );
23919
- shell_check_oom(zOut);
23920
- i = j = n = 0;
23921
- while( i<k ){
23922
- unsigned char c = z[i];
23923
- if( c>=0xc0 ){
23924
- int u;
23925
- int len = decodeUtf8(&z[i], &u);
23926
- do{ zOut[j++] = z[i++]; }while( (--len)>0 );
23927
- n += cli_wcwidth(u);
23928
- continue;
23929
- }
23930
- if( c>=' ' ){
23931
- n++;
23932
- zOut[j++] = z[i++];
23933
- continue;
23934
- }
23935
- if( c==0 ) break;
23936
- if( z[i]=='\t' ){
23937
- do{
23938
- n++;
23939
- zOut[j++] = ' ';
23940
- }while( (n&7)!=0 && n<mxWidth );
23941
- i++;
23942
- continue;
23943
- }
23944
- switch( p->eEscMode ){
23945
- case SHELL_ESC_SYMBOL:
23946
- zOut[j++] = 0xe2;
23947
- zOut[j++] = 0x90;
23948
- zOut[j++] = 0x80 + c;
23949
- break;
23950
- case SHELL_ESC_ASCII:
23951
- zOut[j++] = '^';
23952
- zOut[j++] = 0x40 + c;
23953
- break;
23954
- case SHELL_ESC_OFF: {
23955
- int nn;
23956
- if( c==0x1b && (nn = isVt100(&z[i]))>0 ){
23957
- memcpy(&zOut[j], &z[i], nn);
23958
- j += nn;
23959
- i += nn - 1;
23960
- }else{
23961
- zOut[j++] = c;
23962
- }
23963
- break;
23964
- }
23965
- }
23966
- i++;
23967
- }
23968
- zOut[j] = 0;
23969
- return (char*)zOut;
23970
-}
23971
-
23972
-/* Return true if the text string z[] contains characters that need
23973
-** unistr() escaping.
23974
-*/
23975
-static int needUnistr(const unsigned char *z){
23976
- unsigned char c;
23977
- if( z==0 ) return 0;
23978
- while( (c = *z)>0x1f || c=='\t' || c=='\n' || (c=='\r' && z[1]=='\n') ){ z++; }
23979
- return c!=0;
23980
-}
23981
-
23982
-/* Extract the value of the i-th current column for pStmt as an SQL literal
23983
-** value. Memory is obtained from sqlite3_malloc64() and must be freed by
23984
-** the caller.
23985
-*/
23986
-static char *quoted_column(sqlite3_stmt *pStmt, int i){
23987
- switch( sqlite3_column_type(pStmt, i) ){
23988
- case SQLITE_NULL: {
23989
- return sqlite3_mprintf("NULL");
23990
- }
23991
- case SQLITE_INTEGER:
23992
- case SQLITE_FLOAT: {
23993
- return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
23994
- }
23995
- case SQLITE_TEXT: {
23996
- const unsigned char *zText = sqlite3_column_text(pStmt,i);
23997
- return sqlite3_mprintf(needUnistr(zText)?"%#Q":"%Q",zText);
23998
- }
23999
- case SQLITE_BLOB: {
24000
- int j;
24001
- sqlite3_str *pStr = sqlite3_str_new(0);
24002
- const unsigned char *a = sqlite3_column_blob(pStmt,i);
24003
- int n = sqlite3_column_bytes(pStmt,i);
24004
- sqlite3_str_append(pStr, "x'", 2);
24005
- for(j=0; j<n; j++){
24006
- sqlite3_str_appendf(pStr, "%02x", a[j]);
24007
- }
24008
- sqlite3_str_append(pStr, "'", 1);
24009
- return sqlite3_str_finish(pStr);
24010
- }
24011
- }
24012
- return 0; /* Not reached */
24013
-}
24014
-
24015
-/*
24016
-** Run a prepared statement and output the result in one of the
24017
-** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
24018
-** or MODE_Box.
24019
-**
24020
-** This is different from ordinary exec_prepared_stmt() in that
24021
-** it has to run the entire query and gather the results into memory
24022
-** first, in order to determine column widths, before providing
24023
-** any output.
24024
-*/
24025
-static void exec_prepared_stmt_columnar(
24026
- ShellState *p, /* Pointer to ShellState */
24027
- sqlite3_stmt *pStmt /* Statement to run */
24028
-){
24029
- sqlite3_int64 nRow = 0;
24030
- int nColumn = 0;
24031
- char **azData = 0;
24032
- sqlite3_int64 nAlloc = 0;
24033
- char *abRowDiv = 0;
24034
- const unsigned char *uz;
24035
- const char *z;
24036
- char **azQuoted = 0;
24037
- int rc;
24038
- sqlite3_int64 i, nData;
24039
- int j, nTotal, w, n;
24040
- const char *colSep = 0;
24041
- const char *rowSep = 0;
24042
- const unsigned char **azNextLine = 0;
24043
- int bNextLine = 0;
24044
- int bMultiLineRowExists = 0;
24045
- int bw = p->cmOpts.bWordWrap;
24046
- const char *zEmpty = "";
24047
- const char *zShowNull = p->nullValue;
24048
-
24049
- rc = sqlite3_step(pStmt);
24050
- if( rc!=SQLITE_ROW ) return;
24051
- nColumn = sqlite3_column_count(pStmt);
24052
- if( nColumn==0 ) goto columnar_end;
24053
- nAlloc = nColumn*4;
24054
- if( nAlloc<=0 ) nAlloc = 1;
24055
- azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
24056
- shell_check_oom(azData);
24057
- azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
24058
- shell_check_oom(azNextLine);
24059
- memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
24060
- if( p->cmOpts.bQuote ){
24061
- azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
24062
- shell_check_oom(azQuoted);
24063
- memset(azQuoted, 0, nColumn*sizeof(char*) );
24064
- }
24065
- abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
24066
- shell_check_oom(abRowDiv);
24067
- if( nColumn>p->nWidth ){
24068
- p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
24069
- shell_check_oom(p->colWidth);
24070
- for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
24071
- p->nWidth = nColumn;
24072
- p->actualWidth = &p->colWidth[nColumn];
24073
- }
24074
- memset(p->actualWidth, 0, nColumn*sizeof(int));
24075
- for(i=0; i<nColumn; i++){
24076
- w = p->colWidth[i];
24077
- if( w<0 ) w = -w;
24078
- p->actualWidth[i] = w;
24079
- }
24080
- for(i=0; i<nColumn; i++){
24081
- const unsigned char *zNotUsed;
24082
- int wx = p->colWidth[i];
24083
- if( wx==0 ){
24084
- wx = p->cmOpts.iWrap;
24085
- }
24086
- if( wx<0 ) wx = -wx;
24087
- uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
24088
- if( uz==0 ) uz = (u8*)"";
24089
- azData[i] = translateForDisplayAndDup(p, uz, &zNotUsed, wx, bw);
24090
- }
24091
- do{
24092
- int useNextLine = bNextLine;
24093
- bNextLine = 0;
24094
- if( (nRow+2)*nColumn >= nAlloc ){
24095
- nAlloc *= 2;
24096
- azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
24097
- shell_check_oom(azData);
24098
- abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
24099
- shell_check_oom(abRowDiv);
24100
- }
24101
- abRowDiv[nRow] = 1;
24102
- nRow++;
24103
- for(i=0; i<nColumn; i++){
24104
- int wx = p->colWidth[i];
24105
- if( wx==0 ){
24106
- wx = p->cmOpts.iWrap;
24107
- }
24108
- if( wx<0 ) wx = -wx;
24109
- if( useNextLine ){
24110
- uz = azNextLine[i];
24111
- if( uz==0 ) uz = (u8*)zEmpty;
24112
- }else if( p->cmOpts.bQuote ){
24113
- assert( azQuoted!=0 );
24114
- sqlite3_free(azQuoted[i]);
24115
- azQuoted[i] = quoted_column(pStmt,i);
24116
- uz = (const unsigned char*)azQuoted[i];
24117
- }else{
24118
- uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
24119
- if( uz==0 ) uz = (u8*)zShowNull;
24120
- }
24121
- azData[nRow*nColumn + i]
24122
- = translateForDisplayAndDup(p, uz, &azNextLine[i], wx, bw);
24123
- if( azNextLine[i] ){
24124
- bNextLine = 1;
24125
- abRowDiv[nRow-1] = 0;
24126
- bMultiLineRowExists = 1;
24127
- }
24128
- }
24129
- }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
24130
- nTotal = nColumn*(nRow+1);
24131
- for(i=0; i<nTotal; i++){
24132
- z = azData[i];
24133
- if( z==0 ) z = (char*)zEmpty;
24134
- n = strlenChar(z);
24135
- j = i%nColumn;
24136
- if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
24137
- }
24138
- if( seenInterrupt ) goto columnar_end;
24139
- switch( p->cMode ){
24140
- case MODE_Column: {
24141
- colSep = " ";
24142
- rowSep = "\n";
24143
- if( p->showHeader ){
24144
- for(i=0; i<nColumn; i++){
24145
- w = p->actualWidth[i];
24146
- if( p->colWidth[i]<0 ) w = -w;
24147
- utf8_width_print(p->out, w, azData[i]);
24148
- sqlite3_fputs(i==nColumn-1?"\n":" ", p->out);
24149
- }
24150
- for(i=0; i<nColumn; i++){
24151
- print_dashes(p->out, p->actualWidth[i]);
24152
- sqlite3_fputs(i==nColumn-1?"\n":" ", p->out);
24153
- }
24154
- }
24155
- break;
24156
- }
24157
- case MODE_Table: {
24158
- colSep = " | ";
24159
- rowSep = " |\n";
24160
- print_row_separator(p, nColumn, "+");
24161
- sqlite3_fputs("| ", p->out);
24162
- for(i=0; i<nColumn; i++){
24163
- w = p->actualWidth[i];
24164
- n = strlenChar(azData[i]);
24165
- sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "",
24166
- azData[i], (w-n+1)/2, "");
24167
- sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out);
24168
- }
24169
- print_row_separator(p, nColumn, "+");
24170
- break;
24171
- }
24172
- case MODE_Markdown: {
24173
- colSep = " | ";
24174
- rowSep = " |\n";
24175
- sqlite3_fputs("| ", p->out);
24176
- for(i=0; i<nColumn; i++){
24177
- w = p->actualWidth[i];
24178
- n = strlenChar(azData[i]);
24179
- sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "",
24180
- azData[i], (w-n+1)/2, "");
24181
- sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out);
24182
- }
24183
- print_row_separator(p, nColumn, "|");
24184
- break;
24185
- }
24186
- case MODE_Box: {
24187
- colSep = " " BOX_13 " ";
24188
- rowSep = " " BOX_13 "\n";
24189
- print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
24190
- sqlite3_fputs(BOX_13 " ", p->out);
24191
- for(i=0; i<nColumn; i++){
24192
- w = p->actualWidth[i];
24193
- n = strlenChar(azData[i]);
24194
- sqlite3_fprintf(p->out, "%*s%s%*s%s",
24195
- (w-n)/2, "", azData[i], (w-n+1)/2, "",
24196
- i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
24197
- }
24198
- print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
24199
- break;
24200
- }
24201
- }
24202
- for(i=nColumn, j=0; i<nTotal; i++, j++){
24203
- if( j==0 && p->cMode!=MODE_Column ){
24204
- sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out);
24205
- }
24206
- z = azData[i];
24207
- if( z==0 ) z = p->nullValue;
24208
- w = p->actualWidth[j];
24209
- if( p->colWidth[j]<0 ) w = -w;
24210
- utf8_width_print(p->out, w, z);
24211
- if( j==nColumn-1 ){
24212
- sqlite3_fputs(rowSep, p->out);
24213
- if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
24214
- if( p->cMode==MODE_Table ){
24215
- print_row_separator(p, nColumn, "+");
24216
- }else if( p->cMode==MODE_Box ){
24217
- print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
24218
- }else if( p->cMode==MODE_Column ){
24219
- sqlite3_fputs("\n", p->out);
24220
- }
24221
- }
24222
- j = -1;
24223
- if( seenInterrupt ) goto columnar_end;
24224
- }else{
24225
- sqlite3_fputs(colSep, p->out);
24226
- }
24227
- }
24228
- if( p->cMode==MODE_Table ){
24229
- print_row_separator(p, nColumn, "+");
24230
- }else if( p->cMode==MODE_Box ){
24231
- print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
24232
- }
24233
-columnar_end:
24234
- if( seenInterrupt ){
24235
- sqlite3_fputs("Interrupt\n", p->out);
24236
- }
24237
- nData = (nRow+1)*nColumn;
24238
- for(i=0; i<nData; i++){
24239
- z = azData[i];
24240
- if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
24241
- }
24242
- sqlite3_free(azData);
24243
- sqlite3_free((void*)azNextLine);
24244
- sqlite3_free(abRowDiv);
24245
- if( azQuoted ){
24246
- for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
24247
- sqlite3_free(azQuoted);
24248
- }
24249
-}
24250
-
24251
-/*
24252
-** Run a prepared statement
24253
-*/
24254
-static void exec_prepared_stmt(
24255
- ShellState *pArg, /* Pointer to ShellState */
24256
- sqlite3_stmt *pStmt /* Statement to run */
24257
-){
24258
- int rc;
24259
- sqlite3_uint64 nRow = 0;
24260
-
24261
- if( pArg->cMode==MODE_Column
24262
- || pArg->cMode==MODE_Table
24263
- || pArg->cMode==MODE_Box
24264
- || pArg->cMode==MODE_Markdown
24265
- ){
24266
- exec_prepared_stmt_columnar(pArg, pStmt);
24267
- return;
24268
- }
24269
-
24270
- /* perform the first step. this will tell us if we
24271
- ** have a result set or not and how wide it is.
24272
- */
24273
- rc = sqlite3_step(pStmt);
24274
- /* if we have a result set... */
24275
- if( SQLITE_ROW == rc ){
24276
- /* allocate space for col name ptr, value ptr, and type */
24277
- int nCol = sqlite3_column_count(pStmt);
24278
- void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
24279
- if( !pData ){
24280
- shell_out_of_memory();
24281
- }else{
24282
- char **azCols = (char **)pData; /* Names of result columns */
24283
- char **azVals = &azCols[nCol]; /* Results */
24284
- int *aiTypes = (int *)&azVals[nCol]; /* Result types */
24285
- int i, x;
24286
- assert(sizeof(int) <= sizeof(char *));
24287
- /* save off ptrs to column names */
24288
- for(i=0; i<nCol; i++){
24289
- azCols[i] = (char *)sqlite3_column_name(pStmt, i);
24290
- }
24291
- do{
24292
- nRow++;
24293
- /* extract the data and data types */
24294
- for(i=0; i<nCol; i++){
24295
- aiTypes[i] = x = sqlite3_column_type(pStmt, i);
24296
- if( x==SQLITE_BLOB
24297
- && pArg
24298
- && (pArg->cMode==MODE_Insert || pArg->cMode==MODE_Quote)
24299
- ){
24300
- azVals[i] = "";
24301
- }else{
24302
- azVals[i] = (char*)sqlite3_column_text(pStmt, i);
24303
- }
24304
- if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
24305
- rc = SQLITE_NOMEM;
24306
- break; /* from for */
24307
- }
24308
- } /* end for */
24309
-
24310
- /* if data and types extracted successfully... */
24311
- if( SQLITE_ROW == rc ){
24312
- /* call the supplied callback with the result row data */
24313
- if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
24314
- rc = SQLITE_ABORT;
24315
- }else{
24316
- rc = sqlite3_step(pStmt);
24317
- }
24318
- }
24319
- } while( SQLITE_ROW == rc );
24320
- sqlite3_free(pData);
24321
- if( pArg->cMode==MODE_Json ){
24322
- sqlite3_fputs("]\n", pArg->out);
24323
- }else if( pArg->cMode==MODE_Www ){
24324
- sqlite3_fputs("</TABLE>\n<PRE>\n", pArg->out);
24325
- }else if( pArg->cMode==MODE_Count ){
24326
- char zBuf[200];
24327
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n",
24328
- nRow, nRow!=1 ? "s" : "");
24329
- printf("%s", zBuf);
24330
- }
24331
- }
24332
- }
24333
-}
24334
-
2433525519
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2433625520
/*
2433725521
** This function is called to process SQL if the previous shell command
2433825522
** was ".expert". It passes the SQL in the second argument directly to
2433925523
** the sqlite3expert object.
@@ -24381,25 +25565,25 @@
2438125565
int nQuery = sqlite3_expert_count(p);
2438225566
int i;
2438325567
2438425568
if( bVerbose ){
2438525569
const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
24386
- sqlite3_fputs("-- Candidates -----------------------------\n", out);
24387
- sqlite3_fprintf(out, "%s\n", zCand);
25570
+ cli_puts("-- Candidates -----------------------------\n", out);
25571
+ cli_printf(out, "%s\n", zCand);
2438825572
}
2438925573
for(i=0; i<nQuery; i++){
2439025574
const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
2439125575
const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
2439225576
const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
2439325577
if( zIdx==0 ) zIdx = "(no new indexes)\n";
2439425578
if( bVerbose ){
24395
- sqlite3_fprintf(out,
25579
+ cli_printf(out,
2439625580
"-- Query %d --------------------------------\n"
2439725581
"%s\n\n"
2439825582
,i+1, zSql);
2439925583
}
24400
- sqlite3_fprintf(out, "%s\n%s\n", zIdx, zEQP);
25584
+ cli_printf(out, "%s\n%s\n", zIdx, zEQP);
2440125585
}
2440225586
}
2440325587
}
2440425588
sqlite3_expert_destroy(p);
2440525589
pState->expert.pExpert = 0;
@@ -24430,30 +25614,30 @@
2443025614
if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){
2443125615
pState->expert.bVerbose = 1;
2443225616
}
2443325617
else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
2443425618
if( i==(nArg-1) ){
24435
- sqlite3_fprintf(stderr, "option requires an argument: %s\n", z);
25619
+ cli_printf(stderr, "option requires an argument: %s\n", z);
2443625620
rc = SQLITE_ERROR;
2443725621
}else{
2443825622
iSample = (int)integerValue(azArg[++i]);
2443925623
if( iSample<0 || iSample>100 ){
24440
- sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]);
25624
+ cli_printf(stderr,"value out of range: %s\n", azArg[i]);
2444125625
rc = SQLITE_ERROR;
2444225626
}
2444325627
}
2444425628
}
2444525629
else{
24446
- sqlite3_fprintf(stderr,"unknown option: %s\n", z);
25630
+ cli_printf(stderr,"unknown option: %s\n", z);
2444725631
rc = SQLITE_ERROR;
2444825632
}
2444925633
}
2445025634
2445125635
if( rc==SQLITE_OK ){
2445225636
pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
2445325637
if( pState->expert.pExpert==0 ){
24454
- sqlite3_fprintf(stderr,
25638
+ cli_printf(stderr,
2445525639
"sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
2445625640
rc = SQLITE_ERROR;
2445725641
}else{
2445825642
sqlite3_expert_config(
2445925643
pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
@@ -24463,10 +25647,19 @@
2446325647
sqlite3_free(zErr);
2446425648
2446525649
return rc;
2446625650
}
2446725651
#endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */
25652
+
25653
+/*
25654
+** QRF write callback
25655
+*/
25656
+static int shellWriteQR(void *pX, const char *z, sqlite3_int64 n){
25657
+ ShellState *pArg = (ShellState*)pX;
25658
+ cli_printf(pArg->out, "%.*s", (int)n, z);
25659
+ return SQLITE_OK;
25660
+}
2446825661
2446925662
/*
2447025663
** Execute a statement or set of statements. Print
2447125664
** any result rows/columns depending on the current mode
2447225665
** set via the supplied callback.
@@ -24483,13 +25676,26 @@
2448325676
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
2448425677
int rc = SQLITE_OK; /* Return Code */
2448525678
int rc2;
2448625679
const char *zLeftover; /* Tail of unprocessed SQL */
2448725680
sqlite3 *db = pArg->db;
25681
+ unsigned char eStyle;
25682
+ sqlite3_qrf_spec spec;
2448825683
2448925684
if( pzErrMsg ){
2449025685
*pzErrMsg = NULL;
25686
+ }
25687
+ memcpy(&spec, &pArg->mode.spec, sizeof(spec));
25688
+ spec.xWrite = shellWriteQR;
25689
+ spec.pWriteArg = (void*)pArg;
25690
+ if( pArg->mode.eMode==MODE_Insert && ShellHasFlag(pArg, SHFLG_PreserveRowid) ){
25691
+ spec.bTitles = QRF_SW_On;
25692
+ }
25693
+ assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) );
25694
+ eStyle = aModeInfo[pArg->mode.eMode].eStyle;
25695
+ if( pArg->mode.bAutoScreenWidth ){
25696
+ spec.nScreenWidth = shellScreenWidth();
2449125697
}
2449225698
2449325699
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2449425700
if( pArg->expert.pExpert ){
2449525701
rc = expertHandleSQL(pArg, zSql, pzErrMsg);
@@ -24503,10 +25709,11 @@
2450325709
if( SQLITE_OK != rc ){
2450425710
if( pzErrMsg ){
2450525711
*pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
2450625712
}
2450725713
}else{
25714
+ int isExplain;
2450825715
if( !pStmt ){
2450925716
/* this happens for a comment or white-space */
2451025717
zSql = zLeftover;
2451125718
while( IsSpace(zSql[0]) ) zSql++;
2451225719
continue;
@@ -24513,93 +25720,73 @@
2451325720
}
2451425721
zStmtSql = sqlite3_sql(pStmt);
2451525722
if( zStmtSql==0 ) zStmtSql = "";
2451625723
while( IsSpace(zStmtSql[0]) ) zStmtSql++;
2451725724
24518
- /* save off the prepared statement handle and reset row count */
25725
+ /* save off the prepared statement handle */
2451925726
if( pArg ){
2452025727
pArg->pStmt = pStmt;
24521
- pArg->cnt = 0;
2452225728
}
24523
-
25729
+
2452425730
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
24525
- if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
24526
- sqlite3_stmt *pExplain;
25731
+ isExplain = sqlite3_stmt_isexplain(pStmt);
25732
+ if( pArg && pArg->mode.autoEQP && isExplain==0 ){
2452725733
int triggerEQP = 0;
2452825734
disable_debug_trace_modes();
2452925735
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
24530
- if( pArg->autoEQP>=AUTOEQP_trigger ){
25736
+ if( pArg->mode.autoEQP>=AUTOEQP_trigger ){
2453125737
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
2453225738
}
24533
- pExplain = pStmt;
24534
- sqlite3_reset(pExplain);
24535
- rc = sqlite3_stmt_explain(pExplain, 2);
24536
- if( rc==SQLITE_OK ){
24537
- bind_prepared_stmt(pArg, pExplain);
24538
- while( sqlite3_step(pExplain)==SQLITE_ROW ){
24539
- const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
24540
- int iEqpId = sqlite3_column_int(pExplain, 0);
24541
- int iParentId = sqlite3_column_int(pExplain, 1);
24542
- if( zEQPLine==0 ) zEQPLine = "";
24543
- if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
24544
- eqp_append(pArg, iEqpId, iParentId, zEQPLine);
24545
- }
24546
- eqp_render(pArg, 0);
24547
- }
24548
- if( pArg->autoEQP>=AUTOEQP_full ){
24549
- /* Also do an EXPLAIN for ".eqp full" mode */
24550
- sqlite3_reset(pExplain);
24551
- rc = sqlite3_stmt_explain(pExplain, 1);
24552
- if( rc==SQLITE_OK ){
24553
- pArg->cMode = MODE_Explain;
24554
- assert( sqlite3_stmt_isexplain(pExplain)==1 );
24555
- bind_prepared_stmt(pArg, pExplain);
24556
- explain_data_prepare(pArg, pExplain);
24557
- exec_prepared_stmt(pArg, pExplain);
24558
- explain_data_delete(pArg);
24559
- }
24560
- }
24561
- if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
25739
+ sqlite3_reset(pStmt);
25740
+ spec.eStyle = QRF_STYLE_Auto;
25741
+ sqlite3_stmt_explain(pStmt, 2-(pArg->mode.autoEQP>=AUTOEQP_full));
25742
+ sqlite3_format_query_result(pStmt, &spec, 0);
25743
+ if( pArg->mode.autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
2456225744
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
2456325745
}
2456425746
sqlite3_reset(pStmt);
2456525747
sqlite3_stmt_explain(pStmt, 0);
2456625748
restore_debug_trace_modes();
2456725749
}
2456825750
24569
- if( pArg ){
24570
- int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1);
24571
- pArg->cMode = pArg->mode;
24572
- if( pArg->autoExplain ){
24573
- if( bIsExplain ){
24574
- pArg->cMode = MODE_Explain;
24575
- }
24576
- if( sqlite3_stmt_isexplain(pStmt)==2 ){
24577
- pArg->cMode = MODE_EQP;
24578
- }
24579
- }
24580
-
24581
- /* If the shell is currently in ".explain" mode, gather the extra
24582
- ** data required to add indents to the output.*/
24583
- if( pArg->cMode==MODE_Explain && bIsExplain ){
24584
- explain_data_prepare(pArg, pStmt);
24585
- }
24586
- }
24587
-
2458825751
bind_prepared_stmt(pArg, pStmt);
24589
- exec_prepared_stmt(pArg, pStmt);
24590
- explain_data_delete(pArg);
24591
- eqp_render(pArg, 0);
25752
+ if( isExplain && pArg->mode.autoExplain ){
25753
+ spec.eStyle = isExplain==1 ? QRF_STYLE_Explain : QRF_STYLE_Eqp;
25754
+ sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25755
+ }else if( pArg->mode.eMode==MODE_Www ){
25756
+ cli_printf(pArg->out,
25757
+ "</PRE>\n"
25758
+ "<TABLE border='1' cellspacing='0' cellpadding='2'>\n");
25759
+ spec.eStyle = QRF_STYLE_Html;
25760
+ sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25761
+ cli_printf(pArg->out,
25762
+ "</TABLE>\n"
25763
+ "<PRE>");
25764
+ }else{
25765
+ spec.eStyle = eStyle;
25766
+ sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25767
+ }
2459225768
2459325769
/* print usage stats if stats on */
2459425770
if( pArg && pArg->statsOn ){
2459525771
display_stats(db, pArg, 0);
2459625772
}
2459725773
2459825774
/* print loop-counters if required */
24599
- if( pArg && pArg->scanstatsOn ){
24600
- display_scanstats(db, pArg);
25775
+ if( pArg && pArg->mode.scanstatsOn ){
25776
+ char *zErr = 0;
25777
+ switch( pArg->mode.scanstatsOn ){
25778
+ case 1: spec.eStyle = QRF_STYLE_Stats; break;
25779
+ case 2: spec.eStyle = QRF_STYLE_StatsEst; break;
25780
+ default: spec.eStyle = QRF_STYLE_StatsVm; break;
25781
+ }
25782
+ sqlite3_reset(pStmt);
25783
+ rc = sqlite3_format_query_result(pStmt, &spec, &zErr);
25784
+ if( rc ){
25785
+ cli_printf(stderr, "Stats query failed: %s\n", zErr);
25786
+ sqlite3_free(zErr);
25787
+ }
2460125788
}
2460225789
2460325790
/* Finalize the statement just executed. If this fails, save a
2460425791
** copy of the error message. Otherwise, set zSql to point to the
2460525792
** next statement to execute. */
@@ -24791,34 +25978,34 @@
2479125978
** have been recreated by prior repopulations. See forum posts:
2479225979
** 2024-10-13T17:10:01z and 2025-10-29T19:38:43z
2479325980
*/
2479425981
if( db_int(p->db, "SELECT count(*) FROM sqlite_sequence")>0 ){
2479525982
if( !p->writableSchema ){
24796
- sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
25983
+ cli_puts("PRAGMA writable_schema=ON;\n", p->out);
2479725984
p->writableSchema = 1;
2479825985
}
24799
- sqlite3_fputs("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n"
25986
+ cli_puts("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n"
2480025987
"DELETE FROM sqlite_sequence;\n", p->out);
2480125988
}
2480225989
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
24803
- if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
25990
+ if( !dataOnly ) cli_puts("ANALYZE sqlite_schema;\n", p->out);
2480425991
}else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
2480525992
return 0;
2480625993
}else if( dataOnly ){
2480725994
/* no-op */
2480825995
}else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2480925996
char *zIns;
2481025997
if( !p->writableSchema ){
24811
- sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
25998
+ cli_puts("PRAGMA writable_schema=ON;\n", p->out);
2481225999
p->writableSchema = 1;
2481326000
}
2481426001
zIns = sqlite3_mprintf(
2481526002
"INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
2481626003
"VALUES('table','%q','%q',0,'%q');",
2481726004
zTable, zTable, zSql);
2481826005
shell_check_oom(zIns);
24819
- sqlite3_fprintf(p->out, "%s\n", zIns);
26006
+ cli_printf(p->out, "%s\n", zIns);
2482026007
sqlite3_free(zIns);
2482126008
return 0;
2482226009
}else{
2482326010
printSchemaLine(p->out, zSql, ";\n");
2482426011
}
@@ -24826,12 +26013,11 @@
2482626013
if( cli_strcmp(zType, "table")==0 ){
2482726014
ShellText sSelect;
2482826015
ShellText sTable;
2482926016
char **azCol;
2483026017
int i;
24831
- char *savedDestTable;
24832
- int savedMode;
26018
+ Mode savedMode;
2483326019
2483426020
azCol = tableColumnList(p, zTable);
2483526021
if( azCol==0 ){
2483626022
p->nErr++;
2483726023
return 0;
@@ -24870,22 +26056,22 @@
2487026056
}
2487126057
freeColumnList(azCol);
2487226058
appendText(&sSelect, " FROM ", 0);
2487326059
appendText(&sSelect, zTable, quoteChar(zTable));
2487426060
24875
- savedDestTable = p->zDestTable;
26061
+
2487626062
savedMode = p->mode;
24877
- p->zDestTable = sTable.zTxt;
24878
- p->mode = p->cMode = MODE_Insert;
26063
+ p->mode.spec.zTableName = (char*)zTable;
26064
+ p->mode.eMode = MODE_Insert;
26065
+ p->mode.spec.bTitles = QRF_No;
2487926066
rc = shell_exec(p, sSelect.zTxt, 0);
2488026067
if( (rc&0xff)==SQLITE_CORRUPT ){
24881
- sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
26068
+ cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
2488226069
toggleSelectOrder(p->db);
2488326070
shell_exec(p, sSelect.zTxt, 0);
2488426071
toggleSelectOrder(p->db);
2488526072
}
24886
- p->zDestTable = savedDestTable;
2488726073
p->mode = savedMode;
2488826074
freeText(&sTable);
2488926075
freeText(&sSelect);
2489026076
if( rc ) p->nErr++;
2489126077
}
@@ -24907,22 +26093,22 @@
2490726093
char *zErr = 0;
2490826094
rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
2490926095
if( rc==SQLITE_CORRUPT ){
2491026096
char *zQ2;
2491126097
int len = strlen30(zQuery);
24912
- sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
26098
+ cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
2491326099
if( zErr ){
24914
- sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr);
26100
+ cli_printf(p->out, "/****** %s ******/\n", zErr);
2491526101
sqlite3_free(zErr);
2491626102
zErr = 0;
2491726103
}
2491826104
zQ2 = malloc( len+100 );
2491926105
if( zQ2==0 ) return rc;
2492026106
sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
2492126107
rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2492226108
if( rc ){
24923
- sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
26109
+ cli_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
2492426110
}else{
2492526111
rc = SQLITE_CORRUPT;
2492626112
}
2492726113
free(zQ2);
2492826114
}
@@ -25019,27 +26205,14 @@
2501926205
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
2502026206
".filectrl CMD ... Run various sqlite3_file_control() operations",
2502126207
" --schema SCHEMA Use SCHEMA instead of \"main\"",
2502226208
" --help Show CMD details",
2502326209
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
25024
- ".headers on|off Turn display of headers on or off",
26210
+ ",headers on|off Turn display of headers on or off",
2502526211
".help ?-all? ?PATTERN? Show help text for PATTERN",
2502626212
#ifndef SQLITE_SHELL_FIDDLE
2502726213
".import FILE TABLE Import data from FILE into TABLE",
25028
- " Options:",
25029
- " --ascii Use \\037 and \\036 as column and row separators",
25030
- " --csv Use , and \\n as column and row separators",
25031
- " --skip N Skip the first N rows of input",
25032
- " --schema S Target table to be S.TABLE",
25033
- " -v \"Verbose\" - increase auxiliary output",
25034
- " Notes:",
25035
- " * If TABLE does not exist, it is created. The first row of input",
25036
- " determines the column names.",
25037
- " * If neither --csv or --ascii are used, the input mode is derived",
25038
- " from the \".mode\" output mode",
25039
- " * If FILE begins with \"|\" then it is a command that generates the",
25040
- " input text.",
2504126214
#endif
2504226215
#ifndef SQLITE_OMIT_TEST_CONTROL
2504326216
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
2504426217
#endif
2504526218
".indexes ?TABLE? Show names of indexes",
@@ -25060,46 +26233,16 @@
2506026233
".log FILE|on|off Turn logging on or off. FILE can be stderr/stdout",
2506126234
#else
2506226235
".log on|off Turn logging on or off.",
2506326236
#endif
2506426237
".mode ?MODE? ?OPTIONS? Set output mode",
25065
- " MODE is one of:",
25066
- " ascii Columns/rows delimited by 0x1F and 0x1E",
25067
- " box Tables using unicode box-drawing characters",
25068
- " csv Comma-separated values",
25069
- " column Output in columns. (See .width)",
25070
- " html HTML <table> code",
25071
- " insert SQL insert statements for TABLE",
25072
- " json Results in a JSON array",
25073
- " line One value per line",
25074
- " list Values delimited by \"|\"",
25075
- " markdown Markdown table format",
25076
- " qbox Shorthand for \"box --wrap 60 --quote\"",
25077
- " quote Escape answers as for SQL",
25078
- " table ASCII-art table",
25079
- " tabs Tab-separated values",
25080
- " tcl TCL list elements",
25081
- " OPTIONS: (for columnar modes or insert mode):",
25082
- " --escape T ctrl-char escape; T is one of: symbol, ascii, off",
25083
- " --wrap N Wrap output lines to no longer than N characters",
25084
- " --wordwrap B Wrap or not at word boundaries per B (on/off)",
25085
- " --ww Shorthand for \"--wordwrap 1\"",
25086
- " --quote Quote output text as SQL literals",
25087
- " --noquote Do not quote output text",
25088
- " TABLE The name of SQL table used for \"insert\" mode",
2508926238
#ifndef SQLITE_SHELL_FIDDLE
2509026239
".nonce STRING Suspend safe mode for one command if nonce matches",
2509126240
#endif
2509226241
".nullvalue STRING Use STRING in place of NULL values",
2509326242
#ifndef SQLITE_SHELL_FIDDLE
2509426243
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
25095
- " If FILE begins with '|' then open as a pipe",
25096
- " --bom Put a UTF8 byte-order mark at the beginning",
25097
- " -e Send output to the system text editor",
25098
- " --plain Use text/plain output instead of HTML for -w option",
25099
- " -w Send output as HTML to a web browser (same as \".www\")",
25100
- " -x Send output as CSV to a spreadsheet (same as \".excel\")",
2510126244
/* Note that .open is (partially) available in WASM builds but is
2510226245
** currently only intended to be used by the fiddle tool, not
2510326246
** end users, so is "undocumented." */
2510426247
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
2510526248
" Options:",
@@ -25121,18 +26264,10 @@
2512126264
" --nofollow Do not follow symbolic links",
2512226265
" --readonly Open FILE readonly",
2512326266
" --zip FILE is a ZIP archive",
2512426267
#ifndef SQLITE_SHELL_FIDDLE
2512526268
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
25126
- " If FILE begins with '|' then open it as a pipe.",
25127
- " If FILE is 'off' then output is disabled.",
25128
- " Options:",
25129
- " --bom Prefix output with a UTF8 byte-order mark",
25130
- " -e Send output to the system text editor",
25131
- " --plain Use text/plain for -w option",
25132
- " -w Send output to a web browser",
25133
- " -x Send output as CSV to a spreadsheet",
2513426269
#endif
2513526270
".parameter CMD ... Manage SQL parameter bindings",
2513626271
" clear Erase all bindings",
2513726272
" init Initialize the TEMP table that holds bindings",
2513826273
" list List the current parameter bindings",
@@ -25171,11 +26306,11 @@
2517126306
" --nosys Omit objects whose names start with \"sqlite_\"",
2517226307
",selftest ?OPTIONS? Run tests defined in the SELFTEST table",
2517326308
" Options:",
2517426309
" --init Create a new SELFTEST table",
2517526310
" -v Verbose output",
25176
- ".separator COL ?ROW? Change the column and row separators",
26311
+ ",separator COL ?ROW? Change the column and row separators",
2517726312
#if defined(SQLITE_ENABLE_SESSION)
2517826313
".session ?NAME? CMD ... Create or control sessions",
2517926314
" Subcommands:",
2518026315
" attach TABLE Attach TABLE",
2518126316
" changeset FILE Write a changeset into FILE",
@@ -25198,11 +26333,11 @@
2519826333
" --sha3-512 Use the sha3-512 algorithm",
2519926334
" Any other argument is a LIKE pattern for tables to hash",
2520026335
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE)
2520126336
".shell CMD ARGS... Run CMD ARGS... in a system shell",
2520226337
#endif
25203
- ".show Show the current values for various settings",
26338
+ ",show Show the current values for various settings",
2520426339
".stats ?ARG? Show stats or turn stats on or off",
2520526340
" off Turn off automatic stat display",
2520626341
" on Turn on automatic stat display",
2520726342
" stmt Show statement stats",
2520826343
" vmstep Show the virtual machine step count only",
@@ -25239,17 +26374,167 @@
2523926374
#endif
2524026375
".version Show source, library and compiler versions",
2524126376
".vfsinfo ?AUX? Information about the top-level VFS",
2524226377
".vfslist List all available VFSes",
2524326378
".vfsname ?AUX? Print the name of the VFS stack",
25244
- ".width NUM1 NUM2 ... Set minimum column widths for columnar output",
26379
+ ",width NUM1 NUM2 ... Set minimum column widths for columnar output",
2524526380
" Negative values right-justify",
2524626381
#ifndef SQLITE_SHELL_FIDDLE
2524726382
".www Display output of the next command in web browser",
2524826383
" --plain Show results as text/plain, not as HTML",
2524926384
#endif
2525026385
};
26386
+
26387
+/**************************************************************
26388
+** "Usage" help text automatically generated from comments */
26389
+static const struct {
26390
+ const char *zCmd; /* Name of the dot-command */
26391
+ const char *zUsage; /* Documentation */
26392
+} aUsage[] = {
26393
+ { ".import",
26394
+"USAGE: .import [OPTIONS] FILE TABLE\n"
26395
+"\n"
26396
+"Import CSV or similar text from FILE into TABLE. If TABLE does\n"
26397
+"not exist, it is created using the first row of FILE as the column\n"
26398
+"names. If FILE begins with \"|\" then it is a command that is run\n"
26399
+"and the output from the command is used as the input data.\n"
26400
+"\n"
26401
+"FILE is assumed to be in a CSV format, unless the current mode\n"
26402
+"is \"ascii\" or \"tabs\" or unless one of the options below specify\n"
26403
+"an alternative.\n"
26404
+"\n"
26405
+"Options:\n"
26406
+" --ascii Use \\037 and \\036 as column and row separators on input\n"
26407
+" --csv Input is standard RFC-4180 CSV.\n"
26408
+" --schema S When creating TABLE, put it in schema S\n"
26409
+" --skip N Ignore the first N rows of input\n"
26410
+" -v Verbose mode\n"
26411
+ },
26412
+ { ".mode",
26413
+"USAGE: .mode [MODE] [OPTIONS]\n"
26414
+"\n"
26415
+"Change the output mode to MODE and/or apply OPTIONS to the\n"
26416
+"output mode. If no arguments, show the current output mode\n"
26417
+"and relevant options.\n"
26418
+"\n"
26419
+"Options:\n"
26420
+" --align STRING Set the alignment of text in columnar modes\n"
26421
+" String consists of characters 'L', 'C', 'R'\n"
26422
+" meaning \"left\", \"centered\", and \"right\", with\n"
26423
+" one letter per column starting from the left.\n"
26424
+" Unspecified alignment defaults to 'L'.\n"
26425
+" --charlimit N Set the maximum number of output characters to\n"
26426
+" show for any single SQL value to N. Longer values\n"
26427
+" truncated. Zero means \"no limit\".\n"
26428
+" --colsep STRING Use STRING as the column separator\n"
26429
+" --escape ESC Enable/disable escaping of control characters\n"
26430
+" in output. ESC can be \"off\", \"ascii\", or\n"
26431
+" \"symbol\".\n"
26432
+" --linelimit N Set the maximum number of output lines to show for\n"
26433
+" any single SQL value to N. Longer values are\n"
26434
+" truncated. Zero means \"no limit\". Only works\n"
26435
+" in \"line\" mode and in columnar modes.\n"
26436
+" --list List available modes\n"
26437
+" --null STRING Render SQL NULL values as the given string\n"
26438
+" --once Setting changes to the right are reverted after\n"
26439
+" the next SQL command.\n"
26440
+" --quote ARG Enable/disable quoting of text. ARG can be\n"
26441
+" \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n"
26442
+" or \"json\". \"off\" means show the text as-is.\n"
26443
+" \"on and \"sql\" are synonyms.\n"
26444
+" --reset Changes all mode settings back to their default.\n"
26445
+" --rowsep STRING Use STRING as the row separator\n"
26446
+" --screenwidth N Declare the screen width of the output device\n"
26447
+" to be N characters. An attempt may be made to\n"
26448
+" wrap output text to fit within this limit. Zero\n"
26449
+" means \"no limit\". Or N can be \"auto\" to set the\n"
26450
+" width automatically.\n"
26451
+" --tablename NAME Set the name of the table for \"insert\" mode.\n"
26452
+" --tag NAME Save mode to the left as NAME.\n"
26453
+" --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
26454
+" --title ARG Whether or not to show column headers, and if so\n"
26455
+" how to encode them. ARG can be \"off\", \"on\",\n"
26456
+" \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
26457
+" -v|--verbose Verbose output\n"
26458
+" --widths LIST Set the columns widths for columnar modes. The\n"
26459
+" argument is a list of integers, one for each\n"
26460
+" column. A \"0\" width means use a dynamic width\n"
26461
+" based on the actual width of data. If there are\n"
26462
+" fewer entries in LIST than columns, \"0\" is used\n"
26463
+" for the unspecified widths.\n"
26464
+" --wordwrap BOOLEAN Enable/disable word wrapping\n"
26465
+" --wrap N Wrap columns wider than N characters\n"
26466
+" --ww Shorthand for \"--wordwrap on\"\n"
26467
+ },
26468
+ { ".output",
26469
+"USAGE: .output [OPTIONS] [FILE]\n"
26470
+"\n"
26471
+"Begin redirecting output to FILE. Or if FILE is omitted, revert\n"
26472
+"to sending output to the console. If FILE begins with \"|\" then\n"
26473
+"the remainder of file is taken as a pipe and output is directed\n"
26474
+"into that pipe. If FILE is \"memory\" then output is captured in an\n"
26475
+"internal memory buffer. If FILE is \"off\" then output is redirected\n"
26476
+"into /dev/null or the equivalent.\n"
26477
+"\n"
26478
+"Options:\n"
26479
+" --bom Prepend a byte-order mark to the output\n"
26480
+" -e Accumulate output in a temporary text file then\n"
26481
+" launch a text editor when the redirection ends.\n"
26482
+" --error-prefix X Use X as the left-margin prefix for error messages.\n"
26483
+" Set to an empty string to restore the default.\n"
26484
+" --glob GLOB Raise an error if the memory buffer does not match\n"
26485
+" the GLOB pattern.\n"
26486
+" --keep Continue using the same \"memory\" buffer. Do not\n"
26487
+" reset it or delete it. Useful in combination with\n"
26488
+" --glob, --not-glob, and/or --verify.\n"
26489
+" ---notglob GLOB Raise an error if the memory buffer does not match\n"
26490
+" the GLOB pattern.\n"
26491
+" --plain Use plain text rather than HTML tables with -w\n"
26492
+" --show Write the memory buffer to the screen, for debugging.\n"
26493
+" --verify ENDMARK Read subsequent lines of text until the first line\n"
26494
+" that matches ENDMARK. Discard the ENDMARK. Compare\n"
26495
+" the text against the accumulated output in memory and\n"
26496
+" raise an error if there are any differences.\n"
26497
+" -w Show the output in a web browser. Output is\n"
26498
+" written into a temporary HTML file until the\n"
26499
+" redirect ends, then the web browser is launched.\n"
26500
+" Query results are shown as HTML tables, unless\n"
26501
+" the --plain is used too.\n"
26502
+" -x Show the output in a spreadsheet. Output is\n"
26503
+" written to a temp file as CSV then the spreadsheet\n"
26504
+" is launched when\n"
26505
+ },
26506
+ { ".once",
26507
+"USAGE: .once [OPTIONS] FILE ...\n"
26508
+"\n"
26509
+"Write the output for the next line of SQL or the next dot-command into\n"
26510
+"FILE. If FILE begins with \"|\" then it is a program into which output\n"
26511
+"is written. The FILE argument should be omitted if one of the -e, -w,\n"
26512
+"or -x options is used.\n"
26513
+"\n"
26514
+"Options:\n"
26515
+" -e Capture output into a temporary file then bring up\n"
26516
+" a text editor on that temporary file.\n"
26517
+" --plain Use plain text rather than HTML tables with -w\n"
26518
+" -w Capture output into an HTML file then bring up that\n"
26519
+" file in a web browser\n"
26520
+" -x Show the output in a spreadsheet. Output is\n"
26521
+" written to a temp file as CSV then the spreadsheet\n"
26522
+" is launched when\n"
26523
+ },
26524
+};
26525
+
26526
+/*
26527
+** Return a pointer to usage text for zCmd, or NULL if none exists.
26528
+*/
26529
+static const char *findUsage(const char *zCmd){
26530
+ int i;
26531
+ for(i=0; i<ArraySize(aUsage); i++){
26532
+ if( sqlite3_strglob(zCmd, aUsage[i].zCmd)==0 ) return aUsage[i].zUsage;
26533
+ }
26534
+ return 0;
26535
+}
2525126536
2525226537
/*
2525326538
** Output help text for commands that match zPattern.
2525426539
**
2525526540
** * If zPattern is NULL, then show all documented commands, but
@@ -25276,10 +26561,11 @@
2527626561
static int showHelp(FILE *out, const char *zPattern){
2527726562
int i = 0;
2527826563
int j = 0;
2527926564
int n = 0;
2528026565
char *zPat;
26566
+ const char *zHit = 0;
2528126567
if( zPattern==0 ){
2528226568
/* Show just the first line for all help topics */
2528326569
zPattern = "[a-z]";
2528426570
}else if( cli_strcmp(zPattern,"-a")==0
2528526571
|| cli_strcmp(zPattern,"-all")==0
@@ -25293,41 +26579,50 @@
2529326579
for(i=0; i<ArraySize(azHelp); i++){
2529426580
if( azHelp[i][0]=='.' ){
2529526581
show = 0;
2529626582
}else if( azHelp[i][0]==',' ){
2529726583
show = 1;
25298
- sqlite3_fprintf(out, ".%s\n", &azHelp[i][1]);
26584
+ cli_printf(out, ".%s\n", &azHelp[i][1]);
2529926585
n++;
2530026586
}else if( show ){
25301
- sqlite3_fprintf(out, "%s\n", azHelp[i]);
26587
+ cli_printf(out, "%s\n", azHelp[i]);
2530226588
}
2530326589
}
2530426590
return n;
2530526591
}
2530626592
2530726593
/* Seek documented commands for which zPattern is an exact prefix */
25308
- zPat = sqlite3_mprintf(".%s*", zPattern);
26594
+ zPat = sqlite3_mprintf(".%s*", zPattern[0]=='.' ? &zPattern[1] : zPattern);
2530926595
shell_check_oom(zPat);
2531026596
for(i=0; i<ArraySize(azHelp); i++){
2531126597
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
25312
- sqlite3_fprintf(out, "%s\n", azHelp[i]);
26598
+ if( zHit ) cli_printf(out, "%s\n", zHit);
26599
+ zHit = azHelp[i];
2531326600
j = i+1;
2531426601
n++;
2531526602
}
2531626603
}
25317
- sqlite3_free(zPat);
2531826604
if( n ){
2531926605
if( n==1 ){
25320
- /* when zPattern is a prefix of exactly one command, then include
25321
- ** the details of that command, which should begin at offset j */
25322
- while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
25323
- sqlite3_fprintf(out, "%s\n", azHelp[j]);
25324
- j++;
25325
- }
25326
- }
25327
- return n;
25328
- }
26606
+ const char *zUsage = findUsage(zPat);
26607
+ if( zUsage ){
26608
+ cli_puts(zUsage, out);
26609
+ }else{
26610
+ /* when zPattern is a prefix of exactly one command, then include
26611
+ ** the details of that command, which should begin at offset j */
26612
+ cli_printf(out, "%s\n", zHit);
26613
+ while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
26614
+ cli_printf(out, "%s\n", azHelp[j]);
26615
+ j++;
26616
+ }
26617
+ }
26618
+ }else{
26619
+ cli_printf(out, "%s\n", zHit);
26620
+ }
26621
+ }
26622
+ sqlite3_free(zPat);
26623
+ if( n ) return n;
2532926624
2533026625
/* Look for documented commands that contain zPattern anywhere.
2533126626
** Show complete text of all documented commands that match. */
2533226627
zPat = sqlite3_mprintf("%%%s%%", zPattern);
2533326628
shell_check_oom(zPat);
@@ -25336,14 +26631,14 @@
2533626631
while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
2533726632
continue;
2533826633
}
2533926634
if( azHelp[i][0]=='.' ) j = i;
2534026635
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
25341
- sqlite3_fprintf(out, "%s\n", azHelp[j]);
26636
+ cli_printf(out, "%s\n", azHelp[j]);
2534226637
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
2534326638
j++;
25344
- sqlite3_fprintf(out, "%s\n", azHelp[j]);
26639
+ cli_printf(out, "%s\n", azHelp[j]);
2534526640
}
2534626641
i = j;
2534726642
n++;
2534826643
}
2534926644
}
@@ -25376,27 +26671,27 @@
2537626671
char *pBuf;
2537726672
int rc;
2537826673
if( in==0 ) return 0;
2537926674
rc = fseek(in, 0, SEEK_END);
2538026675
if( rc!=0 ){
25381
- sqlite3_fprintf(stderr,"Error: '%s' not seekable\n", zName);
26676
+ cli_printf(stderr,"Error: '%s' not seekable\n", zName);
2538226677
fclose(in);
2538326678
return 0;
2538426679
}
2538526680
nIn = ftell(in);
2538626681
rewind(in);
2538726682
pBuf = sqlite3_malloc64( nIn+1 );
2538826683
if( pBuf==0 ){
25389
- sqlite3_fputs("Error: out of memory\n", stderr);
26684
+ cli_puts("Error: out of memory\n", stderr);
2539026685
fclose(in);
2539126686
return 0;
2539226687
}
2539326688
nRead = fread(pBuf, nIn, 1, in);
2539426689
fclose(in);
2539526690
if( nRead!=1 ){
2539626691
sqlite3_free(pBuf);
25397
- sqlite3_fprintf(stderr,"Error: cannot read '%s'\n", zName);
26692
+ cli_printf(stderr,"Error: cannot read '%s'\n", zName);
2539826693
return 0;
2539926694
}
2540026695
pBuf[nIn] = 0;
2540126696
if( pnByte ) *pnByte = nIn;
2540226697
return pBuf;
@@ -25529,11 +26824,11 @@
2552926824
unsigned int x[16];
2553026825
char zLine[1000];
2553126826
if( zDbFilename ){
2553226827
in = sqlite3_fopen(zDbFilename, "r");
2553326828
if( in==0 ){
25534
- sqlite3_fprintf(stderr,"cannot open \"%s\" for reading\n", zDbFilename);
26829
+ cli_printf(stderr,"cannot open \"%s\" for reading\n", zDbFilename);
2553526830
return 0;
2553626831
}
2553726832
nLine = 0;
2553826833
}else{
2553926834
in = p->in;
@@ -25545,11 +26840,11 @@
2554526840
if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
2554626841
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
2554726842
if( rc!=2 ) goto readHexDb_error;
2554826843
if( n<0 ) goto readHexDb_error;
2554926844
if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
25550
- sqlite3_fputs("invalid pagesize\n", stderr);
26845
+ cli_puts("invalid pagesize\n", stderr);
2555126846
goto readHexDb_error;
2555226847
}
2555326848
sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
2555426849
a = sqlite3_malloc64( sz ? sz : 1 );
2555526850
shell_check_oom(a);
@@ -25556,11 +26851,11 @@
2555626851
memset(a, 0, sz);
2555726852
for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
2555826853
int j = 0; /* Page number from "| page" line */
2555926854
int k = 0; /* Offset from "| page" line */
2556026855
if( nLine>=2000000000 ){
25561
- sqlite3_fprintf(stderr, "input too big\n");
26856
+ cli_printf(stderr, "input too big\n");
2556226857
goto readHexDb_error;
2556326858
}
2556426859
rc = sscanf(zLine, "| page %d offset %d", &j, &k);
2556526860
if( rc==2 ){
2556626861
iOffset = k;
@@ -25597,11 +26892,11 @@
2559726892
if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
2559826893
}
2559926894
p->lineno = nLine;
2560026895
}
2560126896
sqlite3_free(a);
25602
- sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine);
26897
+ cli_printf(stderr,"Error on line %lld of --hexdb input\n", nLine);
2560326898
return 0;
2560426899
}
2560526900
#endif /* SQLITE_OMIT_DESERIALIZE */
2560626901
2560726902
/*
@@ -25702,23 +26997,23 @@
2570226997
sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0);
2570326998
break;
2570426999
}
2570527000
}
2570627001
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
25707
- sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
27002
+ cli_printf(stderr,"Error: unable to open database \"%s\": %s\n",
2570827003
zDbFilename, sqlite3_errmsg(p->db));
2570927004
if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
25710
- exit(1);
27005
+ cli_exit(1);
2571127006
}
2571227007
sqlite3_close(p->db);
2571327008
sqlite3_open(":memory:", &p->db);
2571427009
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
25715
- sqlite3_fputs("Also: unable to open substitute in-memory database.\n",
27010
+ cli_puts("Also: unable to open substitute in-memory database.\n",
2571627011
stderr);
25717
- exit(1);
27012
+ cli_exit(1);
2571827013
}else{
25719
- sqlite3_fprintf(stderr,
27014
+ cli_printf(stderr,
2572027015
"Notice: using substitute in-memory database instead of \"%s\"\n",
2572127016
zDbFilename);
2572227017
}
2572327018
}
2572427019
globalDb = p->db;
@@ -25792,10 +27087,12 @@
2579227087
shellAddSchemaName, 0, 0);
2579327088
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, p,
2579427089
shellModuleSchema, 0, 0);
2579527090
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
2579627091
shellPutsFunc, 0, 0);
27092
+ sqlite3_create_function(p->db, "shell_format_schema", 2, SQLITE_UTF8, p,
27093
+ shellFormatSchema, 0, 0);
2579727094
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
2579827095
shellUSleepFunc, 0, 0);
2579927096
#ifndef SQLITE_NOHAVE_SYSTEM
2580027097
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
2580127098
editFunc, 0, 0);
@@ -25826,11 +27123,11 @@
2582627123
}
2582727124
rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
2582827125
SQLITE_DESERIALIZE_RESIZEABLE |
2582927126
SQLITE_DESERIALIZE_FREEONCLOSE);
2583027127
if( rc ){
25831
- sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc);
27128
+ cli_printf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc);
2583227129
}
2583327130
if( p->szMax>0 ){
2583427131
sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
2583527132
}
2583627133
}
@@ -25841,11 +27138,11 @@
2584127138
if( p->bSafeModePersist ){
2584227139
sqlite3_set_authorizer(p->db, safeModeAuth, p);
2584327140
}
2584427141
#endif
2584527142
sqlite3_db_config(
25846
- p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
27143
+ p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->mode.scanstatsOn, (int*)0
2584727144
);
2584827145
}
2584927146
}
2585027147
2585127148
/*
@@ -25852,11 +27149,11 @@
2585227149
** Attempt to close the database connection. Report errors.
2585327150
*/
2585427151
void close_db(sqlite3 *db){
2585527152
int rc = sqlite3_close(db);
2585627153
if( rc ){
25857
- sqlite3_fprintf(stderr,
27154
+ cli_printf(stderr,
2585827155
"Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
2585927156
}
2586027157
}
2586127158
2586227159
#if (HAVE_READLINE || HAVE_EDITLINE) \
@@ -26025,11 +27322,11 @@
2602527322
return 1;
2602627323
}
2602727324
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2602827325
return 0;
2602927326
}
26030
- sqlite3_fprintf(stderr,
27327
+ cli_printf(stderr,
2603127328
"ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
2603227329
return 0;
2603327330
}
2603427331
2603527332
/*
@@ -26053,22 +27350,22 @@
2605327350
/*
2605427351
** Try to open an output file. The names "stdout" and "stderr" are
2605527352
** recognized and do the right thing. NULL is returned if the output
2605627353
** filename is "off".
2605727354
*/
26058
-static FILE *output_file_open(const char *zFile){
27355
+static FILE *output_file_open(ShellState *p, const char *zFile){
2605927356
FILE *f;
2606027357
if( cli_strcmp(zFile,"stdout")==0 ){
2606127358
f = stdout;
2606227359
}else if( cli_strcmp(zFile, "stderr")==0 ){
2606327360
f = stderr;
26064
- }else if( cli_strcmp(zFile, "off")==0 ){
27361
+ }else if( cli_strcmp(zFile, "off")==0 || p->bSafeMode ){
2606527362
f = 0;
2606627363
}else{
2606727364
f = sqlite3_fopen(zFile, "w");
2606827365
if( f==0 ){
26069
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
27366
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", zFile);
2607027367
}
2607127368
}
2607227369
return f;
2607327370
}
2607427371
@@ -26117,16 +27414,16 @@
2611727414
if( nSql>1000000000 ) nSql = 1000000000;
2611827415
while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
2611927416
switch( mType ){
2612027417
case SQLITE_TRACE_ROW:
2612127418
case SQLITE_TRACE_STMT: {
26122
- sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
27419
+ cli_printf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
2612327420
break;
2612427421
}
2612527422
case SQLITE_TRACE_PROFILE: {
2612627423
sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
26127
- sqlite3_fprintf(p->traceOut,
27424
+ cli_printf(p->traceOut,
2612827425
"%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
2612927426
break;
2613027427
}
2613127428
}
2613227429
return 0;
@@ -26230,15 +27527,15 @@
2623027527
do{ p->n--; }while( p->z[p->n]!=cQuote );
2623127528
p->cTerm = c;
2623227529
break;
2623327530
}
2623427531
if( pc==cQuote && c!='\r' ){
26235
- sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n",
27532
+ cli_printf(stderr,"%s:%d: unescaped %c character\n",
2623627533
p->zFile, p->nLine, cQuote);
2623727534
}
2623827535
if( c==EOF ){
26239
- sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n",
27536
+ cli_printf(stderr,"%s:%d: unterminated %c-quoted field\n",
2624027537
p->zFile, startLine, cQuote);
2624127538
p->cTerm = c;
2624227539
break;
2624327540
}
2624427541
import_append_char(p, c);
@@ -26333,11 +27630,11 @@
2633327630
2633427631
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2633527632
shell_check_oom(zQuery);
2633627633
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2633727634
if( rc ){
26338
- sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
27635
+ cli_printf(stderr,"Error %d: %s on [%s]\n",
2633927636
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
2634027637
goto end_data_xfer;
2634127638
}
2634227639
n = sqlite3_column_count(pQuery);
2634327640
zInsert = sqlite3_malloc64(200 + nTable + n*3);
@@ -26350,11 +27647,11 @@
2635027647
i += 2;
2635127648
}
2635227649
memcpy(zInsert+i, ");", 3);
2635327650
rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2635427651
if( rc ){
26355
- sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
27652
+ cli_printf(stderr,"Error %d: %s on [%s]\n",
2635627653
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert);
2635727654
goto end_data_xfer;
2635827655
}
2635927656
for(k=0; k<2; k++){
2636027657
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
@@ -26386,11 +27683,11 @@
2638627683
}
2638727684
}
2638827685
} /* End for */
2638927686
rc = sqlite3_step(pInsert);
2639027687
if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
26391
- sqlite3_fprintf(stderr,"Error %d: %s\n",
27688
+ cli_printf(stderr,"Error %d: %s\n",
2639227689
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb));
2639327690
}
2639427691
sqlite3_reset(pInsert);
2639527692
cnt++;
2639627693
if( (cnt%spinRate)==0 ){
@@ -26404,11 +27701,11 @@
2640427701
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2640527702
zTable);
2640627703
shell_check_oom(zQuery);
2640727704
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2640827705
if( rc ){
26409
- sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable);
27706
+ cli_printf(stderr,"Warning: cannot step \"%s\" backwards", zTable);
2641027707
break;
2641127708
}
2641227709
} /* End for(k=0...) */
2641327710
2641427711
end_data_xfer:
@@ -26441,24 +27738,24 @@
2644127738
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
2644227739
" WHERE %s ORDER BY rowid ASC", zWhere);
2644327740
shell_check_oom(zQuery);
2644427741
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2644527742
if( rc ){
26446
- sqlite3_fprintf(stderr,
27743
+ cli_printf(stderr,
2644727744
"Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
2644827745
sqlite3_errmsg(p->db), zQuery);
2644927746
goto end_schema_xfer;
2645027747
}
2645127748
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2645227749
zName = sqlite3_column_text(pQuery, 0);
2645327750
zSql = sqlite3_column_text(pQuery, 1);
2645427751
if( zName==0 || zSql==0 ) continue;
2645527752
if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
26456
- sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
27753
+ cli_printf(stdout, "%s... ", zName); fflush(stdout);
2645727754
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2645827755
if( zErrMsg ){
26459
- sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
27756
+ cli_printf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2646027757
sqlite3_free(zErrMsg);
2646127758
zErrMsg = 0;
2646227759
}
2646327760
}
2646427761
if( xForEach ){
@@ -26472,23 +27769,23 @@
2647227769
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
2647327770
" WHERE %s ORDER BY rowid DESC", zWhere);
2647427771
shell_check_oom(zQuery);
2647527772
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2647627773
if( rc ){
26477
- sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n",
27774
+ cli_printf(stderr,"Error: (%d) %s on [%s]\n",
2647827775
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
2647927776
goto end_schema_xfer;
2648027777
}
2648127778
while( sqlite3_step(pQuery)==SQLITE_ROW ){
2648227779
zName = sqlite3_column_text(pQuery, 0);
2648327780
zSql = sqlite3_column_text(pQuery, 1);
2648427781
if( zName==0 || zSql==0 ) continue;
2648527782
if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
26486
- sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
27783
+ cli_printf(stdout, "%s... ", zName); fflush(stdout);
2648727784
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2648827785
if( zErrMsg ){
26489
- sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
27786
+ cli_printf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2649027787
sqlite3_free(zErrMsg);
2649127788
zErrMsg = 0;
2649227789
}
2649327790
if( xForEach ){
2649427791
xForEach(p, newDb, (const char*)zName);
@@ -26508,16 +27805,16 @@
2650827805
*/
2650927806
static void tryToClone(ShellState *p, const char *zNewDb){
2651027807
int rc;
2651127808
sqlite3 *newDb = 0;
2651227809
if( access(zNewDb,0)==0 ){
26513
- sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb);
27810
+ cli_printf(stderr,"File \"%s\" already exists.\n", zNewDb);
2651427811
return;
2651527812
}
2651627813
rc = sqlite3_open(zNewDb, &newDb);
2651727814
if( rc ){
26518
- sqlite3_fprintf(stderr,
27815
+ cli_printf(stderr,
2651927816
"Cannot create output database: %s\n", sqlite3_errmsg(newDb));
2652027817
}else{
2652127818
sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
2652227819
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
2652327820
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
@@ -26532,16 +27829,16 @@
2653227829
/*
2653327830
** Change the output stream (file or pipe or console) to something else.
2653427831
*/
2653527832
static void output_redir(ShellState *p, FILE *pfNew){
2653627833
if( p->out != stdout ){
26537
- sqlite3_fputs("Output already redirected.\n", stderr);
27834
+ cli_puts("Output already redirected.\n", stderr);
2653827835
}else{
2653927836
p->out = pfNew;
2654027837
setCrlfMode(p);
26541
- if( p->mode==MODE_Www ){
26542
- sqlite3_fputs(
27838
+ if( p->mode.eMode==MODE_Www ){
27839
+ cli_puts(
2654327840
"<!DOCTYPE html>\n"
2654427841
"<HTML><BODY><PRE>\n",
2654527842
p->out
2654627843
);
2654727844
}
@@ -26559,12 +27856,12 @@
2655927856
if( p->outfile[0]=='|' ){
2656027857
#ifndef SQLITE_OMIT_POPEN
2656127858
pclose(p->out);
2656227859
#endif
2656327860
}else{
26564
- if( p->mode==MODE_Www ){
26565
- sqlite3_fputs("</PRE></BODY></HTML>\n", p->out);
27861
+ if( p->mode.eMode==MODE_Www ){
27862
+ cli_puts("</PRE></BODY></HTML>\n", p->out);
2656627863
}
2656727864
output_file_close(p->out);
2656827865
#ifndef SQLITE_NOHAVE_SYSTEM
2656927866
if( p->doXdgOpen ){
2657027867
const char *zXdgOpenCmd =
@@ -26576,26 +27873,30 @@
2657627873
"xdg-open";
2657727874
#endif
2657827875
char *zCmd;
2657927876
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
2658027877
if( system(zCmd) ){
26581
- sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd);
27878
+ cli_printf(stderr,"Failed: [%s]\n", zCmd);
2658227879
}else{
2658327880
/* Give the start/open/xdg-open command some time to get
2658427881
** going before we continue, and potential delete the
2658527882
** p->zTempFile data file out from under it */
2658627883
sqlite3_sleep(2000);
2658727884
}
2658827885
sqlite3_free(zCmd);
26589
- outputModePop(p);
27886
+ modePop(p);
2659027887
p->doXdgOpen = 0;
2659127888
}
2659227889
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
2659327890
}
2659427891
p->outfile[0] = 0;
2659527892
p->out = stdout;
2659627893
setCrlfMode(p);
27894
+ if( cli_output_capture ){
27895
+ sqlite3_str_free(cli_output_capture);
27896
+ cli_output_capture = 0;
27897
+ }
2659727898
}
2659827899
#else
2659927900
# define output_redir(SS,pfO)
2660027901
# define output_reset(SS)
2660127902
#endif
@@ -26676,11 +27977,11 @@
2667627977
if( p->db==0 ) return 1;
2667727978
rc = sqlite3_prepare_v2(p->db,
2667827979
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
2667927980
-1, &pStmt, 0);
2668027981
if( rc ){
26681
- sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db));
27982
+ cli_printf(stderr,"error: %s\n", sqlite3_errmsg(p->db));
2668227983
sqlite3_finalize(pStmt);
2668327984
return 1;
2668427985
}
2668527986
sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
2668627987
if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -26689,32 +27990,32 @@
2668927990
const u8 *pb = sqlite3_column_blob(pStmt,0);
2669027991
shell_check_oom(pb);
2669127992
memcpy(aHdr, pb, 100);
2669227993
sqlite3_finalize(pStmt);
2669327994
}else{
26694
- sqlite3_fputs("unable to read database header\n", stderr);
27995
+ cli_puts("unable to read database header\n", stderr);
2669527996
sqlite3_finalize(pStmt);
2669627997
return 1;
2669727998
}
2669827999
i = get2byteInt(aHdr+16);
2669928000
if( i==1 ) i = 65536;
26700
- sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i);
26701
- sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
26702
- sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
26703
- sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
28001
+ cli_printf(p->out, "%-20s %d\n", "database page size:", i);
28002
+ cli_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
28003
+ cli_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
28004
+ cli_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2670428005
for(i=0; i<ArraySize(aField); i++){
2670528006
int ofst = aField[i].ofst;
2670628007
unsigned int val = get4byteInt(aHdr + ofst);
26707
- sqlite3_fprintf(p->out, "%-20s %u", aField[i].zName, val);
28008
+ cli_printf(p->out, "%-20s %u", aField[i].zName, val);
2670828009
switch( ofst ){
2670928010
case 56: {
26710
- if( val==1 ) sqlite3_fputs(" (utf8)", p->out);
26711
- if( val==2 ) sqlite3_fputs(" (utf16le)", p->out);
26712
- if( val==3 ) sqlite3_fputs(" (utf16be)", p->out);
28011
+ if( val==1 ) cli_puts(" (utf8)", p->out);
28012
+ if( val==2 ) cli_puts(" (utf16le)", p->out);
28013
+ if( val==3 ) cli_puts(" (utf16be)", p->out);
2671328014
}
2671428015
}
26715
- sqlite3_fputs("\n", p->out);
28016
+ cli_puts("\n", p->out);
2671628017
}
2671728018
if( zDb==0 ){
2671828019
zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
2671928020
}else if( cli_strcmp(zDb,"temp")==0 ){
2672028021
zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
@@ -26721,15 +28022,15 @@
2672128022
}else{
2672228023
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
2672328024
}
2672428025
for(i=0; i<ArraySize(aQuery); i++){
2672528026
int val = db_int(p->db, aQuery[i].zSql, zSchemaTab);
26726
- sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
28027
+ cli_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2672728028
}
2672828029
sqlite3_free(zSchemaTab);
2672928030
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
26730
- sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion);
28031
+ cli_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
2673128032
return 0;
2673228033
}
2673328034
#endif /* SQLITE_SHELL_HAVE_RECOVER */
2673428035
2673528036
/*
@@ -26785,11 +28086,11 @@
2678528086
zTail++;
2678628087
}
2678728088
}
2678828089
zName = strdup(zTail);
2678928090
shell_check_oom(zName);
26790
- sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
28091
+ cli_printf(p->out, "| size %lld pagesize %d filename %s\n",
2679128092
nPage*pgSz, pgSz, zName);
2679228093
sqlite3_finalize(pStmt);
2679328094
pStmt = 0;
2679428095
rc = sqlite3_prepare_v2(p->db,
2679528096
"SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
@@ -26801,31 +28102,31 @@
2680128102
for(i=0; i<pgSz; i+=16){
2680228103
const u8 *aLine = aData+i;
2680328104
for(j=0; j<16 && aLine[j]==0; j++){}
2680428105
if( j==16 ) continue;
2680528106
if( !seenPageLabel ){
26806
- sqlite3_fprintf(p->out, "| page %lld offset %lld\n",pgno,(pgno-1)*pgSz);
28107
+ cli_printf(p->out, "| page %lld offset %lld\n",pgno,(pgno-1)*pgSz);
2680728108
seenPageLabel = 1;
2680828109
}
26809
- sqlite3_fprintf(p->out, "| %5d:", i);
26810
- for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
26811
- sqlite3_fprintf(p->out, " ");
28110
+ cli_printf(p->out, "| %5d:", i);
28111
+ for(j=0; j<16; j++) cli_printf(p->out, " %02x", aLine[j]);
28112
+ cli_printf(p->out, " ");
2681228113
for(j=0; j<16; j++){
2681328114
unsigned char c = (unsigned char)aLine[j];
26814
- sqlite3_fprintf(p->out, "%c", bShow[c]);
28115
+ cli_printf(p->out, "%c", bShow[c]);
2681528116
}
26816
- sqlite3_fprintf(p->out, "\n");
28117
+ cli_printf(p->out, "\n");
2681728118
}
2681828119
}
2681928120
sqlite3_finalize(pStmt);
26820
- sqlite3_fprintf(p->out, "| end %s\n", zName);
28121
+ cli_printf(p->out, "| end %s\n", zName);
2682128122
free(zName);
2682228123
return 0;
2682328124
2682428125
dbtotxt_error:
2682528126
if( rc ){
26826
- sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
28127
+ cli_printf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
2682728128
}
2682828129
sqlite3_finalize(pStmt);
2682928130
free(zName);
2683028131
return 1;
2683128132
}
@@ -26832,11 +28133,11 @@
2683228133
2683328134
/*
2683428135
** Print the given string as an error message.
2683528136
*/
2683628137
static void shellEmitError(const char *zErr){
26837
- sqlite3_fprintf(stderr,"Error: %s\n", zErr);
28138
+ cli_printf(stderr,"Error: %s\n", zErr);
2683828139
}
2683928140
/*
2684028141
** Print the current sqlite3_errmsg() value to stderr and return 1.
2684128142
*/
2684228143
static int shellDatabaseError(sqlite3 *db){
@@ -27015,42 +28316,45 @@
2701528316
if( shellDeleteFile(p->zTempFile) ) return;
2701628317
sqlite3_free(p->zTempFile);
2701728318
p->zTempFile = 0;
2701828319
}
2701928320
28321
+/* Forward reference */
28322
+static char *find_home_dir(int clearFlag);
28323
+
2702028324
/*
2702128325
** Create a new temp file name with the given suffix.
28326
+**
28327
+** Because the classic temp folders like /tmp are no longer
28328
+** accessible to web browsers, for security reasons, create the
28329
+** temp file in the user's home directory.
2702228330
*/
2702328331
static void newTempFile(ShellState *p, const char *zSuffix){
28332
+ char *zHome; /* Home directory */
28333
+ int i; /* Loop counter */
28334
+ sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
28335
+ char zRand[32]; /* Text string with 160 bits of randomness */
28336
+#ifdef _WIN32
28337
+ const char cDirSep = '\\';
28338
+#else
28339
+ const char cDirSep = '/';
28340
+#endif
28341
+
28342
+ for(i=0; i<31; i++){
28343
+ if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
28344
+ zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
28345
+ r /= 36;
28346
+ }
28347
+ zRand[i] = 0;
2702428348
clearTempFile(p);
2702528349
sqlite3_free(p->zTempFile);
2702628350
p->zTempFile = 0;
27027
- if( p->db ){
27028
- sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
27029
- }
27030
- if( p->zTempFile==0 ){
27031
- /* If p->db is an in-memory database then the TEMPFILENAME file-control
27032
- ** will not work and we will need to fallback to guessing */
27033
- char *zTemp;
27034
- sqlite3_uint64 r;
27035
- sqlite3_randomness(sizeof(r), &r);
27036
- zTemp = getenv("TEMP");
27037
- if( zTemp==0 ) zTemp = getenv("TMP");
27038
- if( zTemp==0 ){
27039
-#ifdef _WIN32
27040
- zTemp = "\\tmp";
27041
-#else
27042
- zTemp = "/tmp";
27043
-#endif
27044
- }
27045
- p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
27046
- }else{
27047
- p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
27048
- }
28351
+ zHome = find_home_dir(0);
28352
+ p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
28353
+ zHome,cDirSep,zRand,zSuffix);
2704928354
shell_check_oom(p->zTempFile);
2705028355
}
27051
-
2705228356
2705328357
/*
2705428358
** The implementation of SQL scalar function fkey_collate_clause(), used
2705528359
** by the ".lint fkey-indexes" command. This scalar function is always
2705628360
** called with four arguments - the parent table name, the parent column name,
@@ -27192,11 +28496,11 @@
2719228496
else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
2719328497
bGroupByParent = 1;
2719428498
zIndent = " ";
2719528499
}
2719628500
else{
27197
- sqlite3_fprintf(stderr,
28501
+ cli_printf(stderr,
2719828502
"Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]);
2719928503
return SQLITE_ERROR;
2720028504
}
2720128505
}
2720228506
@@ -27237,45 +28541,45 @@
2723728541
}
2723828542
rc = sqlite3_finalize(pExplain);
2723928543
if( rc!=SQLITE_OK ) break;
2724028544
2724128545
if( res<0 ){
27242
- sqlite3_fputs("Error: internal error", stderr);
28546
+ cli_puts("Error: internal error", stderr);
2724328547
break;
2724428548
}else{
2724528549
if( bGroupByParent
2724628550
&& (bVerbose || res==0)
2724728551
&& (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
2724828552
){
27249
- sqlite3_fprintf(out, "-- Parent table %s\n", zParent);
28553
+ cli_printf(out, "-- Parent table %s\n", zParent);
2725028554
sqlite3_free(zPrev);
2725128555
zPrev = sqlite3_mprintf("%s", zParent);
2725228556
}
2725328557
2725428558
if( res==0 ){
27255
- sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
28559
+ cli_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
2725628560
}else if( bVerbose ){
27257
- sqlite3_fprintf(out,
28561
+ cli_printf(out,
2725828562
"%s/* no extra indexes required for %s -> %s */\n",
2725928563
zIndent, zFrom, zTarget
2726028564
);
2726128565
}
2726228566
}
2726328567
}
2726428568
sqlite3_free(zPrev);
2726528569
2726628570
if( rc!=SQLITE_OK ){
27267
- sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
28571
+ cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
2726828572
}
2726928573
2727028574
rc2 = sqlite3_finalize(pSql);
2727128575
if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
2727228576
rc = rc2;
27273
- sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
28577
+ cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
2727428578
}
2727528579
}else{
27276
- sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
28580
+ cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
2727728581
}
2727828582
2727928583
return rc;
2728028584
}
2728128585
@@ -27291,13 +28595,13 @@
2729128595
n = (nArg>=2 ? strlen30(azArg[1]) : 0);
2729228596
if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
2729328597
return lintFkeyIndexes(pState, azArg, nArg);
2729428598
2729528599
usage:
27296
- sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]);
27297
- sqlite3_fprintf(stderr, "Where sub-commands are:\n");
27298
- sqlite3_fprintf(stderr, " fkey-indexes\n");
28600
+ cli_printf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]);
28601
+ cli_printf(stderr, "Where sub-commands are:\n");
28602
+ cli_printf(stderr, " fkey-indexes\n");
2729928603
return SQLITE_ERROR;
2730028604
}
2730128605
2730228606
static void shellPrepare(
2730328607
sqlite3 *db,
@@ -27307,11 +28611,11 @@
2730728611
){
2730828612
*ppStmt = 0;
2730928613
if( *pRc==SQLITE_OK ){
2731028614
int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
2731128615
if( rc!=SQLITE_OK ){
27312
- sqlite3_fprintf(stderr,
28616
+ cli_printf(stderr,
2731328617
"sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db));
2731428618
*pRc = rc;
2731528619
}
2731628620
}
2731728621
}
@@ -27352,11 +28656,11 @@
2735228656
if( pStmt ){
2735328657
sqlite3 *db = sqlite3_db_handle(pStmt);
2735428658
int rc = sqlite3_finalize(pStmt);
2735528659
if( *pRc==SQLITE_OK ){
2735628660
if( rc!=SQLITE_OK ){
27357
- sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
28661
+ cli_printf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
2735828662
}
2735928663
*pRc = rc;
2736028664
}
2736128665
}
2736228666
}
@@ -27374,11 +28678,11 @@
2737428678
){
2737528679
int rc = sqlite3_reset(pStmt);
2737628680
if( *pRc==SQLITE_OK ){
2737728681
if( rc!=SQLITE_OK ){
2737828682
sqlite3 *db = sqlite3_db_handle(pStmt);
27379
- sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
28683
+ cli_printf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
2738028684
}
2738128685
*pRc = rc;
2738228686
}
2738328687
}
2738428688
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
@@ -27427,13 +28731,13 @@
2742728731
va_start(ap, zFmt);
2742828732
z = sqlite3_vmprintf(zFmt, ap);
2742928733
va_end(ap);
2743028734
shellEmitError(z);
2743128735
if( pAr->fromCmdLine ){
27432
- sqlite3_fputs("Use \"-A\" for more help\n", stderr);
28736
+ cli_puts("Use \"-A\" for more help\n", stderr);
2743328737
}else{
27434
- sqlite3_fputs("Use \".archive --help\" for more help\n", stderr);
28738
+ cli_puts("Use \".archive --help\" for more help\n", stderr);
2743528739
}
2743628740
sqlite3_free(z);
2743728741
return SQLITE_ERROR;
2743828742
}
2743928743
@@ -27529,11 +28833,11 @@
2752928833
};
2753028834
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
2753128835
struct ArSwitch *pEnd = &aSwitch[nSwitch];
2753228836
2753328837
if( nArg<=1 ){
27534
- sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n");
28838
+ cli_printf(stderr, "Wrong number of arguments. Usage:\n");
2753528839
return arUsage(stderr);
2753628840
}else{
2753728841
char *z = azArg[1];
2753828842
if( z[0]!='-' ){
2753928843
/* Traditional style [tar] invocation */
@@ -27635,11 +28939,11 @@
2763528939
}
2763628940
}
2763728941
}
2763828942
}
2763928943
if( pAr->eCmd==0 ){
27640
- sqlite3_fprintf(stderr, "Required argument missing. Usage:\n");
28944
+ cli_printf(stderr, "Required argument missing. Usage:\n");
2764128945
return arUsage(stderr);
2764228946
}
2764328947
return SQLITE_OK;
2764428948
}
2764528949
@@ -27678,11 +28982,11 @@
2767828982
if( SQLITE_ROW==sqlite3_step(pTest) ){
2767928983
bOk = 1;
2768028984
}
2768128985
shellReset(&rc, pTest);
2768228986
if( rc==SQLITE_OK && bOk==0 ){
27683
- sqlite3_fprintf(stderr,"not found in archive: %s\n", z);
28987
+ cli_printf(stderr,"not found in archive: %s\n", z);
2768428988
rc = SQLITE_ERROR;
2768528989
}
2768628990
}
2768728991
shellFinalize(&rc, pTest);
2768828992
}
@@ -27761,19 +29065,19 @@
2776129065
arWhereClause(&rc, pAr, &zWhere);
2776229066
2776329067
shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
2776429068
pAr->zSrcTable, zWhere);
2776529069
if( pAr->bDryRun ){
27766
- sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql));
29070
+ cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
2776729071
}else{
2776829072
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
2776929073
if( pAr->bVerbose ){
27770
- sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n",
29074
+ cli_printf(pAr->out, "%s % 10d %s %s\n",
2777129075
sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1),
2777229076
sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3));
2777329077
}else{
27774
- sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
29078
+ cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
2777529079
}
2777629080
}
2777729081
}
2777829082
shellFinalize(&rc, pSql);
2777929083
sqlite3_free(zWhere);
@@ -27796,11 +29100,11 @@
2779629100
}
2779729101
if( rc==SQLITE_OK ){
2779829102
zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
2779929103
pAr->zSrcTable, zWhere);
2780029104
if( pAr->bDryRun ){
27801
- sqlite3_fprintf(pAr->out, "%s\n", zSql);
29105
+ cli_printf(pAr->out, "%s\n", zSql);
2780229106
}else{
2780329107
char *zErr = 0;
2780429108
rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
2780529109
if( rc==SQLITE_OK ){
2780629110
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
@@ -27809,11 +29113,11 @@
2780929113
}else{
2781029114
rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
2781129115
}
2781229116
}
2781329117
if( zErr ){
27814
- sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */
29118
+ cli_printf(stdout, "ERROR: %s\n", zErr); /* stdout? */
2781529119
sqlite3_free(zErr);
2781629120
}
2781729121
}
2781829122
}
2781929123
sqlite3_free(zWhere);
@@ -27873,15 +29177,15 @@
2787329177
** populating them changes the timestamp). */
2787429178
for(i=0; i<2; i++){
2787529179
j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
2787629180
sqlite3_bind_int(pSql, j, i);
2787729181
if( pAr->bDryRun ){
27878
- sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql));
29182
+ cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
2787929183
}else{
2788029184
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
2788129185
if( i==0 && pAr->bVerbose ){
27882
- sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
29186
+ cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
2788329187
}
2788429188
}
2788529189
}
2788629190
shellReset(&rc, pSql);
2788729191
}
@@ -27897,17 +29201,17 @@
2789729201
** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
2789829202
*/
2789929203
static int arExecSql(ArCommand *pAr, const char *zSql){
2790029204
int rc;
2790129205
if( pAr->bDryRun ){
27902
- sqlite3_fprintf(pAr->out, "%s\n", zSql);
29206
+ cli_printf(pAr->out, "%s\n", zSql);
2790329207
rc = SQLITE_OK;
2790429208
}else{
2790529209
char *zErr = 0;
2790629210
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
2790729211
if( zErr ){
27908
- sqlite3_fprintf(stdout, "ERROR: %s\n", zErr);
29212
+ cli_printf(stdout, "ERROR: %s\n", zErr);
2790929213
sqlite3_free(zErr);
2791029214
}
2791129215
}
2791229216
return rc;
2791329217
}
@@ -28079,17 +29383,17 @@
2807929383
}else{
2808029384
flags = SQLITE_OPEN_READONLY;
2808129385
}
2808229386
cmd.db = 0;
2808329387
if( cmd.bDryRun ){
28084
- sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile,
29388
+ cli_printf(cmd.out, "-- open database '%s'%s\n", cmd.zFile,
2808529389
eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
2808629390
}
2808729391
rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
2808829392
eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
2808929393
if( rc!=SQLITE_OK ){
28090
- sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n",
29394
+ cli_printf(stderr, "cannot open file: %s (%s)\n",
2809129395
cmd.zFile, sqlite3_errmsg(cmd.db));
2809229396
goto end_ar_command;
2809329397
}
2809429398
sqlite3_fileio_init(cmd.db, 0, 0);
2809529399
sqlite3_sqlar_init(cmd.db, 0, 0);
@@ -28099,11 +29403,11 @@
2809929403
}
2810029404
if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
2810129405
if( cmd.eCmd!=AR_CMD_CREATE
2810229406
&& sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
2810329407
){
28104
- sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n");
29408
+ cli_printf(stderr, "database does not contain an 'sqlar' table\n");
2810529409
rc = SQLITE_ERROR;
2810629410
goto end_ar_command;
2810729411
}
2810829412
cmd.zSrcTable = sqlite3_mprintf("sqlar");
2810929413
}
@@ -28157,11 +29461,11 @@
2815729461
** This function is used as a callback by the recover extension. Simply
2815829462
** print the supplied SQL statement to stdout.
2815929463
*/
2816029464
static int recoverSqlCb(void *pCtx, const char *zSql){
2816129465
ShellState *pState = (ShellState*)pCtx;
28162
- sqlite3_fprintf(pState->out, "%s;\n", zSql);
29466
+ cli_printf(pState->out, "%s;\n", zSql);
2816329467
return SQLITE_OK;
2816429468
}
2816529469
2816629470
/*
2816729471
** This function is called to recover data from the database. A script
@@ -28200,11 +29504,11 @@
2820029504
}else
2820129505
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
2820229506
bRowids = 0;
2820329507
}
2820429508
else{
28205
- sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]);
29509
+ cli_printf(stderr,"unexpected option: %s\n", azArg[i]);
2820629510
showHelp(pState->out, azArg[0]);
2820729511
return 1;
2820829512
}
2820929513
}
2821029514
@@ -28215,16 +29519,16 @@
2821529519
sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */
2821629520
sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
2821729521
sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
2821829522
sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
2821929523
28220
- sqlite3_fprintf(pState->out, ".dbconfig defensive off\n");
29524
+ cli_printf(pState->out, ".dbconfig defensive off\n");
2822129525
sqlite3_recover_run(p);
2822229526
if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
2822329527
const char *zErr = sqlite3_recover_errmsg(p);
2822429528
int errCode = sqlite3_recover_errcode(p);
28225
- sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode);
29529
+ cli_printf(stderr,"sql error: %s (%d)\n", zErr, errCode);
2822629530
}
2822729531
rc = sqlite3_recover_finish(p);
2822829532
return rc;
2822929533
}
2823029534
#endif /* SQLITE_SHELL_HAVE_RECOVER */
@@ -28242,25 +29546,25 @@
2824229546
i64 nError = 0;
2824329547
const char *zErr = 0;
2824429548
while( SQLITE_OK==sqlite3_intck_step(p) ){
2824529549
const char *zMsg = sqlite3_intck_message(p);
2824629550
if( zMsg ){
28247
- sqlite3_fprintf(pState->out, "%s\n", zMsg);
29551
+ cli_printf(pState->out, "%s\n", zMsg);
2824829552
nError++;
2824929553
}
2825029554
nStep++;
2825129555
if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){
2825229556
sqlite3_intck_unlock(p);
2825329557
}
2825429558
}
2825529559
rc = sqlite3_intck_error(p, &zErr);
2825629560
if( zErr ){
28257
- sqlite3_fprintf(stderr,"%s\n", zErr);
29561
+ cli_printf(stderr,"%s\n", zErr);
2825829562
}
2825929563
sqlite3_intck_close(p);
2826029564
28261
- sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError);
29565
+ cli_printf(pState->out, "%lld steps, %lld errors\n", nStep, nError);
2826229566
}
2826329567
2826429568
return rc;
2826529569
}
2826629570
@@ -28279,11 +29583,11 @@
2827929583
*/
2828029584
#ifdef SHELL_DEBUG
2828129585
#define rc_err_oom_die(rc) \
2828229586
if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
2828329587
else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
28284
- sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0)
29588
+ cli_printf(stderr,"E:%d\n",rc), assert(0)
2828529589
#else
2828629590
static void rc_err_oom_die(int rc){
2828729591
if( rc==SQLITE_NOMEM ) shell_check_oom(0);
2828829592
assert(rc==SQLITE_OK||rc==SQLITE_DONE);
2828929593
}
@@ -28496,11 +29800,11 @@
2849629800
shellPreparePrintf(p->db, &rc, &pStmt,
2849729801
"SELECT 1 FROM sqlite_schema o WHERE "
2849829802
"sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true"
2849929803
);
2850029804
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
28501
- sqlite3_fputs("/* WARNING: "
29805
+ cli_puts("/* WARNING: "
2850229806
"Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n",
2850329807
p->out
2850429808
);
2850529809
}
2850629810
shellFinalize(&rc, pStmt);
@@ -28529,69 +29833,1323 @@
2852929833
return SQLITE_OK;
2853029834
}
2853129835
if( faultsim_state.iCnt ){
2853229836
if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--;
2853329837
if( faultsim_state.eVerbose>=2 ){
28534
- sqlite3_fprintf(stdout,
29838
+ cli_printf(stdout,
2853529839
"FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt);
2853629840
}
2853729841
return SQLITE_OK;
2853829842
}
2853929843
if( faultsim_state.eVerbose>=1 ){
28540
- sqlite3_fprintf(stdout,
29844
+ cli_printf(stdout,
2854129845
"FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr);
2854229846
}
2854329847
faultsim_state.iCnt = faultsim_state.iInterval;
2854429848
faultsim_state.nHit++;
2854529849
if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){
2854629850
faultsim_state.iCnt = -1;
2854729851
}
2854829852
return faultsim_state.iErr;
2854929853
}
29854
+
29855
+/*
29856
+** pickStr(zArg, &zErr, zS1, zS2, ..., "");
29857
+**
29858
+** Try to match zArg against zS1, zS2, and so forth until the first
29859
+** emptry string. Return the index of the match or -1 if none is found.
29860
+** If no match is found, and &zErr is not NULL, then write into
29861
+** zErr a message describing the valid choices.
29862
+*/
29863
+static int pickStr(const char *zArg, char **pzErr, ...){
29864
+ int i, n;
29865
+ const char *z;
29866
+ sqlite3_str *pMsg;
29867
+ va_list ap;
29868
+ va_start(ap, pzErr);
29869
+ i = 0;
29870
+ while( (z = va_arg(ap,const char*))!=0 && z[0]!=0 ){
29871
+ if( cli_strcmp(zArg, z)==0 ) return i;
29872
+ i++;
29873
+ }
29874
+ va_end(ap);
29875
+ if( pzErr==0 ) return -1;
29876
+ n = i;
29877
+ pMsg = sqlite3_str_new(0);
29878
+ va_start(ap, pzErr);
29879
+ sqlite3_str_appendall(pMsg, "should be");
29880
+ i = 0;
29881
+ while( (z = va_arg(ap, const char*))!=0 && z[0]!=0 ){
29882
+ if( i==n-1 ){
29883
+ sqlite3_str_append(pMsg,", or",4);
29884
+ }else if( i>0 ){
29885
+ sqlite3_str_append(pMsg, ",", 1);
29886
+ }
29887
+ sqlite3_str_appendf(pMsg, " %s", z);
29888
+ i++;
29889
+ }
29890
+ va_end(ap);
29891
+ *pzErr = sqlite3_str_finish(pMsg);
29892
+ return -1;
29893
+}
29894
+
29895
+/*
29896
+** DOT-COMMAND: .import
29897
+**
29898
+** USAGE: .import [OPTIONS] FILE TABLE
29899
+**
29900
+** Import CSV or similar text from FILE into TABLE. If TABLE does
29901
+** not exist, it is created using the first row of FILE as the column
29902
+** names. If FILE begins with "|" then it is a command that is run
29903
+** and the output from the command is used as the input data.
29904
+**
29905
+** FILE is assumed to be in a CSV format, unless the current mode
29906
+** is "ascii" or "tabs" or unless one of the options below specify
29907
+** an alternative.
29908
+**
29909
+** Options:
29910
+** --ascii Use \037 and \036 as column and row separators on input
29911
+** --csv Input is standard RFC-4180 CSV.
29912
+** --schema S When creating TABLE, put it in schema S
29913
+** --skip N Ignore the first N rows of input
29914
+** -v Verbose mode
29915
+*/
29916
+static int dotCmdImport(ShellState *p){
29917
+ int nArg = p->dot.nArg; /* Number of arguments */
29918
+ char **azArg = p->dot.azArg;/* Argument list */
29919
+ char *zTable = 0; /* Insert data into this table */
29920
+ char *zSchema = 0; /* Schema of zTable */
29921
+ char *zFile = 0; /* Name of file to extra content from */
29922
+ sqlite3_stmt *pStmt = NULL; /* A statement */
29923
+ int nCol; /* Number of columns in the table */
29924
+ i64 nByte; /* Number of bytes in an SQL string */
29925
+ int i, j; /* Loop counters */
29926
+ int needCommit; /* True to COMMIT or ROLLBACK at end */
29927
+ int nSep; /* Number of bytes in spec.zColumnSep */
29928
+ char *zSql = 0; /* An SQL statement */
29929
+ ImportCtx sCtx; /* Reader context */
29930
+ char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29931
+ int eVerbose = 0; /* Larger for more console output */
29932
+ i64 nSkip = 0; /* Initial lines to skip */
29933
+ int useOutputMode = 1; /* Use output mode to determine separators */
29934
+ char *zCreate = 0; /* CREATE TABLE statement text */
29935
+ int rc; /* Result code */
29936
+
29937
+ failIfSafeMode(p, "cannot run .import in safe mode");
29938
+ memset(&sCtx, 0, sizeof(sCtx));
29939
+ if( p->mode.eMode==MODE_Ascii ){
29940
+ xRead = ascii_read_one_field;
29941
+ }else{
29942
+ xRead = csv_read_one_field;
29943
+ }
29944
+ for(i=1; i<nArg; i++){
29945
+ char *z = azArg[i];
29946
+ if( z[0]=='-' && z[1]=='-' ) z++;
29947
+ if( z[0]!='-' ){
29948
+ if( zFile==0 ){
29949
+ zFile = z;
29950
+ }else if( zTable==0 ){
29951
+ zTable = z;
29952
+ }else{
29953
+ dotCmdError(p, i, "unknown argument", 0);
29954
+ return 1;
29955
+ }
29956
+ }else if( cli_strcmp(z,"-v")==0 ){
29957
+ eVerbose++;
29958
+ }else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){
29959
+ zSchema = azArg[++i];
29960
+ }else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){
29961
+ nSkip = integerValue(azArg[++i]);
29962
+ }else if( cli_strcmp(z,"-ascii")==0 ){
29963
+ sCtx.cColSep = SEP_Unit[0];
29964
+ sCtx.cRowSep = SEP_Record[0];
29965
+ xRead = ascii_read_one_field;
29966
+ useOutputMode = 0;
29967
+ }else if( cli_strcmp(z,"-csv")==0 ){
29968
+ sCtx.cColSep = ',';
29969
+ sCtx.cRowSep = '\n';
29970
+ xRead = csv_read_one_field;
29971
+ useOutputMode = 0;
29972
+ }else{
29973
+ dotCmdError(p, i, "unknown option", 0);
29974
+ return 1;
29975
+ }
29976
+ }
29977
+ if( zTable==0 ){
29978
+ cli_printf(p->out, "ERROR: missing %s argument\n",
29979
+ zFile==0 ? "FILE" : "TABLE");
29980
+ return 1;
29981
+ }
29982
+ seenInterrupt = 0;
29983
+ open_db(p, 0);
29984
+ if( useOutputMode ){
29985
+ /* If neither the --csv or --ascii options are specified, then set
29986
+ ** the column and row separator characters from the output mode. */
29987
+ if( p->mode.spec.zColumnSep==0 ){
29988
+ modeSetStr(&p->mode.spec.zColumnSep, ",");
29989
+ nSep = 1;
29990
+ }else if( (nSep = strlen30(p->mode.spec.zColumnSep))==0 ){
29991
+ eputz("Error: non-null column separator required for import\n");
29992
+ return 1;
29993
+ }
29994
+ if( nSep>1 ){
29995
+ eputz("Error: multi-character column separators not allowed"
29996
+ " for import\n");
29997
+ return 1;
29998
+ }
29999
+ if( p->mode.spec.zRowSep==0 ){
30000
+ modeSetStr(&p->mode.spec.zRowSep, "\n");
30001
+ nSep = 1;
30002
+ }else if( (nSep = strlen30(p->mode.spec.zRowSep))==0 ){
30003
+ eputz("Error: non-null row separator required for import\n");
30004
+ return 1;
30005
+ }
30006
+ if( nSep==2 && p->mode.eMode==MODE_Csv
30007
+ && cli_strcmp(p->mode.spec.zRowSep,SEP_CrLf)==0
30008
+ ){
30009
+ /* When importing CSV (only), if the row separator is set to the
30010
+ ** default output row separator, change it to the default input
30011
+ ** row separator. This avoids having to maintain different input
30012
+ ** and output row separators. */
30013
+ modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
30014
+ nSep = strlen30(p->mode.spec.zRowSep);
30015
+ }
30016
+ if( nSep>1 ){
30017
+ eputz("Error: multi-character row separators not allowed"
30018
+ " for import\n");
30019
+ return 1;
30020
+ }
30021
+ sCtx.cColSep = (u8)p->mode.spec.zColumnSep[0];
30022
+ sCtx.cRowSep = (u8)p->mode.spec.zRowSep[0];
30023
+ }
30024
+ sCtx.zFile = zFile;
30025
+ sCtx.nLine = 1;
30026
+ if( sCtx.zFile[0]=='|' ){
30027
+#ifdef SQLITE_OMIT_POPEN
30028
+ eputz("Error: pipes are not supported in this OS\n");
30029
+ return 1;
30030
+#else
30031
+ sCtx.in = sqlite3_popen(sCtx.zFile+1, "r");
30032
+ sCtx.zFile = "<pipe>";
30033
+ sCtx.xCloser = pclose;
30034
+#endif
30035
+ }else{
30036
+ sCtx.in = sqlite3_fopen(sCtx.zFile, "rb");
30037
+ sCtx.xCloser = fclose;
30038
+ }
30039
+ if( sCtx.in==0 ){
30040
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", zFile);
30041
+ return 1;
30042
+ }
30043
+ if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
30044
+ char zSep[2];
30045
+ zSep[1] = 0;
30046
+ zSep[0] = sCtx.cColSep;
30047
+ cli_puts("Column separator ", p->out);
30048
+ output_c_string(p->out, zSep);
30049
+ cli_puts(", row separator ", p->out);
30050
+ zSep[0] = sCtx.cRowSep;
30051
+ output_c_string(p->out, zSep);
30052
+ cli_puts("\n", p->out);
30053
+ }
30054
+ sCtx.z = sqlite3_malloc64(120);
30055
+ if( sCtx.z==0 ){
30056
+ import_cleanup(&sCtx);
30057
+ shell_out_of_memory();
30058
+ }
30059
+ /* Below, resources must be freed before exit. */
30060
+ while( nSkip>0 ){
30061
+ nSkip--;
30062
+ while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
30063
+ }
30064
+ import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
30065
+ if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
30066
+ && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
30067
+ " WHERE name=%Q AND type='view'",
30068
+ zSchema ? zSchema : "main", zTable)
30069
+ ){
30070
+ /* Table does not exist. Create it. */
30071
+ sqlite3 *dbCols = 0;
30072
+ char *zRenames = 0;
30073
+ char *zColDefs;
30074
+ zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
30075
+ zSchema ? zSchema : "main", zTable);
30076
+ while( xRead(&sCtx) ){
30077
+ zAutoColumn(sCtx.z, &dbCols, 0);
30078
+ if( sCtx.cTerm!=sCtx.cColSep ) break;
30079
+ }
30080
+ zColDefs = zAutoColumn(0, &dbCols, &zRenames);
30081
+ if( zRenames!=0 ){
30082
+ cli_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
30083
+ "Columns renamed during .import %s due to duplicates:\n"
30084
+ "%s\n", sCtx.zFile, zRenames);
30085
+ sqlite3_free(zRenames);
30086
+ }
30087
+ assert(dbCols==0);
30088
+ if( zColDefs==0 ){
30089
+ cli_printf(stderr,"%s: empty file\n", sCtx.zFile);
30090
+ import_cleanup(&sCtx);
30091
+ sqlite3_free(zCreate);
30092
+ return 1;
30093
+ }
30094
+ zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
30095
+ if( zCreate==0 ){
30096
+ import_cleanup(&sCtx);
30097
+ shell_out_of_memory();
30098
+ }
30099
+ if( eVerbose>=1 ){
30100
+ cli_printf(p->out, "%s\n", zCreate);
30101
+ }
30102
+ rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
30103
+ if( rc ){
30104
+ cli_printf(stderr,
30105
+ "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
30106
+ }
30107
+ sqlite3_free(zCreate);
30108
+ zCreate = 0;
30109
+ if( rc ){
30110
+ import_cleanup(&sCtx);
30111
+ return 1;
30112
+ }
30113
+ }
30114
+ zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
30115
+ zTable, zSchema);
30116
+ if( zSql==0 ){
30117
+ import_cleanup(&sCtx);
30118
+ shell_out_of_memory();
30119
+ }
30120
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
30121
+ sqlite3_free(zSql);
30122
+ zSql = 0;
30123
+ if( rc ){
30124
+ if (pStmt) sqlite3_finalize(pStmt);
30125
+ shellDatabaseError(p->db);
30126
+ import_cleanup(&sCtx);
30127
+ return 1;
30128
+ }
30129
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
30130
+ nCol = sqlite3_column_int(pStmt, 0);
30131
+ }else{
30132
+ nCol = 0;
30133
+ }
30134
+ sqlite3_finalize(pStmt);
30135
+ pStmt = 0;
30136
+ if( nCol==0 ) return 0; /* no columns, no error */
30137
+
30138
+ nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */
30139
+ + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */
30140
+ + strlen(zTable)*2 + 2 /* Quoted table name */
30141
+ + nCol*2; /* Space for ",?" for each column */
30142
+ zSql = sqlite3_malloc64( nByte );
30143
+ if( zSql==0 ){
30144
+ import_cleanup(&sCtx);
30145
+ shell_out_of_memory();
30146
+ }
30147
+ if( zSchema ){
30148
+ sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
30149
+ zSchema, zTable);
30150
+ }else{
30151
+ sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
30152
+ }
30153
+ j = strlen30(zSql);
30154
+ for(i=1; i<nCol; i++){
30155
+ zSql[j++] = ',';
30156
+ zSql[j++] = '?';
30157
+ }
30158
+ zSql[j++] = ')';
30159
+ zSql[j] = 0;
30160
+ assert( j<nByte );
30161
+ if( eVerbose>=2 ){
30162
+ cli_printf(p->out, "Insert using: %s\n", zSql);
30163
+ }
30164
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
30165
+ sqlite3_free(zSql);
30166
+ zSql = 0;
30167
+ if( rc ){
30168
+ shellDatabaseError(p->db);
30169
+ if (pStmt) sqlite3_finalize(pStmt);
30170
+ import_cleanup(&sCtx);
30171
+ return 1;
30172
+ }
30173
+ needCommit = sqlite3_get_autocommit(p->db);
30174
+ if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
30175
+ do{
30176
+ int startLine = sCtx.nLine;
30177
+ for(i=0; i<nCol; i++){
30178
+ char *z = xRead(&sCtx);
30179
+ /*
30180
+ ** Did we reach end-of-file before finding any columns?
30181
+ ** If so, stop instead of NULL filling the remaining columns.
30182
+ */
30183
+ if( z==0 && i==0 ) break;
30184
+ /*
30185
+ ** Did we reach end-of-file OR end-of-line before finding any
30186
+ ** columns in ASCII mode? If so, stop instead of NULL filling
30187
+ ** the remaining columns.
30188
+ */
30189
+ if( p->mode.eMode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
30190
+ /*
30191
+ ** For CSV mode, per RFC 4180, accept EOF in lieu of final
30192
+ ** record terminator but only for last field of multi-field row.
30193
+ ** (If there are too few fields, it's not valid CSV anyway.)
30194
+ */
30195
+ if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
30196
+ z = "";
30197
+ }
30198
+ sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
30199
+ if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
30200
+ cli_printf(stderr,"%s:%d: expected %d columns but found %d"
30201
+ " - filling the rest with NULL\n",
30202
+ sCtx.zFile, startLine, nCol, i+1);
30203
+ i += 2;
30204
+ while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
30205
+ }
30206
+ }
30207
+ if( sCtx.cTerm==sCtx.cColSep ){
30208
+ do{
30209
+ xRead(&sCtx);
30210
+ i++;
30211
+ }while( sCtx.cTerm==sCtx.cColSep );
30212
+ cli_printf(stderr,
30213
+ "%s:%d: expected %d columns but found %d - extras ignored\n",
30214
+ sCtx.zFile, startLine, nCol, i);
30215
+ }
30216
+ if( i>=nCol ){
30217
+ sqlite3_step(pStmt);
30218
+ rc = sqlite3_reset(pStmt);
30219
+ if( rc!=SQLITE_OK ){
30220
+ cli_printf(stderr,"%s:%d: INSERT failed: %s\n",
30221
+ sCtx.zFile, startLine, sqlite3_errmsg(p->db));
30222
+ sCtx.nErr++;
30223
+ }else{
30224
+ sCtx.nRow++;
30225
+ }
30226
+ }
30227
+ }while( sCtx.cTerm!=EOF );
30228
+
30229
+ import_cleanup(&sCtx);
30230
+ sqlite3_finalize(pStmt);
30231
+ if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
30232
+ if( eVerbose>0 ){
30233
+ cli_printf(p->out,
30234
+ "Added %d rows with %d errors using %d lines of input\n",
30235
+ sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
30236
+ }
30237
+ return 0;
30238
+}
30239
+
30240
+
30241
+/*
30242
+** This function computes what to show the user about the configured
30243
+** titles (or column-names). Output is an integer between 0 and 3:
30244
+**
30245
+** 0: The titles do not matter. Never show anything.
30246
+** 1: Show "--titles off"
30247
+** 2: Show "--titles on"
30248
+** 3: Show "--title VALUE" where VALUE is an encoding method
30249
+** to use, one of: plain sql csv html tcl json
30250
+**
30251
+** Inputs are:
30252
+**
30253
+** spec.bTitles (bT) Whether or not to show the titles
30254
+** spec.eTitle (eT) The actual encoding to be used for titles
30255
+** ModeInfo.bHdr (bH) Default value for spec.bTitles
30256
+** ModeInfo.eHdr (eH) Default value for spec.eTitle
30257
+** bAll Whether the -v option is used
30258
+*/
30259
+static int modeTitleDsply(ShellState *p, int bAll){
30260
+ int eMode = p->mode.eMode;
30261
+ const ModeInfo *pI = &aModeInfo[eMode];
30262
+ int bT = p->mode.spec.bTitles;
30263
+ int eT = p->mode.spec.eTitle;
30264
+ int bH = pI->bHdr;
30265
+ int eH = pI->eHdr;
30266
+
30267
+ /* Variable "v" is the truth table that will determine the answer
30268
+ **
30269
+ ** Actual encoding is different from default
30270
+ ** vvvvvvvv */
30271
+ sqlite3_uint64 v = 0x0133013311220102;
30272
+ /* ^^^^ ^^^^
30273
+ ** Upper 2-byte groups for when ON/OFF disagrees with
30274
+ ** the default. */
30275
+
30276
+ if( bH==0 ) return 0; /* Header not appliable. Ex: off, count */
30277
+
30278
+ if( eT==0 ) eT = eH; /* Fill in missing spec.eTitle */
30279
+ if( bT==0 ) bT = bH; /* Fill in missing spec.bTitles */
30280
+
30281
+ if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
30282
+ if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
30283
+ if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
30284
+ if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
30285
+
30286
+ return v & 3; /* Return the selected truth-table entry */
30287
+}
30288
+
30289
+/*
30290
+** DOT-COMMAND: .mode
30291
+**
30292
+** USAGE: .mode [MODE] [OPTIONS]
30293
+**
30294
+** Change the output mode to MODE and/or apply OPTIONS to the
30295
+** output mode. If no arguments, show the current output mode
30296
+** and relevant options.
30297
+**
30298
+** Options:
30299
+** --align STRING Set the alignment of text in columnar modes
30300
+** String consists of characters 'L', 'C', 'R'
30301
+** meaning "left", "centered", and "right", with
30302
+** one letter per column starting from the left.
30303
+** Unspecified alignment defaults to 'L'.
30304
+** --charlimit N Set the maximum number of output characters to
30305
+** show for any single SQL value to N. Longer values
30306
+** truncated. Zero means "no limit".
30307
+** --colsep STRING Use STRING as the column separator
30308
+** --escape ESC Enable/disable escaping of control characters
30309
+** in output. ESC can be "off", "ascii", or
30310
+** "symbol".
30311
+** --linelimit N Set the maximum number of output lines to show for
30312
+** any single SQL value to N. Longer values are
30313
+** truncated. Zero means "no limit". Only works
30314
+** in "line" mode and in columnar modes.
30315
+** --list List available modes
30316
+** --null STRING Render SQL NULL values as the given string
30317
+** --once Setting changes to the right are reverted after
30318
+** the next SQL command.
30319
+** --quote ARG Enable/disable quoting of text. ARG can be
30320
+** "off", "on", "sql", "csv", "html", "tcl",
30321
+** or "json". "off" means show the text as-is.
30322
+** "on and "sql" are synonyms.
30323
+** --reset Changes all mode settings back to their default.
30324
+** --rowsep STRING Use STRING as the row separator
30325
+** --screenwidth N Declare the screen width of the output device
30326
+** to be N characters. An attempt may be made to
30327
+** wrap output text to fit within this limit. Zero
30328
+** means "no limit". Or N can be "auto" to set the
30329
+** width automatically.
30330
+** --tablename NAME Set the name of the table for "insert" mode.
30331
+** --tag NAME Save mode to the left as NAME.
30332
+** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
30333
+** --title ARG Whether or not to show column headers, and if so
30334
+** how to encode them. ARG can be "off", "on",
30335
+** "sql", "csv", "html", "tcl", or "json".
30336
+** -v|--verbose Verbose output
30337
+** --widths LIST Set the columns widths for columnar modes. The
30338
+** argument is a list of integers, one for each
30339
+** column. A "0" width means use a dynamic width
30340
+** based on the actual width of data. If there are
30341
+** fewer entries in LIST than columns, "0" is used
30342
+** for the unspecified widths.
30343
+** --wordwrap BOOLEAN Enable/disable word wrapping
30344
+** --wrap N Wrap columns wider than N characters
30345
+** --ww Shorthand for "--wordwrap on"
30346
+*/
30347
+static int dotCmdMode(ShellState *p){
30348
+ int nArg = p->dot.nArg; /* Number of arguments */
30349
+ char **azArg = p->dot.azArg;/* Argument list */
30350
+ int eMode = -1; /* New mode value, or -1 for none */
30351
+ int iMode = -1; /* Index of the argument that is the mode name */
30352
+ int i; /* Loop counter */
30353
+ int k; /* Misc index variable */
30354
+ int chng = 0; /* True if anything has changed */
30355
+ int bAll = 0; /* Show all details of the mode */
30356
+
30357
+ for(i=1; i<nArg; i++){
30358
+ const char *z = azArg[i];
30359
+ if( z[0]=='-' && z[1]=='-' ) z++;
30360
+ if( z[0]!='-'
30361
+ && iMode<0
30362
+ && (eMode = modeFind(p, azArg[i]))>=0
30363
+ && eMode!=MODE_Www
30364
+ ){
30365
+ iMode = i;
30366
+ modeChange(p, eMode);
30367
+ /* (Legacy) If the mode is MODE_Insert and the next argument
30368
+ ** is not an option, then the next argument must be the table
30369
+ ** name.
30370
+ */
30371
+ if( i+1<nArg && azArg[i+1][0]!='-' ){
30372
+ i++;
30373
+ modeSetStr(&p->mode.spec.zTableName, azArg[i]);
30374
+ }
30375
+ chng = 1;
30376
+ }else if( optionMatch(z,"align") ){
30377
+ char *zAlign;
30378
+ int nAlign;
30379
+ int nErr = 0;
30380
+ if( i+1>=nArg ){
30381
+ dotCmdError(p, i, "missing argument", 0);
30382
+ return 1;
30383
+ }
30384
+ i++;
30385
+ zAlign = azArg[i];
30386
+ nAlign = 0x3fff & strlen(zAlign);
30387
+ free(p->mode.spec.aAlign);
30388
+ p->mode.spec.aAlign = malloc(nAlign);
30389
+ shell_check_oom(p->mode.spec.aAlign);
30390
+ for(k=0; k<nAlign; k++){
30391
+ unsigned char c = 0;
30392
+ switch( zAlign[k] ){
30393
+ case 'l': case 'L': c = QRF_ALIGN_Left; break;
30394
+ case 'c': case 'C': c = QRF_ALIGN_Center; break;
30395
+ case 'r': case 'R': c = QRF_ALIGN_Right; break;
30396
+ default: nErr++; break;
30397
+ }
30398
+ p->mode.spec.aAlign[k] = c;
30399
+ }
30400
+ p->mode.spec.nAlign = nAlign;
30401
+ chng = 1;
30402
+ if( nErr ){
30403
+ dotCmdError(p, i, "bad alignment string",
30404
+ "Should contain only characters L, C, and R.");
30405
+ return 1;
30406
+ }
30407
+ }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
30408
+ int w; /* 0 1 */
30409
+ if( i+1>=nArg ){
30410
+ dotCmdError(p, i, "missing argument", 0);
30411
+ return 1;
30412
+ }
30413
+ w = integerValue(azArg[++i]);
30414
+ if( k==0 ){
30415
+ p->mode.spec.nCharLimit = w;
30416
+ }else{
30417
+ p->mode.spec.nLineLimit = w;
30418
+ }
30419
+ chng = 1;
30420
+ }else if( 0<=(k=pickStr(z,0,"-tablename","-rowsep","-colsep","-null","")) ){
30421
+ /* 0 1 2 3 */
30422
+ if( i+1>=nArg ){
30423
+ dotCmdError(p, i, "missing argument", 0);
30424
+ return 1;
30425
+ }
30426
+ i++;
30427
+ switch( k ){
30428
+ case 0: modeSetStr(&p->mode.spec.zTableName, azArg[i]); break;
30429
+ case 1: modeSetStr(&p->mode.spec.zRowSep, azArg[i]); break;
30430
+ case 2: modeSetStr(&p->mode.spec.zColumnSep, azArg[i]); break;
30431
+ case 3: modeSetStr(&p->mode.spec.zNull, azArg[i]); break;
30432
+ }
30433
+ chng = 1;
30434
+ }else if( optionMatch(z,"escape") ){
30435
+ /* See similar code at tag-20250224-1 */
30436
+ char *zErr = 0;
30437
+ if( i+1>=nArg ){
30438
+ dotCmdError(p, i, "missing argument", 0);
30439
+ return 1;
30440
+ }
30441
+ i++; /* 0 1 2 <-- One less than QRF_ESC_ */
30442
+ k = pickStr(azArg[i],&zErr,"off","ascii","symbol","");
30443
+ if( k<0 ){
30444
+ dotCmdError(p, i, "unknown escape type", "%s", zErr);
30445
+ sqlite3_free(zErr);
30446
+ return 1;
30447
+ }
30448
+ p->mode.spec.eEsc = k+1;
30449
+ chng = 1;
30450
+ }else if( optionMatch(z,"list") ){
30451
+ int ii;
30452
+ cli_puts("available modes:", p->out);
30453
+ for(ii=0; ii<ArraySize(aModeInfo); ii++){
30454
+ if( ii==MODE_Www ) continue;
30455
+ cli_printf(p->out, " %s", aModeInfo[ii].zName);
30456
+ }
30457
+ for(ii=0; ii<p->nSavedModes; ii++){
30458
+ cli_printf(p->out, " %s", p->aSavedModes[ii].zTag);
30459
+ }
30460
+ cli_puts(" batch tty\n", p->out);
30461
+ }else if( optionMatch(z,"quote") ){
30462
+ if( i+1<nArg
30463
+ && azArg[i+1][0]!='-'
30464
+ && (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0)
30465
+ ){
30466
+ /* --quote is followed by an argument other that is not an option
30467
+ ** or a mode name. See it must be a boolean or a keyword to describe
30468
+ ** how to set quoting. */
30469
+ i++;
30470
+ if( (k = pickStr(azArg[i],0,"no","yes","0","1",""))>=0 ){
30471
+ k &= 1; /* 0 for "off". 1 for "on". */
30472
+ }else{
30473
+ char *zErr = 0; /* 0 1 2 3 4 5 6 */
30474
+ k = pickStr(azArg[i],&zErr,"off","on","sql","csv","html","tcl","json",
30475
+ "");
30476
+ if( k<0 ){
30477
+ dotCmdError(p, i, "unknown", "%z", zErr);
30478
+ return 1;
30479
+ }
30480
+ }
30481
+ }else{
30482
+ /* (Legacy) no following boolean argument. Turn quoting on */
30483
+ k = 1;
30484
+ }
30485
+ switch( k ){
30486
+ case 1: /* on */
30487
+ case 2: /* sql */
30488
+ p->mode.spec.eText = QRF_TEXT_Sql;
30489
+ p->mode.spec.eBlob = QRF_BLOB_Sql;
30490
+ break;
30491
+ case 3: /* csv */
30492
+ p->mode.spec.eText = QRF_TEXT_Csv;
30493
+ p->mode.spec.eBlob = QRF_BLOB_Text;
30494
+ break;
30495
+ case 4: /* html */
30496
+ p->mode.spec.eText = QRF_TEXT_Html;
30497
+ p->mode.spec.eBlob = QRF_BLOB_Text;
30498
+ break;
30499
+ case 5: /* tcl */
30500
+ p->mode.spec.eText = QRF_TEXT_Tcl;
30501
+ p->mode.spec.eBlob = QRF_BLOB_Text;
30502
+ break;
30503
+ case 6: /* json */
30504
+ p->mode.spec.eText = QRF_TEXT_Json;
30505
+ p->mode.spec.eBlob = QRF_BLOB_Json;
30506
+ break;
30507
+ default: /* off */
30508
+ p->mode.spec.eText = QRF_TEXT_Plain;
30509
+ p->mode.spec.eBlob = QRF_BLOB_Text;
30510
+ break;
30511
+ }
30512
+ chng = 1;
30513
+ }else if( optionMatch(z,"once") ){
30514
+ p->nPopMode = 0;
30515
+ modePush(p);
30516
+ p->nPopMode = 1;
30517
+ }else if( optionMatch(z,"noquote") ){
30518
+ /* (undocumented legacy) --noquote always turns quoting off */
30519
+ p->mode.spec.eText = QRF_TEXT_Plain;
30520
+ p->mode.spec.eBlob = QRF_BLOB_Text;
30521
+ chng = 1;
30522
+ }else if( optionMatch(z,"reset") ){
30523
+ int saved_eMode = p->mode.eMode;
30524
+ modeFree(&p->mode);
30525
+ modeChange(p, saved_eMode);
30526
+ }else if( optionMatch(z,"screenwidth") ){
30527
+ if( i+1>=nArg ){
30528
+ dotCmdError(p, i, "missing argument", 0);
30529
+ return 1;
30530
+ }
30531
+ k = pickStr(azArg[i+1],0,"off","auto","");
30532
+ if( k==0 ){
30533
+ p->mode.bAutoScreenWidth = 0;
30534
+ p->mode.spec.nScreenWidth = 0;
30535
+ }else if( k==1 ){
30536
+ p->mode.bAutoScreenWidth = 1;
30537
+ }else{
30538
+ i64 w = integerValue(azArg[i+1]);
30539
+ p->mode.bAutoScreenWidth = 0;
30540
+ if( w<0 ) w = 0;
30541
+ if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30542
+ p->mode.spec.nScreenWidth = w;
30543
+ }
30544
+ i++;
30545
+ chng = 1;
30546
+ }else if( optionMatch(z,"tag") ){
30547
+ size_t nByte;
30548
+ int n;
30549
+ const char *zTag;
30550
+ if( i+1>=nArg ){
30551
+ dotCmdError(p, i, "missing argument", 0);
30552
+ return 1;
30553
+ }
30554
+ zTag = azArg[++i];
30555
+ if( modeFind(p, zTag)>=0 ){
30556
+ dotCmdError(p, i, "mode already exists", 0);
30557
+ return 1;
30558
+ }
30559
+ if( p->nSavedModes > MODE_N_USER ){
30560
+ dotCmdError(p, i-1, "cannot add more modes", 0);
30561
+ return 1;
30562
+ }
30563
+ n = p->nSavedModes++;
30564
+ nByte = sizeof(p->aSavedModes[0]);
30565
+ nByte *= n+1;
30566
+ p->aSavedModes = realloc( p->aSavedModes, nByte );
30567
+ shell_check_oom(p->aSavedModes);
30568
+ p->aSavedModes[n].zTag = strdup(zTag);
30569
+ shell_check_oom(p->aSavedModes[n].zTag);
30570
+ modeDup(&p->aSavedModes[n].mode, &p->mode);
30571
+ chng = 1;
30572
+ }else if( optionMatch(z,"textjsonb") ){
30573
+ if( i+1>=nArg ){
30574
+ dotCmdError(p, i, "missing argument", 0);
30575
+ return 1;
30576
+ }
30577
+ p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
30578
+ chng = 1;
30579
+ }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
30580
+ char *zErr = 0;
30581
+ if( i+1>=nArg ){
30582
+ dotCmdError(p, i, "missing argument", 0);
30583
+ return 1;
30584
+ }
30585
+ k = pickStr(azArg[++i],&zErr,
30586
+ "off","on","plain","sql","csv","html","tcl","json","");
30587
+ /* 0 1 2 3 4 5 6 7 */
30588
+ if( k<0 ){
30589
+ dotCmdError(p, i, "bad --titles value","%z", zErr);
30590
+ return 1;
30591
+ }
30592
+ p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
30593
+ p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
30594
+ chng = 1;
30595
+ }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
30596
+ int nWidth = 0;
30597
+ short int *aWidth;
30598
+ const char *zW;
30599
+ if( i+1>=nArg ){
30600
+ dotCmdError(p, i, "missing argument", 0);
30601
+ return 1;
30602
+ }
30603
+ zW = azArg[++i];
30604
+ /* Every width value takes at least 2 bytes in the input string to
30605
+ ** specify, so strlen(zW) bytes should be plenty of space to hold the
30606
+ ** result. */
30607
+ aWidth = malloc( strlen(zW) );
30608
+ while( isspace(zW[0]) ) zW++;
30609
+ while( zW[0] ){
30610
+ int w = 0;
30611
+ int nDigit = 0;
30612
+ k = zW[0]=='-' && isdigit(zW[1]);
30613
+ while( isdigit(zW[k]) ){
30614
+ w = w*10 + zW[k] - '0';
30615
+ if( w>QRF_MAX_WIDTH ){
30616
+ dotCmdError(p,i+1,"width too big",
30617
+ "Maximum column width is %d", QRF_MAX_WIDTH);
30618
+ free(aWidth);
30619
+ return 1;
30620
+ }
30621
+ nDigit++;
30622
+ k++;
30623
+ }
30624
+ if( nDigit==0 ){
30625
+ dotCmdError(p,i+1,"syntax error",
30626
+ "should be a comma-separated list if integers");
30627
+ free(aWidth);
30628
+ return 1;
30629
+ }
30630
+ if( zW[0]=='-' ) w = -w;
30631
+ aWidth[nWidth++] = w;
30632
+ zW += k;
30633
+ if( zW[0]==',' ) zW++;
30634
+ while( isspace(zW[0]) ) zW++;
30635
+ }
30636
+ free(p->mode.spec.aWidth);
30637
+ p->mode.spec.aWidth = aWidth;
30638
+ p->mode.spec.nWidth = nWidth;
30639
+ chng = 1;
30640
+ }else if( optionMatch(z,"wrap") ){
30641
+ int w;
30642
+ if( i+1>=nArg ){
30643
+ dotCmdError(p, i, "missing argument", 0);
30644
+ return 1;
30645
+ }
30646
+ w = integerValue(azArg[++i]);
30647
+ if( w<(-QRF_MAX_WIDTH) ) w = -QRF_MAX_WIDTH;
30648
+ if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30649
+ p->mode.spec.nWrap = w;
30650
+ chng = 1;
30651
+ }else if( optionMatch(z,"ww") ){
30652
+ p->mode.spec.bWordWrap = QRF_Yes;
30653
+ chng = 1;
30654
+ }else if( optionMatch(z,"wordwrap") ){
30655
+ if( i+1>=nArg ){
30656
+ dotCmdError(p, i, "missing argument", 0);
30657
+ return 1;
30658
+ }
30659
+ p->mode.spec.bWordWrap = (u8)booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
30660
+ chng = 1;
30661
+ }else if( optionMatch(z,"v") || optionMatch(z,"verbose") ){
30662
+ bAll = 1;
30663
+ }else if( z[0]=='-' ){
30664
+ dotCmdError(p, i, "bad option", "Use \".help .mode\" for more info");
30665
+ return 1;
30666
+ }else{
30667
+ dotCmdError(p, i, iMode>0?"bad argument":"unknown mode",
30668
+ "Use \".help .mode\" for more info");
30669
+ return 1;
30670
+ }
30671
+ }
30672
+ if( !chng || bAll ){
30673
+ const ModeInfo *pI = aModeInfo + p->mode.eMode;
30674
+ sqlite3_str *pDesc = sqlite3_str_new(p->db);
30675
+ char *zDesc;
30676
+ const char *zSetting;
30677
+
30678
+ if( p->nPopMode ) sqlite3_str_appendall(pDesc, "--once ");
30679
+ sqlite3_str_appendall(pDesc,pI->zName);
30680
+ if( bAll || (p->mode.spec.nAlign && pI->eCx==2) ){
30681
+ int ii;
30682
+ sqlite3_str_appendall(pDesc, " --align \"");
30683
+ for(ii=0; ii<p->mode.spec.nAlign; ii++){
30684
+ unsigned char a = p->mode.spec.aAlign[ii];
30685
+ sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]);
30686
+ }
30687
+ sqlite3_str_append(pDesc, "\"", 1);
30688
+ }
30689
+ if( bAll || p->mode.spec.nCharLimit>0 ){
30690
+ sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit);
30691
+ }
30692
+ zSetting = aModeStr[pI->eCSep];
30693
+ if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){
30694
+ sqlite3_str_appendf(pDesc, " --colsep ");
30695
+ append_c_string(pDesc, p->mode.spec.zColumnSep);
30696
+ }
30697
+ if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
30698
+ sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
30699
+ }
30700
+ if( bAll || (p->mode.spec.nLineLimit>0 && pI->eCx>0) ){
30701
+ sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit);
30702
+ }
30703
+ zSetting = aModeStr[pI->eNull];
30704
+ if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){
30705
+ sqlite3_str_appendf(pDesc, " --null ");
30706
+ append_c_string(pDesc, p->mode.spec.zNull);
30707
+ }
30708
+ if( bAll
30709
+ || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
30710
+ ){
30711
+ sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
30712
+ }
30713
+ zSetting = aModeStr[pI->eRSep];
30714
+ if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
30715
+ sqlite3_str_appendf(pDesc, " --rowsep ");
30716
+ append_c_string(pDesc, p->mode.spec.zRowSep);
30717
+ }
30718
+ if( bAll
30719
+ || (pI->eCx && (p->mode.spec.nScreenWidth>0 || p->mode.bAutoScreenWidth))
30720
+ ){
30721
+ if( p->mode.bAutoScreenWidth ){
30722
+ sqlite3_str_appendall(pDesc, " --screenwidth auto");
30723
+ }else{
30724
+ sqlite3_str_appendf(pDesc," --screenwidth %d",
30725
+ p->mode.spec.nScreenWidth);
30726
+ }
30727
+ }
30728
+ if( bAll || p->mode.eMode==MODE_Insert ){
30729
+ sqlite3_str_appendf(pDesc," --tablename ");
30730
+ append_c_string(pDesc, p->mode.spec.zTableName);
30731
+ }
30732
+ if( bAll || p->mode.spec.bTextJsonb ){
30733
+ sqlite3_str_appendf(pDesc," --textjsonb %s",
30734
+ p->mode.spec.bTextJsonb==QRF_Yes ? "on" : "off");
30735
+ }
30736
+ k = modeTitleDsply(p, bAll);
30737
+ if( k==1 ){
30738
+ sqlite3_str_appendall(pDesc, " --titles off");
30739
+ }else if( k==2 ){
30740
+ sqlite3_str_appendall(pDesc, " --titles on");
30741
+ }else if( k==3 ){
30742
+ static const char *azTitle[] =
30743
+ { "plain", "sql", "csv", "html", "tcl", "json"};
30744
+ sqlite3_str_appendf(pDesc, " --titles %s",
30745
+ azTitle[p->mode.spec.eTitle-1]);
30746
+ }
30747
+ if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
30748
+ int ii;
30749
+ const char *zSep = " --widths ";
30750
+ for(ii=0; ii<p->mode.spec.nWidth; ii++){
30751
+ sqlite3_str_appendf(pDesc, "%s%d", zSep, (int)p->mode.spec.aWidth[ii]);
30752
+ zSep = ",";
30753
+ }
30754
+ }else if( bAll ){
30755
+ sqlite3_str_appendall(pDesc, " --widths \"\"");
30756
+ }
30757
+ if( bAll || (pI->eCx>0 && p->mode.spec.bWordWrap) ){
30758
+ if( bAll ){
30759
+ sqlite3_str_appendf(pDesc, " --wordwrap %s",
30760
+ p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off");
30761
+ }
30762
+ if( p->mode.spec.nWrap ){
30763
+ sqlite3_str_appendf(pDesc, " --wrap %d", p->mode.spec.nWrap);
30764
+ }
30765
+ if( !bAll ) sqlite3_str_append(pDesc, " --ww", 5);
30766
+ }
30767
+ zDesc = sqlite3_str_finish(pDesc);
30768
+ cli_printf(p->out, "current output mode: %s\n", zDesc);
30769
+ fflush(p->out);
30770
+ sqlite3_free(zDesc);
30771
+ }
30772
+ return 0;
30773
+}
30774
+
30775
+/*
30776
+** DOT-COMMAND: .output
30777
+** USAGE: .output [OPTIONS] [FILE]
30778
+**
30779
+** Begin redirecting output to FILE. Or if FILE is omitted, revert
30780
+** to sending output to the console. If FILE begins with "|" then
30781
+** the remainder of file is taken as a pipe and output is directed
30782
+** into that pipe. If FILE is "memory" then output is captured in an
30783
+** internal memory buffer. If FILE is "off" then output is redirected
30784
+** into /dev/null or the equivalent.
30785
+**
30786
+** Options:
30787
+** --bom Prepend a byte-order mark to the output
30788
+** -e Accumulate output in a temporary text file then
30789
+** launch a text editor when the redirection ends.
30790
+** --error-prefix X Use X as the left-margin prefix for error messages.
30791
+** Set to an empty string to restore the default.
30792
+** --glob GLOB Raise an error if the memory buffer does not match
30793
+** the GLOB pattern.
30794
+** --keep Continue using the same "memory" buffer. Do not
30795
+** reset it or delete it. Useful in combination with
30796
+** --glob, --not-glob, and/or --verify.
30797
+** ---notglob GLOB Raise an error if the memory buffer does not match
30798
+** the GLOB pattern.
30799
+** --plain Use plain text rather than HTML tables with -w
30800
+** --show Write the memory buffer to the screen, for debugging.
30801
+** --verify ENDMARK Read subsequent lines of text until the first line
30802
+** that matches ENDMARK. Discard the ENDMARK. Compare
30803
+** the text against the accumulated output in memory and
30804
+** raise an error if there are any differences.
30805
+** -w Show the output in a web browser. Output is
30806
+** written into a temporary HTML file until the
30807
+** redirect ends, then the web browser is launched.
30808
+** Query results are shown as HTML tables, unless
30809
+** the --plain is used too.
30810
+** -x Show the output in a spreadsheet. Output is
30811
+** written to a temp file as CSV then the spreadsheet
30812
+** is launched when
30813
+**
30814
+** DOT-COMMAND: .once
30815
+** USAGE: .once [OPTIONS] FILE ...
30816
+**
30817
+** Write the output for the next line of SQL or the next dot-command into
30818
+** FILE. If FILE begins with "|" then it is a program into which output
30819
+** is written. The FILE argument should be omitted if one of the -e, -w,
30820
+** or -x options is used.
30821
+**
30822
+** Options:
30823
+** -e Capture output into a temporary file then bring up
30824
+** a text editor on that temporary file.
30825
+** --plain Use plain text rather than HTML tables with -w
30826
+** -w Capture output into an HTML file then bring up that
30827
+** file in a web browser
30828
+** -x Show the output in a spreadsheet. Output is
30829
+** written to a temp file as CSV then the spreadsheet
30830
+** is launched when
30831
+**
30832
+** DOT-COMMAND: .excel
30833
+** Shorthand for ".once -x"
30834
+**
30835
+** DOT-COMMAND: .www [--plain]
30836
+** Shorthand for ".once -w" or ".once --plain -w"
30837
+*/
30838
+static int dotCmdOutput(ShellState *p){
30839
+ int nArg = p->dot.nArg; /* Number of arguments */
30840
+ char **azArg = p->dot.azArg; /* Text of the arguments */
30841
+ char *zFile = 0; /* The FILE argument */
30842
+ int i; /* Loop counter */
30843
+ int eMode = 0; /* 0: .outout/.once, 'x'=.excel, 'w'=.www */
30844
+ int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */
30845
+ int bPlain = 0; /* --plain option */
30846
+ int bKeep = 0; /* --keep option */
30847
+ char *zCheck = 0; /* Argument to --glob, --notglob, --verify */
30848
+ int eCheck = 0; /* 1: --glob, 2: --notglob, 3: --verify */
30849
+ static const char *zBomUtf8 = "\357\273\277";
30850
+ const char *zBom = 0;
30851
+ char c = azArg[0][0];
30852
+ int n = strlen30(azArg[0]);
30853
+
30854
+ failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
30855
+ if( c=='e' ){
30856
+ eMode = 'x';
30857
+ bOnce = 2;
30858
+ }else if( c=='w' ){
30859
+ eMode = 'w';
30860
+ bOnce = 2;
30861
+ }else if( n>=2 && cli_strncmp(azArg[0],"once",n)==0 ){
30862
+ bOnce = 1;
30863
+ }
30864
+ for(i=1; i<nArg; i++){
30865
+ char *z = azArg[i];
30866
+ if( z[0]=='-' ){
30867
+ if( z[1]=='-' ) z++;
30868
+ if( cli_strcmp(z,"-bom")==0 ){
30869
+ zBom = zBomUtf8;
30870
+ }else if( cli_strcmp(z,"-plain")==0 ){
30871
+ bPlain = 1;
30872
+ }else if( c=='o' && z[0]=='1' && z[1]!=0 && z[2]==0
30873
+ && (z[1]=='x' || z[1]=='e' || z[1]=='w') ){
30874
+ if( bKeep || eMode || eCheck ){
30875
+ dotCmdError(p, i, "incompatible with prior options",0);
30876
+ goto dotCmdOutput_error;
30877
+ }
30878
+ eMode = z[1];
30879
+ }else if( cli_strcmp(z,"-keep")==0 ){
30880
+ bKeep = 1;
30881
+ }else if( cli_strcmp(z,"-show")==0 ){
30882
+ if( cli_output_capture ){
30883
+ sqlite3_fprintf(stdout, "%s", sqlite3_str_value(cli_output_capture));
30884
+ }
30885
+ bKeep = 1;
30886
+ }else if( cli_strcmp(z,"-glob")==0
30887
+ || cli_strcmp(z,"-notglob")==0
30888
+ || cli_strcmp(z,"-verify")==0
30889
+ ){
30890
+ if( eCheck || eMode ){
30891
+ dotCmdError(p, i, "incompatible with prior options",0);
30892
+ goto dotCmdOutput_error;
30893
+ }
30894
+ if( i+1>=nArg ){
30895
+ dotCmdError(p, i, "missing argument", 0);
30896
+ goto dotCmdOutput_error;
30897
+ }
30898
+ zCheck = azArg[++i];
30899
+ eCheck = z[1]=='g' ? 1 : z[1]=='n' ? 2 : 3;
30900
+ }else if( optionMatch(z,"error-prefix") ){
30901
+ if( i+1>=nArg ){
30902
+ dotCmdError(p, i, "missing argument", 0);
30903
+ return 1;
30904
+ }
30905
+ free(p->zErrPrefix);
30906
+ i++;
30907
+ p->zErrPrefix = azArg[i][0]==0 ? 0 : strdup(azArg[i]);
30908
+ }else{
30909
+ dotCmdError(p, i, "unknown option", 0);
30910
+ sqlite3_free(zFile);
30911
+ return 1;
30912
+ }
30913
+ }else if( zFile==0 && eMode==0 ){
30914
+ if( bKeep || eCheck ){
30915
+ dotCmdError(p, i, "incompatible with prior options",0);
30916
+ goto dotCmdOutput_error;
30917
+ }
30918
+ if( cli_strcmp(z, "memory")==0 && bOnce ){
30919
+ dotCmdError(p, 0, "cannot redirect to \"memory\"", 0);
30920
+ goto dotCmdOutput_error;
30921
+ }
30922
+ if( cli_strcmp(z, "off")==0 ){
30923
+#ifdef _WIN32
30924
+ zFile = sqlite3_mprintf("nul");
30925
+#else
30926
+ zFile = sqlite3_mprintf("/dev/null");
30927
+#endif
30928
+ }else{
30929
+ zFile = sqlite3_mprintf("%s", z);
30930
+ }
30931
+ if( zFile && zFile[0]=='|' ){
30932
+ while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
30933
+ break;
30934
+ }
30935
+ }else{
30936
+ dotCmdError(p, i, "surplus argument", 0);
30937
+ sqlite3_free(zFile);
30938
+ return 1;
30939
+ }
30940
+ }
30941
+ if( zFile==0 && !bKeep ){
30942
+ zFile = sqlite3_mprintf("stdout");
30943
+ shell_check_oom(zFile);
30944
+ }
30945
+ if( bOnce ){
30946
+ p->nPopOutput = 2;
30947
+ }else{
30948
+ p->nPopOutput = 0;
30949
+ }
30950
+ if( eCheck ){
30951
+ char *zTest;
30952
+ if( cli_output_capture ){
30953
+ zTest = sqlite3_str_value(cli_output_capture);
30954
+ }else{
30955
+ zTest = "";
30956
+ }
30957
+ p->nTestRun++;
30958
+ if( eCheck==3 ){
30959
+ int nCheck = strlen30(zCheck);
30960
+ sqlite3_str *pPattern = sqlite3_str_new(p->db);
30961
+ char *zPattern;
30962
+ sqlite3_int64 iStart = p->lineno;
30963
+ char zLine[2000];
30964
+ while( sqlite3_fgets(zLine,sizeof(zLine),p->in) ){
30965
+ if( strchr(zLine,'\n') ) p->lineno++;
30966
+ if( cli_strncmp(zCheck,zLine,nCheck)==0 ) break;
30967
+ sqlite3_str_appendall(pPattern, zLine);
30968
+ }
30969
+ zPattern = sqlite3_str_finish(pPattern);
30970
+ if( cli_strcmp(zPattern,zTest)!=0 ){
30971
+ sqlite3_fprintf(stderr,
30972
+ "%s:%lld: --verify does matches prior output\n",
30973
+ p->zInFile, iStart);
30974
+ p->nTestErr++;
30975
+ }
30976
+ sqlite3_free(zPattern);
30977
+ }else{
30978
+ char *zGlob = sqlite3_mprintf("*%s*", zCheck);
30979
+ if( eCheck==1 && sqlite3_strglob(zGlob, zTest)!=0 ){
30980
+ sqlite3_fprintf(stderr,
30981
+ "%s:%lld: --glob \"%s\" does not match prior output\n",
30982
+ p->zInFile, p->lineno, zCheck);
30983
+ p->nTestErr++;
30984
+ }else if( eCheck==2 && sqlite3_strglob(zGlob, zTest)==0 ){
30985
+ sqlite3_fprintf(stderr,
30986
+ "%s:%lld: --notglob \"%s\" matches prior output\n",
30987
+ p->zInFile, p->lineno, zCheck);
30988
+ p->nTestErr++;
30989
+ }
30990
+ sqlite3_free(zGlob);
30991
+ }
30992
+ }
30993
+ if( !bKeep ) output_reset(p);
30994
+#ifndef SQLITE_NOHAVE_SYSTEM
30995
+ if( eMode=='e' || eMode=='x' || eMode=='w' ){
30996
+ p->doXdgOpen = 1;
30997
+ modePush(p);
30998
+ if( eMode=='x' ){
30999
+ /* spreadsheet mode. Output as CSV. */
31000
+ newTempFile(p, "csv");
31001
+ p->mode.mFlags &= ~MFLG_ECHO;
31002
+ p->mode.eMode = MODE_Csv;
31003
+ modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
31004
+ modeSetStr(&p->mode.spec.zRowSep, SEP_CrLf);
31005
+#ifdef _WIN32
31006
+ zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does
31007
+ ** not work without it. */
31008
+#endif
31009
+ }else if( eMode=='w' ){
31010
+ /* web-browser mode. */
31011
+ newTempFile(p, "html");
31012
+ if( !bPlain ) p->mode.eMode = MODE_Www;
31013
+ }else{
31014
+ /* text editor mode */
31015
+ newTempFile(p, "txt");
31016
+ }
31017
+ sqlite3_free(zFile);
31018
+ zFile = sqlite3_mprintf("%s", p->zTempFile);
31019
+ }
31020
+#endif /* SQLITE_NOHAVE_SYSTEM */
31021
+ if( !bKeep ) shell_check_oom(zFile);
31022
+ if( bKeep ){
31023
+ /* no-op */
31024
+ }else if( cli_strcmp(zFile,"memory")==0 ){
31025
+ if( cli_output_capture ){
31026
+ sqlite3_str_free(cli_output_capture);
31027
+ }
31028
+ cli_output_capture = sqlite3_str_new(0);
31029
+ }else if( zFile[0]=='|' ){
31030
+#ifdef SQLITE_OMIT_POPEN
31031
+ eputz("Error: pipes are not supported in this OS\n");
31032
+ output_redir(p, stdout);
31033
+ goto dotCmdOutput_error;
31034
+#else
31035
+ FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
31036
+ if( pfPipe==0 ){
31037
+ assert( stderr!=NULL );
31038
+ cli_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
31039
+ goto dotCmdOutput_error;
31040
+ }else{
31041
+ output_redir(p, pfPipe);
31042
+ if( zBom ) cli_puts(zBom, pfPipe);
31043
+ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
31044
+ }
31045
+#endif
31046
+ }else{
31047
+ FILE *pfFile = output_file_open(p, zFile);
31048
+ if( pfFile==0 ){
31049
+ if( cli_strcmp(zFile,"off")!=0 ){
31050
+ assert( stderr!=NULL );
31051
+ cli_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
31052
+ }
31053
+ goto dotCmdOutput_error;
31054
+ } else {
31055
+ output_redir(p, pfFile);
31056
+ if( zBom ) cli_puts(zBom, pfFile);
31057
+ if( bPlain && eMode=='w' ){
31058
+ cli_puts(
31059
+ "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n",
31060
+ pfFile
31061
+ );
31062
+ }
31063
+ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
31064
+ }
31065
+ }
31066
+ sqlite3_free(zFile);
31067
+ return 0;
31068
+
31069
+dotCmdOutput_error:
31070
+ sqlite3_free(zFile);
31071
+ return 1;
31072
+}
31073
+/*
31074
+** Parse input line zLine up into individual arguments. Retain the
31075
+** parse in the p->dot substructure.
31076
+*/
31077
+static void parseDotRealloc(ShellState *p, int nArg){
31078
+ p->dot.nAlloc = nArg+22;
31079
+ p->dot.azArg = realloc(p->dot.azArg,p->dot.nAlloc*sizeof(char*));
31080
+ shell_check_oom(p->dot.azArg);
31081
+ p->dot.aiOfst = realloc(p->dot.aiOfst,p->dot.nAlloc*sizeof(int));
31082
+ shell_check_oom(p->dot.aiOfst);
31083
+ p->dot.abQuot = realloc(p->dot.abQuot,p->dot.nAlloc);
31084
+ shell_check_oom(p->dot.abQuot);
31085
+}
31086
+static void parseDotCmdArgs(const char *zLine, ShellState *p){
31087
+ char *z;
31088
+ int h = 1;
31089
+ int nArg = 0;
31090
+
31091
+ p->dot.zOrig = zLine;
31092
+ free(p->dot.zCopy);
31093
+ z = p->dot.zCopy = strdup(zLine);
31094
+ shell_check_oom(z);
31095
+ parseDotRealloc(p, 2);
31096
+ while( z[h] ){
31097
+ while( IsSpace(z[h]) ){ h++; }
31098
+ if( z[h]==0 ) break;
31099
+ if( nArg+2>p->dot.nAlloc ){
31100
+ parseDotRealloc(p, nArg);
31101
+ }
31102
+ if( z[h]=='\'' || z[h]=='"' ){
31103
+ int delim = z[h++];
31104
+ p->dot.abQuot[nArg] = 1;
31105
+ p->dot.azArg[nArg] = &z[h];
31106
+ p->dot.aiOfst[nArg] = h;
31107
+ while( z[h] && z[h]!=delim ){
31108
+ if( z[h]=='\\' && delim=='"' && z[h+1]!=0 ) h++;
31109
+ h++;
31110
+ }
31111
+ if( z[h]==delim ){
31112
+ z[h++] = 0;
31113
+ }
31114
+ if( delim=='"' ) resolve_backslashes(p->dot.azArg[nArg]);
31115
+ }else{
31116
+ p->dot.abQuot[nArg] = 0;
31117
+ p->dot.azArg[nArg] = &z[h];
31118
+ p->dot.aiOfst[nArg] = h;
31119
+ while( z[h] && !IsSpace(z[h]) ){ h++; }
31120
+ if( z[h] ) z[h++] = 0;
31121
+ }
31122
+ nArg++;
31123
+ }
31124
+ p->dot.nArg = nArg;
31125
+ p->dot.azArg[nArg] = 0;
31126
+}
2855031127
2855131128
/*
2855231129
** If an input line begins with "." then invoke this routine to
2855331130
** process that line.
2855431131
**
2855531132
** Return 1 on error, 2 to exit, and 0 otherwise.
2855631133
*/
28557
-static int do_meta_command(char *zLine, ShellState *p){
28558
- int h = 1;
28559
- int nArg = 0;
31134
+static int do_meta_command(const char *zLine, ShellState *p){
31135
+ int nArg;
2856031136
int n, c;
2856131137
int rc = 0;
28562
- char *azArg[52];
31138
+ char **azArg;
2856331139
2856431140
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2856531141
if( p->expert.pExpert ){
2856631142
expertFinish(p, 1, 0);
2856731143
}
2856831144
#endif
2856931145
28570
- /* Parse the input line into tokens.
31146
+ /* Parse the input line into tokens stored in p->dot.
2857131147
*/
28572
- while( zLine[h] && nArg<ArraySize(azArg)-1 ){
28573
- while( IsSpace(zLine[h]) ){ h++; }
28574
- if( zLine[h]==0 ) break;
28575
- if( zLine[h]=='\'' || zLine[h]=='"' ){
28576
- int delim = zLine[h++];
28577
- azArg[nArg++] = &zLine[h];
28578
- while( zLine[h] && zLine[h]!=delim ){
28579
- if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
28580
- h++;
28581
- }
28582
- if( zLine[h]==delim ){
28583
- zLine[h++] = 0;
28584
- }
28585
- if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
28586
- }else{
28587
- azArg[nArg++] = &zLine[h];
28588
- while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
28589
- if( zLine[h] ) zLine[h++] = 0;
28590
- }
28591
- }
28592
- azArg[nArg] = 0;
31148
+ parseDotCmdArgs(zLine, p);
31149
+ nArg = p->dot.nArg;
31150
+ azArg = p->dot.azArg;
2859331151
2859431152
/* Process the input line.
2859531153
*/
2859631154
if( nArg==0 ) return 0; /* no tokens, no error */
2859731155
n = strlen30(azArg[0]);
@@ -28599,11 +31157,11 @@
2859931157
clearTempFile(p);
2860031158
2860131159
#ifndef SQLITE_OMIT_AUTHORIZATION
2860231160
if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
2860331161
if( nArg!=2 ){
28604
- sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n");
31162
+ cli_printf(stderr, "Usage: .auth ON|OFF\n");
2860531163
rc = 1;
2860631164
goto meta_command_exit;
2860731165
}
2860831166
open_db(p, 0);
2860931167
if( booleanValue(azArg[1]) ){
@@ -28646,32 +31204,32 @@
2864631204
}else
2864731205
if( cli_strcmp(z, "-async")==0 ){
2864831206
bAsync = 1;
2864931207
}else
2865031208
{
28651
- sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]);
31209
+ dotCmdError(p, j, "unknown option", "should be -append or -async");
2865231210
return 1;
2865331211
}
2865431212
}else if( zDestFile==0 ){
2865531213
zDestFile = azArg[j];
2865631214
}else if( zDb==0 ){
2865731215
zDb = zDestFile;
2865831216
zDestFile = azArg[j];
2865931217
}else{
28660
- sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
31218
+ cli_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
2866131219
return 1;
2866231220
}
2866331221
}
2866431222
if( zDestFile==0 ){
28665
- sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n");
31223
+ cli_printf(stderr, "missing FILENAME argument on .backup\n");
2866631224
return 1;
2866731225
}
2866831226
if( zDb==0 ) zDb = "main";
2866931227
rc = sqlite3_open_v2(zDestFile, &pDest,
2867031228
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
2867131229
if( rc!=SQLITE_OK ){
28672
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile);
31230
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", zDestFile);
2867331231
close_db(pDest);
2867431232
return 1;
2867531233
}
2867631234
if( bAsync ){
2867731235
sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
@@ -28728,11 +31286,11 @@
2872831286
sqlite3_free(z);
2872931287
#else
2873031288
rc = chdir(azArg[1]);
2873131289
#endif
2873231290
if( rc ){
28733
- sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]);
31291
+ cli_printf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]);
2873431292
rc = 1;
2873531293
}
2873631294
}else{
2873731295
eputz("Usage: .cd DIRECTORY\n");
2873831296
rc = 1;
@@ -28761,16 +31319,16 @@
2876131319
eputz("Usage: .check GLOB-PATTERN\n");
2876231320
rc = 2;
2876331321
}else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
2876431322
rc = 2;
2876531323
}else if( testcase_glob(azArg[1],zRes)==0 ){
28766
- sqlite3_fprintf(stderr,
31324
+ cli_printf(stderr,
2876731325
"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
2876831326
p->zTestcase, azArg[1], zRes);
2876931327
rc = 1;
2877031328
}else{
28771
- sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase);
31329
+ cli_printf(p->out, "testcase-%s ok\n", p->zTestcase);
2877231330
p->nCheck++;
2877331331
}
2877431332
sqlite3_free(zRes);
2877531333
}else
2877631334
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28799,13 +31357,13 @@
2879931357
zFile = "(memory)";
2880031358
}else if( zFile[0]==0 ){
2880131359
zFile = "(temporary-file)";
2880231360
}
2880331361
if( p->pAuxDb == &p->aAuxDb[i] ){
28804
- sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile);
31362
+ cli_printf(stdout, "ACTIVE %d: %s\n", i, zFile);
2880531363
}else if( p->aAuxDb[i].db!=0 ){
28806
- sqlite3_fprintf(stdout, " %d: %s\n", i, zFile);
31364
+ cli_printf(stdout, " %d: %s\n", i, zFile);
2880731365
}
2880831366
}
2880931367
}else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){
2881031368
int i = azArg[1][0] - '0';
2881131369
if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){
@@ -28837,16 +31395,21 @@
2883731395
&& (cli_strncmp(azArg[0], "crlf", n)==0
2883831396
|| cli_strncmp(azArg[0], "crnl",n)==0)
2883931397
){
2884031398
if( nArg==2 ){
2884131399
#ifdef _WIN32
28842
- p->crlfMode = booleanValue(azArg[1]);
31400
+ if( booleanValue(azArg[1]) ){
31401
+ p->mode.mFlags |= MFLG_CRLF;
31402
+ }else{
31403
+ p->mode.mFlags &= ~MFLG_CRLF;
31404
+ }
2884331405
#else
28844
- p->crlfMode = 0;
31406
+ p->mode.mFlags &= ~MFLG_CRLF;
2884531407
#endif
2884631408
}
28847
- sqlite3_fprintf(stderr, "crlf is %s\n", p->crlfMode ? "ON" : "OFF");
31409
+ cli_printf(stderr, "crlf is %s\n",
31410
+ (p->mode.mFlags & MFLG_CRLF)!=0 ? "ON" : "OFF");
2884831411
}else
2884931412
2885031413
if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
2885131414
char **azName = 0;
2885231415
int nName = 0;
@@ -28872,11 +31435,11 @@
2887231435
sqlite3_finalize(pStmt);
2887331436
for(i=0; i<nName; i++){
2887431437
int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
2887531438
int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
2887631439
const char *z = azName[i*2+1];
28877
- sqlite3_fprintf(p->out, "%s: %s %s%s\n",
31440
+ cli_printf(p->out, "%s: %s %s%s\n",
2887831441
azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w",
2887931442
eTxn==SQLITE_TXN_NONE ? "" :
2888031443
eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
2888131444
free(azName[i*2]);
2888231445
free(azName[i*2+1]);
@@ -28917,17 +31480,17 @@
2891731480
if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
2891831481
if( nArg>=3 ){
2891931482
sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
2892031483
}
2892131484
sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
28922
- sqlite3_fprintf(p->out, "%19s %s\n",
31485
+ cli_printf(p->out, "%19s %s\n",
2892331486
aDbConfig[ii].zName, v ? "on" : "off");
2892431487
if( nArg>1 ) break;
2892531488
}
2892631489
if( nArg>1 && ii==ArraySize(aDbConfig) ){
28927
- sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]);
28928
- eputz("Enter \".dbconfig\" with no arguments for a list\n");
31490
+ dotCmdError(p, 1, "unknown dbconfig",
31491
+ "Enter \".dbconfig\" with no arguments for a list");
2892931492
}
2893031493
}else
2893131494
2893231495
#if SQLITE_SHELL_HAVE_RECOVER
2893331496
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
@@ -28942,42 +31505,41 @@
2894231505
2894331506
if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
2894431507
char *zLike = 0;
2894531508
char *zSql;
2894631509
int i;
28947
- int savedShowHeader = p->showHeader;
2894831510
int savedShellFlags = p->shellFlgs;
31511
+ Mode saved_mode;
2894931512
ShellClearFlag(p,
28950
- SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
28951
- |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
31513
+ SHFLG_PreserveRowid|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
2895231514
for(i=1; i<nArg; i++){
2895331515
if( azArg[i][0]=='-' ){
2895431516
const char *z = azArg[i]+1;
2895531517
if( z[0]=='-' ) z++;
2895631518
if( cli_strcmp(z,"preserve-rowids")==0 ){
2895731519
#ifdef SQLITE_OMIT_VIRTUALTABLE
28958
- eputz("The --preserve-rowids option is not compatible"
28959
- " with SQLITE_OMIT_VIRTUALTABLE\n");
31520
+ dotCmdError(p, i, "unable",
31521
+ "The --preserve-rowids option is not compatible"
31522
+ " with SQLITE_OMIT_VIRTUALTABLE");
2896031523
rc = 1;
2896131524
sqlite3_free(zLike);
2896231525
goto meta_command_exit;
2896331526
#else
2896431527
ShellSetFlag(p, SHFLG_PreserveRowid);
2896531528
#endif
2896631529
}else
2896731530
if( cli_strcmp(z,"newlines")==0 ){
28968
- ShellSetFlag(p, SHFLG_Newlines);
31531
+ /*ShellSetFlag(p, SHFLG_Newlines);*/
2896931532
}else
2897031533
if( cli_strcmp(z,"data-only")==0 ){
2897131534
ShellSetFlag(p, SHFLG_DumpDataOnly);
2897231535
}else
2897331536
if( cli_strcmp(z,"nosys")==0 ){
2897431537
ShellSetFlag(p, SHFLG_DumpNoSys);
2897531538
}else
2897631539
{
28977
- sqlite3_fprintf(stderr,
28978
- "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
31540
+ dotCmdError(p, i, "unknown option", 0);
2897931541
rc = 1;
2898031542
sqlite3_free(zLike);
2898131543
goto meta_command_exit;
2898231544
}
2898331545
}else{
@@ -29003,20 +31565,21 @@
2900331565
}
2900431566
}
2900531567
2900631568
open_db(p, 0);
2900731569
31570
+ modeDup(&saved_mode, &p->mode);
2900831571
outputDumpWarning(p, zLike);
2900931572
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
2901031573
/* When playing back a "dump", the content might appear in an order
2901131574
** which causes immediate foreign key constraints to be violated.
2901231575
** So disable foreign-key constraint enforcement to prevent problems. */
29013
- sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out);
29014
- sqlite3_fputs("BEGIN TRANSACTION;\n", p->out);
31576
+ cli_puts("PRAGMA foreign_keys=OFF;\n", p->out);
31577
+ cli_puts("BEGIN TRANSACTION;\n", p->out);
2901531578
}
2901631579
p->writableSchema = 0;
29017
- p->showHeader = 0;
31580
+ p->mode.spec.bTitles = QRF_No;
2901831581
/* Set writable_schema=ON since doing so forces SQLite to initialize
2901931582
** as much of the schema as it can even if the sqlite_schema table is
2902031583
** corrupt. */
2902131584
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
2902231585
p->nErr = 0;
@@ -29041,25 +31604,31 @@
2904131604
run_table_dump_query(p, zSql);
2904231605
sqlite3_free(zSql);
2904331606
}
2904431607
sqlite3_free(zLike);
2904531608
if( p->writableSchema ){
29046
- sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out);
31609
+ cli_puts("PRAGMA writable_schema=OFF;\n", p->out);
2904731610
p->writableSchema = 0;
2904831611
}
2904931612
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2905031613
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
2905131614
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
29052
- sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out);
31615
+ cli_puts(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out);
2905331616
}
29054
- p->showHeader = savedShowHeader;
2905531617
p->shellFlgs = savedShellFlags;
31618
+ modeFree(&p->mode);
31619
+ p->mode = saved_mode;
31620
+ rc = p->nErr>0;
2905631621
}else
2905731622
2905831623
if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
2905931624
if( nArg==2 ){
29060
- setOrClearFlag(p, SHFLG_Echo, azArg[1]);
31625
+ if( booleanValue(azArg[1]) ){
31626
+ p->mode.mFlags |= MFLG_ECHO;
31627
+ }else{
31628
+ p->mode.mFlags &= ~MFLG_ECHO;
31629
+ }
2906131630
}else{
2906231631
eputz("Usage: .echo on|off\n");
2906331632
rc = 1;
2906431633
}
2906531634
}else
@@ -29069,74 +31638,58 @@
2906931638
rc = shell_dbtotxt_command(p, nArg, azArg);
2907031639
}else
2907131640
2907231641
if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
2907331642
if( nArg==2 ){
29074
- p->autoEQPtest = 0;
29075
- if( p->autoEQPtrace ){
31643
+ if( p->mode.autoEQPtrace ){
2907631644
if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
29077
- p->autoEQPtrace = 0;
31645
+ p->mode.autoEQPtrace = 0;
2907831646
}
2907931647
if( cli_strcmp(azArg[1],"full")==0 ){
29080
- p->autoEQP = AUTOEQP_full;
31648
+ p->mode.autoEQP = AUTOEQP_full;
2908131649
}else if( cli_strcmp(azArg[1],"trigger")==0 ){
29082
- p->autoEQP = AUTOEQP_trigger;
31650
+ p->mode.autoEQP = AUTOEQP_trigger;
2908331651
#ifdef SQLITE_DEBUG
29084
- }else if( cli_strcmp(azArg[1],"test")==0 ){
29085
- p->autoEQP = AUTOEQP_on;
29086
- p->autoEQPtest = 1;
2908731652
}else if( cli_strcmp(azArg[1],"trace")==0 ){
29088
- p->autoEQP = AUTOEQP_full;
29089
- p->autoEQPtrace = 1;
31653
+ p->mode.autoEQP = AUTOEQP_full;
31654
+ p->mode.autoEQPtrace = 1;
2909031655
open_db(p, 0);
2909131656
sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
2909231657
sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
2909331658
#endif
2909431659
}else{
29095
- p->autoEQP = (u8)booleanValue(azArg[1]);
31660
+ p->mode.autoEQP = (u8)booleanValue(azArg[1]);
2909631661
}
2909731662
}else{
2909831663
eputz("Usage: .eqp off|on|trace|trigger|full\n");
2909931664
rc = 1;
2910031665
}
2910131666
}else
2910231667
2910331668
#ifndef SQLITE_SHELL_FIDDLE
2910431669
if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
29105
- if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
31670
+ if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) cli_exit(rc);
2910631671
rc = 2;
2910731672
}else
2910831673
#endif
2910931674
2911031675
/* The ".explain" command is automatic now. It is largely pointless. It
2911131676
** retained purely for backwards compatibility */
2911231677
if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){
29113
- int val = 1;
2911431678
if( nArg>=2 ){
2911531679
if( cli_strcmp(azArg[1],"auto")==0 ){
29116
- val = 99;
31680
+ p->mode.autoExplain = 1;
2911731681
}else{
29118
- val = booleanValue(azArg[1]);
29119
- }
29120
- }
29121
- if( val==1 && p->mode!=MODE_Explain ){
29122
- p->normalMode = p->mode;
29123
- p->mode = MODE_Explain;
29124
- p->autoExplain = 0;
29125
- }else if( val==0 ){
29126
- if( p->mode==MODE_Explain ) p->mode = p->normalMode;
29127
- p->autoExplain = 0;
29128
- }else if( val==99 ){
29129
- if( p->mode==MODE_Explain ) p->mode = p->normalMode;
29130
- p->autoExplain = 1;
31682
+ p->mode.autoExplain = booleanValue(azArg[1]);
31683
+ }
2913131684
}
2913231685
}else
2913331686
2913431687
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2913531688
if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
2913631689
if( p->bSafeMode ){
29137
- sqlite3_fprintf(stderr,
31690
+ cli_printf(stderr,
2913831691
"Cannot run experimental commands such as \"%s\" in safe mode\n",
2913931692
azArg[0]);
2914031693
rc = 1;
2914131694
}else{
2914231695
open_db(p, 0);
@@ -29190,13 +31743,13 @@
2919031743
if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
2919131744
}
2919231745
2919331746
/* --help lists all file-controls */
2919431747
if( cli_strcmp(zCmd,"help")==0 ){
29195
- sqlite3_fputs("Available file-controls:\n", p->out);
31748
+ cli_puts("Available file-controls:\n", p->out);
2919631749
for(i=0; i<ArraySize(aCtrl); i++){
29197
- sqlite3_fprintf(p->out,
31750
+ cli_printf(p->out,
2919831751
" .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage);
2919931752
}
2920031753
rc = 1;
2920131754
goto meta_command_exit;
2920231755
}
@@ -29208,19 +31761,19 @@
2920831761
if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
2920931762
if( filectrl<0 ){
2921031763
filectrl = aCtrl[i].ctrlCode;
2921131764
iCtrl = i;
2921231765
}else{
29213
- sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n"
31766
+ cli_printf(stderr,"Error: ambiguous file-control: \"%s\"\n"
2921431767
"Use \".filectrl --help\" for help\n", zCmd);
2921531768
rc = 1;
2921631769
goto meta_command_exit;
2921731770
}
2921831771
}
2921931772
}
2922031773
if( filectrl<0 ){
29221
- sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n"
31774
+ cli_printf(stderr,"Error: unknown file-control: %s\n"
2922231775
"Use \".filectrl --help\" for help\n", zCmd);
2922331776
}else{
2922431777
switch(filectrl){
2922531778
case SQLITE_FCNTL_SIZE_LIMIT: {
2922631779
if( nArg!=2 && nArg!=3 ) break;
@@ -29260,11 +31813,11 @@
2926031813
case SQLITE_FCNTL_TEMPFILENAME: {
2926131814
char *z = 0;
2926231815
if( nArg!=2 ) break;
2926331816
sqlite3_file_control(p->db, zSchema, filectrl, &z);
2926431817
if( z ){
29265
- sqlite3_fprintf(p->out, "%s\n", z);
31818
+ cli_printf(p->out, "%s\n", z);
2926631819
sqlite3_free(z);
2926731820
}
2926831821
isOk = 2;
2926931822
break;
2927031823
}
@@ -29274,81 +31827,96 @@
2927431827
x = atoi(azArg[2]);
2927531828
sqlite3_file_control(p->db, zSchema, filectrl, &x);
2927631829
}
2927731830
x = -1;
2927831831
sqlite3_file_control(p->db, zSchema, filectrl, &x);
29279
- sqlite3_fprintf(p->out, "%d\n", x);
31832
+ cli_printf(p->out, "%d\n", x);
2928031833
isOk = 2;
2928131834
break;
2928231835
}
2928331836
}
2928431837
}
2928531838
if( isOk==0 && iCtrl>=0 ){
29286
- sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n",
31839
+ cli_printf(p->out, "Usage: .filectrl %s %s\n",
2928731840
zCmd, aCtrl[iCtrl].zUsage);
2928831841
rc = 1;
2928931842
}else if( isOk==1 ){
2929031843
char zBuf[100];
2929131844
sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
29292
- sqlite3_fprintf(p->out, "%s\n", zBuf);
31845
+ cli_printf(p->out, "%s\n", zBuf);
2929331846
}
2929431847
}else
2929531848
2929631849
if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){
2929731850
ShellState data;
2929831851
int doStats = 0;
29299
- memcpy(&data, p, sizeof(data));
29300
- data.showHeader = 0;
29301
- data.cMode = data.mode = MODE_Semi;
31852
+ int hasStat[5];
31853
+ int flgs = 0;
31854
+ char *zSql;
2930231855
if( nArg==2 && optionMatch(azArg[1], "indent") ){
29303
- data.cMode = data.mode = MODE_Pretty;
2930431856
nArg = 1;
2930531857
}
2930631858
if( nArg!=1 ){
2930731859
eputz("Usage: .fullschema ?--indent?\n");
2930831860
rc = 1;
2930931861
goto meta_command_exit;
2931031862
}
2931131863
open_db(p, 0);
29312
- rc = sqlite3_exec(p->db,
29313
- "SELECT sql FROM"
31864
+ zSql = sqlite3_mprintf(
31865
+ "SELECT shell_format_schema(sql,%d) FROM"
2931431866
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2931531867
" FROM sqlite_schema UNION ALL"
2931631868
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
2931731869
"WHERE type!='meta' AND sql NOTNULL"
29318
- " AND name NOT LIKE 'sqlite__%' ESCAPE '_' "
29319
- "ORDER BY x",
29320
- callback, &data, 0
29321
- );
31870
+ " AND name NOT LIKE 'sqlite__%%' ESCAPE '_' "
31871
+ "ORDER BY x", flgs);
31872
+ memcpy(&data, p, sizeof(data));
31873
+ data.mode.spec.bTitles = QRF_No;
31874
+ data.mode.eMode = MODE_List;
31875
+ data.mode.spec.eText = QRF_TEXT_Plain;
31876
+ data.mode.spec.nCharLimit = 0;
31877
+ data.mode.spec.zRowSep = "\n";
31878
+ rc = shell_exec(&data,zSql,0);
31879
+ sqlite3_free(zSql);
2932231880
if( rc==SQLITE_OK ){
31881
+ memset(hasStat, 0, sizeof(hasStat));
2932331882
sqlite3_stmt *pStmt;
2932431883
rc = sqlite3_prepare_v2(p->db,
29325
- "SELECT rowid FROM sqlite_schema"
31884
+ "SELECT substr(name,12,1) FROM sqlite_schema"
2932631885
" WHERE name GLOB 'sqlite_stat[134]'",
2932731886
-1, &pStmt, 0);
2932831887
if( rc==SQLITE_OK ){
29329
- doStats = sqlite3_step(pStmt)==SQLITE_ROW;
29330
- sqlite3_finalize(pStmt);
31888
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
31889
+ int k = sqlite3_column_int(pStmt,0);
31890
+ assert( k==1 || k==3 || k==4 );
31891
+ hasStat[k] = 1;
31892
+ doStats = 1;
31893
+ }
2933131894
}
31895
+ sqlite3_finalize(pStmt);
2933231896
}
2933331897
if( doStats==0 ){
29334
- sqlite3_fputs("/* No STAT tables available */\n", p->out);
31898
+ cli_puts("/* No STAT tables available */\n", p->out);
2933531899
}else{
29336
- sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
29337
- data.cMode = data.mode = MODE_Insert;
29338
- data.zDestTable = "sqlite_stat1";
29339
- shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
29340
- data.zDestTable = "sqlite_stat4";
29341
- shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
29342
- sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
31900
+ cli_puts("ANALYZE sqlite_schema;\n", p->out);
31901
+ data.mode.eMode = MODE_Insert;
31902
+ if( hasStat[1] ){
31903
+ data.mode.spec.zTableName = "sqlite_stat1";
31904
+ shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
31905
+ }
31906
+ if( hasStat[4] ){
31907
+ data.mode.spec.zTableName = "sqlite_stat4";
31908
+ shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
31909
+ }
31910
+ cli_puts("ANALYZE sqlite_schema;\n", p->out);
2934331911
}
2934431912
}else
2934531913
2934631914
if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
2934731915
if( nArg==2 ){
29348
- p->showHeader = booleanValue(azArg[1]);
29349
- p->shellFlgs |= SHFLG_HeaderSet;
31916
+ p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
31917
+ p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
2935031918
}else{
2935131919
eputz("Usage: .headers on|off\n");
2935231920
rc = 1;
2935331921
}
2935431922
}else
@@ -29355,340 +31923,20 @@
2935531923
2935631924
if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
2935731925
if( nArg>=2 ){
2935831926
n = showHelp(p->out, azArg[1]);
2935931927
if( n==0 ){
29360
- sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]);
31928
+ cli_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
2936131929
}
2936231930
}else{
2936331931
showHelp(p->out, 0);
2936431932
}
2936531933
}else
2936631934
2936731935
#ifndef SQLITE_SHELL_FIDDLE
2936831936
if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
29369
- char *zTable = 0; /* Insert data into this table */
29370
- char *zSchema = 0; /* Schema of zTable */
29371
- char *zFile = 0; /* Name of file to extra content from */
29372
- sqlite3_stmt *pStmt = NULL; /* A statement */
29373
- int nCol; /* Number of columns in the table */
29374
- i64 nByte; /* Number of bytes in an SQL string */
29375
- int i, j; /* Loop counters */
29376
- int needCommit; /* True to COMMIT or ROLLBACK at end */
29377
- int nSep; /* Number of bytes in p->colSeparator[] */
29378
- char *zSql = 0; /* An SQL statement */
29379
- ImportCtx sCtx; /* Reader context */
29380
- char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29381
- int eVerbose = 0; /* Larger for more console output */
29382
- i64 nSkip = 0; /* Initial lines to skip */
29383
- int useOutputMode = 1; /* Use output mode to determine separators */
29384
- char *zCreate = 0; /* CREATE TABLE statement text */
29385
-
29386
- failIfSafeMode(p, "cannot run .import in safe mode");
29387
- memset(&sCtx, 0, sizeof(sCtx));
29388
- if( p->mode==MODE_Ascii ){
29389
- xRead = ascii_read_one_field;
29390
- }else{
29391
- xRead = csv_read_one_field;
29392
- }
29393
- rc = 1;
29394
- for(i=1; i<nArg; i++){
29395
- char *z = azArg[i];
29396
- if( z[0]=='-' && z[1]=='-' ) z++;
29397
- if( z[0]!='-' ){
29398
- if( zFile==0 ){
29399
- zFile = z;
29400
- }else if( zTable==0 ){
29401
- zTable = z;
29402
- }else{
29403
- sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z);
29404
- showHelp(p->out, "import");
29405
- goto meta_command_exit;
29406
- }
29407
- }else if( cli_strcmp(z,"-v")==0 ){
29408
- eVerbose++;
29409
- }else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){
29410
- zSchema = azArg[++i];
29411
- }else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){
29412
- nSkip = integerValue(azArg[++i]);
29413
- }else if( cli_strcmp(z,"-ascii")==0 ){
29414
- sCtx.cColSep = SEP_Unit[0];
29415
- sCtx.cRowSep = SEP_Record[0];
29416
- xRead = ascii_read_one_field;
29417
- useOutputMode = 0;
29418
- }else if( cli_strcmp(z,"-csv")==0 ){
29419
- sCtx.cColSep = ',';
29420
- sCtx.cRowSep = '\n';
29421
- xRead = csv_read_one_field;
29422
- useOutputMode = 0;
29423
- }else{
29424
- sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
29425
- showHelp(p->out, "import");
29426
- goto meta_command_exit;
29427
- }
29428
- }
29429
- if( zTable==0 ){
29430
- sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n",
29431
- zFile==0 ? "FILE" : "TABLE");
29432
- showHelp(p->out, "import");
29433
- goto meta_command_exit;
29434
- }
29435
- seenInterrupt = 0;
29436
- open_db(p, 0);
29437
- if( useOutputMode ){
29438
- /* If neither the --csv or --ascii options are specified, then set
29439
- ** the column and row separator characters from the output mode. */
29440
- nSep = strlen30(p->colSeparator);
29441
- if( nSep==0 ){
29442
- eputz("Error: non-null column separator required for import\n");
29443
- goto meta_command_exit;
29444
- }
29445
- if( nSep>1 ){
29446
- eputz("Error: multi-character column separators not allowed"
29447
- " for import\n");
29448
- goto meta_command_exit;
29449
- }
29450
- nSep = strlen30(p->rowSeparator);
29451
- if( nSep==0 ){
29452
- eputz("Error: non-null row separator required for import\n");
29453
- goto meta_command_exit;
29454
- }
29455
- if( nSep==2 && p->mode==MODE_Csv
29456
- && cli_strcmp(p->rowSeparator,SEP_CrLf)==0
29457
- ){
29458
- /* When importing CSV (only), if the row separator is set to the
29459
- ** default output row separator, change it to the default input
29460
- ** row separator. This avoids having to maintain different input
29461
- ** and output row separators. */
29462
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
29463
- nSep = strlen30(p->rowSeparator);
29464
- }
29465
- if( nSep>1 ){
29466
- eputz("Error: multi-character row separators not allowed"
29467
- " for import\n");
29468
- goto meta_command_exit;
29469
- }
29470
- sCtx.cColSep = (u8)p->colSeparator[0];
29471
- sCtx.cRowSep = (u8)p->rowSeparator[0];
29472
- }
29473
- sCtx.zFile = zFile;
29474
- sCtx.nLine = 1;
29475
- if( sCtx.zFile[0]=='|' ){
29476
-#ifdef SQLITE_OMIT_POPEN
29477
- eputz("Error: pipes are not supported in this OS\n");
29478
- goto meta_command_exit;
29479
-#else
29480
- sCtx.in = sqlite3_popen(sCtx.zFile+1, "r");
29481
- sCtx.zFile = "<pipe>";
29482
- sCtx.xCloser = pclose;
29483
-#endif
29484
- }else{
29485
- sCtx.in = sqlite3_fopen(sCtx.zFile, "rb");
29486
- sCtx.xCloser = fclose;
29487
- }
29488
- if( sCtx.in==0 ){
29489
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
29490
- goto meta_command_exit;
29491
- }
29492
- if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
29493
- char zSep[2];
29494
- zSep[1] = 0;
29495
- zSep[0] = sCtx.cColSep;
29496
- sqlite3_fputs("Column separator ", p->out);
29497
- output_c_string(p->out, zSep);
29498
- sqlite3_fputs(", row separator ", p->out);
29499
- zSep[0] = sCtx.cRowSep;
29500
- output_c_string(p->out, zSep);
29501
- sqlite3_fputs("\n", p->out);
29502
- }
29503
- sCtx.z = sqlite3_malloc64(120);
29504
- if( sCtx.z==0 ){
29505
- import_cleanup(&sCtx);
29506
- shell_out_of_memory();
29507
- }
29508
- /* Below, resources must be freed before exit. */
29509
- while( nSkip>0 ){
29510
- nSkip--;
29511
- while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
29512
- }
29513
- import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
29514
- if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
29515
- && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
29516
- " WHERE name=%Q AND type='view'",
29517
- zSchema ? zSchema : "main", zTable)
29518
- ){
29519
- /* Table does not exist. Create it. */
29520
- sqlite3 *dbCols = 0;
29521
- char *zRenames = 0;
29522
- char *zColDefs;
29523
- zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
29524
- zSchema ? zSchema : "main", zTable);
29525
- while( xRead(&sCtx) ){
29526
- zAutoColumn(sCtx.z, &dbCols, 0);
29527
- if( sCtx.cTerm!=sCtx.cColSep ) break;
29528
- }
29529
- zColDefs = zAutoColumn(0, &dbCols, &zRenames);
29530
- if( zRenames!=0 ){
29531
- sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
29532
- "Columns renamed during .import %s due to duplicates:\n"
29533
- "%s\n", sCtx.zFile, zRenames);
29534
- sqlite3_free(zRenames);
29535
- }
29536
- assert(dbCols==0);
29537
- if( zColDefs==0 ){
29538
- sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile);
29539
- import_cleanup(&sCtx);
29540
- rc = 1;
29541
- sqlite3_free(zCreate);
29542
- goto meta_command_exit;
29543
- }
29544
- zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
29545
- if( zCreate==0 ){
29546
- import_cleanup(&sCtx);
29547
- shell_out_of_memory();
29548
- }
29549
- if( eVerbose>=1 ){
29550
- sqlite3_fprintf(p->out, "%s\n", zCreate);
29551
- }
29552
- rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
29553
- if( rc ){
29554
- sqlite3_fprintf(stderr,
29555
- "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
29556
- }
29557
- sqlite3_free(zCreate);
29558
- zCreate = 0;
29559
- if( rc ){
29560
- import_cleanup(&sCtx);
29561
- rc = 1;
29562
- goto meta_command_exit;
29563
- }
29564
- }
29565
- zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
29566
- zTable, zSchema);
29567
- if( zSql==0 ){
29568
- import_cleanup(&sCtx);
29569
- shell_out_of_memory();
29570
- }
29571
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
29572
- sqlite3_free(zSql);
29573
- zSql = 0;
29574
- if( rc ){
29575
- if (pStmt) sqlite3_finalize(pStmt);
29576
- shellDatabaseError(p->db);
29577
- import_cleanup(&sCtx);
29578
- rc = 1;
29579
- goto meta_command_exit;
29580
- }
29581
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
29582
- nCol = sqlite3_column_int(pStmt, 0);
29583
- }else{
29584
- nCol = 0;
29585
- }
29586
- sqlite3_finalize(pStmt);
29587
- pStmt = 0;
29588
- if( nCol==0 ) return 0; /* no columns, no error */
29589
-
29590
- nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */
29591
- + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */
29592
- + strlen(zTable)*2 + 2 /* Quoted table name */
29593
- + nCol*2; /* Space for ",?" for each column */
29594
- zSql = sqlite3_malloc64( nByte );
29595
- if( zSql==0 ){
29596
- import_cleanup(&sCtx);
29597
- shell_out_of_memory();
29598
- }
29599
- if( zSchema ){
29600
- sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
29601
- zSchema, zTable);
29602
- }else{
29603
- sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
29604
- }
29605
- j = strlen30(zSql);
29606
- for(i=1; i<nCol; i++){
29607
- zSql[j++] = ',';
29608
- zSql[j++] = '?';
29609
- }
29610
- zSql[j++] = ')';
29611
- zSql[j] = 0;
29612
- assert( j<nByte );
29613
- if( eVerbose>=2 ){
29614
- sqlite3_fprintf(p->out, "Insert using: %s\n", zSql);
29615
- }
29616
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
29617
- sqlite3_free(zSql);
29618
- zSql = 0;
29619
- if( rc ){
29620
- shellDatabaseError(p->db);
29621
- if (pStmt) sqlite3_finalize(pStmt);
29622
- import_cleanup(&sCtx);
29623
- rc = 1;
29624
- goto meta_command_exit;
29625
- }
29626
- needCommit = sqlite3_get_autocommit(p->db);
29627
- if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
29628
- do{
29629
- int startLine = sCtx.nLine;
29630
- for(i=0; i<nCol; i++){
29631
- char *z = xRead(&sCtx);
29632
- /*
29633
- ** Did we reach end-of-file before finding any columns?
29634
- ** If so, stop instead of NULL filling the remaining columns.
29635
- */
29636
- if( z==0 && i==0 ) break;
29637
- /*
29638
- ** Did we reach end-of-file OR end-of-line before finding any
29639
- ** columns in ASCII mode? If so, stop instead of NULL filling
29640
- ** the remaining columns.
29641
- */
29642
- if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
29643
- /*
29644
- ** For CSV mode, per RFC 4180, accept EOF in lieu of final
29645
- ** record terminator but only for last field of multi-field row.
29646
- ** (If there are too few fields, it's not valid CSV anyway.)
29647
- */
29648
- if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
29649
- z = "";
29650
- }
29651
- sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
29652
- if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
29653
- sqlite3_fprintf(stderr,"%s:%d: expected %d columns but found %d"
29654
- " - filling the rest with NULL\n",
29655
- sCtx.zFile, startLine, nCol, i+1);
29656
- i += 2;
29657
- while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
29658
- }
29659
- }
29660
- if( sCtx.cTerm==sCtx.cColSep ){
29661
- do{
29662
- xRead(&sCtx);
29663
- i++;
29664
- }while( sCtx.cTerm==sCtx.cColSep );
29665
- sqlite3_fprintf(stderr,
29666
- "%s:%d: expected %d columns but found %d - extras ignored\n",
29667
- sCtx.zFile, startLine, nCol, i);
29668
- }
29669
- if( i>=nCol ){
29670
- sqlite3_step(pStmt);
29671
- rc = sqlite3_reset(pStmt);
29672
- if( rc!=SQLITE_OK ){
29673
- sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n",
29674
- sCtx.zFile, startLine, sqlite3_errmsg(p->db));
29675
- sCtx.nErr++;
29676
- }else{
29677
- sCtx.nRow++;
29678
- }
29679
- }
29680
- }while( sCtx.cTerm!=EOF );
29681
-
29682
- import_cleanup(&sCtx);
29683
- sqlite3_finalize(pStmt);
29684
- if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
29685
- if( eVerbose>0 ){
29686
- sqlite3_fprintf(p->out,
29687
- "Added %d rows with %d errors using %d lines of input\n",
29688
- sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
29689
- }
31937
+ rc = dotCmdImport(p);
2969031938
}else
2969131939
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
2969231940
2969331941
#ifndef SQLITE_UNTESTABLE
2969431942
if( c=='i' && cli_strncmp(azArg[0], "imposter", n)==0 ){
@@ -29758,11 +32006,11 @@
2975832006
zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
2975932007
}
2976032008
}
2976132009
sqlite3_finalize(pStmt);
2976232010
if( i==0 || tnum==0 ){
29763
- sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]);
32011
+ cli_printf(stderr,"no such index: \"%s\"\n", azArg[1]);
2976432012
rc = 1;
2976532013
sqlite3_free(zCollist);
2976632014
goto meta_command_exit;
2976732015
}
2976832016
if( lenPK==0 ) lenPK = 100000;
@@ -29773,17 +32021,17 @@
2977332021
rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum);
2977432022
if( rc==SQLITE_OK ){
2977532023
rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
2977632024
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
2977732025
if( rc ){
29778
- sqlite3_fprintf(stderr,
32026
+ cli_printf(stderr,
2977932027
"Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
2978032028
}else{
29781
- sqlite3_fprintf(stdout, "%s;\n", zSql);
32029
+ cli_printf(stdout, "%s;\n", zSql);
2978232030
}
2978332031
}else{
29784
- sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
32032
+ cli_printf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
2978532033
rc = 1;
2978632034
}
2978732035
sqlite3_free(zSql);
2978832036
}else
2978932037
#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
@@ -29793,11 +32041,11 @@
2979332041
if( nArg==2 ){
2979432042
iArg = integerValue(azArg[1]);
2979532043
if( iArg==0 ) iArg = -1;
2979632044
}
2979732045
if( (nArg!=1 && nArg!=2) || iArg<0 ){
29798
- sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
32046
+ cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
2979932047
rc = 1;
2980032048
goto meta_command_exit;
2980132049
}
2980232050
open_db(p, 0);
2980332051
rc = intckDatabaseCmd(p, iArg);
@@ -29814,11 +32062,11 @@
2981432062
sqlite3IoTrace = iotracePrintf;
2981532063
iotrace = stdout;
2981632064
}else{
2981732065
iotrace = sqlite3_fopen(azArg[1], "w");
2981832066
if( iotrace==0 ){
29819
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32067
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2982032068
sqlite3IoTrace = 0;
2982132069
rc = 1;
2982232070
}else{
2982332071
sqlite3IoTrace = iotracePrintf;
2982432072
}
@@ -29833,10 +32081,11 @@
2983332081
} aLimit[] = {
2983432082
{ "length", SQLITE_LIMIT_LENGTH },
2983532083
{ "sql_length", SQLITE_LIMIT_SQL_LENGTH },
2983632084
{ "column", SQLITE_LIMIT_COLUMN },
2983732085
{ "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
32086
+ { "parser_depth", SQLITE_LIMIT_PARSER_DEPTH },
2983832087
{ "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
2983932088
{ "vdbe_op", SQLITE_LIMIT_VDBE_OP },
2984032089
{ "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
2984132090
{ "attached", SQLITE_LIMIT_ATTACHED },
2984232091
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
@@ -29846,11 +32095,11 @@
2984632095
};
2984732096
int i, n2;
2984832097
open_db(p, 0);
2984932098
if( nArg==1 ){
2985032099
for(i=0; i<ArraySize(aLimit); i++){
29851
- sqlite3_fprintf(stdout, "%20s %d\n", aLimit[i].zLimitName,
32100
+ cli_printf(stdout, "%20s %d\n", aLimit[i].zLimitName,
2985232101
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
2985332102
}
2985432103
}else if( nArg>3 ){
2985532104
eputz("Usage: .limit NAME ?NEW-VALUE?\n");
2985632105
rc = 1;
@@ -29861,28 +32110,28 @@
2986132110
for(i=0; i<ArraySize(aLimit); i++){
2986232111
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
2986332112
if( iLimit<0 ){
2986432113
iLimit = i;
2986532114
}else{
29866
- sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]);
32115
+ cli_printf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]);
2986732116
rc = 1;
2986832117
goto meta_command_exit;
2986932118
}
2987032119
}
2987132120
}
2987232121
if( iLimit<0 ){
29873
- sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n"
32122
+ cli_printf(stderr,"unknown limit: \"%s\"\n"
2987432123
"enter \".limits\" with no arguments for a list.\n",
2987532124
azArg[1]);
2987632125
rc = 1;
2987732126
goto meta_command_exit;
2987832127
}
2987932128
if( nArg==3 ){
2988032129
sqlite3_limit(p->db, aLimit[iLimit].limitCode,
2988132130
(int)integerValue(azArg[2]));
2988232131
}
29883
- sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName,
32132
+ cli_printf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName,
2988432133
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
2988532134
}
2988632135
}else
2988732136
2988832137
if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){
@@ -29927,189 +32176,27 @@
2992732176
" than \"on\" or \"off\"\n");
2992832177
zFile = "off";
2992932178
}
2993032179
output_file_close(p->pLog);
2993132180
if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
29932
- p->pLog = output_file_open(zFile);
32181
+ p->pLog = output_file_open(p, zFile);
2993332182
}
2993432183
}else
2993532184
2993632185
if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){
29937
- const char *zMode = 0;
29938
- const char *zTabname = 0;
29939
- int i, n2;
29940
- int chng = 0; /* 0x01: change to cmopts. 0x02: Any other change */
29941
- ColModeOpts cmOpts = ColModeOpts_default;
29942
- for(i=1; i<nArg; i++){
29943
- const char *z = azArg[i];
29944
- if( optionMatch(z,"wrap") && i+1<nArg ){
29945
- cmOpts.iWrap = integerValue(azArg[++i]);
29946
- chng |= 1;
29947
- }else if( optionMatch(z,"ww") ){
29948
- cmOpts.bWordWrap = 1;
29949
- chng |= 1;
29950
- }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
29951
- cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
29952
- chng |= 1;
29953
- }else if( optionMatch(z,"quote") ){
29954
- cmOpts.bQuote = 1;
29955
- chng |= 1;
29956
- }else if( optionMatch(z,"noquote") ){
29957
- cmOpts.bQuote = 0;
29958
- chng |= 1;
29959
- }else if( optionMatch(z,"escape") && i+1<nArg ){
29960
- /* See similar code at tag-20250224-1 */
29961
- const char *zEsc = azArg[++i];
29962
- int k;
29963
- for(k=0; k<ArraySize(shell_EscModeNames); k++){
29964
- if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){
29965
- p->eEscMode = k;
29966
- chng |= 2;
29967
- break;
29968
- }
29969
- }
29970
- if( k>=ArraySize(shell_EscModeNames) ){
29971
- sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
29972
- " - choices:", zEsc);
29973
- for(k=0; k<ArraySize(shell_EscModeNames); k++){
29974
- sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
29975
- }
29976
- sqlite3_fprintf(stderr, "\n");
29977
- rc = 1;
29978
- goto meta_command_exit;
29979
- }
29980
- }else if( zMode==0 ){
29981
- zMode = z;
29982
- /* Apply defaults for qbox pseudo-mode. If that
29983
- * overwrites already-set values, user was informed of this.
29984
- */
29985
- chng |= 1;
29986
- if( cli_strcmp(z, "qbox")==0 ){
29987
- ColModeOpts cmo = ColModeOpts_default_qbox;
29988
- zMode = "box";
29989
- cmOpts = cmo;
29990
- }
29991
- }else if( zTabname==0 ){
29992
- zTabname = z;
29993
- }else if( z[0]=='-' ){
29994
- sqlite3_fprintf(stderr,"unknown option: %s\n", z);
29995
- eputz("options:\n"
29996
- " --escape MODE\n"
29997
- " --noquote\n"
29998
- " --quote\n"
29999
- " --wordwrap on/off\n"
30000
- " --wrap N\n"
30001
- " --ww\n");
30002
- rc = 1;
30003
- goto meta_command_exit;
30004
- }else{
30005
- sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
30006
- rc = 1;
30007
- goto meta_command_exit;
30008
- }
30009
- }
30010
- if( !chng ){
30011
- if( p->mode==MODE_Column
30012
- || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
30013
- ){
30014
- sqlite3_fprintf(p->out,
30015
- "current output mode: %s --wrap %d --wordwrap %s "
30016
- "--%squote --escape %s\n",
30017
- modeDescr[p->mode], p->cmOpts.iWrap,
30018
- p->cmOpts.bWordWrap ? "on" : "off",
30019
- p->cmOpts.bQuote ? "" : "no",
30020
- shell_EscModeNames[p->eEscMode]
30021
- );
30022
- }else{
30023
- sqlite3_fprintf(p->out,
30024
- "current output mode: %s --escape %s\n",
30025
- modeDescr[p->mode],
30026
- shell_EscModeNames[p->eEscMode]
30027
- );
30028
- }
30029
- }
30030
- if( zMode==0 ){
30031
- zMode = modeDescr[p->mode];
30032
- if( (chng&1)==0 ) cmOpts = p->cmOpts;
30033
- }
30034
- n2 = strlen30(zMode);
30035
- if( cli_strncmp(zMode,"lines",n2)==0 ){
30036
- p->mode = MODE_Line;
30037
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30038
- }else if( cli_strncmp(zMode,"columns",n2)==0 ){
30039
- p->mode = MODE_Column;
30040
- if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
30041
- p->showHeader = 1;
30042
- }
30043
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30044
- p->cmOpts = cmOpts;
30045
- }else if( cli_strncmp(zMode,"list",n2)==0 ){
30046
- p->mode = MODE_List;
30047
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
30048
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30049
- }else if( cli_strncmp(zMode,"html",n2)==0 ){
30050
- p->mode = MODE_Html;
30051
- }else if( cli_strncmp(zMode,"tcl",n2)==0 ){
30052
- p->mode = MODE_Tcl;
30053
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
30054
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30055
- }else if( cli_strncmp(zMode,"csv",n2)==0 ){
30056
- p->mode = MODE_Csv;
30057
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30058
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
30059
- }else if( cli_strncmp(zMode,"tabs",n2)==0 ){
30060
- p->mode = MODE_List;
30061
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
30062
- }else if( cli_strncmp(zMode,"insert",n2)==0 ){
30063
- p->mode = MODE_Insert;
30064
- set_table_name(p, zTabname ? zTabname : "table");
30065
- if( p->eEscMode==SHELL_ESC_OFF ){
30066
- ShellSetFlag(p, SHFLG_Newlines);
30067
- }else{
30068
- ShellClearFlag(p, SHFLG_Newlines);
30069
- }
30070
- }else if( cli_strncmp(zMode,"quote",n2)==0 ){
30071
- p->mode = MODE_Quote;
30072
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30073
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30074
- }else if( cli_strncmp(zMode,"ascii",n2)==0 ){
30075
- p->mode = MODE_Ascii;
30076
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
30077
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
30078
- }else if( cli_strncmp(zMode,"markdown",n2)==0 ){
30079
- p->mode = MODE_Markdown;
30080
- p->cmOpts = cmOpts;
30081
- }else if( cli_strncmp(zMode,"table",n2)==0 ){
30082
- p->mode = MODE_Table;
30083
- p->cmOpts = cmOpts;
30084
- }else if( cli_strncmp(zMode,"box",n2)==0 ){
30085
- p->mode = MODE_Box;
30086
- p->cmOpts = cmOpts;
30087
- }else if( cli_strncmp(zMode,"count",n2)==0 ){
30088
- p->mode = MODE_Count;
30089
- }else if( cli_strncmp(zMode,"off",n2)==0 ){
30090
- p->mode = MODE_Off;
30091
- }else if( cli_strncmp(zMode,"json",n2)==0 ){
30092
- p->mode = MODE_Json;
30093
- }else{
30094
- eputz("Error: mode should be one of: "
30095
- "ascii box column csv html insert json line list markdown "
30096
- "qbox quote table tabs tcl\n");
30097
- rc = 1;
30098
- }
30099
- p->cMode = p->mode;
32186
+ rc = dotCmdMode(p);
3010032187
}else
3010132188
3010232189
#ifndef SQLITE_SHELL_FIDDLE
3010332190
if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
3010432191
if( nArg!=2 ){
3010532192
eputz("Usage: .nonce NONCE\n");
3010632193
rc = 1;
3010732194
}else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
30108
- sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
32195
+ cli_printf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
3010932196
p->lineno, azArg[1]);
30110
- exit(1);
32197
+ cli_exit(1);
3011132198
}else{
3011232199
p->bSafeMode = 0;
3011332200
return 0; /* Return immediately to bypass the safe mode reset
3011432201
** at the end of this procedure */
3011532202
}
@@ -30116,12 +32203,11 @@
3011632203
}else
3011732204
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
3011832205
3011932206
if( c=='n' && cli_strncmp(azArg[0], "nullvalue", n)==0 ){
3012032207
if( nArg==2 ){
30121
- sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
30122
- "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
32208
+ modeSetStr(&p->mode.spec.zNull, azArg[1]);
3012332209
}else{
3012432210
eputz("Usage: .nullvalue STRING\n");
3012532211
rc = 1;
3012632212
}
3012732213
}else
@@ -30166,15 +32252,15 @@
3016632252
p->szMax = integerValue(azArg[++iName]);
3016732253
#endif /* SQLITE_OMIT_DESERIALIZE */
3016832254
}else
3016932255
#endif /* !SQLITE_SHELL_FIDDLE */
3017032256
if( z[0]=='-' ){
30171
- sqlite3_fprintf(stderr,"unknown option: %s\n", z);
32257
+ cli_printf(stderr,"unknown option: %s\n", z);
3017232258
rc = 1;
3017332259
goto meta_command_exit;
3017432260
}else if( zFN ){
30175
- sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
32261
+ cli_printf(stderr,"extra argument: \"%s\"\n", z);
3017632262
rc = 1;
3017732263
goto meta_command_exit;
3017832264
}else{
3017932265
zFN = z;
3018032266
}
@@ -30221,11 +32307,11 @@
3022132307
zNewFilename = 0;
3022232308
}
3022332309
p->pAuxDb->zDbFilename = zNewFilename;
3022432310
open_db(p, OPEN_DB_KEEPALIVE);
3022532311
if( p->db==0 ){
30226
- sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename);
32312
+ cli_printf(stderr,"Error: cannot open '%s'\n", zNewFilename);
3022732313
sqlite3_free(zNewFilename);
3022832314
}else{
3022932315
p->pAuxDb->zFreeOnClose = zNewFilename;
3023032316
}
3023132317
}
@@ -30241,149 +32327,11 @@
3024132327
&& (cli_strncmp(azArg[0], "output", n)==0
3024232328
|| cli_strncmp(azArg[0], "once", n)==0))
3024332329
|| (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0)
3024432330
|| (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0)
3024532331
){
30246
- char *zFile = 0;
30247
- int i;
30248
- int eMode = 0; /* 0: .outout/.once, 'x'=.excel, 'w'=.www */
30249
- int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */
30250
- int bPlain = 0; /* --plain option */
30251
- static const char *zBomUtf8 = "\357\273\277";
30252
- const char *zBom = 0;
30253
-
30254
- failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
30255
- if( c=='e' ){
30256
- eMode = 'x';
30257
- bOnce = 2;
30258
- }else if( c=='w' ){
30259
- eMode = 'w';
30260
- bOnce = 2;
30261
- }else if( cli_strncmp(azArg[0],"once",n)==0 ){
30262
- bOnce = 1;
30263
- }
30264
- for(i=1; i<nArg; i++){
30265
- char *z = azArg[i];
30266
- if( z[0]=='-' ){
30267
- if( z[1]=='-' ) z++;
30268
- if( cli_strcmp(z,"-bom")==0 ){
30269
- zBom = zBomUtf8;
30270
- }else if( cli_strcmp(z,"-plain")==0 ){
30271
- bPlain = 1;
30272
- }else if( c=='o' && cli_strcmp(z,"-x")==0 ){
30273
- eMode = 'x'; /* spreadsheet */
30274
- }else if( c=='o' && cli_strcmp(z,"-e")==0 ){
30275
- eMode = 'e'; /* text editor */
30276
- }else if( c=='o' && cli_strcmp(z,"-w")==0 ){
30277
- eMode = 'w'; /* Web browser */
30278
- }else{
30279
- sqlite3_fprintf(p->out,
30280
- "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
30281
- showHelp(p->out, azArg[0]);
30282
- rc = 1;
30283
- sqlite3_free(zFile);
30284
- goto meta_command_exit;
30285
- }
30286
- }else if( zFile==0 && eMode==0 ){
30287
- if( cli_strcmp(z, "off")==0 ){
30288
-#ifdef _WIN32
30289
- zFile = sqlite3_mprintf("nul");
30290
-#else
30291
- zFile = sqlite3_mprintf("/dev/null");
30292
-#endif
30293
- }else{
30294
- zFile = sqlite3_mprintf("%s", z);
30295
- }
30296
- if( zFile && zFile[0]=='|' ){
30297
- while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
30298
- break;
30299
- }
30300
- }else{
30301
- sqlite3_fprintf(p->out,
30302
- "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]);
30303
- showHelp(p->out, azArg[0]);
30304
- rc = 1;
30305
- sqlite3_free(zFile);
30306
- goto meta_command_exit;
30307
- }
30308
- }
30309
- if( zFile==0 ){
30310
- zFile = sqlite3_mprintf("stdout");
30311
- }
30312
- shell_check_oom(zFile);
30313
- if( bOnce ){
30314
- p->outCount = 2;
30315
- }else{
30316
- p->outCount = 0;
30317
- }
30318
- output_reset(p);
30319
-#ifndef SQLITE_NOHAVE_SYSTEM
30320
- if( eMode=='e' || eMode=='x' || eMode=='w' ){
30321
- p->doXdgOpen = 1;
30322
- outputModePush(p);
30323
- if( eMode=='x' ){
30324
- /* spreadsheet mode. Output as CSV. */
30325
- newTempFile(p, "csv");
30326
- ShellClearFlag(p, SHFLG_Echo);
30327
- p->mode = MODE_Csv;
30328
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30329
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
30330
-#ifdef _WIN32
30331
- zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does
30332
- ** not work without it. */
30333
-#endif
30334
- }else if( eMode=='w' ){
30335
- /* web-browser mode. */
30336
- newTempFile(p, "html");
30337
- if( !bPlain ) p->mode = MODE_Www;
30338
- }else{
30339
- /* text editor mode */
30340
- newTempFile(p, "txt");
30341
- }
30342
- sqlite3_free(zFile);
30343
- zFile = sqlite3_mprintf("%s", p->zTempFile);
30344
- }
30345
-#endif /* SQLITE_NOHAVE_SYSTEM */
30346
- shell_check_oom(zFile);
30347
- if( zFile[0]=='|' ){
30348
-#ifdef SQLITE_OMIT_POPEN
30349
- eputz("Error: pipes are not supported in this OS\n");
30350
- rc = 1;
30351
- output_redir(p, stdout);
30352
-#else
30353
- FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
30354
- if( pfPipe==0 ){
30355
- assert( stderr!=NULL );
30356
- sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
30357
- rc = 1;
30358
- }else{
30359
- output_redir(p, pfPipe);
30360
- if( zBom ) sqlite3_fputs(zBom, pfPipe);
30361
- sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
30362
- }
30363
-#endif
30364
- }else{
30365
- FILE *pfFile = output_file_open(zFile);
30366
- if( pfFile==0 ){
30367
- if( cli_strcmp(zFile,"off")!=0 ){
30368
- assert( stderr!=NULL );
30369
- sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
30370
- }
30371
- rc = 1;
30372
- } else {
30373
- output_redir(p, pfFile);
30374
- if( zBom ) sqlite3_fputs(zBom, pfFile);
30375
- if( bPlain && eMode=='w' ){
30376
- sqlite3_fputs(
30377
- "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n",
30378
- pfFile
30379
- );
30380
- }
30381
- sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
30382
- }
30383
- }
30384
- sqlite3_free(zFile);
32332
+ rc = dotCmdOutput(p);
3038532333
}else
3038632334
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
3038732335
3038832336
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "parameter", n)==0 ){
3038932337
open_db(p,0);
@@ -30416,11 +32364,11 @@
3041632364
if( len ){
3041732365
rx = sqlite3_prepare_v2(p->db,
3041832366
"SELECT key, quote(value) "
3041932367
"FROM temp.sqlite_parameters;", -1, &pStmt, 0);
3042032368
while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
30421
- sqlite3_fprintf(p->out,
32369
+ cli_printf(p->out,
3042232370
"%-*s %s\n", len, sqlite3_column_text(pStmt,0),
3042332371
sqlite3_column_text(pStmt,1));
3042432372
}
3042532373
sqlite3_finalize(pStmt);
3042632374
}
@@ -30462,11 +32410,11 @@
3046232410
"VALUES(%Q,%Q);", zKey, zValue);
3046332411
shell_check_oom(zSql);
3046432412
rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3046532413
sqlite3_free(zSql);
3046632414
if( rx!=SQLITE_OK ){
30467
- sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
32415
+ cli_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
3046832416
sqlite3_finalize(pStmt);
3046932417
pStmt = 0;
3047032418
rc = 1;
3047132419
}
3047232420
}
@@ -30492,14 +32440,14 @@
3049232440
}else
3049332441
3049432442
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
3049532443
int i;
3049632444
for(i=1; i<nArg; i++){
30497
- if( i>1 ) sqlite3_fputs(" ", p->out);
30498
- sqlite3_fputs(azArg[i], p->out);
32445
+ if( i>1 ) cli_puts(" ", p->out);
32446
+ cli_puts(azArg[i], p->out);
3049932447
}
30500
- sqlite3_fputs("\n", p->out);
32448
+ cli_puts("\n", p->out);
3050132449
}else
3050232450
3050332451
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
3050432452
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){
3050532453
int i;
@@ -30532,11 +32480,11 @@
3053232480
}else{
3053332481
p->mxProgress = (int)integerValue(azArg[++i]);
3053432482
}
3053532483
continue;
3053632484
}
30537
- sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]);
32485
+ cli_printf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]);
3053832486
rc = 1;
3053932487
goto meta_command_exit;
3054032488
}else{
3054132489
nn = (int)integerValue(z);
3054232490
}
@@ -30576,22 +32524,24 @@
3057632524
eputz("Error: pipes are not supported in this OS\n");
3057732525
rc = 1;
3057832526
#else
3057932527
p->in = sqlite3_popen(azArg[1]+1, "r");
3058032528
if( p->in==0 ){
30581
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32529
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3058232530
rc = 1;
3058332531
}else{
3058432532
rc = process_input(p, "<pipe>");
3058532533
pclose(p->in);
3058632534
}
3058732535
#endif
3058832536
}else if( (p->in = openChrSource(azArg[1]))==0 ){
30589
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32537
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3059032538
rc = 1;
3059132539
}else{
30592
- rc = process_input(p, azArg[1]);
32540
+ char *zFilename = strdup(azArg[1]);
32541
+ rc = process_input(p, zFilename);
32542
+ free(zFilename);
3059332543
fclose(p->in);
3059432544
}
3059532545
p->in = inSaved;
3059632546
p->lineno = savedLineno;
3059732547
}else
@@ -30617,11 +32567,11 @@
3061732567
rc = 1;
3061832568
goto meta_command_exit;
3061932569
}
3062032570
rc = sqlite3_open(zSrcFile, &pSrc);
3062132571
if( rc!=SQLITE_OK ){
30622
- sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile);
32572
+ cli_printf(stderr,"Error: cannot open \"%s\"\n", zSrcFile);
3062332573
close_db(pSrc);
3062432574
return 1;
3062532575
}
3062632576
open_db(p, 0);
3062732577
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
@@ -30655,25 +32605,25 @@
3065532605
(cli_strncmp(azArg[0], "scanstats", n)==0 ||
3065632606
cli_strncmp(azArg[0], "scanstatus", n)==0)
3065732607
){
3065832608
if( nArg==2 ){
3065932609
if( cli_strcmp(azArg[1], "vm")==0 ){
30660
- p->scanstatsOn = 3;
32610
+ p->mode.scanstatsOn = 3;
3066132611
}else
3066232612
if( cli_strcmp(azArg[1], "est")==0 ){
30663
- p->scanstatsOn = 2;
32613
+ p->mode.scanstatsOn = 2;
3066432614
}else{
30665
- p->scanstatsOn = (u8)booleanValue(azArg[1]);
32615
+ p->mode.scanstatsOn = (u8)booleanValue(azArg[1]);
3066632616
}
3066732617
open_db(p, 0);
3066832618
sqlite3_db_config(
30669
- p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
32619
+ p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->mode.scanstatsOn, (int*)0
3067032620
);
3067132621
#if !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
3067232622
eputz("Warning: .scanstats not available in this build.\n");
3067332623
#elif !defined(SQLITE_ENABLE_BYTECODE_VTAB)
30674
- if( p->scanstatsOn==3 ){
32624
+ if( p->mode.scanstatsOn==3 ){
3067532625
eputz("Warning: \".scanstats vm\" not available in this build.\n");
3067632626
}
3067732627
#endif
3067832628
}else{
3067932629
eputz("Usage: .scanstats on|off|est\n");
@@ -30680,34 +32630,38 @@
3068032630
rc = 1;
3068132631
}
3068232632
}else
3068332633
3068432634
if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){
30685
- ShellText sSelect;
3068632635
ShellState data;
3068732636
char *zErrMsg = 0;
3068832637
const char *zDiv = "(";
3068932638
const char *zName = 0;
3069032639
int iSchema = 0;
3069132640
int bDebug = 0;
3069232641
int bNoSystemTabs = 0;
32642
+ int bIndent = 0;
3069332643
int ii;
30694
-
32644
+ sqlite3_str *pSql;
32645
+ sqlite3_stmt *pStmt = 0;
32646
+
3069532647
open_db(p, 0);
3069632648
memcpy(&data, p, sizeof(data));
30697
- data.showHeader = 0;
30698
- data.cMode = data.mode = MODE_Semi;
30699
- initText(&sSelect);
32649
+ data.mode.spec.bTitles = QRF_No;
32650
+ data.mode.eMode = MODE_List;
32651
+ data.mode.spec.eText = QRF_TEXT_Plain;
32652
+ data.mode.spec.nCharLimit = 0;
32653
+ data.mode.spec.zRowSep = "\n";
3070032654
for(ii=1; ii<nArg; ii++){
3070132655
if( optionMatch(azArg[ii],"indent") ){
30702
- data.cMode = data.mode = MODE_Pretty;
32656
+ bIndent = 1;
3070332657
}else if( optionMatch(azArg[ii],"debug") ){
3070432658
bDebug = 1;
3070532659
}else if( optionMatch(azArg[ii],"nosys") ){
3070632660
bNoSystemTabs = 1;
3070732661
}else if( azArg[ii][0]=='-' ){
30708
- sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]);
32662
+ cli_printf(stderr,"Unknown option: \"%s\"\n", azArg[ii]);
3070932663
rc = 1;
3071032664
goto meta_command_exit;
3071132665
}else if( zName==0 ){
3071232666
zName = azArg[ii];
3071332667
}else{
@@ -30720,100 +32674,87 @@
3072032674
int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
3072132675
|| sqlite3_strlike(zName, "sqlite_schema", '\\')==0
3072232676
|| sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
3072332677
|| sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
3072432678
if( isSchema ){
30725
- char *new_argv[2], *new_colv[2];
30726
- new_argv[0] = sqlite3_mprintf(
32679
+ cli_printf(p->out,
3072732680
"CREATE TABLE %s (\n"
3072832681
" type text,\n"
3072932682
" name text,\n"
3073032683
" tbl_name text,\n"
3073132684
" rootpage integer,\n"
3073232685
" sql text\n"
30733
- ")", zName);
30734
- shell_check_oom(new_argv[0]);
30735
- new_argv[1] = 0;
30736
- new_colv[0] = "sql";
30737
- new_colv[1] = 0;
30738
- callback(&data, 1, new_argv, new_colv);
30739
- sqlite3_free(new_argv[0]);
30740
- }
30741
- }
30742
- if( zDiv ){
30743
- sqlite3_stmt *pStmt = 0;
30744
- rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
30745
- -1, &pStmt, 0);
30746
- if( rc ){
30747
- shellDatabaseError(p->db);
30748
- sqlite3_finalize(pStmt);
30749
- rc = 1;
30750
- goto meta_command_exit;
30751
- }
30752
- appendText(&sSelect, "SELECT sql FROM", 0);
30753
- iSchema = 0;
30754
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
30755
- const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
30756
- char zScNum[30];
30757
- sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
30758
- appendText(&sSelect, zDiv, 0);
30759
- zDiv = " UNION ALL ";
30760
- appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
30761
- if( sqlite3_stricmp(zDb, "main")!=0 ){
30762
- appendText(&sSelect, zDb, '\'');
30763
- }else{
30764
- appendText(&sSelect, "NULL", 0);
30765
- }
30766
- appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
30767
- appendText(&sSelect, zScNum, 0);
30768
- appendText(&sSelect, " AS snum, ", 0);
30769
- appendText(&sSelect, zDb, '\'');
30770
- appendText(&sSelect, " AS sname FROM ", 0);
30771
- appendText(&sSelect, zDb, quoteChar(zDb));
30772
- appendText(&sSelect, ".sqlite_schema", 0);
30773
- }
30774
- sqlite3_finalize(pStmt);
32686
+ ");\n", zName);
32687
+ }
32688
+ }
32689
+ rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
32690
+ -1, &pStmt, 0);
32691
+ if( rc ){
32692
+ shellDatabaseError(p->db);
32693
+ sqlite3_finalize(pStmt);
32694
+
32695
+ rc = 1;
32696
+ goto meta_command_exit;
32697
+ }
32698
+ pSql = sqlite3_str_new(p->db);
32699
+ sqlite3_str_appendf(pSql, "SELECT sql FROM", 0);
32700
+ iSchema = 0;
32701
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
32702
+ const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
32703
+ char zScNum[30];
32704
+ sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
32705
+ sqlite3_str_appendall(pSql, zDiv);
32706
+ zDiv = " UNION ALL ";
32707
+ if( sqlite3_stricmp(zDb, "main")==0 ){
32708
+ sqlite3_str_appendf(pSql,
32709
+ "SELECT shell_format_schema(shell_add_schema(sql,NULL,name),%d)",
32710
+ bIndent);
32711
+ }else{
32712
+ sqlite3_str_appendf(pSql,
32713
+ "SELECT shell_format_schema(shell_add_schema(sql,%Q,name),%d))",
32714
+ zDb, bIndent);
32715
+ }
32716
+ sqlite3_str_appendf(pSql,
32717
+ " AS sql, type, tbl_name, name, rowid, %d AS snum, %Q as sname",
32718
+ ++iSchema, zDb);
32719
+ sqlite3_str_appendf(pSql," FROM \"%w\".sqlite_schema", zDb);
32720
+ }
32721
+ sqlite3_finalize(pStmt);
3077532722
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
30776
- if( zName ){
30777
- appendText(&sSelect,
30778
- " UNION ALL SELECT shell_module_schema(name),"
30779
- " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
30780
- 0);
30781
- }
30782
-#endif
30783
- appendText(&sSelect, ") WHERE ", 0);
30784
- if( zName ){
30785
- char *zQarg = sqlite3_mprintf("%Q", zName);
30786
- int bGlob;
30787
- shell_check_oom(zQarg);
30788
- bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
30789
- strchr(zName, '[') != 0;
30790
- if( strchr(zName, '.') ){
30791
- appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
30792
- }else{
30793
- appendText(&sSelect, "lower(tbl_name)", 0);
30794
- }
30795
- appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
30796
- appendText(&sSelect, zQarg, 0);
30797
- if( !bGlob ){
30798
- appendText(&sSelect, " ESCAPE '\\' ", 0);
30799
- }
30800
- appendText(&sSelect, " AND ", 0);
30801
- sqlite3_free(zQarg);
30802
- }
30803
- if( bNoSystemTabs ){
30804
- appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
30805
- }
30806
- appendText(&sSelect, "sql IS NOT NULL"
30807
- " ORDER BY snum, rowid", 0);
30808
- if( bDebug ){
30809
- sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
30810
- }else{
30811
- rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
30812
- }
30813
- freeText(&sSelect);
30814
- }
32723
+ if( zName ){
32724
+ sqlite3_str_appendall(pSql,
32725
+ " UNION ALL SELECT shell_module_schema(name),"
32726
+ " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list");
32727
+ }
32728
+#endif
32729
+ sqlite3_str_appendf(pSql, ") WHERE ", 0);
32730
+ if( zName ){
32731
+ int bGlob;
32732
+ bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
32733
+ strchr(zName, '[') != 0;
32734
+ if( strchr(zName, '.') ){
32735
+ sqlite3_str_appendall(pSql, "lower(format('%%s.%%s',sname,tbl_name))");
32736
+ }else{
32737
+ sqlite3_str_appendall(pSql, "lower(tbl_name)");
32738
+ }
32739
+ if( bGlob ){
32740
+ sqlite3_str_appendf(pSql, " GLOB %Q AND ", zName);
32741
+ }else{
32742
+ sqlite3_str_appendf(pSql, " LIKE %Q ESCAPE '\\' AND ", zName);
32743
+ }
32744
+ }
32745
+ if( bNoSystemTabs ){
32746
+ sqlite3_str_appendf(pSql, " name NOT LIKE 'sqlite__%%' ESCALE '_' AND ");
32747
+ }
32748
+ sqlite3_str_appendf(pSql, "sql IS NOT NULL ORDER BY snum, rowid");
32749
+ if( bDebug ){
32750
+ cli_printf(p->out, "SQL: %s;\n", sqlite3_str_value(pSql));
32751
+ }else{
32752
+ rc = shell_exec(&data, sqlite3_str_value(pSql), &zErrMsg);
32753
+ }
32754
+ sqlite3_str_free(pSql);
32755
+
3081532756
if( zErrMsg ){
3081632757
shellEmitError(zErrMsg);
3081732758
sqlite3_free(zErrMsg);
3081832759
rc = 1;
3081932760
}else if( rc != SQLITE_OK ){
@@ -30865,11 +32806,11 @@
3086532806
session_not_open:
3086632807
eputz("ERROR: No sessions are open\n");
3086732808
}else{
3086832809
rc = sqlite3session_attach(pSession->p, azCmd[1]);
3086932810
if( rc ){
30870
- sqlite3_fprintf(stderr,
32811
+ cli_printf(stderr,
3087132812
"ERROR: sqlite3session_attach() returns %d\n",rc);
3087232813
rc = 0;
3087332814
}
3087432815
}
3087532816
}else
@@ -30885,11 +32826,11 @@
3088532826
failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
3088632827
if( nCmd!=2 ) goto session_syntax_error;
3088732828
if( pSession->p==0 ) goto session_not_open;
3088832829
out = sqlite3_fopen(azCmd[1], "wb");
3088932830
if( out==0 ){
30890
- sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n",
32831
+ cli_printf(stderr,"ERROR: cannot open \"%s\" for writing\n",
3089132832
azCmd[1]);
3089232833
}else{
3089332834
int szChng;
3089432835
void *pChng;
3089532836
if( azCmd[0][0]=='c' ){
@@ -30896,16 +32837,16 @@
3089632837
rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
3089732838
}else{
3089832839
rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
3089932840
}
3090032841
if( rc ){
30901
- sqlite3_fprintf(stdout, "Error: error code %d\n", rc);
32842
+ cli_printf(stdout, "Error: error code %d\n", rc);
3090232843
rc = 0;
3090332844
}
3090432845
if( pChng
3090532846
&& fwrite(pChng, szChng, 1, out)!=1 ){
30906
- sqlite3_fprintf(stderr,
32847
+ cli_printf(stderr,
3090732848
"ERROR: Failed to write entire %d-byte output\n", szChng);
3090832849
}
3090932850
sqlite3_free(pChng);
3091032851
fclose(out);
3091132852
}
@@ -30929,11 +32870,11 @@
3092932870
int ii;
3093032871
if( nCmd>2 ) goto session_syntax_error;
3093132872
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3093232873
if( pAuxDb->nSession ){
3093332874
ii = sqlite3session_enable(pSession->p, ii);
30934
- sqlite3_fprintf(p->out,
32875
+ cli_printf(p->out,
3093532876
"session %s enable flag = %d\n", pSession->zName, ii);
3093632877
}
3093732878
}else
3093832879
3093932880
/* .session filter GLOB ....
@@ -30966,11 +32907,11 @@
3096632907
int ii;
3096732908
if( nCmd>2 ) goto session_syntax_error;
3096832909
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3096932910
if( pAuxDb->nSession ){
3097032911
ii = sqlite3session_indirect(pSession->p, ii);
30971
- sqlite3_fprintf(p->out,
32912
+ cli_printf(p->out,
3097232913
"session %s indirect flag = %d\n", pSession->zName, ii);
3097332914
}
3097432915
}else
3097532916
3097632917
/* .session isempty
@@ -30979,21 +32920,21 @@
3097932920
if( cli_strcmp(azCmd[0], "isempty")==0 ){
3098032921
int ii;
3098132922
if( nCmd!=1 ) goto session_syntax_error;
3098232923
if( pAuxDb->nSession ){
3098332924
ii = sqlite3session_isempty(pSession->p);
30984
- sqlite3_fprintf(p->out,
32925
+ cli_printf(p->out,
3098532926
"session %s isempty flag = %d\n", pSession->zName, ii);
3098632927
}
3098732928
}else
3098832929
3098932930
/* .session list
3099032931
** List all currently open sessions
3099132932
*/
3099232933
if( cli_strcmp(azCmd[0],"list")==0 ){
3099332934
for(i=0; i<pAuxDb->nSession; i++){
30994
- sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName);
32935
+ cli_printf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName);
3099532936
}
3099632937
}else
3099732938
3099832939
/* .session open DB NAME
3099932940
** Open a new session called NAME on the attached database DB.
@@ -31004,23 +32945,23 @@
3100432945
if( nCmd!=3 ) goto session_syntax_error;
3100532946
zName = azCmd[2];
3100632947
if( zName[0]==0 ) goto session_syntax_error;
3100732948
for(i=0; i<pAuxDb->nSession; i++){
3100832949
if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){
31009
- sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName);
32950
+ cli_printf(stderr,"Session \"%s\" already exists\n", zName);
3101032951
goto meta_command_exit;
3101132952
}
3101232953
}
3101332954
if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
31014
- sqlite3_fprintf(stderr,
32955
+ cli_printf(stderr,
3101532956
"Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
3101632957
goto meta_command_exit;
3101732958
}
3101832959
pSession = &pAuxDb->aSession[pAuxDb->nSession];
3101932960
rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
3102032961
if( rc ){
31021
- sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc);
32962
+ cli_printf(stderr,"Cannot open session: error code=%d\n", rc);
3102232963
rc = 0;
3102332964
goto meta_command_exit;
3102432965
}
3102532966
pSession->nFilter = 0;
3102632967
sqlite3session_table_filter(pSession->p, session_filter, pSession);
@@ -31040,20 +32981,20 @@
3104032981
if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){
3104132982
if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3104232983
int i, v;
3104332984
for(i=1; i<nArg; i++){
3104432985
v = booleanValue(azArg[i]);
31045
- sqlite3_fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
32986
+ cli_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3104632987
}
3104732988
}
3104832989
if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){
3104932990
int i; sqlite3_int64 v;
3105032991
for(i=1; i<nArg; i++){
3105132992
char zBuf[200];
3105232993
v = integerValue(azArg[i]);
3105332994
sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
31054
- sqlite3_fputs(zBuf, p->out);
32995
+ cli_puts(zBuf, p->out);
3105532996
}
3105632997
}
3105732998
}else
3105832999
#endif
3105933000
@@ -31076,13 +33017,13 @@
3107633017
}else
3107733018
if( cli_strcmp(z,"-v")==0 ){
3107833019
bVerbose++;
3107933020
}else
3108033021
{
31081
- sqlite3_fprintf(stderr,
33022
+ cli_printf(stderr,
3108233023
"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
31083
- sqlite3_fputs("Should be one of: --init -v\n", stderr);
33024
+ cli_puts("Should be one of: --init -v\n", stderr);
3108433025
rc = 1;
3108533026
goto meta_command_exit;
3108633027
}
3108733028
}
3108833029
if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
@@ -31123,61 +33064,59 @@
3112333064
if( zOp==0 ) continue;
3112433065
if( zSql==0 ) continue;
3112533066
if( zAns==0 ) continue;
3112633067
k = 0;
3112733068
if( bVerbose>0 ){
31128
- sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql);
33069
+ cli_printf(stdout, "%d: %s %s\n", tno, zOp, zSql);
3112933070
}
3113033071
if( cli_strcmp(zOp,"memo")==0 ){
31131
- sqlite3_fprintf(p->out, "%s\n", zSql);
33072
+ cli_printf(p->out, "%s\n", zSql);
3113233073
}else
3113333074
if( cli_strcmp(zOp,"run")==0 ){
3113433075
char *zErrMsg = 0;
3113533076
str.n = 0;
3113633077
str.zTxt[0] = 0;
3113733078
rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
3113833079
nTest++;
3113933080
if( bVerbose ){
31140
- sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt);
33081
+ cli_printf(p->out, "Result: %s\n", str.zTxt);
3114133082
}
3114233083
if( rc || zErrMsg ){
3114333084
nErr++;
3114433085
rc = 1;
31145
- sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
33086
+ cli_printf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
3114633087
sqlite3_free(zErrMsg);
3114733088
}else if( cli_strcmp(zAns,str.zTxt)!=0 ){
3114833089
nErr++;
3114933090
rc = 1;
31150
- sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
31151
- sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
33091
+ cli_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
33092
+ cli_printf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
3115233093
}
3115333094
}
3115433095
else{
31155
- sqlite3_fprintf(stderr,
33096
+ cli_printf(stderr,
3115633097
"Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
3115733098
rc = 1;
3115833099
break;
3115933100
}
3116033101
} /* End loop over rows of content from SELFTEST */
3116133102
sqlite3_finalize(pStmt);
3116233103
} /* End loop over k */
3116333104
freeText(&str);
31164
- sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest);
33105
+ cli_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
3116533106
}else
3116633107
3116733108
if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){
3116833109
if( nArg<2 || nArg>3 ){
3116933110
eputz("Usage: .separator COL ?ROW?\n");
3117033111
rc = 1;
3117133112
}
3117233113
if( nArg>=2 ){
31173
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
31174
- "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
33114
+ modeSetStr(&p->mode.spec.zColumnSep, azArg[1]);
3117533115
}
3117633116
if( nArg>=3 ){
31177
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
31178
- "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
33117
+ modeSetStr(&p->mode.spec.zRowSep,azArg[2]);
3117933118
}
3118033119
}else
3118133120
3118233121
if( c=='s' && n>=4 && cli_strncmp(azArg[0],"sha3sum",n)==0 ){
3118333122
const char *zLike = 0; /* Which table to checksum. 0 means everything */
@@ -31207,11 +33146,11 @@
3120733146
}else
3120833147
if( cli_strcmp(z,"debug")==0 ){
3120933148
bDebug = 1;
3121033149
}else
3121133150
{
31212
- sqlite3_fprintf(stderr,
33151
+ cli_printf(stderr,
3121333152
"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
3121433153
showHelp(p->out, azArg[0]);
3121533154
rc = 1;
3121633155
goto meta_command_exit;
3121733156
}
@@ -31286,11 +33225,11 @@
3128633225
}
3128733226
shell_check_oom(zSql);
3128833227
freeText(&sQuery);
3128933228
freeText(&sSql);
3129033229
if( bDebug ){
31291
- sqlite3_fprintf(p->out, "%s\n", zSql);
33230
+ cli_printf(p->out, "%s\n", zSql);
3129233231
}else{
3129333232
shell_exec(p, zSql, 0);
3129433233
}
3129533234
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
3129633235
{
@@ -31316,11 +33255,11 @@
3131633255
"||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
3131733256
"|| ' AND typeof('||cname||')=''text'' ',\n"
3131833257
"' OR ') as query, tname from tabcols group by tname)"
3131933258
, zRevText);
3132033259
shell_check_oom(zRevText);
31321
- if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText);
33260
+ if( bDebug ) cli_printf(p->out, "%s\n", zRevText);
3132233261
lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
3132333262
if( lrc!=SQLITE_OK ){
3132433263
/* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the
3132533264
** user does cruel and unnatural things like ".limit expr_depth 0". */
3132633265
rc = 1;
@@ -31329,19 +33268,19 @@
3132933268
lrc = SQLITE_ROW==sqlite3_step(pStmt);
3133033269
if( lrc ){
3133133270
const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
3133233271
sqlite3_stmt *pCheckStmt;
3133333272
lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
31334
- if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery);
33273
+ if( bDebug ) cli_printf(p->out, "%s\n", zGenQuery);
3133533274
if( lrc!=SQLITE_OK ){
3133633275
rc = 1;
3133733276
}else{
3133833277
if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
3133933278
double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
3134033279
if( countIrreversible>0 ){
3134133280
int sz = (int)(countIrreversible + 0.5);
31342
- sqlite3_fprintf(stderr,
33281
+ cli_printf(stderr,
3134333282
"Digest includes %d invalidly encoded text field%s.\n",
3134433283
sz, (sz>1)? "s": "");
3134533284
}
3134633285
}
3134733286
sqlite3_finalize(pCheckStmt);
@@ -31376,11 +33315,11 @@
3137633315
}
3137733316
/*consoleRestore();*/
3137833317
x = zCmd!=0 ? system(zCmd) : 1;
3137933318
/*consoleRenewSetup();*/
3138033319
sqlite3_free(zCmd);
31381
- if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x);
33320
+ if( x ) cli_printf(stderr,"System command returns %d\n", x);
3138233321
}else
3138333322
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */
3138433323
3138533324
if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){
3138633325
static const char *azBool[] = { "off", "on", "trigger", "full"};
@@ -31389,52 +33328,55 @@
3138933328
if( nArg!=1 ){
3139033329
eputz("Usage: .show\n");
3139133330
rc = 1;
3139233331
goto meta_command_exit;
3139333332
}
31394
- sqlite3_fprintf(p->out, "%12.12s: %s\n","echo",
31395
- azBool[ShellHasFlag(p, SHFLG_Echo)]);
31396
- sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
31397
- sqlite3_fprintf(p->out, "%12.12s: %s\n","explain",
31398
- p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
31399
- sqlite3_fprintf(p->out, "%12.12s: %s\n","headers",
31400
- azBool[p->showHeader!=0]);
31401
- if( p->mode==MODE_Column
31402
- || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
33333
+ cli_printf(p->out, "%12.12s: %s\n","echo",
33334
+ azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
33335
+ cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
33336
+ cli_printf(p->out, "%12.12s: %s\n","explain",
33337
+ p->mode.autoExplain ? "auto" : "off");
33338
+ cli_printf(p->out, "%12.12s: %s\n","headers",
33339
+ azBool[p->mode.spec.bTitles==QRF_Yes]);
33340
+ if( p->mode.spec.eStyle==QRF_STYLE_Column
33341
+ || p->mode.spec.eStyle==QRF_STYLE_Box
33342
+ || p->mode.spec.eStyle==QRF_STYLE_Table
33343
+ || p->mode.spec.eStyle==QRF_STYLE_Markdown
3140333344
){
31404
- sqlite3_fprintf(p->out,
33345
+ cli_printf(p->out,
3140533346
"%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
31406
- modeDescr[p->mode], p->cmOpts.iWrap,
31407
- p->cmOpts.bWordWrap ? "on" : "off",
31408
- p->cmOpts.bQuote ? "" : "no");
33347
+ aModeInfo[p->mode.eMode].zName, p->mode.spec.nWrap,
33348
+ p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off",
33349
+ p->mode.spec.eText==QRF_TEXT_Sql ? "" : "no");
3140933350
}else{
31410
- sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
33351
+ cli_printf(p->out, "%12.12s: %s\n","mode",
33352
+ aModeInfo[p->mode.eMode].zName);
3141133353
}
31412
- sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue");
31413
- output_c_string(p->out, p->nullValue);
31414
- sqlite3_fputs("\n", p->out);
31415
- sqlite3_fprintf(p->out, "%12.12s: %s\n","output",
33354
+ cli_printf(p->out, "%12.12s: ", "nullvalue");
33355
+ output_c_string(p->out, p->mode.spec.zNull);
33356
+ cli_puts("\n", p->out);
33357
+ cli_printf(p->out, "%12.12s: %s\n","output",
3141633358
strlen30(p->outfile) ? p->outfile : "stdout");
31417
- sqlite3_fprintf(p->out, "%12.12s: ", "colseparator");
31418
- output_c_string(p->out, p->colSeparator);
31419
- sqlite3_fputs("\n", p->out);
31420
- sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator");
31421
- output_c_string(p->out, p->rowSeparator);
31422
- sqlite3_fputs("\n", p->out);
33359
+ cli_printf(p->out, "%12.12s: ", "colseparator");
33360
+ output_c_string(p->out, p->mode.spec.zColumnSep);
33361
+ cli_puts("\n", p->out);
33362
+ cli_printf(p->out, "%12.12s: ", "rowseparator");
33363
+ output_c_string(p->out, p->mode.spec.zRowSep);
33364
+ cli_puts("\n", p->out);
3142333365
switch( p->statsOn ){
3142433366
case 0: zOut = "off"; break;
3142533367
default: zOut = "on"; break;
3142633368
case 2: zOut = "stmt"; break;
3142733369
case 3: zOut = "vmstep"; break;
3142833370
}
31429
- sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut);
31430
- sqlite3_fprintf(p->out, "%12.12s: ", "width");
31431
- for (i=0;i<p->nWidth;i++) {
31432
- sqlite3_fprintf(p->out, "%d ", p->colWidth[i]);
33371
+ cli_printf(p->out, "%12.12s: %s\n","stats", zOut);
33372
+ cli_printf(p->out, "%12.12s: ", "width");
33373
+ for(i=0; i<p->mode.spec.nWidth; i++){
33374
+ cli_printf(p->out, "%d ", (int)p->mode.spec.aWidth[i]);
3143333375
}
31434
- sqlite3_fputs("\n", p->out);
31435
- sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename",
33376
+ cli_puts("\n", p->out);
33377
+ cli_printf(p->out, "%12.12s: %s\n", "filename",
3143633378
p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
3143733379
}else
3143833380
3143933381
if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){
3144033382
if( nArg==2 ){
@@ -31542,20 +33484,20 @@
3154233484
int nPrintCol, nPrintRow;
3154333485
for(i=0; i<nRow; i++){
3154433486
len = strlen30(azResult[i]);
3154533487
if( len>maxlen ) maxlen = len;
3154633488
}
31547
- nPrintCol = 80/(maxlen+2);
33489
+ nPrintCol = shellScreenWidth()/(maxlen+2);
3154833490
if( nPrintCol<1 ) nPrintCol = 1;
3154933491
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3155033492
for(i=0; i<nPrintRow; i++){
3155133493
for(j=i; j<nRow; j+=nPrintRow){
3155233494
char *zSp = j<nPrintRow ? "" : " ";
31553
- sqlite3_fprintf(p->out,
33495
+ cli_printf(p->out,
3155433496
"%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
3155533497
}
31556
- sqlite3_fputs("\n", p->out);
33498
+ cli_puts("\n", p->out);
3155733499
}
3155833500
}
3155933501
3156033502
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3156133503
sqlite3_free(azResult);
@@ -31563,11 +33505,11 @@
3156333505
3156433506
#ifndef SQLITE_SHELL_FIDDLE
3156533507
/* Begin redirecting output to the file "testcase-out.txt" */
3156633508
if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){
3156733509
output_reset(p);
31568
- p->out = output_file_open("testcase-out.txt");
33510
+ p->out = output_file_open(p, "testcase-out.txt");
3156933511
if( p->out==0 ){
3157033512
eputz("Error: cannot open 'testcase-out.txt'\n");
3157133513
}
3157233514
if( nArg>=2 ){
3157333515
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
@@ -31626,14 +33568,14 @@
3162633568
if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
3162733569
}
3162833570
3162933571
/* --help lists all test-controls */
3163033572
if( cli_strcmp(zCmd,"help")==0 ){
31631
- sqlite3_fputs("Available test-controls:\n", p->out);
33573
+ cli_puts("Available test-controls:\n", p->out);
3163233574
for(i=0; i<ArraySize(aCtrl); i++){
3163333575
if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue;
31634
- sqlite3_fprintf(p->out, " .testctrl %s %s\n",
33576
+ cli_printf(p->out, " .testctrl %s %s\n",
3163533577
aCtrl[i].zCtrlName, aCtrl[i].zUsage);
3163633578
}
3163733579
rc = 1;
3163833580
goto meta_command_exit;
3163933581
}
@@ -31646,19 +33588,19 @@
3164633588
if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
3164733589
if( testctrl<0 ){
3164833590
testctrl = aCtrl[i].ctrlCode;
3164933591
iCtrl = i;
3165033592
}else{
31651
- sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n"
33593
+ cli_printf(stderr,"Error: ambiguous test-control: \"%s\"\n"
3165233594
"Use \".testctrl --help\" for help\n", zCmd);
3165333595
rc = 1;
3165433596
goto meta_command_exit;
3165533597
}
3165633598
}
3165733599
}
3165833600
if( testctrl<0 ){
31659
- sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n"
33601
+ cli_printf(stderr,"Error: unknown test-control: %s\n"
3166033602
"Use \".testctrl --help\" for help\n", zCmd);
3166133603
}else{
3166233604
switch(testctrl){
3166333605
3166433606
/* Special processing for .testctrl opt MASK ...
@@ -31734,17 +33676,17 @@
3173433676
int jj;
3173533677
for(jj=0; jj<ArraySize(aLabel); jj++){
3173633678
if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
3173733679
}
3173833680
if( jj>=ArraySize(aLabel) ){
31739
- sqlite3_fprintf(stderr,
33681
+ cli_printf(stderr,
3174033682
"Error: no such optimization: \"%s\"\n", zLabel);
31741
- sqlite3_fputs("Should be one of:", stderr);
33683
+ cli_puts("Should be one of:", stderr);
3174233684
for(jj=0; jj<ArraySize(aLabel); jj++){
31743
- sqlite3_fprintf(stderr," %s", aLabel[jj].zLabel);
33685
+ cli_printf(stderr," %s", aLabel[jj].zLabel);
3174433686
}
31745
- sqlite3_fputs("\n", stderr);
33687
+ cli_puts("\n", stderr);
3174633688
rc = 1;
3174733689
goto meta_command_exit;
3174833690
}
3174933691
if( useLabel=='+' ){
3175033692
newOpt &= ~aLabel[jj].mask;
@@ -31758,27 +33700,27 @@
3175833700
}
3175933701
for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){
3176033702
if( m & newOpt ) nOff++;
3176133703
}
3176233704
if( nOff<12 ){
31763
- sqlite3_fputs("+All", p->out);
33705
+ cli_puts("+All", p->out);
3176433706
for(ii=0; ii<ArraySize(aLabel); ii++){
3176533707
if( !aLabel[ii].bDsply ) continue;
3176633708
if( (newOpt & aLabel[ii].mask)!=0 ){
31767
- sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel);
33709
+ cli_printf(p->out, " -%s", aLabel[ii].zLabel);
3176833710
}
3176933711
}
3177033712
}else{
31771
- sqlite3_fputs("-All", p->out);
33713
+ cli_puts("-All", p->out);
3177233714
for(ii=0; ii<ArraySize(aLabel); ii++){
3177333715
if( !aLabel[ii].bDsply ) continue;
3177433716
if( (newOpt & aLabel[ii].mask)==0 ){
31775
- sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel);
33717
+ cli_printf(p->out, " +%s", aLabel[ii].zLabel);
3177633718
}
3177733719
}
3177833720
}
31779
- sqlite3_fputs("\n", p->out);
33721
+ cli_puts("\n", p->out);
3178033722
rc2 = isOk = 3;
3178133723
break;
3178233724
}
3178333725
3178433726
/* sqlite3_test_control(int, db, int) */
@@ -31814,11 +33756,11 @@
3181433756
if( nArg==3 || nArg==4 ){
3181533757
int ii = (int)integerValue(azArg[2]);
3181633758
sqlite3 *db;
3181733759
if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){
3181833760
sqlite3_randomness(sizeof(ii),&ii);
31819
- sqlite3_fprintf(stdout, "-- random seed: %d\n", ii);
33761
+ cli_printf(stdout, "-- random seed: %d\n", ii);
3182033762
}
3182133763
if( nArg==3 ){
3182233764
db = 0;
3182333765
}else{
3182433766
db = p->db;
@@ -31867,11 +33809,11 @@
3186733809
break;
3186833810
3186933811
case SQLITE_TESTCTRL_SEEK_COUNT: {
3187033812
u64 x = 0;
3187133813
rc2 = sqlite3_test_control(testctrl, p->db, &x);
31872
- sqlite3_fprintf(p->out, "%llu\n", x);
33814
+ cli_printf(p->out, "%llu\n", x);
3187333815
isOk = 3;
3187433816
break;
3187533817
}
3187633818
3187733819
#ifdef YYCOVERAGE
@@ -31898,15 +33840,15 @@
3189833840
int id = 1;
3189933841
while(1){
3190033842
int val = 0;
3190133843
rc2 = sqlite3_test_control(testctrl, -id, &val);
3190233844
if( rc2!=SQLITE_OK ) break;
31903
- if( id>1 ) sqlite3_fputs(" ", p->out);
31904
- sqlite3_fprintf(p->out, "%d: %d", id, val);
33845
+ if( id>1 ) cli_puts(" ", p->out);
33846
+ cli_printf(p->out, "%d: %d", id, val);
3190533847
id++;
3190633848
}
31907
- if( id>1 ) sqlite3_fputs("\n", p->out);
33849
+ if( id>1 ) cli_puts("\n", p->out);
3190833850
isOk = 3;
3190933851
}
3191033852
break;
3191133853
}
3191233854
#endif
@@ -31941,11 +33883,11 @@
3194133883
const char *zTestArg;
3194233884
int nOp;
3194333885
int ii, jj, x;
3194433886
int *aOp;
3194533887
if( nArg!=4 ){
31946
- sqlite3_fprintf(stderr,
33888
+ cli_printf(stderr,
3194733889
"ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n"
3194833890
);
3194933891
rc = 1;
3195033892
goto meta_command_exit;
3195133893
}
@@ -31964,11 +33906,11 @@
3196433906
x = 0;
3196533907
}
3196633908
}
3196733909
aOp[jj] = x;
3196833910
x = sqlite3_test_control(testctrl, iSize, aOp);
31969
- sqlite3_fprintf(p->out, "result: %d\n", x);
33911
+ cli_printf(p->out, "result: %d\n", x);
3197033912
free(aOp);
3197133913
break;
3197233914
}
3197333915
case SQLITE_TESTCTRL_FAULT_INSTALL: {
3197433916
int kk;
@@ -31987,25 +33929,25 @@
3198733929
}else if( cli_strcmp(z,"reset")==0 ){
3198833930
faultsim_state.iCnt = faultsim_state.nSkip;
3198933931
faultsim_state.nHit = 0;
3199033932
sqlite3_test_control(testctrl, faultsim_callback);
3199133933
}else if( cli_strcmp(z,"status")==0 ){
31992
- sqlite3_fprintf(p->out, "faultsim.iId: %d\n",
33934
+ cli_printf(p->out, "faultsim.iId: %d\n",
3199333935
faultsim_state.iId);
31994
- sqlite3_fprintf(p->out, "faultsim.iErr: %d\n",
33936
+ cli_printf(p->out, "faultsim.iErr: %d\n",
3199533937
faultsim_state.iErr);
31996
- sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n",
33938
+ cli_printf(p->out, "faultsim.iCnt: %d\n",
3199733939
faultsim_state.iCnt);
31998
- sqlite3_fprintf(p->out, "faultsim.nHit: %d\n",
33940
+ cli_printf(p->out, "faultsim.nHit: %d\n",
3199933941
faultsim_state.nHit);
32000
- sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n",
33942
+ cli_printf(p->out, "faultsim.iInterval: %d\n",
3200133943
faultsim_state.iInterval);
32002
- sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n",
33944
+ cli_printf(p->out, "faultsim.eVerbose: %d\n",
3200333945
faultsim_state.eVerbose);
32004
- sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n",
33946
+ cli_printf(p->out, "faultsim.nRepeat: %d\n",
3200533947
faultsim_state.nRepeat);
32006
- sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n",
33948
+ cli_printf(p->out, "faultsim.nSkip: %d\n",
3200733949
faultsim_state.nSkip);
3200833950
}else if( cli_strcmp(z,"-v")==0 ){
3200933951
if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++;
3201033952
}else if( cli_strcmp(z,"-q")==0 ){
3201133953
if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--;
@@ -32020,20 +33962,20 @@
3202033962
}else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){
3202133963
faultsim_state.nSkip = atoi(azArg[++kk]);
3202233964
}else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){
3202333965
bShowHelp = 1;
3202433966
}else{
32025
- sqlite3_fprintf(stderr,
33967
+ cli_printf(stderr,
3202633968
"Unrecognized fault_install argument: \"%s\"\n",
3202733969
azArg[kk]);
3202833970
rc = 1;
3202933971
bShowHelp = 1;
3203033972
break;
3203133973
}
3203233974
}
3203333975
if( bShowHelp ){
32034
- sqlite3_fputs(
33976
+ cli_puts(
3203533977
"Usage: .testctrl fault_install ARGS\n"
3203633978
"Possible arguments:\n"
3203733979
" off Disable faultsim\n"
3203833980
" on Activate faultsim\n"
3203933981
" reset Reset the trigger counter\n"
@@ -32051,17 +33993,17 @@
3205133993
break;
3205233994
}
3205333995
}
3205433996
}
3205533997
if( isOk==0 && iCtrl>=0 ){
32056
- sqlite3_fprintf(p->out,
33998
+ cli_printf(p->out,
3205733999
"Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
3205834000
rc = 1;
3205934001
}else if( isOk==1 ){
32060
- sqlite3_fprintf(p->out, "%d\n", rc2);
34002
+ cli_printf(p->out, "%d\n", rc2);
3206134003
}else if( isOk==2 ){
32062
- sqlite3_fprintf(p->out, "0x%08x\n", rc2);
34004
+ cli_printf(p->out, "0x%08x\n", rc2);
3206334005
}
3206434006
}else
3206534007
#endif /* !defined(SQLITE_UNTESTABLE) */
3206634008
3206734009
if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){
@@ -32112,17 +34054,17 @@
3211234054
}
3211334055
else if( optionMatch(z, "close") ){
3211434056
mType |= SQLITE_TRACE_CLOSE;
3211534057
}
3211634058
else {
32117
- sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".trace\"\n", z);
34059
+ cli_printf(stderr,"Unknown option \"%s\" on \".trace\"\n", z);
3211834060
rc = 1;
3211934061
goto meta_command_exit;
3212034062
}
3212134063
}else{
3212234064
output_file_close(p->traceOut);
32123
- p->traceOut = output_file_open(z);
34065
+ p->traceOut = output_file_open(p, z);
3212434066
}
3212534067
}
3212634068
if( p->traceOut==0 ){
3212734069
sqlite3_trace_v2(p->db, 0, 0, 0);
3212834070
}else{
@@ -32157,38 +34099,38 @@
3215734099
}else
3215834100
#endif
3215934101
3216034102
if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
3216134103
char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
32162
- sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
34104
+ cli_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
3216334105
sqlite3_libversion(), sqlite3_sourceid());
3216434106
#if SQLITE_HAVE_ZLIB
32165
- sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion());
34107
+ cli_printf(p->out, "zlib version %s\n", zlibVersion());
3216634108
#endif
3216734109
#define CTIMEOPT_VAL_(opt) #opt
3216834110
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
3216934111
#if defined(__clang__) && defined(__clang_major__)
32170
- sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
34112
+ cli_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
3217134113
CTIMEOPT_VAL(__clang_minor__) "."
3217234114
CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz);
3217334115
#elif defined(_MSC_VER)
32174
- sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
34116
+ cli_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
3217534117
#elif defined(__GNUC__) && defined(__VERSION__)
32176
- sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz);
34118
+ cli_printf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz);
3217734119
#endif
3217834120
}else
3217934121
3218034122
if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){
3218134123
const char *zDbName = nArg==2 ? azArg[1] : "main";
3218234124
sqlite3_vfs *pVfs = 0;
3218334125
if( p->db ){
3218434126
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
3218534127
if( pVfs ){
32186
- sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
32187
- sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
32188
- sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
32189
- sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
34128
+ cli_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
34129
+ cli_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
34130
+ cli_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
34131
+ cli_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
3219034132
}
3219134133
}
3219234134
}else
3219334135
3219434136
if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){
@@ -32196,17 +34138,17 @@
3219634138
sqlite3_vfs *pCurrent = 0;
3219734139
if( p->db ){
3219834140
sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
3219934141
}
3220034142
for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
32201
- sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
34143
+ cli_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
3220234144
pVfs==pCurrent ? " <--- CURRENT" : "");
32203
- sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
32204
- sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
32205
- sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
34145
+ cli_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
34146
+ cli_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
34147
+ cli_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
3220634148
if( pVfs->pNext ){
32207
- sqlite3_fputs("-----------------------------------\n", p->out);
34149
+ cli_puts("-----------------------------------\n", p->out);
3220834150
}
3220934151
}
3221034152
}else
3221134153
3221234154
if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){
@@ -32213,11 +34155,11 @@
3221334155
const char *zDbName = nArg==2 ? azArg[1] : "main";
3221434156
char *zVfsName = 0;
3221534157
if( p->db ){
3221634158
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3221734159
if( zVfsName ){
32218
- sqlite3_fprintf(p->out, "%s\n", zVfsName);
34160
+ cli_printf(p->out, "%s\n", zVfsName);
3221934161
sqlite3_free(zVfsName);
3222034162
}
3222134163
}
3222234164
}else
3222334165
@@ -32226,33 +34168,32 @@
3222634168
sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
3222734169
}else
3222834170
3222934171
if( c=='w' && cli_strncmp(azArg[0], "width", n)==0 ){
3223034172
int j;
32231
- assert( nArg<=ArraySize(azArg) );
32232
- p->nWidth = nArg-1;
32233
- p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2);
32234
- if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
32235
- if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
34173
+ p->mode.spec.nWidth = nArg-1;
34174
+ p->mode.spec.aWidth = realloc(p->mode.spec.aWidth,
34175
+ (p->mode.spec.nWidth+1)*sizeof(short int));
34176
+ shell_check_oom(p->mode.spec.aWidth);
3223634177
for(j=1; j<nArg; j++){
3223734178
i64 w = integerValue(azArg[j]);
32238
- if( w < -30000 ) w = -30000;
32239
- if( w > +30000 ) w = +30000;
32240
- p->colWidth[j-1] = (int)w;
34179
+ if( w < -QRF_MAX_WIDTH ) w = -QRF_MAX_WIDTH;
34180
+ if( w > QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
34181
+ p->mode.spec.aWidth[j-1] = (short int)w;
3224134182
}
3224234183
}else
3224334184
3224434185
{
32245
- sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: "
34186
+ cli_printf(stderr,"Error: unknown command or invalid arguments: "
3224634187
" \"%s\". Enter \".help\" for help\n", azArg[0]);
3224734188
rc = 1;
3224834189
}
3224934190
3225034191
meta_command_exit:
32251
- if( p->outCount ){
32252
- p->outCount--;
32253
- if( p->outCount==0 ) output_reset(p);
34192
+ if( p->nPopOutput ){
34193
+ p->nPopOutput--;
34194
+ if( p->nPopOutput==0 ) output_reset(p);
3225434195
}
3225534196
p->bSafeMode = p->bSafeModePersist;
3225634197
return rc;
3225734198
}
3225834199
@@ -32513,29 +34454,29 @@
3251334454
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
3251434455
"%s near line %d:", zErrorType, startline);
3251534456
}else{
3251634457
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
3251734458
}
32518
- sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail);
34459
+ cli_printf(stderr,"%s %s\n", zPrefix, zErrorTail);
3251934460
sqlite3_free(zErrMsg);
3252034461
zErrMsg = 0;
3252134462
return 1;
3252234463
}else if( ShellHasFlag(p, SHFLG_CountChanges) ){
3252334464
char zLineBuf[2000];
3252434465
sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
3252534466
"changes: %lld total_changes: %lld",
3252634467
sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
32527
- sqlite3_fprintf(p->out, "%s\n", zLineBuf);
34468
+ cli_printf(p->out, "%s\n", zLineBuf);
3252834469
}
3252934470
3253034471
if( doAutoDetectRestore(p, zSql) ) return 1;
3253134472
return 0;
3253234473
}
3253334474
3253434475
static void echo_group_input(ShellState *p, const char *zDo){
32535
- if( ShellHasFlag(p, SHFLG_Echo) ){
32536
- sqlite3_fprintf(p->out, "%s\n", zDo);
34476
+ if( p->mode.mFlags & MFLG_ECHO ){
34477
+ cli_printf(p->out, "%s\n", zDo);
3253734478
fflush(p->out);
3253834479
}
3253934480
}
3254034481
3254134482
#ifdef SQLITE_SHELL_FIDDLE
@@ -32588,26 +34529,31 @@
3258834529
i64 nAlloc = 0; /* Allocated zSql[] space */
3258934530
int rc; /* Error code */
3259034531
int errCnt = 0; /* Number of errors seen */
3259134532
i64 startline = 0; /* Line number for start of current input */
3259234533
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
34534
+ const char *saved_zInFile; /* Prior value of p->zInFile */
34535
+ i64 saved_lineno; /* Prior value of p->lineno */
3259334536
3259434537
if( p->inputNesting==MAX_INPUT_NESTING ){
3259534538
/* This will be more informative in a later version. */
32596
- sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
34539
+ cli_printf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
3259734540
" Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
3259834541
return 1;
3259934542
}
3260034543
++p->inputNesting;
34544
+ saved_zInFile = p->zInFile;
34545
+ p->zInFile = zSrc;
34546
+ saved_lineno = p->lineno;
3260134547
p->lineno = 0;
3260234548
CONTINUE_PROMPT_RESET;
3260334549
while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
3260434550
fflush(p->out);
3260534551
zLine = one_input_line(p->in, zLine, nSql>0);
3260634552
if( zLine==0 ){
3260734553
/* End of input */
32608
- if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out);
34554
+ if( p->in==0 && stdin_is_interactive ) cli_puts("\n", p->out);
3260934555
break;
3261034556
}
3261134557
if( seenInterrupt ){
3261234558
if( p->in!=0 ) break;
3261334559
seenInterrupt = 0;
@@ -32660,25 +34606,29 @@
3266034606
nSql += nLine;
3266134607
}
3266234608
if( nSql>0x7fff0000 ){
3266334609
char zSize[100];
3266434610
sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
32665
- sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
34611
+ cli_printf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
3266634612
zSrc, startline, zSize);
3266734613
nSql = 0;
3266834614
errCnt++;
3266934615
break;
3267034616
}else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
3267134617
echo_group_input(p, zSql);
3267234618
errCnt += runOneSqlLine(p, zSql, p->in, startline);
3267334619
CONTINUE_PROMPT_RESET;
3267434620
nSql = 0;
32675
- if( p->outCount ){
34621
+ if( p->nPopOutput ){
3267634622
output_reset(p);
32677
- p->outCount = 0;
34623
+ p->nPopOutput = 0;
3267834624
}else{
3267934625
clearTempFile(p);
34626
+ }
34627
+ if( p->nPopMode ){
34628
+ modePop(p);
34629
+ p->nPopMode = 0;
3268034630
}
3268134631
p->bSafeMode = p->bSafeModePersist;
3268234632
qss = QSS_Start;
3268334633
}else if( nSql && QSS_PLAINWHITE(qss) ){
3268434634
echo_group_input(p, zSql);
@@ -32693,10 +34643,12 @@
3269334643
CONTINUE_PROMPT_RESET;
3269434644
}
3269534645
free(zSql);
3269634646
free(zLine);
3269734647
--p->inputNesting;
34648
+ p->zInFile = saved_zInFile;
34649
+ p->lineno = saved_lineno;
3269834650
return errCnt>0;
3269934651
}
3270034652
3270134653
/*
3270234654
** Return a pathname which is the user's home directory. A
@@ -32853,17 +34805,17 @@
3285334805
shell_check_oom(sqliterc);
3285434806
}
3285534807
p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
3285634808
if( p->in ){
3285734809
if( stdin_is_interactive ){
32858
- sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
34810
+ cli_printf(stderr,"-- Loading resources from %s\n", sqliterc);
3285934811
}
32860
- if( process_input(p, sqliterc) && bail_on_error ) exit(1);
34812
+ if( process_input(p, sqliterc) && bail_on_error ) cli_exit(1);
3286134813
fclose(p->in);
3286234814
}else if( sqliterc_override!=0 ){
32863
- sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
32864
- if( bail_on_error ) exit(1);
34815
+ cli_printf(stderr,"cannot open: \"%s\"\n", sqliterc);
34816
+ if( bail_on_error ) cli_exit(1);
3286534817
}
3286634818
p->in = inSaved;
3286734819
p->lineno = savedLineno;
3286834820
if( sqliterc != sqliterc_override ){
3286934821
sqlite3_free(sqliterc);
@@ -32881,12 +34833,13 @@
3288134833
" -append append the database to the end of the file\n"
3288234834
" -ascii set output mode to 'ascii'\n"
3288334835
" -bail stop after hitting an error\n"
3288434836
" -batch force batch I/O\n"
3288534837
" -box set output mode to 'box'\n"
32886
- " -column set output mode to 'column'\n"
3288734838
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
34839
+ " -column set output mode to 'column'\n"
34840
+ " -compat YYYYMMDD set default options for date YYYYMMDD\n"
3288834841
" -csv set output mode to 'csv'\n"
3288934842
#if !defined(SQLITE_OMIT_DESERIALIZE)
3289034843
" -deserialize open the database using sqlite3_deserialize()\n"
3289134844
#endif
3289234845
" -echo print inputs before execution\n"
@@ -32913,18 +34866,20 @@
3291334866
#ifdef SQLITE_ENABLE_MULTIPLEX
3291434867
" -multiplex enable the multiplexor VFS\n"
3291534868
#endif
3291634869
" -newline SEP set output row separator. Default: '\\n'\n"
3291734870
" -nofollow refuse to open symbolic links to database files\n"
34871
+ " -noinit Do not read the ~/.sqliterc file at startup\n"
3291834872
" -nonce STRING set the safe-mode escape nonce\n"
3291934873
" -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
3292034874
" -nullvalue TEXT set text string for NULL values. Default ''\n"
3292134875
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
3292234876
" -pcachetrace trace all page cache operations\n"
3292334877
" -quote set output mode to 'quote'\n"
3292434878
" -readonly open the database read-only\n"
3292534879
" -safe enable safe-mode\n"
34880
+ " -screenwidth N use N as the default screenwidth \n"
3292634881
" -separator SEP set output column separator. Default: '|'\n"
3292734882
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
3292834883
" -sorterref SIZE sorter references threshold size\n"
3292934884
#endif
3293034885
" -stats print memory stats before each finalize\n"
@@ -32937,15 +34892,15 @@
3293734892
#ifdef SQLITE_HAVE_ZLIB
3293834893
" -zip open the file as a ZIP Archive\n"
3293934894
#endif
3294034895
;
3294134896
static void usage(int showDetail){
32942
- sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL...]]\n"
34897
+ cli_printf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL...]]\n"
3294334898
"FILENAME is the name of an SQLite database. A new database is created\n"
3294434899
"if the file does not previously exist. Defaults to :memory:.\n", Argv0);
3294534900
if( showDetail ){
32946
- sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions);
34901
+ cli_printf(stderr,"OPTIONS include:\n%s", zOptions);
3294734902
}else{
3294834903
eputz("Use the -help option for additional information\n");
3294934904
}
3295034905
exit(0);
3295134906
}
@@ -32962,23 +34917,20 @@
3296234917
}
3296334918
3296434919
/*
3296534920
** Initialize the state information in data
3296634921
*/
32967
-static void main_init(ShellState *data) {
32968
- memset(data, 0, sizeof(*data));
32969
- data->normalMode = data->cMode = data->mode = MODE_List;
32970
- data->autoExplain = 1;
32971
-#ifdef _WIN32
32972
- data->crlfMode = 1;
34922
+static void main_init(ShellState *p) {
34923
+ memset(p, 0, sizeof(*p));
34924
+#if defined(COMPATIBILITY_DATE)
34925
+ p->iCompat = COMPATIBILITY_DATE;
34926
+#else
34927
+ p->iCompat = 20251116;
3297334928
#endif
32974
- data->pAuxDb = &data->aAuxDb[0];
32975
- memcpy(data->colSeparator,SEP_Column, 2);
32976
- memcpy(data->rowSeparator,SEP_Row, 2);
32977
- data->showHeader = 0;
32978
- data->shellFlgs = SHFLG_Lookaside;
32979
- sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
34929
+ p->pAuxDb = &p->aAuxDb[0];
34930
+ p->shellFlgs = SHFLG_Lookaside;
34931
+ sqlite3_config(SQLITE_CONFIG_LOG, shellLog, p);
3298034932
#if !defined(SQLITE_SHELL_FIDDLE)
3298134933
verify_uninitialized();
3298234934
#endif
3298334935
sqlite3_config(SQLITE_CONFIG_URI, 1);
3298434936
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
@@ -33004,23 +34956,23 @@
3300434956
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
3300534957
#endif
3300634958
}
3300734959
#else
3300834960
static void printBold(const char *zText){
33009
- sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText);
34961
+ cli_printf(stdout, "\033[1m%s\033[0m", zText);
3301034962
}
3301134963
#endif
3301234964
3301334965
/*
3301434966
** Get the argument to an --option. Throw an error and die if no argument
3301534967
** is available.
3301634968
*/
3301734969
static char *cmdline_option_value(int argc, char **argv, int i){
3301834970
if( i==argc ){
33019
- sqlite3_fprintf(stderr,
34971
+ cli_printf(stderr,
3302034972
"%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
33021
- exit(1);
34973
+ cli_exit(1);
3302234974
}
3302334975
return argv[i];
3302434976
}
3302534977
3302634978
static void sayAbnormalExit(void){
@@ -33029,11 +34981,11 @@
3302934981
3303034982
/* Routine to output from vfstrace
3303134983
*/
3303234984
static int vfstraceOut(const char *z, void *pArg){
3303334985
ShellState *p = (ShellState*)pArg;
33034
- sqlite3_fputs(z, p->out);
34986
+ cli_puts(z, p->out);
3303534987
fflush(p->out);
3303634988
return 1;
3303734989
}
3303834990
3303934991
#ifndef SQLITE_SHELL_IS_UTF8
@@ -33067,14 +35019,16 @@
3306735019
const char *zInitFile = 0;
3306835020
int i;
3306935021
int rc = 0;
3307035022
int warnInmemoryDb = 0;
3307135023
int readStdin = 1;
35024
+ int noInit = 0; /* Do not read ~/.sqliterc if true */
3307235025
int nCmd = 0;
3307335026
int nOptsEnd = argc;
3307435027
int bEnableVfstrace = 0;
3307535028
char **azCmd = 0;
35029
+ int *aiCmd = 0;
3307635030
const char *zVfs = 0; /* Value of -vfs command-line option */
3307735031
#if !SQLITE_SHELL_IS_UTF8
3307835032
char **argvToFree = 0;
3307935033
int argcToFree = 0;
3308035034
#endif
@@ -33094,11 +35048,11 @@
3309435048
#endif
3309535049
#if !defined(_WIN32_WCE)
3309635050
if( getenv("SQLITE_DEBUG_BREAK") ){
3309735051
if( isatty(0) && isatty(2) ){
3309835052
char zLine[100];
33099
- sqlite3_fprintf(stderr,
35053
+ cli_printf(stderr,
3310035054
"attach debugger to process %d and press ENTER to continue...",
3310135055
GETPID());
3310235056
if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0
3310335057
&& cli_strcmp(zLine,"stop")==0
3310435058
){
@@ -33126,11 +35080,11 @@
3312635080
}
3312735081
#endif
3312835082
3312935083
#if USE_SYSTEM_SQLITE+0!=1
3313035084
if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
33131
- sqlite3_fprintf(stderr,
35085
+ cli_printf(stderr,
3313235086
"SQLite header and source version mismatch\n%s\n%s\n",
3313335087
sqlite3_sourceid(), SQLITE_SOURCE_ID);
3313435088
exit(1);
3313535089
}
3313635090
#endif
@@ -33193,14 +35147,18 @@
3319335147
data.aAuxDb->zDbFilename = z;
3319435148
}else{
3319535149
/* Excess arguments are interpreted as SQL (or dot-commands) and
3319635150
** mean that nothing is read from stdin */
3319735151
readStdin = 0;
35152
+ stdin_is_interactive = 0;
3319835153
nCmd++;
3319935154
azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
3320035155
shell_check_oom(azCmd);
35156
+ aiCmd = realloc(aiCmd, sizeof(aiCmd[0])*nCmd);
35157
+ shell_check_oom(azCmd);
3320135158
azCmd[nCmd-1] = z;
35159
+ aiCmd[nCmd-1] = i;
3320235160
}
3320335161
continue;
3320435162
}
3320535163
if( z[1]=='-' ) z++;
3320635164
if( cli_strcmp(z, "-")==0 ){
@@ -33219,10 +35177,24 @@
3321935177
/* Need to check for batch mode here to so we can avoid printing
3322035178
** informational messages (like from process_sqliterc) before
3322135179
** we do the actual processing of arguments later in a second pass.
3322235180
*/
3322335181
stdin_is_interactive = 0;
35182
+ stdout_is_console = 0;
35183
+ modeChange(&data, MODE_BATCH);
35184
+ }else if( cli_strcmp(z,"-screenwidth")==0 ){
35185
+ int n = atoi(cmdline_option_value(argc, argv, ++i));
35186
+ if( n<2 ){
35187
+ sqlite3_fprintf(stderr,"minimum --screenwidth is 2\n");
35188
+ exit(1);
35189
+ }
35190
+ stdout_tty_width = n;
35191
+ }else if( cli_strcmp(z,"-compat")==0 ){
35192
+ data.iCompat = atoi(cmdline_option_value(argc, argv, ++i));
35193
+ modeFree(&data.mode);
35194
+ memset(&data.mode, 0, sizeof(data.mode));
35195
+ modeDefault(&data);
3322435196
}else if( cli_strcmp(z,"-utf8")==0 ){
3322535197
}else if( cli_strcmp(z,"-no-utf8")==0 ){
3322635198
}else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
3322735199
int val = 0;
3322835200
sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val);
@@ -33252,11 +35224,11 @@
3325235224
if( sz>0 && (sz & (sz-1))==0 ){
3325335225
/* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */
3325435226
int szHdr = 0;
3325535227
sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr);
3325635228
sz += szHdr;
33257
- sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate"
35229
+ cli_printf(stdout, "Page cache size increased to %d to accommodate"
3325835230
" the %d-byte headers\n", (int)sz, szHdr);
3325935231
}
3326035232
verify_uninitialized();
3326135233
sqlite3_config(SQLITE_CONFIG_PAGECACHE,
3326235234
(n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
@@ -33313,10 +35285,12 @@
3331335285
}else if( cli_strcmp(z,"-readonly")==0 ){
3331435286
data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
3331535287
data.openFlags |= SQLITE_OPEN_READONLY;
3331635288
}else if( cli_strcmp(z,"-nofollow")==0 ){
3331735289
data.openFlags |= SQLITE_OPEN_NOFOLLOW;
35290
+ }else if( cli_strcmp(z,"-noinit")==0 ){
35291
+ noInit = 1;
3331835292
}else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
3331935293
data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
3332035294
}else if( cli_strcmp(z,"-ifexists")==0 ){
3332135295
data.openFlags &= ~(SQLITE_OPEN_CREATE);
3332235296
if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
@@ -33367,21 +35341,21 @@
3336735341
if( zVfs ){
3336835342
sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
3336935343
if( pVfs ){
3337035344
sqlite3_vfs_register(pVfs, 1);
3337135345
}else{
33372
- sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs);
35346
+ cli_printf(stderr,"no such VFS: \"%s\"\n", zVfs);
3337335347
exit(1);
3337435348
}
3337535349
}
3337635350
3337735351
if( data.pAuxDb->zDbFilename==0 ){
3337835352
#ifndef SQLITE_OMIT_MEMORYDB
3337935353
data.pAuxDb->zDbFilename = ":memory:";
3338035354
warnInmemoryDb = argc==1;
3338135355
#else
33382
- sqlite3_fprintf(stderr,
35356
+ cli_printf(stderr,
3338335357
"%s: Error: no database filename specified\n", Argv0);
3338435358
return 1;
3338535359
#endif
3338635360
}
3338735361
data.out = stdout;
@@ -33389,10 +35363,11 @@
3338935363
vfstrace_register("trace",0,vfstraceOut, &data, 1);
3339035364
}
3339135365
#ifndef SQLITE_SHELL_FIDDLE
3339235366
sqlite3_appendvfs_init(0,0,0);
3339335367
#endif
35368
+ modeDefault(&data);
3339435369
3339535370
/* Go ahead and open the database file if it already exists. If the
3339635371
** file does not exist, delay opening it. This prevents empty database
3339735372
** files from being created if a user mistypes the database name argument
3339835373
** to the sqlite command-line tool.
@@ -33403,11 +35378,11 @@
3340335378
3340435379
/* Process the initialization file if there is one. If no -init option
3340535380
** is given on the command line, look for a file named ~/.sqliterc and
3340635381
** try to process it.
3340735382
*/
33408
- process_sqliterc(&data,zInitFile);
35383
+ if( !noInit ) process_sqliterc(&data,zInitFile);
3340935384
3341035385
/* Make a second pass through the command-line argument and set
3341135386
** options. This second pass is delayed until after the initialization
3341235387
** file is processed so that the command-line arguments will override
3341335388
** settings in the initialization file.
@@ -33417,49 +35392,46 @@
3341735392
if( z[0]!='-' || i>=nOptsEnd ) continue;
3341835393
if( z[1]=='-' ){ z++; }
3341935394
if( cli_strcmp(z,"-init")==0 ){
3342035395
i++;
3342135396
}else if( cli_strcmp(z,"-html")==0 ){
33422
- data.mode = MODE_Html;
35397
+ modeChange(&data, MODE_Html);
3342335398
}else if( cli_strcmp(z,"-list")==0 ){
33424
- data.mode = MODE_List;
35399
+ modeChange(&data, MODE_List);
3342535400
}else if( cli_strcmp(z,"-quote")==0 ){
33426
- data.mode = MODE_Quote;
33427
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
33428
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
35401
+ modeChange(&data, MODE_Quote);
3342935402
}else if( cli_strcmp(z,"-line")==0 ){
33430
- data.mode = MODE_Line;
35403
+ modeChange(&data, MODE_Line);
3343135404
}else if( cli_strcmp(z,"-column")==0 ){
33432
- data.mode = MODE_Column;
35405
+ modeChange(&data, MODE_Column);
3343335406
}else if( cli_strcmp(z,"-json")==0 ){
33434
- data.mode = MODE_Json;
35407
+ modeChange(&data, MODE_Json);
3343535408
}else if( cli_strcmp(z,"-markdown")==0 ){
33436
- data.mode = MODE_Markdown;
35409
+ modeChange(&data, MODE_Markdown);
3343735410
}else if( cli_strcmp(z,"-table")==0 ){
33438
- data.mode = MODE_Table;
35411
+ modeChange(&data, MODE_Table);
3343935412
}else if( cli_strcmp(z,"-box")==0 ){
33440
- data.mode = MODE_Box;
35413
+ modeChange(&data, MODE_Box);
3344135414
}else if( cli_strcmp(z,"-csv")==0 ){
33442
- data.mode = MODE_Csv;
33443
- memcpy(data.colSeparator,",",2);
35415
+ modeChange(&data, MODE_Csv);
3344435416
}else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
3344535417
/* See similar code at tag-20250224-1 */
3344635418
const char *zEsc = argv[++i];
3344735419
int k;
33448
- for(k=0; k<ArraySize(shell_EscModeNames); k++){
33449
- if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){
33450
- data.eEscMode = k;
35420
+ for(k=0; k<ArraySize(qrfEscNames); k++){
35421
+ if( sqlite3_stricmp(zEsc,qrfEscNames[k])==0 ){
35422
+ data.mode.spec.eEsc = k;
3345135423
break;
3345235424
}
3345335425
}
33454
- if( k>=ArraySize(shell_EscModeNames) ){
33455
- sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
35426
+ if( k>=ArraySize(qrfEscNames) ){
35427
+ cli_printf(stderr, "unknown control character escape mode \"%s\""
3345635428
" - choices:", zEsc);
33457
- for(k=0; k<ArraySize(shell_EscModeNames); k++){
33458
- sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
35429
+ for(k=0; k<ArraySize(qrfEscNames); k++){
35430
+ cli_printf(stderr, " %s", qrfEscNames[k]);
3345935431
}
33460
- sqlite3_fprintf(stderr, "\n");
35432
+ cli_printf(stderr, "\n");
3346135433
exit(1);
3346235434
}
3346335435
#ifdef SQLITE_HAVE_ZLIB
3346435436
}else if( cli_strcmp(z,"-zip")==0 ){
3346535437
data.openMode = SHELL_OPEN_ZIPFILE;
@@ -33475,48 +35447,44 @@
3347535447
}else if( cli_strcmp(z,"-readonly")==0 ){
3347635448
data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
3347735449
data.openFlags |= SQLITE_OPEN_READONLY;
3347835450
}else if( cli_strcmp(z,"-nofollow")==0 ){
3347935451
data.openFlags |= SQLITE_OPEN_NOFOLLOW;
35452
+ }else if( cli_strcmp(z,"-noinit")==0 ){
35453
+ /* No-op */
3348035454
}else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
3348135455
data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
3348235456
}else if( cli_strcmp(z,"-ifexists")==0 ){
3348335457
data.openFlags &= ~(SQLITE_OPEN_CREATE);
3348435458
if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
3348535459
}else if( cli_strcmp(z,"-ascii")==0 ){
33486
- data.mode = MODE_Ascii;
33487
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit);
33488
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record);
35460
+ modeChange(&data, MODE_Ascii);
3348935461
}else if( cli_strcmp(z,"-tabs")==0 ){
33490
- data.mode = MODE_List;
33491
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab);
33492
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row);
35462
+ modeChange(&data, MODE_Tabs);
3349335463
}else if( cli_strcmp(z,"-separator")==0 ){
33494
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
33495
- "%s",cmdline_option_value(argc,argv,++i));
35464
+ modeSetStr(&data.mode.spec.zColumnSep,
35465
+ cmdline_option_value(argc,argv,++i));
3349635466
}else if( cli_strcmp(z,"-newline")==0 ){
33497
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
33498
- "%s",cmdline_option_value(argc,argv,++i));
35467
+ modeSetStr(&data.mode.spec.zRowSep,
35468
+ cmdline_option_value(argc,argv,++i));
3349935469
}else if( cli_strcmp(z,"-nullvalue")==0 ){
33500
- sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
33501
- "%s",cmdline_option_value(argc,argv,++i));
35470
+ modeSetStr(&data.mode.spec.zNull,
35471
+ cmdline_option_value(argc,argv,++i));
3350235472
}else if( cli_strcmp(z,"-header")==0 ){
33503
- data.showHeader = 1;
33504
- ShellSetFlag(&data, SHFLG_HeaderSet);
35473
+ data.mode.spec.bTitles = QRF_Yes;
3350535474
}else if( cli_strcmp(z,"-noheader")==0 ){
33506
- data.showHeader = 0;
33507
- ShellSetFlag(&data, SHFLG_HeaderSet);
35475
+ data.mode.spec.bTitles = QRF_No;
3350835476
}else if( cli_strcmp(z,"-echo")==0 ){
33509
- ShellSetFlag(&data, SHFLG_Echo);
35477
+ data.mode.mFlags |= MFLG_ECHO;
3351035478
}else if( cli_strcmp(z,"-eqp")==0 ){
33511
- data.autoEQP = AUTOEQP_on;
35479
+ data.mode.autoEQP = AUTOEQP_on;
3351235480
}else if( cli_strcmp(z,"-eqpfull")==0 ){
33513
- data.autoEQP = AUTOEQP_full;
35481
+ data.mode.autoEQP = AUTOEQP_full;
3351435482
}else if( cli_strcmp(z,"-stats")==0 ){
3351535483
data.statsOn = 1;
3351635484
}else if( cli_strcmp(z,"-scanstats")==0 ){
33517
- data.scanstatsOn = 1;
35485
+ data.mode.scanstatsOn = 1;
3351835486
}else if( cli_strcmp(z,"-backslash")==0 ){
3351935487
/* Undocumented command-line option: -backslash
3352035488
** Causes C-style backslash escapes to be evaluated in SQL statements
3352135489
** prior to sending the SQL into SQLite. Useful for injecting
3352235490
** crazy bytes in the middle of SQL statements for testing and debugging.
@@ -33523,20 +35491,24 @@
3352335491
*/
3352435492
ShellSetFlag(&data, SHFLG_Backslash);
3352535493
}else if( cli_strcmp(z,"-bail")==0 ){
3352635494
/* No-op. The bail_on_error flag should already be set. */
3352735495
}else if( cli_strcmp(z,"-version")==0 ){
33528
- sqlite3_fprintf(stdout, "%s %s (%d-bit)\n",
35496
+ cli_printf(stdout, "%s %s (%d-bit)\n",
3352935497
sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
3353035498
return 0;
3353135499
}else if( cli_strcmp(z,"-interactive")==0 ){
3353235500
/* Need to check for interactive override here to so that it can
3353335501
** affect console setup (for Windows only) and testing thereof.
3353435502
*/
3353535503
stdin_is_interactive = 1;
3353635504
}else if( cli_strcmp(z,"-batch")==0 ){
3353735505
/* already handled */
35506
+ }else if( cli_strcmp(z,"-screenwidth")==0 ){
35507
+ i++;
35508
+ }else if( cli_strcmp(z,"-compat")==0 ){
35509
+ i++;
3353835510
}else if( cli_strcmp(z,"-utf8")==0 ){
3353935511
/* already handled */
3354035512
}else if( cli_strcmp(z,"-no-utf8")==0 ){
3354135513
/* already handled */
3354235514
}else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
@@ -33584,20 +35556,21 @@
3358435556
}else{
3358535557
open_db(&data, 0);
3358635558
rc = shell_exec(&data, z, &zErrMsg);
3358735559
if( zErrMsg!=0 ){
3358835560
shellEmitError(zErrMsg);
35561
+ sqlite3_free(zErrMsg);
3358935562
if( bail_on_error ) return rc!=0 ? rc : 1;
3359035563
}else if( rc!=0 ){
33591
- sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
35564
+ cli_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3359235565
if( bail_on_error ) return rc;
3359335566
}
3359435567
}
3359535568
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
3359635569
}else if( cli_strncmp(z, "-A", 2)==0 ){
3359735570
if( nCmd>0 ){
33598
- sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands"
35571
+ cli_printf(stderr,"Error: cannot mix regular SQL or dot-commands"
3359935572
" with \"%s\"\n", z);
3360035573
return 1;
3360135574
}
3360235575
open_db(&data, OPEN_DB_ZIPFILE);
3360335576
if( z[2] ){
@@ -33605,22 +35578,22 @@
3360535578
arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
3360635579
}else{
3360735580
arDotCommand(&data, 1, argv+i, argc-i);
3360835581
}
3360935582
readStdin = 0;
35583
+ stdin_is_interactive = 0;
3361035584
break;
3361135585
#endif
3361235586
}else if( cli_strcmp(z,"-safe")==0 ){
3361335587
data.bSafeMode = data.bSafeModePersist = 1;
3361435588
}else if( cli_strcmp(z,"-unsafe-testing")==0 ){
3361535589
/* Acted upon in first pass. */
3361635590
}else{
33617
- sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
35591
+ cli_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
3361835592
eputz("Use -help for a list of options.\n");
3361935593
return 1;
3362035594
}
33621
- data.cMode = data.mode;
3362235595
}
3362335596
3362435597
if( !readStdin ){
3362535598
/* Run all arguments that do not begin with '-' as if they were separate
3362635599
** command-line inputs, except for the argToSkip argument which contains
@@ -33627,11 +35600,18 @@
3362735600
** the database filename.
3362835601
*/
3362935602
for(i=0; i<nCmd; i++){
3363035603
echo_group_input(&data, azCmd[i]);
3363135604
if( azCmd[i][0]=='.' ){
35605
+ char *zErrCtx = malloc( 64 );
35606
+ shell_check_oom(zErrCtx);
35607
+ sqlite3_snprintf(64,zErrCtx,"argv[%i]:",aiCmd[i]);
35608
+ data.zInFile = "<cmdline>";
35609
+ data.zErrPrefix = zErrCtx;
3363235610
rc = do_meta_command(azCmd[i], &data);
35611
+ free(data.zErrPrefix);
35612
+ data.zErrPrefix = 0;
3363335613
if( rc ){
3363435614
if( rc==2 ) rc = 0;
3363535615
goto shell_main_exit;
3363635616
}
3363735617
}else{
@@ -33639,11 +35619,11 @@
3363935619
rc = shell_exec(&data, azCmd[i], &zErrMsg);
3364035620
if( zErrMsg || rc ){
3364135621
if( zErrMsg!=0 ){
3364235622
shellEmitError(zErrMsg);
3364335623
}else{
33644
- sqlite3_fprintf(stderr,
35624
+ cli_printf(stderr,
3364535625
"Error: unable to process SQL: %s\n", azCmd[i]);
3364635626
}
3364735627
sqlite3_free(zErrMsg);
3364835628
if( rc==0 ) rc = 1;
3364935629
goto shell_main_exit;
@@ -33654,11 +35634,11 @@
3365435634
/* Run commands received from standard input
3365535635
*/
3365635636
if( stdin_is_interactive ){
3365735637
char *zHome;
3365835638
char *zHistory;
33659
- sqlite3_fprintf(stdout,
35639
+ cli_printf(stdout,
3366035640
"SQLite version %s %.19s\n" /*extra-version-info*/
3366135641
"Enter \".help\" for usage hints.\n",
3366235642
sqlite3_libversion(), sqlite3_sourceid());
3366335643
if( warnInmemoryDb ){
3366435644
sputz(stdout, "Connected to a ");
@@ -33707,10 +35687,11 @@
3370735687
expertFinish(&data, 1, 0);
3370835688
}
3370935689
#endif
3371035690
shell_main_exit:
3371135691
free(azCmd);
35692
+ free(aiCmd);
3371235693
set_table_name(&data, 0);
3371335694
if( data.db ){
3371435695
session_close_all(&data, -1);
3371535696
close_db(data.db);
3371635697
}
@@ -33727,21 +35708,41 @@
3372735708
clearTempFile(&data);
3372835709
#if !SQLITE_SHELL_IS_UTF8
3372935710
for(i=0; i<argcToFree; i++) free(argvToFree[i]);
3373035711
free(argvToFree);
3373135712
#endif
33732
- free(data.colWidth);
35713
+ modeFree(&data.mode);
35714
+ if( data.nSavedModes ){
35715
+ int ii;
35716
+ for(ii=0; ii<data.nSavedModes; ii++){
35717
+ modeFree(&data.aSavedModes[ii].mode);
35718
+ free(data.aSavedModes[ii].zTag);
35719
+ }
35720
+ free(data.aSavedModes);
35721
+ }
35722
+ free(data.zErrPrefix);
3373335723
free(data.zNonce);
35724
+ free(data.dot.zCopy);
35725
+ free(data.dot.azArg);
35726
+ free(data.dot.aiOfst);
35727
+ free(data.dot.abQuot);
35728
+ if( data.nTestRun ){
35729
+ sqlite3_fprintf(stdout, "%d test%s run with %d error%s\n",
35730
+ data.nTestRun, data.nTestRun==1 ? "" : "s",
35731
+ data.nTestErr, data.nTestErr==1 ? "" : "s");
35732
+ fflush(stdout);
35733
+ rc = data.nTestErr>0;
35734
+ }
3373435735
/* Clear the global data structure so that valgrind will detect memory
3373535736
** leaks */
3373635737
memset(&data, 0, sizeof(data));
3373735738
if( bEnableVfstrace ){
3373835739
vfstrace_unregister("trace");
3373935740
}
3374035741
#ifdef SQLITE_DEBUG
3374135742
if( sqlite3_memory_used()>mem_main_enter ){
33742
- sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n",
35743
+ cli_printf(stderr,"Memory leaked: %u bytes\n",
3374335744
(unsigned int)(sqlite3_memory_used()-mem_main_enter));
3374435745
}
3374535746
#endif
3374635747
#else /* SQLITE_SHELL_FIDDLE... */
3374735748
shell_main_exit:
@@ -33777,11 +35778,11 @@
3377735778
return pVfs;
3377835779
}
3377935780
3378035781
/* Only for emcc experimentation purposes. */
3378135782
sqlite3 * fiddle_db_arg(sqlite3 *arg){
33782
- sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg);
35783
+ cli_printf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg);
3378335784
return arg;
3378435785
}
3378535786
3378635787
/*
3378735788
** Intended to be called via a SharedWorker() while a separate
@@ -33814,11 +35815,11 @@
3381435815
while( sqlite3_txn_state(globalDb,0)>0 ){
3381535816
/*
3381635817
** Resolve problem reported in
3381735818
** https://sqlite.org/forum/forumpost/0b41a25d65
3381835819
*/
33819
- sqlite3_fputs("Rolling back in-progress transaction.\n", stdout);
35820
+ cli_puts("Rolling back in-progress transaction.\n", stdout);
3382035821
sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0);
3382135822
}
3382235823
rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
3382335824
if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0);
3382435825
sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
@@ -33881,5 +35882,6 @@
3388135882
process_input(&shellState, "<stdin>");
3388235883
shellState.wasm.zInput = shellState.wasm.zPos = 0;
3388335884
}
3388435885
}
3388535886
#endif /* SQLITE_SHELL_FIDDLE */
35887
+/************************* End src/shell.c.in ******************/
3388635888
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1,23 +1,47 @@
1 /* DO NOT EDIT!
2 ** This file is automatically generated by the script in the canonical
3 ** SQLite source tree at tool/mkshellc.tcl. That script combines source
4 ** code from various constituent source files of SQLite into this single
5 ** "shell.c" file used to implement the SQLite command-line shell.
6 **
7 ** Most of the code found below comes from the "src/shell.c.in" file in
8 ** the canonical SQLite source tree. That main file contains "INCLUDE"
9 ** lines that specify other files in the canonical source tree that are
10 ** inserted to getnerate this complete program source file.
11 **
12 ** The code from multiple files is combined into this single "shell.c"
13 ** source file to help make the command-line program easier to compile.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14 **
15 ** To modify this program, get a copy of the canonical SQLite source tree,
16 ** edit the src/shell.c.in" and/or some of the other files that are included
17 ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
18 */
 
19 /*
20 ** 2001 September 15
21 **
22 ** The author disclaims copyright to this source code. In place of
23 ** a legal notice, here is a blessing:
@@ -124,10 +148,11 @@
124 typedef unsigned char u8;
125 #include <ctype.h>
126 #include <stdarg.h>
127 #ifndef _WIN32
128 # include <sys/time.h>
 
129 #endif
130
131 #if !defined(_WIN32) && !defined(WIN32)
132 # include <signal.h>
133 # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
@@ -253,11 +278,11 @@
253 /* string conversion routines only needed on Win32 */
254 extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
255 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
256 #endif
257
258 /************************* Begin ../ext/misc/sqlite3_stdio.h ******************/
259 /*
260 ** 2024-09-24
261 **
262 ** The author disclaims copyright to this source code. In place of
263 ** a legal notice, here is a blessing:
@@ -287,17 +312,19 @@
287 #ifndef _SQLITE3_STDIO_H_
288 #define _SQLITE3_STDIO_H_ 1
289 #ifdef _WIN32
290 /**** Definitions For Windows ****/
291 #include <stdio.h>
 
292 #include <windows.h>
293
294 FILE *sqlite3_fopen(const char *zFilename, const char *zMode);
295 FILE *sqlite3_popen(const char *zCommand, const char *type);
296 char *sqlite3_fgets(char *s, int size, FILE *stream);
297 int sqlite3_fputs(const char *s, FILE *stream);
298 int sqlite3_fprintf(FILE *stream, const char *format, ...);
 
299 void sqlite3_fsetmode(FILE *stream, int mode);
300
301
302 #else
303 /**** Definitions For All Other Platforms ****/
@@ -305,17 +332,18 @@
305 #define sqlite3_fopen fopen
306 #define sqlite3_popen popen
307 #define sqlite3_fgets fgets
308 #define sqlite3_fputs fputs
309 #define sqlite3_fprintf fprintf
 
310 #define sqlite3_fsetmode(F,X) /*no-op*/
311
312 #endif
313 #endif /* _SQLITE3_STDIO_H_ */
314
315 /************************* End ../ext/misc/sqlite3_stdio.h ********************/
316 /************************* Begin ../ext/misc/sqlite3_stdio.c ******************/
317 /*
318 ** 2024-09-24
319 **
320 ** The author disclaims copyright to this source code. In place of
321 ** a legal notice, here is a blessing:
@@ -572,11 +600,11 @@
572 }
573 }
574
575
576 /*
577 ** Work-alike for fprintf() from the standard C library.
578 */
579 int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
580 int rc;
581 if( UseWtextForOutput(out) ){
582 /* When writing to the command-prompt in Windows, it is necessary
@@ -599,10 +627,28 @@
599 rc = vfprintf(out, zFormat, ap);
600 va_end(ap);
601 }
602 return rc;
603 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
605 /*
606 ** Set the mode for an output stream. mode argument is typically _O_BINARY or
607 ** _O_TEXT.
608 */
@@ -617,11 +663,2697 @@
617 }
618 }
619
620 #endif /* defined(_WIN32) */
621
622 /************************* End ../ext/misc/sqlite3_stdio.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
624 /* Use console I/O package as a direct INCLUDE. */
625 #define SQLITE_INTERNAL_LINKAGE static
626
627 #ifdef SQLITE_SHELL_FIDDLE
@@ -631,12 +3363,71 @@
631 # define SQLITE_CIO_NO_TRANSLATE
632 # define SQLITE_CIO_NO_SETMODE
633 # define SQLITE_CIO_NO_FLUSH
634 #endif
635
636 #define eputz(z) sqlite3_fputs(z,stderr)
637 #define sputz(fp,z) sqlite3_fputs(z,fp)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
638
639 /* True if the timer is enabled */
640 static int enableTimer = 0;
641
642 /* A version of strcmp() that works with NULL values */
@@ -723,11 +3514,11 @@
723 static void endTimer(FILE *out){
724 if( enableTimer ){
725 sqlite3_int64 iEnd = timeOfDay();
726 struct rusage sEnd;
727 getrusage(RUSAGE_SELF, &sEnd);
728 sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
729 (iEnd - iBegin)*0.000001,
730 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
731 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
732 }
733 }
@@ -804,17 +3595,17 @@
804 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
805 sqlite3_int64 ftWallEnd = timeOfDay();
806 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
807 #ifdef _WIN64
808 /* microsecond precision on 64-bit windows */
809 sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
810 (ftWallEnd - ftWallBegin)*0.000001,
811 timeDiff(&ftUserBegin, &ftUserEnd),
812 timeDiff(&ftKernelBegin, &ftKernelEnd));
813 #else
814 /* millisecond precisino on 32-bit windows */
815 sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
816 (ftWallEnd - ftWallBegin)*0.000001,
817 timeDiff(&ftUserBegin, &ftUserEnd),
818 timeDiff(&ftKernelBegin, &ftKernelEnd));
819 #endif
820 }
@@ -851,16 +3642,21 @@
851 ** is true. Otherwise, assume stdin is connected to a file or pipe.
852 */
853 static int stdin_is_interactive = 1;
854
855 /*
856 ** On Windows systems we need to know if standard output is a console
857 ** in order to show that UTF-16 translation is done in the sign-on
858 ** banner. The following variable is true if it is the console.
859 */
860 static int stdout_is_console = 1;
861
 
 
 
 
 
 
 
862 /*
863 ** The following is the open SQLite database. We make a pointer
864 ** to this database a static variable so that it can be accessed
865 ** by the SIGINT handler to interrupt database processing.
866 */
@@ -994,11 +3790,11 @@
994 #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
995
996 /* Indicate out-of-memory and exit. */
997 static void shell_out_of_memory(void){
998 eputz("Error: out of memory\n");
999 exit(1);
1000 }
1001
1002 /* Check a pointer to see if it is NULL. If it is NULL, exit with an
1003 ** out-of-memory error.
1004 */
@@ -1025,306 +3821,24 @@
1025 char *z;
1026 if( iotrace==0 ) return;
1027 va_start(ap, zFormat);
1028 z = sqlite3_vmprintf(zFormat, ap);
1029 va_end(ap);
1030 sqlite3_fprintf(iotrace, "%s", z);
1031 sqlite3_free(z);
1032 }
1033 #endif
1034
1035 /* Lookup table to estimate the number of columns consumed by a Unicode
1036 ** character.
1037 */
1038 static const struct {
1039 unsigned char w; /* Width of the character in columns */
1040 int iFirst; /* First character in a span having this width */
1041 } aUWidth[] = {
1042 /* {1, 0x00000}, */
1043 {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488},
1044 {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0},
1045 {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7},
1046 {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616},
1047 {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6},
1048 {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee},
1049 {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730},
1050 {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4},
1051 {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941},
1052 {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955},
1053 {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc},
1054 {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce},
1055 {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c},
1056 {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49},
1057 {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81},
1058 {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6},
1059 {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2},
1060 {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d},
1061 {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d},
1062 {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83},
1063 {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e},
1064 {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e},
1065 {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf},
1066 {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce},
1067 {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d},
1068 {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5},
1069 {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34},
1070 {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2},
1071 {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8},
1072 {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36},
1073 {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71},
1074 {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88},
1075 {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6},
1076 {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033},
1077 {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058},
1078 {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f},
1079 {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735},
1080 {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4},
1081 {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7},
1082 {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b},
1083 {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923},
1084 {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939},
1085 {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04},
1086 {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c},
1087 {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74},
1088 {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b},
1089 {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064},
1090 {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329},
1091 {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f},
1092 {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806},
1093 {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827},
1094 {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e},
1095 {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20},
1096 {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00},
1097 {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc},
1098 {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c},
1099 {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40},
1100 {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185},
1101 {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245},
1102 {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001},
1103 {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0}
1104 };
1105
1106 /*
1107 ** Return an estimate of the width, in columns, for the single Unicode
1108 ** character c. For normal characters, the answer is always 1. But the
1109 ** estimate might be 0 or 2 for zero-width and double-width characters.
1110 **
1111 ** Different display devices display unicode using different widths. So
1112 ** it is impossible to know that true display width with 100% accuracy.
1113 ** Inaccuracies in the width estimates might cause columns to be misaligned.
1114 ** Unfortunately, there is nothing we can do about that.
1115 */
1116 int cli_wcwidth(int c){
1117 int iFirst, iLast;
1118
1119 /* Fast path for common characters */
1120 if( c<=0x300 ) return 1;
1121
1122 /* The general case */
1123 iFirst = 0;
1124 iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1;
1125 while( iFirst<iLast-1 ){
1126 int iMid = (iFirst+iLast)/2;
1127 int cMid = aUWidth[iMid].iFirst;
1128 if( cMid < c ){
1129 iFirst = iMid;
1130 }else if( cMid > c ){
1131 iLast = iMid - 1;
1132 }else{
1133 return aUWidth[iMid].w;
1134 }
1135 }
1136 if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w;
1137 return aUWidth[iLast].w;
1138 }
1139
1140 /*
1141 ** Compute the value and length of a multi-byte UTF-8 character that
1142 ** begins at z[0]. Return the length. Write the Unicode value into *pU.
1143 **
1144 ** This routine only works for *multi-byte* UTF-8 characters.
1145 */
1146 static int decodeUtf8(const unsigned char *z, int *pU){
1147 if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){
1148 *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f);
1149 return 2;
1150 }
1151 if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){
1152 *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f);
1153 return 3;
1154 }
1155 if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1156 && (z[3] & 0xc0)==0x80
1157 ){
1158 *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1159 | (z[3] & 0x3f);
1160 return 4;
1161 }
1162 *pU = 0;
1163 return 1;
1164 }
1165
1166
1167 #if 0 /* NOT USED */
1168 /*
1169 ** Return the width, in display columns, of a UTF-8 string.
1170 **
1171 ** Each normal character counts as 1. Zero-width characters count
1172 ** as zero, and double-width characters count as 2.
1173 */
1174 int cli_wcswidth(const char *z){
1175 const unsigned char *a = (const unsigned char*)z;
1176 int n = 0;
1177 int i = 0;
1178 unsigned char c;
1179 while( (c = a[i])!=0 ){
1180 if( c>=0xc0 ){
1181 int u;
1182 int len = decodeUtf8(&a[i], &u);
1183 i += len;
1184 n += cli_wcwidth(u);
1185 }else if( c>=' ' ){
1186 n++;
1187 i++;
1188 }else{
1189 i++;
1190 }
1191 }
1192 return n;
1193 }
1194 #endif
1195
1196 /*
1197 ** Check to see if z[] is a valid VT100 escape. If it is, then
1198 ** return the number of bytes in the escape sequence. Return 0 if
1199 ** z[] is not a VT100 escape.
1200 **
1201 ** This routine assumes that z[0] is \033 (ESC).
1202 */
1203 static int isVt100(const unsigned char *z){
1204 int i;
1205 if( z[1]!='[' ) return 0;
1206 i = 2;
1207 while( z[i]>=0x30 && z[i]<=0x3f ){ i++; }
1208 while( z[i]>=0x20 && z[i]<=0x2f ){ i++; }
1209 if( z[i]<0x40 || z[i]>0x7e ) return 0;
1210 return i+1;
1211 }
1212
1213 /*
1214 ** Output string zUtf to stdout as w characters. If w is negative,
1215 ** then right-justify the text. W is the width in UTF-8 characters, not
1216 ** in bytes. This is different from the %*.*s specification in printf
1217 ** since with %*.*s the width is measured in bytes, not characters.
1218 **
1219 ** Take into account zero-width and double-width Unicode characters.
1220 ** In other words, a zero-width character does not count toward the
1221 ** the w limit. A double-width character counts as two.
1222 **
1223 ** w should normally be a small number. A couple hundred at most. This
1224 ** routine caps w at 100 million to avoid integer overflow issues.
1225 */
1226 static void utf8_width_print(FILE *out, int w, const char *zUtf){
1227 const unsigned char *a = (const unsigned char*)zUtf;
1228 static const int mxW = 10000000;
1229 unsigned char c;
1230 int i = 0;
1231 int n = 0;
1232 int k;
1233 int aw;
1234 if( w<-mxW ){
1235 w = -mxW;
1236 }else if( w>mxW ){
1237 w= mxW;
1238 }
1239 aw = w<0 ? -w : w;
1240 if( zUtf==0 ) zUtf = "";
1241 while( (c = a[i])!=0 ){
1242 if( (c&0xc0)==0xc0 ){
1243 int u;
1244 int len = decodeUtf8(a+i, &u);
1245 int x = cli_wcwidth(u);
1246 if( x+n>aw ){
1247 break;
1248 }
1249 i += len;
1250 n += x;
1251 }else if( c==0x1b && (k = isVt100(&a[i]))>0 ){
1252 i += k;
1253 }else if( n>=aw ){
1254 break;
1255 }else{
1256 n++;
1257 i++;
1258 }
1259 }
1260 if( n>=aw ){
1261 sqlite3_fprintf(out, "%.*s", i, zUtf);
1262 }else if( w<0 ){
1263 sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf);
1264 }else{
1265 sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, "");
1266 }
1267 }
1268
1269
1270 /*
1271 ** Determines if a string is a number of not.
1272 */
1273 static int isNumber(const char *z, int *realnum){
1274 if( *z=='-' || *z=='+' ) z++;
1275 if( !IsDigit(*z) ){
1276 return 0;
1277 }
1278 z++;
1279 if( realnum ) *realnum = 0;
1280 while( IsDigit(*z) ){ z++; }
1281 if( *z=='.' ){
1282 z++;
1283 if( !IsDigit(*z) ) return 0;
1284 while( IsDigit(*z) ){ z++; }
1285 if( realnum ) *realnum = 1;
1286 }
1287 if( *z=='e' || *z=='E' ){
1288 z++;
1289 if( *z=='+' || *z=='-' ) z++;
1290 if( !IsDigit(*z) ) return 0;
1291 while( IsDigit(*z) ){ z++; }
1292 if( realnum ) *realnum = 1;
1293 }
1294 return *z==0;
1295 }
1296
1297 /*
1298 ** Compute a string length that is limited to what can be stored in
1299 ** lower 30 bits of a 32-bit signed integer.
1300 */
1301 static int strlen30(const char *z){
1302 const char *z2 = z;
1303 while( *z2 ){ z2++; }
1304 return 0x3fffffff & (int)(z2 - z);
1305 }
1306
1307 /*
1308 ** Return the length of a string in characters. Multibyte UTF8 characters
1309 ** count as a single character for single-width characters, or as two
1310 ** characters for double-width characters.
1311 */
1312 static int strlenChar(const char *z){
1313 int n = 0;
1314 while( *z ){
1315 if( (0x80&z[0])==0 ){
1316 n++;
1317 z++;
1318 }else{
1319 int u = 0;
1320 int len = decodeUtf8((const u8*)z, &u);
1321 z += len;
1322 n += cli_wcwidth(u);
1323 }
1324 }
1325 return n;
1326 }
1327
1328 /*
1329 ** Return open FILE * if zFile exists, can be opened for read
1330 ** and is an ordinary file or a character stream source.
@@ -1770,11 +4284,11 @@
1770 ** work here in the middle of this regular program.
1771 */
1772 #define SQLITE_EXTENSION_INIT1
1773 #define SQLITE_EXTENSION_INIT2(X) (void)(X)
1774
1775 /************************* Begin ../ext/misc/windirent.h ******************/
1776 /*
1777 ** 2025-06-05
1778 **
1779 ** The author disclaims copyright to this source code. In place of
1780 ** a legal notice, here is a blessing:
@@ -1935,12 +4449,12 @@
1935 return &pDir->cur;
1936 }
1937
1938 #endif /* defined(_WIN32) && defined(_MSC_VER) */
1939
1940 /************************* End ../ext/misc/windirent.h ********************/
1941 /************************* Begin ../ext/misc/memtrace.c ******************/
1942 /*
1943 ** 2019-01-21
1944 **
1945 ** The author disclaims copyright to this source code. In place of
1946 ** a legal notice, here is a blessing:
@@ -2046,12 +4560,12 @@
2046 }
2047 memtraceOut = 0;
2048 return rc;
2049 }
2050
2051 /************************* End ../ext/misc/memtrace.c ********************/
2052 /************************* Begin ../ext/misc/pcachetrace.c ******************/
2053 /*
2054 ** 2023-06-21
2055 **
2056 ** The author disclaims copyright to this source code. In place of
2057 ** a legal notice, here is a blessing:
@@ -2228,12 +4742,12 @@
2228 }
2229 pcachetraceOut = 0;
2230 return rc;
2231 }
2232
2233 /************************* End ../ext/misc/pcachetrace.c ********************/
2234 /************************* Begin ../ext/misc/shathree.c ******************/
2235 /*
2236 ** 2017-03-08
2237 **
2238 ** The author disclaims copyright to this source code. In place of
2239 ** a legal notice, here is a blessing:
@@ -3085,12 +5599,12 @@
3085 0, sha3QueryFunc, 0, 0);
3086 }
3087 return rc;
3088 }
3089
3090 /************************* End ../ext/misc/shathree.c ********************/
3091 /************************* Begin ../ext/misc/sha1.c ******************/
3092 /*
3093 ** 2017-01-27
3094 **
3095 ** The author disclaims copyright to this source code. In place of
3096 ** a legal notice, here is a blessing:
@@ -3497,12 +6011,12 @@
3497 sha1QueryFunc, 0, 0);
3498 }
3499 return rc;
3500 }
3501
3502 /************************* End ../ext/misc/sha1.c ********************/
3503 /************************* Begin ../ext/misc/uint.c ******************/
3504 /*
3505 ** 2020-04-14
3506 **
3507 ** The author disclaims copyright to this source code. In place of
3508 ** a legal notice, here is a blessing:
@@ -3592,12 +6106,12 @@
3592 SQLITE_EXTENSION_INIT2(pApi);
3593 (void)pzErrMsg; /* Unused parameter */
3594 return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
3595 }
3596
3597 /************************* End ../ext/misc/uint.c ********************/
3598 /************************* Begin ../ext/misc/decimal.c ******************/
3599 /*
3600 ** 2020-06-22
3601 **
3602 ** The author disclaims copyright to this source code. In place of
3603 ** a legal notice, here is a blessing:
@@ -4497,14 +7011,14 @@
4497 0, decimalCollFunc);
4498 }
4499 return rc;
4500 }
4501
4502 /************************* End ../ext/misc/decimal.c ********************/
4503 #undef sqlite3_base_init
4504 #define sqlite3_base_init sqlite3_base64_init
4505 /************************* Begin ../ext/misc/base64.c ******************/
4506 /*
4507 ** 2022-11-18
4508 **
4509 ** The author disclaims copyright to this source code. In place of
4510 ** a legal notice, here is a blessing:
@@ -4799,15 +7313,15 @@
4799 ** allows shell.c, as distributed, to have this extension built in.
4800 */
4801 #define BASE64_INIT(db) sqlite3_base64_init(db, 0, 0)
4802 #define BASE64_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */
4803
4804 /************************* End ../ext/misc/base64.c ********************/
4805 #undef sqlite3_base_init
4806 #define sqlite3_base_init sqlite3_base85_init
4807 #define OMIT_BASE85_CHECKER
4808 /************************* Begin ../ext/misc/base85.c ******************/
4809 /*
4810 ** 2022-11-16
4811 **
4812 ** The author disclaims copyright to this source code. In place of
4813 ** a legal notice, here is a blessing:
@@ -5259,12 +7773,12 @@
5259 return rc;
5260 }
5261
5262 #endif
5263
5264 /************************* End ../ext/misc/base85.c ********************/
5265 /************************* Begin ../ext/misc/ieee754.c ******************/
5266 /*
5267 ** 2013-04-17
5268 **
5269 ** The author disclaims copyright to this source code. In place of
5270 ** a legal notice, here is a blessing:
@@ -5589,12 +8103,12 @@
5589 aFunc[i].xFunc, 0, 0);
5590 }
5591 return rc;
5592 }
5593
5594 /************************* End ../ext/misc/ieee754.c ********************/
5595 /************************* Begin ../ext/misc/series.c ******************/
5596 /*
5597 ** 2015-08-18, 2023-04-28
5598 **
5599 ** The author disclaims copyright to this source code. In place of
5600 ** a legal notice, here is a blessing:
@@ -6529,12 +9043,12 @@
6529 rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
6530 #endif
6531 return rc;
6532 }
6533
6534 /************************* End ../ext/misc/series.c ********************/
6535 /************************* Begin ../ext/misc/regexp.c ******************/
6536 /*
6537 ** 2012-11-13
6538 **
6539 ** The author disclaims copyright to this source code. In place of
6540 ** a legal notice, here is a blessing:
@@ -7446,13 +9960,13 @@
7446 #endif /* SQLITE_DEBUG */
7447 }
7448 return rc;
7449 }
7450
7451 /************************* End ../ext/misc/regexp.c ********************/
7452 #ifndef SQLITE_SHELL_FIDDLE
7453 /************************* Begin ../ext/misc/fileio.c ******************/
7454 /*
7455 ** 2014-06-13
7456 **
7457 ** The author disclaims copyright to this source code. In place of
7458 ** a legal notice, here is a blessing:
@@ -8574,20 +11088,12 @@
8574 rc = fsdirRegister(db);
8575 }
8576 return rc;
8577 }
8578
8579 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
8580 /* To allow a standalone DLL, make test_windirent.c use the same
8581 * redefined SQLite API calls as the above extension code does.
8582 * Just pull in this .c to accomplish this. As a beneficial side
8583 * effect, this extension becomes a single translation unit. */
8584 # include "test_windirent.c"
8585 #endif
8586
8587 /************************* End ../ext/misc/fileio.c ********************/
8588 /************************* Begin ../ext/misc/completion.c ******************/
8589 /*
8590 ** 2017-07-10
8591 **
8592 ** The author disclaims copyright to this source code. In place of
8593 ** a legal notice, here is a blessing:
@@ -9095,12 +11601,12 @@
9095 rc = sqlite3CompletionVtabInit(db);
9096 #endif
9097 return rc;
9098 }
9099
9100 /************************* End ../ext/misc/completion.c ********************/
9101 /************************* Begin ../ext/misc/appendvfs.c ******************/
9102 /*
9103 ** 2017-10-20
9104 **
9105 ** The author disclaims copyright to this source code. In place of
9106 ** a legal notice, here is a blessing:
@@ -9770,14 +12276,14 @@
9770 #endif
9771 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
9772 return rc;
9773 }
9774
9775 /************************* End ../ext/misc/appendvfs.c ********************/
9776 #endif
9777 #ifdef SQLITE_HAVE_ZLIB
9778 /************************* Begin ../ext/misc/zipfile.c ******************/
9779 /*
9780 ** 2017-12-26
9781 **
9782 ** The author disclaims copyright to this source code. In place of
9783 ** a legal notice, here is a blessing:
@@ -12062,12 +14568,12 @@
12062 SQLITE_EXTENSION_INIT2(pApi);
12063 (void)pzErrMsg; /* Unused parameter */
12064 return zipfileRegister(db);
12065 }
12066
12067 /************************* End ../ext/misc/zipfile.c ********************/
12068 /************************* Begin ../ext/misc/sqlar.c ******************/
12069 /*
12070 ** 2017-12-17
12071 **
12072 ** The author disclaims copyright to this source code. In place of
12073 ** a legal notice, here is a blessing:
@@ -12191,14 +14697,14 @@
12191 sqlarUncompressFunc, 0, 0);
12192 }
12193 return rc;
12194 }
12195
12196 /************************* End ../ext/misc/sqlar.c ********************/
12197 #endif
12198 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
12199 /************************* Begin ../ext/expert/sqlite3expert.h ******************/
12200 /*
12201 ** 2017 April 07
12202 **
12203 ** The author disclaims copyright to this source code. In place of
12204 ** a legal notice, here is a blessing:
@@ -12364,12 +14870,12 @@
12364 */
12365 void sqlite3_expert_destroy(sqlite3expert*);
12366
12367 #endif /* !defined(SQLITEEXPERT_H) */
12368
12369 /************************* End ../ext/expert/sqlite3expert.h ********************/
12370 /************************* Begin ../ext/expert/sqlite3expert.c ******************/
12371 /*
12372 ** 2017 April 09
12373 **
12374 ** The author disclaims copyright to this source code. In place of
12375 ** a legal notice, here is a blessing:
@@ -14603,13 +17109,13 @@
14603 }
14604 }
14605
14606 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
14607
14608 /************************* End ../ext/expert/sqlite3expert.c ********************/
14609 #endif
14610 /************************* Begin ../ext/intck/sqlite3intck.h ******************/
14611 /*
14612 ** 2024-02-08
14613 **
14614 ** The author disclaims copyright to this source code. In place of
14615 ** a legal notice, here is a blessing:
@@ -14778,12 +17284,12 @@
14778 } /* end of the 'extern "C"' block */
14779 #endif
14780
14781 #endif /* ifndef _SQLITE_INTCK_H */
14782
14783 /************************* End ../ext/intck/sqlite3intck.h ********************/
14784 /************************* Begin ../ext/intck/sqlite3intck.c ******************/
14785 /*
14786 ** 2024-02-08
14787 **
14788 ** The author disclaims copyright to this source code. In place of
14789 ** a legal notice, here is a blessing:
@@ -14942,10 +17448,11 @@
14942 }
14943 }else{
14944 sqlite3_free(zRet);
14945 zRet = 0;
14946 }
 
14947 return zRet;
14948 }
14949
14950 /*
14951 ** This is used by sqlite3_intck_unlock() to save the vector key value
@@ -15721,12 +18228,12 @@
15721 }
15722 }
15723 return p->zTestSql;
15724 }
15725
15726 /************************* End ../ext/intck/sqlite3intck.c ********************/
15727 /************************* Begin ../ext/misc/stmtrand.c ******************/
15728 /*
15729 ** 2024-05-24
15730 **
15731 ** The author disclaims copyright to this source code. In place of
15732 ** a legal notice, here is a blessing:
@@ -15821,12 +18328,12 @@
15821 stmtrandFunc, 0, 0);
15822 }
15823 return rc;
15824 }
15825
15826 /************************* End ../ext/misc/stmtrand.c ********************/
15827 /************************* Begin ../ext/misc/vfstrace.c ******************/
15828 /*
15829 ** 2011 March 16
15830 **
15831 ** The author disclaims copyright to this source code. In place of
15832 ** a legal notice, here is a blessing:
@@ -17035,19 +19542,19 @@
17035 if( pVfs->xOpen!=vfstraceOpen ) return;
17036 sqlite3_vfs_unregister(pVfs);
17037 sqlite3_free(pVfs);
17038 }
17039
17040 /************************* End ../ext/misc/vfstrace.c ********************/
17041
17042 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
17043 #define SQLITE_SHELL_HAVE_RECOVER 1
17044 #else
17045 #define SQLITE_SHELL_HAVE_RECOVER 0
17046 #endif
17047 #if SQLITE_SHELL_HAVE_RECOVER
17048 /************************* Begin ../ext/recover/sqlite3recover.h ******************/
17049 /*
17050 ** 2022-08-27
17051 **
17052 ** The author disclaims copyright to this source code. In place of
17053 ** a legal notice, here is a blessing:
@@ -17294,13 +19801,13 @@
17294 } /* end of the 'extern "C"' block */
17295 #endif
17296
17297 #endif /* ifndef _SQLITE_RECOVER_H */
17298
17299 /************************* End ../ext/recover/sqlite3recover.h ********************/
17300 # ifndef SQLITE_HAVE_SQLITE3R
17301 /************************* Begin ../ext/recover/dbdata.c ******************/
17302 /*
17303 ** 2019-04-17
17304 **
17305 ** The author disclaims copyright to this source code. In place of
17306 ** a legal notice, here is a blessing:
@@ -18321,12 +20828,12 @@
18321 return sqlite3DbdataRegister(db);
18322 }
18323
18324 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
18325
18326 /************************* End ../ext/recover/dbdata.c ********************/
18327 /************************* Begin ../ext/recover/sqlite3recover.c ******************/
18328 /*
18329 ** 2022-08-27
18330 **
18331 ** The author disclaims copyright to this source code. In place of
18332 ** a legal notice, here is a blessing:
@@ -21225,11 +23732,11 @@
21225 return rc;
21226 }
21227
21228 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
21229
21230 /************************* End ../ext/recover/sqlite3recover.c ********************/
21231 # endif /* SQLITE_HAVE_SQLITE3R */
21232 #endif
21233 #ifdef SQLITE_SHELL_EXTSRC
21234 # include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
21235 #endif
@@ -21253,97 +23760,78 @@
21253 sqlite3expert *pExpert;
21254 int bVerbose;
21255 };
21256 #endif
21257
21258 /* A single line in the EQP output */
21259 typedef struct EQPGraphRow EQPGraphRow;
21260 struct EQPGraphRow {
21261 int iEqpId; /* ID for this row */
21262 int iParentId; /* ID of the parent row */
21263 EQPGraphRow *pNext; /* Next row in sequence */
21264 char zText[1]; /* Text to display for this row */
21265 };
21266
21267 /* All EQP output is collected into an instance of the following */
21268 typedef struct EQPGraph EQPGraph;
21269 struct EQPGraph {
21270 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
21271 EQPGraphRow *pLast; /* Last element of the pRow list */
21272 char zPrefix[100]; /* Graph prefix */
21273 };
21274
21275 /* Parameters affecting columnar mode result display (defaulting together) */
21276 typedef struct ColModeOpts {
21277 int iWrap; /* In columnar modes, wrap lines reaching this limit */
21278 u8 bQuote; /* Quote results for .mode box and table */
21279 u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
21280 } ColModeOpts;
21281 #define ColModeOpts_default { 60, 0, 0 }
21282 #define ColModeOpts_default_qbox { 60, 1, 0 }
21283
21284 /*
21285 ** State information about the database connection is contained in an
21286 ** instance of the following structure.
21287 */
21288 typedef struct ShellState ShellState;
21289 struct ShellState {
21290 sqlite3 *db; /* The database */
21291 u8 autoExplain; /* Automatically turn on .explain mode */
21292 u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */
21293 u8 autoEQPtest; /* autoEQP is in test mode */
21294 u8 autoEQPtrace; /* autoEQP is in trace mode */
21295 u8 scanstatsOn; /* True to display scan stats before each finalize */
21296 u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
21297 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
21298 u8 nEqpLevel; /* Depth of the EQP output graph */
21299 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
21300 u8 bSafeMode; /* True to prohibit unsafe operations */
21301 u8 bSafeModePersist; /* The long-term value of bSafeMode */
21302 u8 eRestoreState; /* See comments above doAutoDetectRestore() */
21303 u8 crlfMode; /* Do NL-to-CRLF translations when enabled (maybe) */
21304 u8 eEscMode; /* Escape mode for text output */
21305 ColModeOpts cmOpts; /* Option values affecting columnar mode output */
21306 unsigned statsOn; /* True to display memory stats before each finalize */
21307 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
 
 
21308 int inputNesting; /* Track nesting level of .read and other redirects */
21309 int outCount; /* Revert to stdout when reaching zero */
21310 int cnt; /* Number of records displayed so far */
21311 i64 lineno; /* Line number of last line read from in */
 
21312 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
21313 FILE *in; /* Read commands from this stream */
21314 FILE *out; /* Write results here */
21315 FILE *traceOut; /* Output for sqlite3_trace() */
21316 int nErr; /* Number of errors seen */
21317 int mode; /* An output mode setting */
21318 int modePrior; /* Saved mode */
21319 int cMode; /* temporary output mode for the current query */
21320 int normalMode; /* Output mode before ".explain on" */
21321 int writableSchema; /* True if PRAGMA writable_schema=ON */
21322 int showHeader; /* True to show column names in List or Column mode */
21323 int nCheck; /* Number of ".check" commands run */
21324 unsigned nProgress; /* Number of progress callbacks encountered */
21325 unsigned mxProgress; /* Maximum progress callbacks before failing */
21326 unsigned flgProgress; /* Flags for the progress callback */
21327 unsigned shellFlgs; /* Various flags */
21328 unsigned priorShFlgs; /* Saved copy of flags */
 
21329 sqlite3_int64 szMax; /* --maxsize argument to .open */
21330 char *zDestTable; /* Name of destination table when MODE_Insert */
21331 char *zTempFile; /* Temporary file that might need deleting */
 
21332 char zTestcase[30]; /* Name of current test case */
21333 char colSeparator[20]; /* Column separator character for several modes */
21334 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
21335 char colSepPrior[20]; /* Saved column separator */
21336 char rowSepPrior[20]; /* Saved row separator */
21337 int *colWidth; /* Requested width of each column in columnar modes */
21338 int *actualWidth; /* Actual width of each column */
21339 int nWidth; /* Number of slots in colWidth[] and actualWidth[] */
21340 char nullValue[20]; /* The text to print when a NULL comes back from
21341 ** the database */
21342 char outfile[FILENAME_MAX]; /* Filename for *out */
21343 sqlite3_stmt *pStmt; /* Current statement if any. */
21344 FILE *pLog; /* Write log output here */
 
 
 
 
 
 
 
21345 struct AuxDb { /* Storage space for auxiliary database connections */
21346 sqlite3 *db; /* Connection pointer */
21347 const char *zDbFilename; /* Filename used to open the connection */
21348 char *zFreeOnClose; /* Free this memory allocation on close */
21349 #if defined(SQLITE_ENABLE_SESSION)
@@ -21350,18 +23838,23 @@
21350 int nSession; /* Number of active sessions */
21351 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
21352 #endif
21353 } aAuxDb[5], /* Array of all database connections */
21354 *pAuxDb; /* Currently active database connection */
21355 int *aiIndent; /* Array of indents used in MODE_Explain */
21356 int nIndent; /* Size of array aiIndent[] */
21357 int iIndent; /* Index of current op in aiIndent[] */
21358 char *zNonce; /* Nonce for temporary safe-mode escapes */
21359 EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
21360 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
21361 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
21362 #endif
 
 
 
 
 
 
 
 
 
21363 #ifdef SQLITE_SHELL_FIDDLE
21364 struct {
21365 const char * zInput; /* Input string from wasm/JS proxy */
21366 const char * zPos; /* Cursor pos into zInput */
21367 const char * zDefaultDbName; /* Default name for db file */
@@ -21372,11 +23865,11 @@
21372 #ifdef SQLITE_SHELL_FIDDLE
21373 static ShellState shellState;
21374 #endif
21375
21376
21377 /* Allowed values for ShellState.autoEQP
21378 */
21379 #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
21380 #define AUTOEQP_on 1 /* Automatic EQP is on */
21381 #define AUTOEQP_trigger 2 /* On and also show plans for triggers */
21382 #define AUTOEQP_full 3 /* Show full EXPLAIN */
@@ -21401,30 +23894,25 @@
21401 #define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progress
21402 ** callback limit is reached, and for each
21403 ** top-level SQL statement */
21404 #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
21405
21406 /* Allowed values for ShellState.eEscMode. The default value should
21407 ** be 0, so to change the default, reorder the names.
21408 */
21409 #define SHELL_ESC_ASCII 0 /* Substitute ^Y for X where Y=X+0x40 */
21410 #define SHELL_ESC_SYMBOL 1 /* Substitute U+2400 graphics */
21411 #define SHELL_ESC_OFF 2 /* Send characters verbatim */
21412
21413 static const char *shell_EscModeNames[] = { "ascii", "symbol", "off" };
21414
21415 /*
21416 ** These are the allowed shellFlgs values
21417 */
21418 #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
21419 #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
21420 #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
21421 #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
21422 #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
21423 #define SHFLG_CountChanges 0x00000020 /* .changes setting */
21424 #define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */
21425 #define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */
21426 #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
21427 #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
21428 #define SHFLG_TestingMode 0x00000400 /* allow unsafe testing features */
21429
21430 /*
@@ -21433,58 +23921,105 @@
21433 #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
21434 #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
21435 #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
21436
21437 /*
21438 ** These are the allowed modes.
 
 
21439 */
21440 #define MODE_Line 0 /* One column per line. Blank line between records */
21441 #define MODE_Column 1 /* One record per line in neat columns */
21442 #define MODE_List 2 /* One record per line with a separator */
21443 #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
21444 #define MODE_Html 4 /* Generate an XHTML table */
21445 #define MODE_Insert 5 /* Generate SQL "insert" statements */
21446 #define MODE_Quote 6 /* Quote values as for SQL */
21447 #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
21448 #define MODE_Csv 8 /* Quote strings, numbers are plain */
21449 #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
21450 #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
21451 #define MODE_Pretty 11 /* Pretty-print schemas */
21452 #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
21453 #define MODE_Json 13 /* Output JSON */
21454 #define MODE_Markdown 14 /* Markdown formatting */
21455 #define MODE_Table 15 /* MySQL-style table formatting */
21456 #define MODE_Box 16 /* Unicode box-drawing characters */
21457 #define MODE_Count 17 /* Output only a count of the rows of output */
21458 #define MODE_Off 18 /* No query output shown */
21459 #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */
21460 #define MODE_Www 20 /* Full web-page output */
21461
21462 static const char *modeDescr[] = {
21463 "line",
21464 "column",
21465 "list",
21466 "semi",
21467 "html",
21468 "insert",
21469 "quote",
21470 "tcl",
21471 "csv",
21472 "explain",
21473 "ascii",
21474 "prettyprint",
21475 "eqp",
21476 "json",
21477 "markdown",
21478 "table",
21479 "box",
21480 "count",
21481 "off",
21482 "scanexp",
21483 "www",
21484 };
21485
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21486 /*
21487 ** These are the column/row/line separators used by the various
21488 ** import/export modes.
21489 */
21490 #define SEP_Column "|"
@@ -21499,18 +24034,183 @@
21499 /*
21500 ** Limit input nesting via .read or any other input redirect.
21501 ** It's not too expensive, so a generous allowance can be made.
21502 */
21503 #define MAX_INPUT_NESTING 25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21504
21505 /*
21506 ** A callback for the sqlite3_log() interface.
21507 */
21508 static void shellLog(void *pArg, int iErrCode, const char *zMsg){
21509 ShellState *p = (ShellState*)pArg;
21510 if( p->pLog==0 ) return;
21511 sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
21512 fflush(p->pLog);
21513 }
21514
21515 /*
21516 ** SQL function: shell_putsnl(X)
@@ -21523,13 +24223,29 @@
21523 int nVal,
21524 sqlite3_value **apVal
21525 ){
21526 ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
21527 (void)nVal;
21528 sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
21529 sqlite3_result_value(pCtx, apVal[0]);
21530 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21531
21532 /*
21533 ** If in safe mode, print an error message described by the arguments
21534 ** and exit immediately.
21535 */
@@ -21539,17 +24255,53 @@
21539 ...
21540 ){
21541 if( p->bSafeMode ){
21542 va_list ap;
21543 char *zMsg;
 
21544 va_start(ap, zErrMsg);
21545 zMsg = sqlite3_vmprintf(zErrMsg, ap);
21546 va_end(ap);
21547 sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg);
21548 exit(1);
21549 }
21550 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21551
21552 /*
21553 ** SQL function: edit(VALUE)
21554 ** edit(VALUE,EDITOR)
21555 **
@@ -21691,161 +24443,25 @@
21691 sqlite3_free(zTempFile);
21692 sqlite3_free(p);
21693 }
21694 #endif /* SQLITE_NOHAVE_SYSTEM */
21695
21696 /*
21697 ** Save or restore the current output mode
21698 */
21699 static void outputModePush(ShellState *p){
21700 p->modePrior = p->mode;
21701 p->priorShFlgs = p->shellFlgs;
21702 memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
21703 memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
21704 }
21705 static void outputModePop(ShellState *p){
21706 p->mode = p->modePrior;
21707 p->shellFlgs = p->priorShFlgs;
21708 memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
21709 memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
21710 }
21711
21712 /*
21713 ** Set output mode to text or binary for Windows.
21714 */
21715 static void setCrlfMode(ShellState *p){
21716 #ifdef _WIN32
21717 if( p->crlfMode ){
21718 sqlite3_fsetmode(p->out, _O_TEXT);
21719 }else{
21720 sqlite3_fsetmode(p->out, _O_BINARY);
21721 }
21722 #else
21723 UNUSED_PARAMETER(p);
21724 #endif
21725 }
21726
21727 /*
21728 ** Output the given string as a hex-encoded blob (eg. X'1234' )
21729 */
21730 static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
21731 int i;
21732 unsigned char *aBlob = (unsigned char*)pBlob;
21733
21734 char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
21735 shell_check_oom(zStr);
21736
21737 for(i=0; i<nBlob; i++){
21738 static const char aHex[] = {
21739 '0', '1', '2', '3', '4', '5', '6', '7',
21740 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
21741 };
21742 zStr[i*2] = aHex[ (aBlob[i] >> 4) ];
21743 zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ];
21744 }
21745 zStr[i*2] = '\0';
21746
21747 sqlite3_fprintf(out, "X'%s'", zStr);
21748 sqlite3_free(zStr);
21749 }
21750
21751 /*
21752 ** Output the given string as a quoted string using SQL quoting conventions:
21753 **
21754 ** (1) Single quotes (') within the string are doubled
21755 ** (2) The while string is enclosed in '...'
21756 ** (3) Control characters other than \n, \t, and \r\n are escaped
21757 ** using \u00XX notation and if such substitutions occur,
21758 ** the whole string is enclosed in unistr('...') instead of '...'.
21759 **
21760 ** Step (3) is omitted if the control-character escape mode is OFF.
21761 **
21762 ** See also: output_quoted_escaped_string() which does the same except
21763 ** that it does not make exceptions for \n, \t, and \r\n in step (3).
21764 */
21765 static void output_quoted_string(ShellState *p, const char *zInX){
21766 int i;
21767 int needUnistr = 0;
21768 int needDblQuote = 0;
21769 const unsigned char *z = (const unsigned char*)zInX;
21770 unsigned char c;
21771 FILE *out = p->out;
21772 sqlite3_fsetmode(out, _O_BINARY);
21773 if( z==0 ) return;
21774 for(i=0; (c = z[i])!=0; i++){
21775 if( c=='\'' ){ needDblQuote = 1; }
21776 if( c>0x1f ) continue;
21777 if( c=='\t' || c=='\n' ) continue;
21778 if( c=='\r' && z[i+1]=='\n' ) continue;
21779 needUnistr = 1;
21780 break;
21781 }
21782 if( (needDblQuote==0 && needUnistr==0)
21783 || (needDblQuote==0 && p->eEscMode==SHELL_ESC_OFF)
21784 ){
21785 sqlite3_fprintf(out, "'%s'",z);
21786 }else if( p->eEscMode==SHELL_ESC_OFF ){
21787 char *zEncoded = sqlite3_mprintf("%Q", z);
21788 sqlite3_fputs(zEncoded, out);
21789 sqlite3_free(zEncoded);
21790 }else{
21791 if( needUnistr ){
21792 sqlite3_fputs("unistr('", out);
21793 }else{
21794 sqlite3_fputs("'", out);
21795 }
21796 while( *z ){
21797 for(i=0; (c = z[i])!=0; i++){
21798 if( c=='\'' ) break;
21799 if( c>0x1f ) continue;
21800 if( c=='\t' || c=='\n' ) continue;
21801 if( c=='\r' && z[i+1]=='\n' ) continue;
21802 break;
21803 }
21804 if( i ){
21805 sqlite3_fprintf(out, "%.*s", i, z);
21806 z += i;
21807 }
21808 if( c==0 ) break;
21809 if( c=='\'' ){
21810 sqlite3_fputs("''", out);
21811 }else{
21812 sqlite3_fprintf(out, "\\u%04x", c);
21813 }
21814 z++;
21815 }
21816 if( needUnistr ){
21817 sqlite3_fputs("')", out);
21818 }else{
21819 sqlite3_fputs("'", out);
21820 }
21821 }
21822 setCrlfMode(p);
21823 }
21824
21825 /*
21826 ** Output the given string as a quoted string using SQL quoting conventions.
21827 ** Additionallly , escape the "\n" and "\r" characters so that they do not
21828 ** get corrupted by end-of-line translation facilities in some operating
21829 ** systems.
21830 **
21831 ** This is like output_quoted_string() but with the addition of the \r\n
21832 ** escape mechanism.
21833 */
21834 static void output_quoted_escaped_string(ShellState *p, const char *z){
21835 char *zEscaped;
21836 sqlite3_fsetmode(p->out, _O_BINARY);
21837 if( p->eEscMode==SHELL_ESC_OFF ){
21838 zEscaped = sqlite3_mprintf("%Q", z);
21839 }else{
21840 zEscaped = sqlite3_mprintf("%#Q", z);
21841 }
21842 sqlite3_fputs(zEscaped, p->out);
21843 sqlite3_free(zEscaped);
21844 setCrlfMode(p);
21845 }
21846
21847 /*
21848 ** Find earliest of chars within s specified in zAny.
21849 ** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated.
21850 */
21851 static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){
@@ -21905,17 +24521,63 @@
21905 static const char *zq = "\"";
21906 static long ctrlMask = ~0L;
21907 static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
21908 char ace[3] = "\\?";
21909 char cbsSay;
21910 sqlite3_fputs(zq, out);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21911 while( *z!=0 ){
21912 const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
21913 const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
21914 const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
21915 if( pcEnd > z ){
21916 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
21917 }
21918 if( (c = *pcEnd)==0 ) break;
21919 ++pcEnd;
21920 switch( c ){
21921 case '\\': case '"':
@@ -21927,255 +24589,63 @@
21927 case '\f': cbsSay = 'f'; break;
21928 default: cbsSay = 0; break;
21929 }
21930 if( cbsSay ){
21931 ace[1] = cbsSay;
21932 sqlite3_fputs(ace, out);
21933 }else if( !isprint(c&0xff) ){
21934 sqlite3_fprintf(out, "\\%03o", c&0xff);
21935 }else{
21936 ace[1] = (char)c;
21937 sqlite3_fputs(ace+1, out);
21938 }
21939 z = pcEnd;
21940 }
21941 sqlite3_fputs(zq, out);
21942 }
21943
21944 /*
21945 ** Output the given string as quoted according to JSON quoting rules.
21946 */
21947 static void output_json_string(FILE *out, const char *z, i64 n){
21948 unsigned char c;
21949 static const char *zq = "\"";
21950 static long ctrlMask = ~0L;
21951 static const char *zDQBS = "\"\\";
21952 const char *pcLimit;
21953 char ace[3] = "\\?";
21954 char cbsSay;
21955
21956 if( z==0 ) z = "";
21957 pcLimit = z + ((n<0)? strlen(z) : (size_t)n);
21958 sqlite3_fputs(zq, out);
21959 while( z < pcLimit ){
21960 const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z);
21961 const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask);
21962 const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast;
21963 if( pcEnd > z ){
21964 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
21965 z = pcEnd;
21966 }
21967 if( z >= pcLimit ) break;
21968 c = (unsigned char)*(z++);
21969 switch( c ){
21970 case '"': case '\\':
21971 cbsSay = (char)c;
21972 break;
21973 case '\b': cbsSay = 'b'; break;
21974 case '\f': cbsSay = 'f'; break;
21975 case '\n': cbsSay = 'n'; break;
21976 case '\r': cbsSay = 'r'; break;
21977 case '\t': cbsSay = 't'; break;
21978 default: cbsSay = 0; break;
21979 }
21980 if( cbsSay ){
21981 ace[1] = cbsSay;
21982 sqlite3_fputs(ace, out);
21983 }else if( c<=0x1f || c>=0x7f ){
21984 sqlite3_fprintf(out, "\\u%04x", c);
21985 }else{
21986 ace[1] = (char)c;
21987 sqlite3_fputs(ace+1, out);
21988 }
21989 }
21990 sqlite3_fputs(zq, out);
21991 }
21992
21993 /*
21994 ** Escape the input string if it is needed and in accordance with
21995 ** eEscMode.
21996 **
21997 ** Escaping is needed if the string contains any control characters
21998 ** other than \t, \n, and \r\n
21999 **
22000 ** If no escaping is needed (the common case) then set *ppFree to NULL
22001 ** and return the original string. If escaping is needed, write the
22002 ** escaped string into memory obtained from sqlite3_malloc64() or the
22003 ** equivalent, and return the new string and set *ppFree to the new string
22004 ** as well.
22005 **
22006 ** The caller is responsible for freeing *ppFree if it is non-NULL in order
22007 ** to reclaim memory.
22008 */
22009 static const char *escapeOutput(
22010 ShellState *p,
22011 const char *zInX,
22012 char **ppFree
22013 ){
22014 i64 i, j;
22015 i64 nCtrl = 0;
22016 unsigned char *zIn;
22017 unsigned char c;
22018 unsigned char *zOut;
22019
22020
22021 /* No escaping if disabled */
22022 if( p->eEscMode==SHELL_ESC_OFF ){
22023 *ppFree = 0;
22024 return zInX;
22025 }
22026
22027 /* Count the number of control characters in the string. */
22028 zIn = (unsigned char*)zInX;
22029 for(i=0; (c = zIn[i])!=0; i++){
22030 if( c<=0x1f
22031 && c!='\t'
22032 && c!='\n'
22033 && (c!='\r' || zIn[i+1]!='\n')
22034 ){
22035 nCtrl++;
22036 }
22037 }
22038 if( nCtrl==0 ){
22039 *ppFree = 0;
22040 return zInX;
22041 }
22042 if( p->eEscMode==SHELL_ESC_SYMBOL ) nCtrl *= 2;
22043 zOut = sqlite3_malloc64( i + nCtrl + 1 );
22044 shell_check_oom(zOut);
22045 for(i=j=0; (c = zIn[i])!=0; i++){
22046 if( c>0x1f
22047 || c=='\t'
22048 || c=='\n'
22049 || (c=='\r' && zIn[i+1]=='\n')
22050 ){
22051 continue;
22052 }
22053 if( i>0 ){
22054 memcpy(&zOut[j], zIn, i);
22055 j += i;
22056 }
22057 zIn += i+1;
22058 i = -1;
22059 switch( p->eEscMode ){
22060 case SHELL_ESC_SYMBOL:
22061 zOut[j++] = 0xe2;
22062 zOut[j++] = 0x90;
22063 zOut[j++] = 0x80+c;
22064 break;
22065 case SHELL_ESC_ASCII:
22066 zOut[j++] = '^';
22067 zOut[j++] = 0x40+c;
22068 break;
22069 }
22070 }
22071 if( i>0 ){
22072 memcpy(&zOut[j], zIn, i);
22073 j += i;
22074 }
22075 zOut[j] = 0;
22076 *ppFree = (char*)zOut;
22077 return (char*)zOut;
22078 }
22079
22080 /*
22081 ** Output the given string with characters that are special to
22082 ** HTML escaped.
22083 */
22084 static void output_html_string(FILE *out, const char *z){
22085 int i;
22086 if( z==0 ) z = "";
22087 while( *z ){
22088 for(i=0; z[i]
22089 && z[i]!='<'
22090 && z[i]!='&'
22091 && z[i]!='>'
22092 && z[i]!='\"'
22093 && z[i]!='\'';
22094 i++){}
22095 if( i>0 ){
22096 sqlite3_fprintf(out, "%.*s",i,z);
22097 }
22098 if( z[i]=='<' ){
22099 sqlite3_fputs("&lt;", out);
22100 }else if( z[i]=='&' ){
22101 sqlite3_fputs("&amp;", out);
22102 }else if( z[i]=='>' ){
22103 sqlite3_fputs("&gt;", out);
22104 }else if( z[i]=='\"' ){
22105 sqlite3_fputs("&quot;", out);
22106 }else if( z[i]=='\'' ){
22107 sqlite3_fputs("&#39;", out);
22108 }else{
22109 break;
22110 }
22111 z += i + 1;
22112 }
22113 }
22114
22115 /*
22116 ** If a field contains any character identified by a 1 in the following
22117 ** array, then the string must be quoted for CSV.
22118 */
22119 static const char needCsvQuote[] = {
22120 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22121 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22122 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
22123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
22128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22136 };
22137
22138 /*
22139 ** Output a single term of CSV. Actually, p->colSeparator is used for
22140 ** the separator, which may or may not be a comma. p->nullValue is
22141 ** the null value. Strings are quoted if necessary. The separator
22142 ** is only issued if bSep is true.
22143 */
22144 static void output_csv(ShellState *p, const char *z, int bSep){
22145 if( z==0 ){
22146 sqlite3_fprintf(p->out, "%s",p->nullValue);
22147 }else{
22148 unsigned i;
22149 for(i=0; z[i]; i++){
22150 if( needCsvQuote[((unsigned char*)z)[i]] ){
22151 i = 0;
22152 break;
22153 }
22154 }
22155 if( i==0 || strstr(z, p->colSeparator)!=0 ){
22156 char *zQuoted = sqlite3_mprintf("\"%w\"", z);
22157 shell_check_oom(zQuoted);
22158 sqlite3_fputs(zQuoted, p->out);
22159 sqlite3_free(zQuoted);
22160 }else{
22161 sqlite3_fputs(z, p->out);
22162 }
22163 }
22164 if( bSep ){
22165 sqlite3_fputs(p->colSeparator, p->out);
22166 }
22167 }
22168
22169 /*
22170 ** This routine runs when the user presses Ctrl-C
22171 */
22172 static void interrupt_handler(int NotUsed){
22173 UNUSED_PARAMETER(NotUsed);
22174 if( ++seenInterrupt>1 ) exit(1);
22175 if( globalDb ) sqlite3_interrupt(globalDb);
22176 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22177
22178 #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
22179 /*
22180 ** This routine runs for console events (e.g. Ctrl-C) on Win32
22181 */
@@ -22268,27 +24738,27 @@
22268 const char *az[4];
22269 az[0] = zA1;
22270 az[1] = zA2;
22271 az[2] = zA3;
22272 az[3] = zA4;
22273 sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]);
22274 for(i=0; i<4; i++){
22275 sqlite3_fputs(" ", p->out);
22276 if( az[i] ){
22277 output_c_string(p->out, az[i]);
22278 }else{
22279 sqlite3_fputs("NULL", p->out);
22280 }
22281 }
22282 sqlite3_fputs("\n", p->out);
22283 if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
22284 return SQLITE_OK;
22285 }
22286 #endif
22287
22288 /*
22289 ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
22290 **
22291 ** This routine converts some CREATE TABLE statements for shadow tables
22292 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
22293 **
22294 ** If the schema statement in z[] contains a start-of-comment and if
@@ -22315,22 +24785,16 @@
22315 }
22316 sqlite3_free(zNew);
22317 }
22318 }
22319 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
22320 sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
22321 }else{
22322 sqlite3_fprintf(out, "%s%s", z, zTail);
22323 }
22324 sqlite3_free(zToFree);
22325 }
22326 static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
22327 char c = z[n];
22328 z[n] = 0;
22329 printSchemaLine(out, z, zTail);
22330 z[n] = c;
22331 }
22332
22333 /*
22334 ** Return true if string z[] has nothing but whitespace and comments to the
22335 ** end of the first line.
22336 */
@@ -22344,99 +24808,132 @@
22344 }
22345 return 1;
22346 }
22347
22348 /*
22349 ** Add a new entry to the EXPLAIN QUERY PLAN data
22350 */
22351 static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
22352 EQPGraphRow *pNew;
22353 i64 nText;
22354 if( zText==0 ) return;
22355 nText = strlen(zText);
22356 if( p->autoEQPtest ){
22357 sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
22358 }
22359 pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
22360 shell_check_oom(pNew);
22361 pNew->iEqpId = iEqpId;
22362 pNew->iParentId = p2;
22363 memcpy(pNew->zText, zText, nText+1);
22364 pNew->pNext = 0;
22365 if( p->sGraph.pLast ){
22366 p->sGraph.pLast->pNext = pNew;
22367 }else{
22368 p->sGraph.pRow = pNew;
22369 }
22370 p->sGraph.pLast = pNew;
22371 }
22372
22373 /*
22374 ** Free and reset the EXPLAIN QUERY PLAN data that has been collected
22375 ** in p->sGraph.
22376 */
22377 static void eqp_reset(ShellState *p){
22378 EQPGraphRow *pRow, *pNext;
22379 for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
22380 pNext = pRow->pNext;
22381 sqlite3_free(pRow);
22382 }
22383 memset(&p->sGraph, 0, sizeof(p->sGraph));
22384 }
22385
22386 /* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
22387 ** pOld, or return the first such line if pOld is NULL
22388 */
22389 static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
22390 EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
22391 while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
22392 return pRow;
22393 }
22394
22395 /* Render a single level of the graph that has iEqpId as its parent. Called
22396 ** recursively to render sublevels.
22397 */
22398 static void eqp_render_level(ShellState *p, int iEqpId){
22399 EQPGraphRow *pRow, *pNext;
22400 i64 n = strlen(p->sGraph.zPrefix);
22401 char *z;
22402 for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
22403 pNext = eqp_next_row(p, iEqpId, pRow);
22404 z = pRow->zText;
22405 sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
22406 pNext ? "|--" : "`--", z);
22407 if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){
22408 memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
22409 eqp_render_level(p, pRow->iEqpId);
22410 p->sGraph.zPrefix[n] = 0;
22411 }
22412 }
22413 }
22414
22415 /*
22416 ** Display and reset the EXPLAIN QUERY PLAN data
22417 */
22418 static void eqp_render(ShellState *p, i64 nCycle){
22419 EQPGraphRow *pRow = p->sGraph.pRow;
22420 if( pRow ){
22421 if( pRow->zText[0]=='-' ){
22422 if( pRow->pNext==0 ){
22423 eqp_reset(p);
22424 return;
22425 }
22426 sqlite3_fprintf(p->out, "%s\n", pRow->zText+3);
22427 p->sGraph.pRow = pRow->pNext;
22428 sqlite3_free(pRow);
22429 }else if( nCycle>0 ){
22430 sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle);
22431 }else{
22432 sqlite3_fputs("QUERY PLAN\n", p->out);
22433 }
22434 p->sGraph.zPrefix[0] = 0;
22435 eqp_render_level(p, 0);
22436 eqp_reset(p);
22437 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22438 }
22439
22440 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
22441 /*
22442 ** Progress handler callback.
@@ -22443,496 +24940,22 @@
22443 */
22444 static int progress_handler(void *pClientData) {
22445 ShellState *p = (ShellState*)pClientData;
22446 p->nProgress++;
22447 if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
22448 sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress);
22449 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
22450 if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
22451 return 1;
22452 }
22453 if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
22454 sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress);
22455 }
22456 return 0;
22457 }
22458 #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
22459
22460 /*
22461 ** Print N dashes
22462 */
22463 static void print_dashes(FILE *out, int N){
22464 const char zDash[] = "--------------------------------------------------";
22465 const int nDash = sizeof(zDash) - 1;
22466 while( N>nDash ){
22467 sqlite3_fputs(zDash, out);
22468 N -= nDash;
22469 }
22470 sqlite3_fprintf(out, "%.*s", N, zDash);
22471 }
22472
22473 /*
22474 ** Print a markdown or table-style row separator using ascii-art
22475 */
22476 static void print_row_separator(
22477 ShellState *p,
22478 int nArg,
22479 const char *zSep
22480 ){
22481 int i;
22482 if( nArg>0 ){
22483 sqlite3_fputs(zSep, p->out);
22484 print_dashes(p->out, p->actualWidth[0]+2);
22485 for(i=1; i<nArg; i++){
22486 sqlite3_fputs(zSep, p->out);
22487 print_dashes(p->out, p->actualWidth[i]+2);
22488 }
22489 sqlite3_fputs(zSep, p->out);
22490 }
22491 sqlite3_fputs("\n", p->out);
22492 }
22493
22494 /*
22495 ** This is the callback routine that the shell
22496 ** invokes for each row of a query result.
22497 */
22498 static int shell_callback(
22499 void *pArg,
22500 int nArg, /* Number of result columns */
22501 char **azArg, /* Text of each result column */
22502 char **azCol, /* Column names */
22503 int *aiType /* Column types. Might be NULL */
22504 ){
22505 int i;
22506 ShellState *p = (ShellState*)pArg;
22507
22508 if( azArg==0 ) return 0;
22509 switch( p->cMode ){
22510 case MODE_Count:
22511 case MODE_Off: {
22512 break;
22513 }
22514 case MODE_Line: {
22515 int w = 5;
22516 if( azArg==0 ) break;
22517 for(i=0; i<nArg; i++){
22518 int len = strlen30(azCol[i] ? azCol[i] : "");
22519 if( len>w ) w = len;
22520 }
22521 if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out);
22522 for(i=0; i<nArg; i++){
22523 char *pFree = 0;
22524 const char *pDisplay;
22525 pDisplay = escapeOutput(p, azArg[i] ? azArg[i] : p->nullValue, &pFree);
22526 sqlite3_fprintf(p->out, "%*s = %s%s", w, azCol[i],
22527 pDisplay, p->rowSeparator);
22528 if( pFree ) sqlite3_free(pFree);
22529 }
22530 break;
22531 }
22532 case MODE_ScanExp:
22533 case MODE_Explain: {
22534 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
22535 static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
22536 static const int aScanExpWidth[] = {4, 15, 6, 13, 4, 4, 4, 13, 2, 13};
22537 static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
22538
22539 const int *aWidth = aExplainWidth;
22540 const int *aMap = aExplainMap;
22541 int nWidth = ArraySize(aExplainWidth);
22542 int iIndent = 1;
22543
22544 if( p->cMode==MODE_ScanExp ){
22545 aWidth = aScanExpWidth;
22546 aMap = aScanExpMap;
22547 nWidth = ArraySize(aScanExpWidth);
22548 iIndent = 3;
22549 }
22550 if( nArg>nWidth ) nArg = nWidth;
22551
22552 /* If this is the first row seen, print out the headers */
22553 if( p->cnt++==0 ){
22554 for(i=0; i<nArg; i++){
22555 utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]);
22556 sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out);
22557 }
22558 for(i=0; i<nArg; i++){
22559 print_dashes(p->out, aWidth[i]);
22560 sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out);
22561 }
22562 }
22563
22564 /* If there is no data, exit early. */
22565 if( azArg==0 ) break;
22566
22567 for(i=0; i<nArg; i++){
22568 const char *zSep = " ";
22569 int w = aWidth[i];
22570 const char *zVal = azArg[ aMap[i] ];
22571 if( i==nArg-1 ) w = 0;
22572 if( zVal && strlenChar(zVal)>w ){
22573 w = strlenChar(zVal);
22574 zSep = " ";
22575 }
22576 if( i==iIndent && p->aiIndent && p->pStmt ){
22577 if( p->iIndent<p->nIndent ){
22578 sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
22579 }
22580 p->iIndent++;
22581 }
22582 utf8_width_print(p->out, w, zVal ? zVal : p->nullValue);
22583 sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out);
22584 }
22585 break;
22586 }
22587 case MODE_Semi: { /* .schema and .fullschema output */
22588 printSchemaLine(p->out, azArg[0], ";\n");
22589 break;
22590 }
22591 case MODE_Pretty: { /* .schema and .fullschema with --indent */
22592 char *z;
22593 int j;
22594 int nParen = 0;
22595 char cEnd = 0;
22596 char c;
22597 int nLine = 0;
22598 int isIndex;
22599 int isWhere = 0;
22600 assert( nArg==1 );
22601 if( azArg[0]==0 ) break;
22602 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
22603 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
22604 ){
22605 sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
22606 break;
22607 }
22608 isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0
22609 || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0;
22610 z = sqlite3_mprintf("%s", azArg[0]);
22611 shell_check_oom(z);
22612 j = 0;
22613 for(i=0; IsSpace(z[i]); i++){}
22614 for(; (c = z[i])!=0; i++){
22615 if( IsSpace(c) ){
22616 if( z[j-1]=='\r' ) z[j-1] = '\n';
22617 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
22618 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
22619 j--;
22620 }
22621 z[j++] = c;
22622 }
22623 while( j>0 && IsSpace(z[j-1]) ){ j--; }
22624 z[j] = 0;
22625 if( strlen30(z)>=79 ){
22626 for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
22627 if( c==cEnd ){
22628 cEnd = 0;
22629 }else if( c=='"' || c=='\'' || c=='`' ){
22630 cEnd = c;
22631 }else if( c=='[' ){
22632 cEnd = ']';
22633 }else if( c=='-' && z[i+1]=='-' ){
22634 cEnd = '\n';
22635 }else if( c=='(' ){
22636 nParen++;
22637 }else if( c==')' ){
22638 nParen--;
22639 if( nLine>0 && nParen==0 && j>0 && !isWhere ){
22640 printSchemaLineN(p->out, z, j, "\n");
22641 j = 0;
22642 }
22643 }else if( (c=='w' || c=='W')
22644 && nParen==0 && isIndex
22645 && sqlite3_strnicmp("WHERE",&z[i],5)==0
22646 && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
22647 isWhere = 1;
22648 }else if( isWhere && (c=='A' || c=='a')
22649 && nParen==0
22650 && sqlite3_strnicmp("AND",&z[i],3)==0
22651 && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
22652 printSchemaLineN(p->out, z, j, "\n ");
22653 j = 0;
22654 }
22655 z[j++] = c;
22656 if( nParen==1 && cEnd==0
22657 && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
22658 && !isWhere
22659 ){
22660 if( c=='\n' ) j--;
22661 printSchemaLineN(p->out, z, j, "\n ");
22662 j = 0;
22663 nLine++;
22664 while( IsSpace(z[i+1]) ){ i++; }
22665 }
22666 }
22667 z[j] = 0;
22668 }
22669 printSchemaLine(p->out, z, ";\n");
22670 sqlite3_free(z);
22671 break;
22672 }
22673 case MODE_List: {
22674 if( p->cnt++==0 && p->showHeader ){
22675 for(i=0; i<nArg; i++){
22676 char *z = azCol[i];
22677 char *pFree;
22678 const char *zOut = escapeOutput(p, z, &pFree);
22679 sqlite3_fprintf(p->out, "%s%s", zOut,
22680 i==nArg-1 ? p->rowSeparator : p->colSeparator);
22681 if( pFree ) sqlite3_free(pFree);
22682 }
22683 }
22684 if( azArg==0 ) break;
22685 for(i=0; i<nArg; i++){
22686 char *z = azArg[i];
22687 char *pFree;
22688 const char *zOut;
22689 if( z==0 ) z = p->nullValue;
22690 zOut = escapeOutput(p, z, &pFree);
22691 sqlite3_fputs(zOut, p->out);
22692 if( pFree ) sqlite3_free(pFree);
22693 sqlite3_fputs((i<nArg-1)? p->colSeparator : p->rowSeparator, p->out);
22694 }
22695 break;
22696 }
22697 case MODE_Www:
22698 case MODE_Html: {
22699 if( p->cnt==0 && p->cMode==MODE_Www ){
22700 sqlite3_fputs(
22701 "</PRE>\n"
22702 "<TABLE border='1' cellspacing='0' cellpadding='2'>\n"
22703 ,p->out
22704 );
22705 }
22706 if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){
22707 sqlite3_fputs("<TR>", p->out);
22708 for(i=0; i<nArg; i++){
22709 sqlite3_fputs("<TH>", p->out);
22710 output_html_string(p->out, azCol[i]);
22711 sqlite3_fputs("</TH>\n", p->out);
22712 }
22713 sqlite3_fputs("</TR>\n", p->out);
22714 }
22715 p->cnt++;
22716 if( azArg==0 ) break;
22717 sqlite3_fputs("<TR>", p->out);
22718 for(i=0; i<nArg; i++){
22719 sqlite3_fputs("<TD>", p->out);
22720 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
22721 sqlite3_fputs("</TD>\n", p->out);
22722 }
22723 sqlite3_fputs("</TR>\n", p->out);
22724 break;
22725 }
22726 case MODE_Tcl: {
22727 if( p->cnt++==0 && p->showHeader ){
22728 for(i=0; i<nArg; i++){
22729 output_c_string(p->out, azCol[i] ? azCol[i] : "");
22730 if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out);
22731 }
22732 sqlite3_fputs(p->rowSeparator, p->out);
22733 }
22734 if( azArg==0 ) break;
22735 for(i=0; i<nArg; i++){
22736 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
22737 if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out);
22738 }
22739 sqlite3_fputs(p->rowSeparator, p->out);
22740 break;
22741 }
22742 case MODE_Csv: {
22743 sqlite3_fsetmode(p->out, _O_BINARY);
22744 if( p->cnt++==0 && p->showHeader ){
22745 for(i=0; i<nArg; i++){
22746 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
22747 }
22748 sqlite3_fputs(p->rowSeparator, p->out);
22749 }
22750 if( nArg>0 ){
22751 for(i=0; i<nArg; i++){
22752 output_csv(p, azArg[i], i<nArg-1);
22753 }
22754 sqlite3_fputs(p->rowSeparator, p->out);
22755 }
22756 setCrlfMode(p);
22757 break;
22758 }
22759 case MODE_Insert: {
22760 if( azArg==0 ) break;
22761 sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable);
22762 if( p->showHeader ){
22763 sqlite3_fputs("(", p->out);
22764 for(i=0; i<nArg; i++){
22765 if( i>0 ) sqlite3_fputs(",", p->out);
22766 if( quoteChar(azCol[i]) ){
22767 char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
22768 shell_check_oom(z);
22769 sqlite3_fputs(z, p->out);
22770 sqlite3_free(z);
22771 }else{
22772 sqlite3_fprintf(p->out, "%s", azCol[i]);
22773 }
22774 }
22775 sqlite3_fputs(")", p->out);
22776 }
22777 p->cnt++;
22778 for(i=0; i<nArg; i++){
22779 sqlite3_fputs(i>0 ? "," : " VALUES(", p->out);
22780 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22781 sqlite3_fputs("NULL", p->out);
22782 }else if( aiType && aiType[i]==SQLITE_TEXT ){
22783 if( ShellHasFlag(p, SHFLG_Newlines) ){
22784 output_quoted_string(p, azArg[i]);
22785 }else{
22786 output_quoted_escaped_string(p, azArg[i]);
22787 }
22788 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
22789 sqlite3_fputs(azArg[i], p->out);
22790 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22791 char z[50];
22792 double r = sqlite3_column_double(p->pStmt, i);
22793 sqlite3_uint64 ur;
22794 memcpy(&ur,&r,sizeof(r));
22795 if( ur==0x7ff0000000000000LL ){
22796 sqlite3_fputs("9.0e+999", p->out);
22797 }else if( ur==0xfff0000000000000LL ){
22798 sqlite3_fputs("-9.0e+999", p->out);
22799 }else{
22800 sqlite3_int64 ir = (sqlite3_int64)r;
22801 if( r==(double)ir ){
22802 sqlite3_snprintf(50,z,"%lld.0", ir);
22803 }else{
22804 sqlite3_snprintf(50,z,"%!.20g", r);
22805 }
22806 sqlite3_fputs(z, p->out);
22807 }
22808 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22809 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22810 int nBlob = sqlite3_column_bytes(p->pStmt, i);
22811 output_hex_blob(p->out, pBlob, nBlob);
22812 }else if( isNumber(azArg[i], 0) ){
22813 sqlite3_fputs(azArg[i], p->out);
22814 }else if( ShellHasFlag(p, SHFLG_Newlines) ){
22815 output_quoted_string(p, azArg[i]);
22816 }else{
22817 output_quoted_escaped_string(p, azArg[i]);
22818 }
22819 }
22820 sqlite3_fputs(");\n", p->out);
22821 break;
22822 }
22823 case MODE_Json: {
22824 if( azArg==0 ) break;
22825 if( p->cnt==0 ){
22826 sqlite3_fputs("[{", p->out);
22827 }else{
22828 sqlite3_fputs(",\n{", p->out);
22829 }
22830 p->cnt++;
22831 for(i=0; i<nArg; i++){
22832 output_json_string(p->out, azCol[i], -1);
22833 sqlite3_fputs(":", p->out);
22834 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22835 sqlite3_fputs("null", p->out);
22836 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22837 char z[50];
22838 double r = sqlite3_column_double(p->pStmt, i);
22839 sqlite3_uint64 ur;
22840 memcpy(&ur,&r,sizeof(r));
22841 if( ur==0x7ff0000000000000LL ){
22842 sqlite3_fputs("9.0e+999", p->out);
22843 }else if( ur==0xfff0000000000000LL ){
22844 sqlite3_fputs("-9.0e+999", p->out);
22845 }else{
22846 sqlite3_snprintf(50,z,"%!.20g", r);
22847 sqlite3_fputs(z, p->out);
22848 }
22849 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22850 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22851 int nBlob = sqlite3_column_bytes(p->pStmt, i);
22852 output_json_string(p->out, pBlob, nBlob);
22853 }else if( aiType && aiType[i]==SQLITE_TEXT ){
22854 output_json_string(p->out, azArg[i], -1);
22855 }else{
22856 sqlite3_fputs(azArg[i], p->out);
22857 }
22858 if( i<nArg-1 ){
22859 sqlite3_fputs(",", p->out);
22860 }
22861 }
22862 sqlite3_fputs("}", p->out);
22863 break;
22864 }
22865 case MODE_Quote: {
22866 if( azArg==0 ) break;
22867 if( p->cnt==0 && p->showHeader ){
22868 for(i=0; i<nArg; i++){
22869 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22870 output_quoted_string(p, azCol[i]);
22871 }
22872 sqlite3_fputs(p->rowSeparator, p->out);
22873 }
22874 p->cnt++;
22875 for(i=0; i<nArg; i++){
22876 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22877 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
22878 sqlite3_fputs("NULL", p->out);
22879 }else if( aiType && aiType[i]==SQLITE_TEXT ){
22880 output_quoted_string(p, azArg[i]);
22881 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
22882 sqlite3_fputs(azArg[i], p->out);
22883 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
22884 char z[50];
22885 double r = sqlite3_column_double(p->pStmt, i);
22886 sqlite3_snprintf(50,z,"%!.20g", r);
22887 sqlite3_fputs(z, p->out);
22888 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
22889 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
22890 int nBlob = sqlite3_column_bytes(p->pStmt, i);
22891 output_hex_blob(p->out, pBlob, nBlob);
22892 }else if( isNumber(azArg[i], 0) ){
22893 sqlite3_fputs(azArg[i], p->out);
22894 }else{
22895 output_quoted_string(p, azArg[i]);
22896 }
22897 }
22898 sqlite3_fputs(p->rowSeparator, p->out);
22899 break;
22900 }
22901 case MODE_Ascii: {
22902 if( p->cnt++==0 && p->showHeader ){
22903 for(i=0; i<nArg; i++){
22904 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22905 sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out);
22906 }
22907 sqlite3_fputs(p->rowSeparator, p->out);
22908 }
22909 if( azArg==0 ) break;
22910 for(i=0; i<nArg; i++){
22911 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
22912 sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out);
22913 }
22914 sqlite3_fputs(p->rowSeparator, p->out);
22915 break;
22916 }
22917 case MODE_EQP: {
22918 eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
22919 break;
22920 }
22921 }
22922 return 0;
22923 }
22924
22925 /*
22926 ** This is the callback routine that the SQLite library
22927 ** invokes for each row of a query result.
22928 */
22929 static int callback(void *pArg, int nArg, char **azArg, char **azCol){
22930 /* since we don't have type info, call the shell_callback with a NULL value */
22931 return shell_callback(pArg, nArg, azArg, azCol, NULL);
22932 }
22933
22934 /*
22935 ** This is the callback routine from sqlite3_exec() that appends all
22936 ** output onto the end of a ShellText object.
22937 */
22938 static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
@@ -22988,11 +25011,11 @@
22988 "INSERT INTO selftest(tno,op,cmd,ans)"
22989 " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
22990 "DROP TABLE [_shell$self];"
22991 ,0,0,&zErrMsg);
22992 if( zErrMsg ){
22993 sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
22994 sqlite3_free(zErrMsg);
22995 }
22996 sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
22997 }
22998
@@ -23006,15 +25029,11 @@
23006 if( p->zDestTable ){
23007 sqlite3_free(p->zDestTable);
23008 p->zDestTable = 0;
23009 }
23010 if( zName==0 ) return;
23011 if( quoteChar(zName) ){
23012 p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
23013 }else{
23014 p->zDestTable = sqlite3_mprintf("%s", zName);
23015 }
23016 shell_check_oom(p->zDestTable);
23017 }
23018
23019 /*
23020 ** Maybe construct two lines of text that point out the position of a
@@ -23080,36 +25099,36 @@
23080 int i;
23081 const char *z;
23082 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
23083 if( rc!=SQLITE_OK || !pSelect ){
23084 char *zContext = shell_error_context(zSelect, p->db);
23085 sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s",
23086 rc, sqlite3_errmsg(p->db), zContext);
23087 sqlite3_free(zContext);
23088 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
23089 return rc;
23090 }
23091 rc = sqlite3_step(pSelect);
23092 nResult = sqlite3_column_count(pSelect);
23093 while( rc==SQLITE_ROW ){
23094 z = (const char*)sqlite3_column_text(pSelect, 0);
23095 sqlite3_fprintf(p->out, "%s", z);
23096 for(i=1; i<nResult; i++){
23097 sqlite3_fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
23098 }
23099 if( z==0 ) z = "";
23100 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
23101 if( z[0] ){
23102 sqlite3_fputs("\n;\n", p->out);
23103 }else{
23104 sqlite3_fputs(";\n", p->out);
23105 }
23106 rc = sqlite3_step(pSelect);
23107 }
23108 rc = sqlite3_finalize(pSelect);
23109 if( rc!=SQLITE_OK ){
23110 sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n",
23111 rc, sqlite3_errmsg(p->db));
23112 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
23113 }
23114 return rc;
23115 }
@@ -23165,11 +25184,11 @@
23165 };
23166 int i;
23167 for(i=0; i<ArraySize(aTrans); i++){
23168 int n = strlen30(aTrans[i].zPattern);
23169 if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){
23170 sqlite3_fprintf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
23171 break;
23172 }
23173 }
23174 }
23175 fclose(in);
@@ -23197,11 +25216,11 @@
23197 if( nPercent>1 ){
23198 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
23199 }else{
23200 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
23201 }
23202 sqlite3_fprintf(out, "%-36s %s\n", zLabel, zLine);
23203 }
23204
23205 /*
23206 ** Display memory stats.
23207 */
@@ -23219,34 +25238,34 @@
23219 if( pArg->pStmt && pArg->statsOn==2 ){
23220 int nCol, i, x;
23221 sqlite3_stmt *pStmt = pArg->pStmt;
23222 char z[100];
23223 nCol = sqlite3_column_count(pStmt);
23224 sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol);
23225 for(i=0; i<nCol; i++){
23226 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
23227 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
23228 #ifndef SQLITE_OMIT_DECLTYPE
23229 sqlite3_snprintf(30, z+x, "declared type:");
23230 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
23231 #endif
23232 #ifdef SQLITE_ENABLE_COLUMN_METADATA
23233 sqlite3_snprintf(30, z+x, "database name:");
23234 sqlite3_fprintf(out, "%-36s %s\n", z,
23235 sqlite3_column_database_name(pStmt,i));
23236 sqlite3_snprintf(30, z+x, "table name:");
23237 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
23238 sqlite3_snprintf(30, z+x, "origin name:");
23239 sqlite3_fprintf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i));
23240 #endif
23241 }
23242 }
23243
23244 if( pArg->statsOn==3 ){
23245 if( pArg->pStmt ){
23246 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
23247 sqlite3_fprintf(out, "VM-steps: %d\n", iCur);
23248 }
23249 return 0;
23250 }
23251
23252 displayStatLine(out, "Memory Used:",
@@ -23271,93 +25290,93 @@
23271 if( db ){
23272 if( pArg->shellFlgs & SHFLG_Lookaside ){
23273 iHiwtr = iCur = -1;
23274 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
23275 &iCur, &iHiwtr, bReset);
23276 sqlite3_fprintf(out,
23277 "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
23278 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
23279 &iCur, &iHiwtr, bReset);
23280 sqlite3_fprintf(out,
23281 "Successful lookaside attempts: %d\n", iHiwtr);
23282 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
23283 &iCur, &iHiwtr, bReset);
23284 sqlite3_fprintf(out,
23285 "Lookaside failures due to size: %d\n", iHiwtr);
23286 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
23287 &iCur, &iHiwtr, bReset);
23288 sqlite3_fprintf(out,
23289 "Lookaside failures due to OOM: %d\n", iHiwtr);
23290 }
23291 iHiwtr = iCur = -1;
23292 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
23293 sqlite3_fprintf(out,
23294 "Pager Heap Usage: %d bytes\n", iCur);
23295 iHiwtr = iCur = -1;
23296 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
23297 sqlite3_fprintf(out,
23298 "Page cache hits: %d\n", iCur);
23299 iHiwtr = iCur = -1;
23300 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
23301 sqlite3_fprintf(out,
23302 "Page cache misses: %d\n", iCur);
23303 iHiwtr64 = iCur64 = -1;
23304 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
23305 0);
23306 iHiwtr = iCur = -1;
23307 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
23308 sqlite3_fprintf(out,
23309 "Page cache writes: %d\n", iCur);
23310 iHiwtr = iCur = -1;
23311 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
23312 sqlite3_fprintf(out,
23313 "Page cache spills: %d\n", iCur);
23314 sqlite3_fprintf(out,
23315 "Temporary data spilled to disk: %lld\n", iCur64);
23316 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
23317 1);
23318 iHiwtr = iCur = -1;
23319 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
23320 sqlite3_fprintf(out,
23321 "Schema Heap Usage: %d bytes\n", iCur);
23322 iHiwtr = iCur = -1;
23323 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
23324 sqlite3_fprintf(out,
23325 "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
23326 }
23327
23328 if( pArg->pStmt ){
23329 int iHit, iMiss;
23330 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
23331 bReset);
23332 sqlite3_fprintf(out,
23333 "Fullscan Steps: %d\n", iCur);
23334 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
23335 sqlite3_fprintf(out,
23336 "Sort Operations: %d\n", iCur);
23337 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
23338 sqlite3_fprintf(out,
23339 "Autoindex Inserts: %d\n", iCur);
23340 iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
23341 bReset);
23342 iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
23343 bReset);
23344 if( iHit || iMiss ){
23345 sqlite3_fprintf(out,
23346 "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss);
23347 }
23348 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
23349 sqlite3_fprintf(out,
23350 "Virtual Machine Steps: %d\n", iCur);
23351 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
23352 sqlite3_fprintf(out,
23353 "Reprepare operations: %d\n", iCur);
23354 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
23355 sqlite3_fprintf(out,
23356 "Number of times run: %d\n", iCur);
23357 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
23358 sqlite3_fprintf(out,
23359 "Memory used by prepared stmt: %d\n", iCur);
23360 }
23361
23362 #ifdef __linux__
23363 displayLinuxIoStats(pArg->out);
@@ -23366,271 +25385,10 @@
23366 /* Do not remove this machine readable comment: extra-stats-output-here */
23367
23368 return 0;
23369 }
23370
23371
23372 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
23373 static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
23374 int iPid = 0;
23375 int ret = 1;
23376 sqlite3_stmt_scanstatus_v2(p, iEntry,
23377 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
23378 );
23379 while( iPid!=0 ){
23380 int ii;
23381 for(ii=0; 1; ii++){
23382 int iId;
23383 int res;
23384 res = sqlite3_stmt_scanstatus_v2(p, ii,
23385 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
23386 );
23387 if( res ) break;
23388 if( iId==iPid ){
23389 sqlite3_stmt_scanstatus_v2(p, ii,
23390 SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
23391 );
23392 }
23393 }
23394 ret++;
23395 }
23396 return ret;
23397 }
23398 #endif
23399
23400 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
23401 static void display_explain_scanstats(
23402 sqlite3 *db, /* Database to query */
23403 ShellState *pArg /* Pointer to ShellState */
23404 ){
23405 static const int f = SQLITE_SCANSTAT_COMPLEX;
23406 sqlite3_stmt *p = pArg->pStmt;
23407 int ii = 0;
23408 i64 nTotal = 0;
23409 int nWidth = 0;
23410 eqp_reset(pArg);
23411
23412 for(ii=0; 1; ii++){
23413 const char *z = 0;
23414 int n = 0;
23415 if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
23416 break;
23417 }
23418 n = (int)strlen(z) + scanStatsHeight(p, ii)*3;
23419 if( n>nWidth ) nWidth = n;
23420 }
23421 nWidth += 4;
23422
23423 sqlite3_stmt_scanstatus_v2(p, -1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal);
23424 for(ii=0; 1; ii++){
23425 i64 nLoop = 0;
23426 i64 nRow = 0;
23427 i64 nCycle = 0;
23428 int iId = 0;
23429 int iPid = 0;
23430 const char *zo = 0;
23431 const char *zName = 0;
23432 char *zText = 0;
23433 double rEst = 0.0;
23434
23435 if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){
23436 break;
23437 }
23438 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_EST,f,(void*)&rEst);
23439 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop);
23440 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow);
23441 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle);
23442 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId);
23443 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid);
23444 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NAME,f,(void*)&zName);
23445
23446 zText = sqlite3_mprintf("%s", zo);
23447 if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
23448 char *z = 0;
23449 if( nCycle>=0 && nTotal>0 ){
23450 z = sqlite3_mprintf("%zcycles=%lld [%d%%]", z,
23451 nCycle, ((nCycle*100)+nTotal/2) / nTotal
23452 );
23453 }
23454 if( nLoop>=0 ){
23455 z = sqlite3_mprintf("%z%sloops=%lld", z, z ? " " : "", nLoop);
23456 }
23457 if( nRow>=0 ){
23458 z = sqlite3_mprintf("%z%srows=%lld", z, z ? " " : "", nRow);
23459 }
23460
23461 if( zName && pArg->scanstatsOn>1 ){
23462 double rpl = (double)nRow / (double)nLoop;
23463 z = sqlite3_mprintf("%z rpl=%.1f est=%.1f", z, rpl, rEst);
23464 }
23465
23466 zText = sqlite3_mprintf(
23467 "% *z (%z)", -1*(nWidth-scanStatsHeight(p, ii)*3), zText, z
23468 );
23469 }
23470
23471 eqp_append(pArg, iId, iPid, zText);
23472 sqlite3_free(zText);
23473 }
23474
23475 eqp_render(pArg, nTotal);
23476 }
23477 #endif
23478
23479
23480 /*
23481 ** Parameter azArray points to a zero-terminated array of strings. zStr
23482 ** points to a single nul-terminated string. Return non-zero if zStr
23483 ** is equal, according to strcmp(), to any of the strings in the array.
23484 ** Otherwise, return zero.
23485 */
23486 static int str_in_array(const char *zStr, const char **azArray){
23487 int i;
23488 for(i=0; azArray[i]; i++){
23489 if( 0==cli_strcmp(zStr, azArray[i]) ) return 1;
23490 }
23491 return 0;
23492 }
23493
23494 /*
23495 ** If compiled statement pSql appears to be an EXPLAIN statement, allocate
23496 ** and populate the ShellState.aiIndent[] array with the number of
23497 ** spaces each opcode should be indented before it is output.
23498 **
23499 ** The indenting rules are:
23500 **
23501 ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
23502 ** all opcodes that occur between the p2 jump destination and the opcode
23503 ** itself by 2 spaces.
23504 **
23505 ** * Do the previous for "Return" instructions for when P2 is positive.
23506 ** See tag-20220407a in wherecode.c and vdbe.c.
23507 **
23508 ** * For each "Goto", if the jump destination is earlier in the program
23509 ** and ends on one of:
23510 ** Yield SeekGt SeekLt RowSetRead Rewind
23511 ** or if the P1 parameter is one instead of zero,
23512 ** then indent all opcodes between the earlier instruction
23513 ** and "Goto" by 2 spaces.
23514 */
23515 static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
23516 int *abYield = 0; /* True if op is an OP_Yield */
23517 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
23518 int iOp; /* Index of operation in p->aiIndent[] */
23519
23520 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
23521 "Return", 0 };
23522 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
23523 "Rewind", 0 };
23524 const char *azGoto[] = { "Goto", 0 };
23525
23526 /* The caller guarantees that the leftmost 4 columns of the statement
23527 ** passed to this function are equivalent to the leftmost 4 columns
23528 ** of EXPLAIN statement output. In practice the statement may be
23529 ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
23530 assert( sqlite3_column_count(pSql)>=4 );
23531 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) );
23532 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) );
23533 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) );
23534 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) );
23535
23536 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
23537 int i;
23538 int iAddr = sqlite3_column_int(pSql, 0);
23539 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
23540 int p1 = sqlite3_column_int(pSql, 2);
23541 int p2 = sqlite3_column_int(pSql, 3);
23542
23543 /* Assuming that p2 is an instruction address, set variable p2op to the
23544 ** index of that instruction in the aiIndent[] array. p2 and p2op may be
23545 ** different if the current instruction is part of a sub-program generated
23546 ** by an SQL trigger or foreign key. */
23547 int p2op = (p2 + (iOp-iAddr));
23548
23549 /* Grow the p->aiIndent array as required */
23550 if( iOp>=nAlloc ){
23551 nAlloc += 100;
23552 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
23553 shell_check_oom(p->aiIndent);
23554 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
23555 shell_check_oom(abYield);
23556 }
23557
23558 abYield[iOp] = str_in_array(zOp, azYield);
23559 p->aiIndent[iOp] = 0;
23560 p->nIndent = iOp+1;
23561 if( str_in_array(zOp, azNext) && p2op>0 ){
23562 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
23563 }
23564 if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
23565 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
23566 }
23567 }
23568
23569 p->iIndent = 0;
23570 sqlite3_free(abYield);
23571 sqlite3_reset(pSql);
23572 }
23573
23574 /*
23575 ** Free the array allocated by explain_data_prepare().
23576 */
23577 static void explain_data_delete(ShellState *p){
23578 sqlite3_free(p->aiIndent);
23579 p->aiIndent = 0;
23580 p->nIndent = 0;
23581 p->iIndent = 0;
23582 }
23583
23584 static void exec_prepared_stmt(ShellState*, sqlite3_stmt*);
23585
23586 /*
23587 ** Display scan stats.
23588 */
23589 static void display_scanstats(
23590 sqlite3 *db, /* Database to query */
23591 ShellState *pArg /* Pointer to ShellState */
23592 ){
23593 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
23594 UNUSED_PARAMETER(db);
23595 UNUSED_PARAMETER(pArg);
23596 #else
23597 if( pArg->scanstatsOn==3 ){
23598 const char *zSql =
23599 " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
23600 " format('% 6s (%.2f%%)',"
23601 " CASE WHEN ncycle<100_000 THEN ncycle || ' '"
23602 " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'"
23603 " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'"
23604 " ELSE (ncycle/1000_000_000) || 'G' END,"
23605 " ncycle*100.0/(sum(ncycle) OVER ())"
23606 " ) AS cycles"
23607 " FROM bytecode(?)";
23608
23609 int rc = SQLITE_OK;
23610 sqlite3_stmt *pStmt = 0;
23611 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
23612 if( rc==SQLITE_OK ){
23613 sqlite3_stmt *pSave = pArg->pStmt;
23614 pArg->pStmt = pStmt;
23615 sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0);
23616
23617 pArg->cnt = 0;
23618 pArg->cMode = MODE_ScanExp;
23619 explain_data_prepare(pArg, pStmt);
23620 exec_prepared_stmt(pArg, pStmt);
23621 explain_data_delete(pArg);
23622
23623 sqlite3_finalize(pStmt);
23624 pArg->pStmt = pSave;
23625 }
23626 }else{
23627 display_explain_scanstats(db, pArg);
23628 }
23629 #endif
23630 }
23631
23632 /*
23633 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
23634 */
23635 static unsigned int savedSelectTrace;
23636 static unsigned int savedWhereTrace;
@@ -23756,584 +25514,10 @@
23756 sqlite3_reset(pQ);
23757 }
23758 sqlite3_finalize(pQ);
23759 }
23760
23761 /*
23762 ** UTF8 box-drawing characters. Imagine box lines like this:
23763 **
23764 ** 1
23765 ** |
23766 ** 4 --+-- 2
23767 ** |
23768 ** 3
23769 **
23770 ** Each box characters has between 2 and 4 of the lines leading from
23771 ** the center. The characters are here identified by the numbers of
23772 ** their corresponding lines.
23773 */
23774 #define BOX_24 "\342\224\200" /* U+2500 --- */
23775 #define BOX_13 "\342\224\202" /* U+2502 | */
23776 #define BOX_23 "\342\224\214" /* U+250c ,- */
23777 #define BOX_34 "\342\224\220" /* U+2510 -, */
23778 #define BOX_12 "\342\224\224" /* U+2514 '- */
23779 #define BOX_14 "\342\224\230" /* U+2518 -' */
23780 #define BOX_123 "\342\224\234" /* U+251c |- */
23781 #define BOX_134 "\342\224\244" /* U+2524 -| */
23782 #define BOX_234 "\342\224\254" /* U+252c -,- */
23783 #define BOX_124 "\342\224\264" /* U+2534 -'- */
23784 #define BOX_1234 "\342\224\274" /* U+253c -|- */
23785
23786 /* Draw horizontal line N characters long using unicode box
23787 ** characters
23788 */
23789 static void print_box_line(FILE *out, int N){
23790 const char zDash[] =
23791 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
23792 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
23793 const int nDash = sizeof(zDash) - 1;
23794 N *= 3;
23795 while( N>nDash ){
23796 sqlite3_fputs(zDash, out);
23797 N -= nDash;
23798 }
23799 sqlite3_fprintf(out, "%.*s", N, zDash);
23800 }
23801
23802 /*
23803 ** Draw a horizontal separator for a MODE_Box table.
23804 */
23805 static void print_box_row_separator(
23806 ShellState *p,
23807 int nArg,
23808 const char *zSep1,
23809 const char *zSep2,
23810 const char *zSep3
23811 ){
23812 int i;
23813 if( nArg>0 ){
23814 sqlite3_fputs(zSep1, p->out);
23815 print_box_line(p->out, p->actualWidth[0]+2);
23816 for(i=1; i<nArg; i++){
23817 sqlite3_fputs(zSep2, p->out);
23818 print_box_line(p->out, p->actualWidth[i]+2);
23819 }
23820 sqlite3_fputs(zSep3, p->out);
23821 }
23822 sqlite3_fputs("\n", p->out);
23823 }
23824
23825 /*
23826 ** z[] is a line of text that is to be displayed the .mode box or table or
23827 ** similar tabular formats. z[] might contain control characters such
23828 ** as \n, \t, \f, or \r.
23829 **
23830 ** Compute characters to display on the first line of z[]. Stop at the
23831 ** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
23832 ** from malloc()) of that first line, which caller should free sometime.
23833 ** Write anything to display on the next line into *pzTail. If this is
23834 ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
23835 */
23836 static char *translateForDisplayAndDup(
23837 ShellState *p, /* To access current settings */
23838 const unsigned char *z, /* Input text to be transformed */
23839 const unsigned char **pzTail, /* OUT: Tail of the input for next line */
23840 int mxWidth, /* Max width. 0 means no limit */
23841 u8 bWordWrap /* If true, avoid breaking mid-word */
23842 ){
23843 int i; /* Input bytes consumed */
23844 int j; /* Output bytes generated */
23845 int k; /* Input bytes to be displayed */
23846 int n; /* Output column number */
23847 unsigned char *zOut; /* Output text */
23848
23849 if( z==0 ){
23850 *pzTail = 0;
23851 return 0;
23852 }
23853 if( mxWidth<0 ) mxWidth = -mxWidth;
23854 if( mxWidth==0 ) mxWidth = 1000000;
23855 i = j = n = 0;
23856 while( n<mxWidth ){
23857 unsigned char c = z[i];
23858 if( c>=0xc0 ){
23859 int u;
23860 int len = decodeUtf8(&z[i], &u);
23861 i += len;
23862 j += len;
23863 n += cli_wcwidth(u);
23864 continue;
23865 }
23866 if( c>=' ' ){
23867 n++;
23868 i++;
23869 j++;
23870 continue;
23871 }
23872 if( c==0 || c=='\n' || (c=='\r' && z[i+1]=='\n') ) break;
23873 if( c=='\t' ){
23874 do{
23875 n++;
23876 j++;
23877 }while( (n&7)!=0 && n<mxWidth );
23878 i++;
23879 continue;
23880 }
23881 if( c==0x1b && p->eEscMode==SHELL_ESC_OFF && (k = isVt100(&z[i]))>0 ){
23882 i += k;
23883 j += k;
23884 }else{
23885 n++;
23886 j += 3;
23887 i++;
23888 }
23889 }
23890 if( n>=mxWidth && bWordWrap ){
23891 /* Perhaps try to back up to a better place to break the line */
23892 for(k=i; k>i/2; k--){
23893 if( IsSpace(z[k-1]) ) break;
23894 }
23895 if( k<=i/2 ){
23896 for(k=i; k>i/2; k--){
23897 if( IsAlnum(z[k-1])!=IsAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
23898 }
23899 }
23900 if( k<=i/2 ){
23901 k = i;
23902 }else{
23903 i = k;
23904 while( z[i]==' ' ) i++;
23905 }
23906 }else{
23907 k = i;
23908 }
23909 if( n>=mxWidth && z[i]>=' ' ){
23910 *pzTail = &z[i];
23911 }else if( z[i]=='\r' && z[i+1]=='\n' ){
23912 *pzTail = z[i+2] ? &z[i+2] : 0;
23913 }else if( z[i]==0 || z[i+1]==0 ){
23914 *pzTail = 0;
23915 }else{
23916 *pzTail = &z[i+1];
23917 }
23918 zOut = malloc( j+1 );
23919 shell_check_oom(zOut);
23920 i = j = n = 0;
23921 while( i<k ){
23922 unsigned char c = z[i];
23923 if( c>=0xc0 ){
23924 int u;
23925 int len = decodeUtf8(&z[i], &u);
23926 do{ zOut[j++] = z[i++]; }while( (--len)>0 );
23927 n += cli_wcwidth(u);
23928 continue;
23929 }
23930 if( c>=' ' ){
23931 n++;
23932 zOut[j++] = z[i++];
23933 continue;
23934 }
23935 if( c==0 ) break;
23936 if( z[i]=='\t' ){
23937 do{
23938 n++;
23939 zOut[j++] = ' ';
23940 }while( (n&7)!=0 && n<mxWidth );
23941 i++;
23942 continue;
23943 }
23944 switch( p->eEscMode ){
23945 case SHELL_ESC_SYMBOL:
23946 zOut[j++] = 0xe2;
23947 zOut[j++] = 0x90;
23948 zOut[j++] = 0x80 + c;
23949 break;
23950 case SHELL_ESC_ASCII:
23951 zOut[j++] = '^';
23952 zOut[j++] = 0x40 + c;
23953 break;
23954 case SHELL_ESC_OFF: {
23955 int nn;
23956 if( c==0x1b && (nn = isVt100(&z[i]))>0 ){
23957 memcpy(&zOut[j], &z[i], nn);
23958 j += nn;
23959 i += nn - 1;
23960 }else{
23961 zOut[j++] = c;
23962 }
23963 break;
23964 }
23965 }
23966 i++;
23967 }
23968 zOut[j] = 0;
23969 return (char*)zOut;
23970 }
23971
23972 /* Return true if the text string z[] contains characters that need
23973 ** unistr() escaping.
23974 */
23975 static int needUnistr(const unsigned char *z){
23976 unsigned char c;
23977 if( z==0 ) return 0;
23978 while( (c = *z)>0x1f || c=='\t' || c=='\n' || (c=='\r' && z[1]=='\n') ){ z++; }
23979 return c!=0;
23980 }
23981
23982 /* Extract the value of the i-th current column for pStmt as an SQL literal
23983 ** value. Memory is obtained from sqlite3_malloc64() and must be freed by
23984 ** the caller.
23985 */
23986 static char *quoted_column(sqlite3_stmt *pStmt, int i){
23987 switch( sqlite3_column_type(pStmt, i) ){
23988 case SQLITE_NULL: {
23989 return sqlite3_mprintf("NULL");
23990 }
23991 case SQLITE_INTEGER:
23992 case SQLITE_FLOAT: {
23993 return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
23994 }
23995 case SQLITE_TEXT: {
23996 const unsigned char *zText = sqlite3_column_text(pStmt,i);
23997 return sqlite3_mprintf(needUnistr(zText)?"%#Q":"%Q",zText);
23998 }
23999 case SQLITE_BLOB: {
24000 int j;
24001 sqlite3_str *pStr = sqlite3_str_new(0);
24002 const unsigned char *a = sqlite3_column_blob(pStmt,i);
24003 int n = sqlite3_column_bytes(pStmt,i);
24004 sqlite3_str_append(pStr, "x'", 2);
24005 for(j=0; j<n; j++){
24006 sqlite3_str_appendf(pStr, "%02x", a[j]);
24007 }
24008 sqlite3_str_append(pStr, "'", 1);
24009 return sqlite3_str_finish(pStr);
24010 }
24011 }
24012 return 0; /* Not reached */
24013 }
24014
24015 /*
24016 ** Run a prepared statement and output the result in one of the
24017 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
24018 ** or MODE_Box.
24019 **
24020 ** This is different from ordinary exec_prepared_stmt() in that
24021 ** it has to run the entire query and gather the results into memory
24022 ** first, in order to determine column widths, before providing
24023 ** any output.
24024 */
24025 static void exec_prepared_stmt_columnar(
24026 ShellState *p, /* Pointer to ShellState */
24027 sqlite3_stmt *pStmt /* Statement to run */
24028 ){
24029 sqlite3_int64 nRow = 0;
24030 int nColumn = 0;
24031 char **azData = 0;
24032 sqlite3_int64 nAlloc = 0;
24033 char *abRowDiv = 0;
24034 const unsigned char *uz;
24035 const char *z;
24036 char **azQuoted = 0;
24037 int rc;
24038 sqlite3_int64 i, nData;
24039 int j, nTotal, w, n;
24040 const char *colSep = 0;
24041 const char *rowSep = 0;
24042 const unsigned char **azNextLine = 0;
24043 int bNextLine = 0;
24044 int bMultiLineRowExists = 0;
24045 int bw = p->cmOpts.bWordWrap;
24046 const char *zEmpty = "";
24047 const char *zShowNull = p->nullValue;
24048
24049 rc = sqlite3_step(pStmt);
24050 if( rc!=SQLITE_ROW ) return;
24051 nColumn = sqlite3_column_count(pStmt);
24052 if( nColumn==0 ) goto columnar_end;
24053 nAlloc = nColumn*4;
24054 if( nAlloc<=0 ) nAlloc = 1;
24055 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
24056 shell_check_oom(azData);
24057 azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
24058 shell_check_oom(azNextLine);
24059 memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
24060 if( p->cmOpts.bQuote ){
24061 azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
24062 shell_check_oom(azQuoted);
24063 memset(azQuoted, 0, nColumn*sizeof(char*) );
24064 }
24065 abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
24066 shell_check_oom(abRowDiv);
24067 if( nColumn>p->nWidth ){
24068 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
24069 shell_check_oom(p->colWidth);
24070 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
24071 p->nWidth = nColumn;
24072 p->actualWidth = &p->colWidth[nColumn];
24073 }
24074 memset(p->actualWidth, 0, nColumn*sizeof(int));
24075 for(i=0; i<nColumn; i++){
24076 w = p->colWidth[i];
24077 if( w<0 ) w = -w;
24078 p->actualWidth[i] = w;
24079 }
24080 for(i=0; i<nColumn; i++){
24081 const unsigned char *zNotUsed;
24082 int wx = p->colWidth[i];
24083 if( wx==0 ){
24084 wx = p->cmOpts.iWrap;
24085 }
24086 if( wx<0 ) wx = -wx;
24087 uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
24088 if( uz==0 ) uz = (u8*)"";
24089 azData[i] = translateForDisplayAndDup(p, uz, &zNotUsed, wx, bw);
24090 }
24091 do{
24092 int useNextLine = bNextLine;
24093 bNextLine = 0;
24094 if( (nRow+2)*nColumn >= nAlloc ){
24095 nAlloc *= 2;
24096 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
24097 shell_check_oom(azData);
24098 abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
24099 shell_check_oom(abRowDiv);
24100 }
24101 abRowDiv[nRow] = 1;
24102 nRow++;
24103 for(i=0; i<nColumn; i++){
24104 int wx = p->colWidth[i];
24105 if( wx==0 ){
24106 wx = p->cmOpts.iWrap;
24107 }
24108 if( wx<0 ) wx = -wx;
24109 if( useNextLine ){
24110 uz = azNextLine[i];
24111 if( uz==0 ) uz = (u8*)zEmpty;
24112 }else if( p->cmOpts.bQuote ){
24113 assert( azQuoted!=0 );
24114 sqlite3_free(azQuoted[i]);
24115 azQuoted[i] = quoted_column(pStmt,i);
24116 uz = (const unsigned char*)azQuoted[i];
24117 }else{
24118 uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
24119 if( uz==0 ) uz = (u8*)zShowNull;
24120 }
24121 azData[nRow*nColumn + i]
24122 = translateForDisplayAndDup(p, uz, &azNextLine[i], wx, bw);
24123 if( azNextLine[i] ){
24124 bNextLine = 1;
24125 abRowDiv[nRow-1] = 0;
24126 bMultiLineRowExists = 1;
24127 }
24128 }
24129 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
24130 nTotal = nColumn*(nRow+1);
24131 for(i=0; i<nTotal; i++){
24132 z = azData[i];
24133 if( z==0 ) z = (char*)zEmpty;
24134 n = strlenChar(z);
24135 j = i%nColumn;
24136 if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
24137 }
24138 if( seenInterrupt ) goto columnar_end;
24139 switch( p->cMode ){
24140 case MODE_Column: {
24141 colSep = " ";
24142 rowSep = "\n";
24143 if( p->showHeader ){
24144 for(i=0; i<nColumn; i++){
24145 w = p->actualWidth[i];
24146 if( p->colWidth[i]<0 ) w = -w;
24147 utf8_width_print(p->out, w, azData[i]);
24148 sqlite3_fputs(i==nColumn-1?"\n":" ", p->out);
24149 }
24150 for(i=0; i<nColumn; i++){
24151 print_dashes(p->out, p->actualWidth[i]);
24152 sqlite3_fputs(i==nColumn-1?"\n":" ", p->out);
24153 }
24154 }
24155 break;
24156 }
24157 case MODE_Table: {
24158 colSep = " | ";
24159 rowSep = " |\n";
24160 print_row_separator(p, nColumn, "+");
24161 sqlite3_fputs("| ", p->out);
24162 for(i=0; i<nColumn; i++){
24163 w = p->actualWidth[i];
24164 n = strlenChar(azData[i]);
24165 sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "",
24166 azData[i], (w-n+1)/2, "");
24167 sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out);
24168 }
24169 print_row_separator(p, nColumn, "+");
24170 break;
24171 }
24172 case MODE_Markdown: {
24173 colSep = " | ";
24174 rowSep = " |\n";
24175 sqlite3_fputs("| ", p->out);
24176 for(i=0; i<nColumn; i++){
24177 w = p->actualWidth[i];
24178 n = strlenChar(azData[i]);
24179 sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "",
24180 azData[i], (w-n+1)/2, "");
24181 sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out);
24182 }
24183 print_row_separator(p, nColumn, "|");
24184 break;
24185 }
24186 case MODE_Box: {
24187 colSep = " " BOX_13 " ";
24188 rowSep = " " BOX_13 "\n";
24189 print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
24190 sqlite3_fputs(BOX_13 " ", p->out);
24191 for(i=0; i<nColumn; i++){
24192 w = p->actualWidth[i];
24193 n = strlenChar(azData[i]);
24194 sqlite3_fprintf(p->out, "%*s%s%*s%s",
24195 (w-n)/2, "", azData[i], (w-n+1)/2, "",
24196 i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
24197 }
24198 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
24199 break;
24200 }
24201 }
24202 for(i=nColumn, j=0; i<nTotal; i++, j++){
24203 if( j==0 && p->cMode!=MODE_Column ){
24204 sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out);
24205 }
24206 z = azData[i];
24207 if( z==0 ) z = p->nullValue;
24208 w = p->actualWidth[j];
24209 if( p->colWidth[j]<0 ) w = -w;
24210 utf8_width_print(p->out, w, z);
24211 if( j==nColumn-1 ){
24212 sqlite3_fputs(rowSep, p->out);
24213 if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
24214 if( p->cMode==MODE_Table ){
24215 print_row_separator(p, nColumn, "+");
24216 }else if( p->cMode==MODE_Box ){
24217 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
24218 }else if( p->cMode==MODE_Column ){
24219 sqlite3_fputs("\n", p->out);
24220 }
24221 }
24222 j = -1;
24223 if( seenInterrupt ) goto columnar_end;
24224 }else{
24225 sqlite3_fputs(colSep, p->out);
24226 }
24227 }
24228 if( p->cMode==MODE_Table ){
24229 print_row_separator(p, nColumn, "+");
24230 }else if( p->cMode==MODE_Box ){
24231 print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
24232 }
24233 columnar_end:
24234 if( seenInterrupt ){
24235 sqlite3_fputs("Interrupt\n", p->out);
24236 }
24237 nData = (nRow+1)*nColumn;
24238 for(i=0; i<nData; i++){
24239 z = azData[i];
24240 if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
24241 }
24242 sqlite3_free(azData);
24243 sqlite3_free((void*)azNextLine);
24244 sqlite3_free(abRowDiv);
24245 if( azQuoted ){
24246 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
24247 sqlite3_free(azQuoted);
24248 }
24249 }
24250
24251 /*
24252 ** Run a prepared statement
24253 */
24254 static void exec_prepared_stmt(
24255 ShellState *pArg, /* Pointer to ShellState */
24256 sqlite3_stmt *pStmt /* Statement to run */
24257 ){
24258 int rc;
24259 sqlite3_uint64 nRow = 0;
24260
24261 if( pArg->cMode==MODE_Column
24262 || pArg->cMode==MODE_Table
24263 || pArg->cMode==MODE_Box
24264 || pArg->cMode==MODE_Markdown
24265 ){
24266 exec_prepared_stmt_columnar(pArg, pStmt);
24267 return;
24268 }
24269
24270 /* perform the first step. this will tell us if we
24271 ** have a result set or not and how wide it is.
24272 */
24273 rc = sqlite3_step(pStmt);
24274 /* if we have a result set... */
24275 if( SQLITE_ROW == rc ){
24276 /* allocate space for col name ptr, value ptr, and type */
24277 int nCol = sqlite3_column_count(pStmt);
24278 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
24279 if( !pData ){
24280 shell_out_of_memory();
24281 }else{
24282 char **azCols = (char **)pData; /* Names of result columns */
24283 char **azVals = &azCols[nCol]; /* Results */
24284 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
24285 int i, x;
24286 assert(sizeof(int) <= sizeof(char *));
24287 /* save off ptrs to column names */
24288 for(i=0; i<nCol; i++){
24289 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
24290 }
24291 do{
24292 nRow++;
24293 /* extract the data and data types */
24294 for(i=0; i<nCol; i++){
24295 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
24296 if( x==SQLITE_BLOB
24297 && pArg
24298 && (pArg->cMode==MODE_Insert || pArg->cMode==MODE_Quote)
24299 ){
24300 azVals[i] = "";
24301 }else{
24302 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
24303 }
24304 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
24305 rc = SQLITE_NOMEM;
24306 break; /* from for */
24307 }
24308 } /* end for */
24309
24310 /* if data and types extracted successfully... */
24311 if( SQLITE_ROW == rc ){
24312 /* call the supplied callback with the result row data */
24313 if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
24314 rc = SQLITE_ABORT;
24315 }else{
24316 rc = sqlite3_step(pStmt);
24317 }
24318 }
24319 } while( SQLITE_ROW == rc );
24320 sqlite3_free(pData);
24321 if( pArg->cMode==MODE_Json ){
24322 sqlite3_fputs("]\n", pArg->out);
24323 }else if( pArg->cMode==MODE_Www ){
24324 sqlite3_fputs("</TABLE>\n<PRE>\n", pArg->out);
24325 }else if( pArg->cMode==MODE_Count ){
24326 char zBuf[200];
24327 sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n",
24328 nRow, nRow!=1 ? "s" : "");
24329 printf("%s", zBuf);
24330 }
24331 }
24332 }
24333 }
24334
24335 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
24336 /*
24337 ** This function is called to process SQL if the previous shell command
24338 ** was ".expert". It passes the SQL in the second argument directly to
24339 ** the sqlite3expert object.
@@ -24381,25 +25565,25 @@
24381 int nQuery = sqlite3_expert_count(p);
24382 int i;
24383
24384 if( bVerbose ){
24385 const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
24386 sqlite3_fputs("-- Candidates -----------------------------\n", out);
24387 sqlite3_fprintf(out, "%s\n", zCand);
24388 }
24389 for(i=0; i<nQuery; i++){
24390 const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
24391 const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
24392 const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
24393 if( zIdx==0 ) zIdx = "(no new indexes)\n";
24394 if( bVerbose ){
24395 sqlite3_fprintf(out,
24396 "-- Query %d --------------------------------\n"
24397 "%s\n\n"
24398 ,i+1, zSql);
24399 }
24400 sqlite3_fprintf(out, "%s\n%s\n", zIdx, zEQP);
24401 }
24402 }
24403 }
24404 sqlite3_expert_destroy(p);
24405 pState->expert.pExpert = 0;
@@ -24430,30 +25614,30 @@
24430 if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){
24431 pState->expert.bVerbose = 1;
24432 }
24433 else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
24434 if( i==(nArg-1) ){
24435 sqlite3_fprintf(stderr, "option requires an argument: %s\n", z);
24436 rc = SQLITE_ERROR;
24437 }else{
24438 iSample = (int)integerValue(azArg[++i]);
24439 if( iSample<0 || iSample>100 ){
24440 sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]);
24441 rc = SQLITE_ERROR;
24442 }
24443 }
24444 }
24445 else{
24446 sqlite3_fprintf(stderr,"unknown option: %s\n", z);
24447 rc = SQLITE_ERROR;
24448 }
24449 }
24450
24451 if( rc==SQLITE_OK ){
24452 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
24453 if( pState->expert.pExpert==0 ){
24454 sqlite3_fprintf(stderr,
24455 "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
24456 rc = SQLITE_ERROR;
24457 }else{
24458 sqlite3_expert_config(
24459 pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
@@ -24463,10 +25647,19 @@
24463 sqlite3_free(zErr);
24464
24465 return rc;
24466 }
24467 #endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */
 
 
 
 
 
 
 
 
 
24468
24469 /*
24470 ** Execute a statement or set of statements. Print
24471 ** any result rows/columns depending on the current mode
24472 ** set via the supplied callback.
@@ -24483,13 +25676,26 @@
24483 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
24484 int rc = SQLITE_OK; /* Return Code */
24485 int rc2;
24486 const char *zLeftover; /* Tail of unprocessed SQL */
24487 sqlite3 *db = pArg->db;
 
 
24488
24489 if( pzErrMsg ){
24490 *pzErrMsg = NULL;
 
 
 
 
 
 
 
 
 
 
 
24491 }
24492
24493 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
24494 if( pArg->expert.pExpert ){
24495 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
@@ -24503,10 +25709,11 @@
24503 if( SQLITE_OK != rc ){
24504 if( pzErrMsg ){
24505 *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
24506 }
24507 }else{
 
24508 if( !pStmt ){
24509 /* this happens for a comment or white-space */
24510 zSql = zLeftover;
24511 while( IsSpace(zSql[0]) ) zSql++;
24512 continue;
@@ -24513,93 +25720,73 @@
24513 }
24514 zStmtSql = sqlite3_sql(pStmt);
24515 if( zStmtSql==0 ) zStmtSql = "";
24516 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
24517
24518 /* save off the prepared statement handle and reset row count */
24519 if( pArg ){
24520 pArg->pStmt = pStmt;
24521 pArg->cnt = 0;
24522 }
24523
24524 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
24525 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
24526 sqlite3_stmt *pExplain;
24527 int triggerEQP = 0;
24528 disable_debug_trace_modes();
24529 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
24530 if( pArg->autoEQP>=AUTOEQP_trigger ){
24531 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
24532 }
24533 pExplain = pStmt;
24534 sqlite3_reset(pExplain);
24535 rc = sqlite3_stmt_explain(pExplain, 2);
24536 if( rc==SQLITE_OK ){
24537 bind_prepared_stmt(pArg, pExplain);
24538 while( sqlite3_step(pExplain)==SQLITE_ROW ){
24539 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
24540 int iEqpId = sqlite3_column_int(pExplain, 0);
24541 int iParentId = sqlite3_column_int(pExplain, 1);
24542 if( zEQPLine==0 ) zEQPLine = "";
24543 if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
24544 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
24545 }
24546 eqp_render(pArg, 0);
24547 }
24548 if( pArg->autoEQP>=AUTOEQP_full ){
24549 /* Also do an EXPLAIN for ".eqp full" mode */
24550 sqlite3_reset(pExplain);
24551 rc = sqlite3_stmt_explain(pExplain, 1);
24552 if( rc==SQLITE_OK ){
24553 pArg->cMode = MODE_Explain;
24554 assert( sqlite3_stmt_isexplain(pExplain)==1 );
24555 bind_prepared_stmt(pArg, pExplain);
24556 explain_data_prepare(pArg, pExplain);
24557 exec_prepared_stmt(pArg, pExplain);
24558 explain_data_delete(pArg);
24559 }
24560 }
24561 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
24562 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
24563 }
24564 sqlite3_reset(pStmt);
24565 sqlite3_stmt_explain(pStmt, 0);
24566 restore_debug_trace_modes();
24567 }
24568
24569 if( pArg ){
24570 int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1);
24571 pArg->cMode = pArg->mode;
24572 if( pArg->autoExplain ){
24573 if( bIsExplain ){
24574 pArg->cMode = MODE_Explain;
24575 }
24576 if( sqlite3_stmt_isexplain(pStmt)==2 ){
24577 pArg->cMode = MODE_EQP;
24578 }
24579 }
24580
24581 /* If the shell is currently in ".explain" mode, gather the extra
24582 ** data required to add indents to the output.*/
24583 if( pArg->cMode==MODE_Explain && bIsExplain ){
24584 explain_data_prepare(pArg, pStmt);
24585 }
24586 }
24587
24588 bind_prepared_stmt(pArg, pStmt);
24589 exec_prepared_stmt(pArg, pStmt);
24590 explain_data_delete(pArg);
24591 eqp_render(pArg, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
24592
24593 /* print usage stats if stats on */
24594 if( pArg && pArg->statsOn ){
24595 display_stats(db, pArg, 0);
24596 }
24597
24598 /* print loop-counters if required */
24599 if( pArg && pArg->scanstatsOn ){
24600 display_scanstats(db, pArg);
 
 
 
 
 
 
 
 
 
 
 
24601 }
24602
24603 /* Finalize the statement just executed. If this fails, save a
24604 ** copy of the error message. Otherwise, set zSql to point to the
24605 ** next statement to execute. */
@@ -24791,34 +25978,34 @@
24791 ** have been recreated by prior repopulations. See forum posts:
24792 ** 2024-10-13T17:10:01z and 2025-10-29T19:38:43z
24793 */
24794 if( db_int(p->db, "SELECT count(*) FROM sqlite_sequence")>0 ){
24795 if( !p->writableSchema ){
24796 sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
24797 p->writableSchema = 1;
24798 }
24799 sqlite3_fputs("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n"
24800 "DELETE FROM sqlite_sequence;\n", p->out);
24801 }
24802 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
24803 if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
24804 }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
24805 return 0;
24806 }else if( dataOnly ){
24807 /* no-op */
24808 }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
24809 char *zIns;
24810 if( !p->writableSchema ){
24811 sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
24812 p->writableSchema = 1;
24813 }
24814 zIns = sqlite3_mprintf(
24815 "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
24816 "VALUES('table','%q','%q',0,'%q');",
24817 zTable, zTable, zSql);
24818 shell_check_oom(zIns);
24819 sqlite3_fprintf(p->out, "%s\n", zIns);
24820 sqlite3_free(zIns);
24821 return 0;
24822 }else{
24823 printSchemaLine(p->out, zSql, ";\n");
24824 }
@@ -24826,12 +26013,11 @@
24826 if( cli_strcmp(zType, "table")==0 ){
24827 ShellText sSelect;
24828 ShellText sTable;
24829 char **azCol;
24830 int i;
24831 char *savedDestTable;
24832 int savedMode;
24833
24834 azCol = tableColumnList(p, zTable);
24835 if( azCol==0 ){
24836 p->nErr++;
24837 return 0;
@@ -24870,22 +26056,22 @@
24870 }
24871 freeColumnList(azCol);
24872 appendText(&sSelect, " FROM ", 0);
24873 appendText(&sSelect, zTable, quoteChar(zTable));
24874
24875 savedDestTable = p->zDestTable;
24876 savedMode = p->mode;
24877 p->zDestTable = sTable.zTxt;
24878 p->mode = p->cMode = MODE_Insert;
 
24879 rc = shell_exec(p, sSelect.zTxt, 0);
24880 if( (rc&0xff)==SQLITE_CORRUPT ){
24881 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
24882 toggleSelectOrder(p->db);
24883 shell_exec(p, sSelect.zTxt, 0);
24884 toggleSelectOrder(p->db);
24885 }
24886 p->zDestTable = savedDestTable;
24887 p->mode = savedMode;
24888 freeText(&sTable);
24889 freeText(&sSelect);
24890 if( rc ) p->nErr++;
24891 }
@@ -24907,22 +26093,22 @@
24907 char *zErr = 0;
24908 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
24909 if( rc==SQLITE_CORRUPT ){
24910 char *zQ2;
24911 int len = strlen30(zQuery);
24912 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
24913 if( zErr ){
24914 sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr);
24915 sqlite3_free(zErr);
24916 zErr = 0;
24917 }
24918 zQ2 = malloc( len+100 );
24919 if( zQ2==0 ) return rc;
24920 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
24921 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
24922 if( rc ){
24923 sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
24924 }else{
24925 rc = SQLITE_CORRUPT;
24926 }
24927 free(zQ2);
24928 }
@@ -25019,27 +26205,14 @@
25019 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
25020 ".filectrl CMD ... Run various sqlite3_file_control() operations",
25021 " --schema SCHEMA Use SCHEMA instead of \"main\"",
25022 " --help Show CMD details",
25023 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
25024 ".headers on|off Turn display of headers on or off",
25025 ".help ?-all? ?PATTERN? Show help text for PATTERN",
25026 #ifndef SQLITE_SHELL_FIDDLE
25027 ".import FILE TABLE Import data from FILE into TABLE",
25028 " Options:",
25029 " --ascii Use \\037 and \\036 as column and row separators",
25030 " --csv Use , and \\n as column and row separators",
25031 " --skip N Skip the first N rows of input",
25032 " --schema S Target table to be S.TABLE",
25033 " -v \"Verbose\" - increase auxiliary output",
25034 " Notes:",
25035 " * If TABLE does not exist, it is created. The first row of input",
25036 " determines the column names.",
25037 " * If neither --csv or --ascii are used, the input mode is derived",
25038 " from the \".mode\" output mode",
25039 " * If FILE begins with \"|\" then it is a command that generates the",
25040 " input text.",
25041 #endif
25042 #ifndef SQLITE_OMIT_TEST_CONTROL
25043 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
25044 #endif
25045 ".indexes ?TABLE? Show names of indexes",
@@ -25060,46 +26233,16 @@
25060 ".log FILE|on|off Turn logging on or off. FILE can be stderr/stdout",
25061 #else
25062 ".log on|off Turn logging on or off.",
25063 #endif
25064 ".mode ?MODE? ?OPTIONS? Set output mode",
25065 " MODE is one of:",
25066 " ascii Columns/rows delimited by 0x1F and 0x1E",
25067 " box Tables using unicode box-drawing characters",
25068 " csv Comma-separated values",
25069 " column Output in columns. (See .width)",
25070 " html HTML <table> code",
25071 " insert SQL insert statements for TABLE",
25072 " json Results in a JSON array",
25073 " line One value per line",
25074 " list Values delimited by \"|\"",
25075 " markdown Markdown table format",
25076 " qbox Shorthand for \"box --wrap 60 --quote\"",
25077 " quote Escape answers as for SQL",
25078 " table ASCII-art table",
25079 " tabs Tab-separated values",
25080 " tcl TCL list elements",
25081 " OPTIONS: (for columnar modes or insert mode):",
25082 " --escape T ctrl-char escape; T is one of: symbol, ascii, off",
25083 " --wrap N Wrap output lines to no longer than N characters",
25084 " --wordwrap B Wrap or not at word boundaries per B (on/off)",
25085 " --ww Shorthand for \"--wordwrap 1\"",
25086 " --quote Quote output text as SQL literals",
25087 " --noquote Do not quote output text",
25088 " TABLE The name of SQL table used for \"insert\" mode",
25089 #ifndef SQLITE_SHELL_FIDDLE
25090 ".nonce STRING Suspend safe mode for one command if nonce matches",
25091 #endif
25092 ".nullvalue STRING Use STRING in place of NULL values",
25093 #ifndef SQLITE_SHELL_FIDDLE
25094 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
25095 " If FILE begins with '|' then open as a pipe",
25096 " --bom Put a UTF8 byte-order mark at the beginning",
25097 " -e Send output to the system text editor",
25098 " --plain Use text/plain output instead of HTML for -w option",
25099 " -w Send output as HTML to a web browser (same as \".www\")",
25100 " -x Send output as CSV to a spreadsheet (same as \".excel\")",
25101 /* Note that .open is (partially) available in WASM builds but is
25102 ** currently only intended to be used by the fiddle tool, not
25103 ** end users, so is "undocumented." */
25104 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
25105 " Options:",
@@ -25121,18 +26264,10 @@
25121 " --nofollow Do not follow symbolic links",
25122 " --readonly Open FILE readonly",
25123 " --zip FILE is a ZIP archive",
25124 #ifndef SQLITE_SHELL_FIDDLE
25125 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
25126 " If FILE begins with '|' then open it as a pipe.",
25127 " If FILE is 'off' then output is disabled.",
25128 " Options:",
25129 " --bom Prefix output with a UTF8 byte-order mark",
25130 " -e Send output to the system text editor",
25131 " --plain Use text/plain for -w option",
25132 " -w Send output to a web browser",
25133 " -x Send output as CSV to a spreadsheet",
25134 #endif
25135 ".parameter CMD ... Manage SQL parameter bindings",
25136 " clear Erase all bindings",
25137 " init Initialize the TEMP table that holds bindings",
25138 " list List the current parameter bindings",
@@ -25171,11 +26306,11 @@
25171 " --nosys Omit objects whose names start with \"sqlite_\"",
25172 ",selftest ?OPTIONS? Run tests defined in the SELFTEST table",
25173 " Options:",
25174 " --init Create a new SELFTEST table",
25175 " -v Verbose output",
25176 ".separator COL ?ROW? Change the column and row separators",
25177 #if defined(SQLITE_ENABLE_SESSION)
25178 ".session ?NAME? CMD ... Create or control sessions",
25179 " Subcommands:",
25180 " attach TABLE Attach TABLE",
25181 " changeset FILE Write a changeset into FILE",
@@ -25198,11 +26333,11 @@
25198 " --sha3-512 Use the sha3-512 algorithm",
25199 " Any other argument is a LIKE pattern for tables to hash",
25200 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE)
25201 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
25202 #endif
25203 ".show Show the current values for various settings",
25204 ".stats ?ARG? Show stats or turn stats on or off",
25205 " off Turn off automatic stat display",
25206 " on Turn on automatic stat display",
25207 " stmt Show statement stats",
25208 " vmstep Show the virtual machine step count only",
@@ -25239,17 +26374,167 @@
25239 #endif
25240 ".version Show source, library and compiler versions",
25241 ".vfsinfo ?AUX? Information about the top-level VFS",
25242 ".vfslist List all available VFSes",
25243 ".vfsname ?AUX? Print the name of the VFS stack",
25244 ".width NUM1 NUM2 ... Set minimum column widths for columnar output",
25245 " Negative values right-justify",
25246 #ifndef SQLITE_SHELL_FIDDLE
25247 ".www Display output of the next command in web browser",
25248 " --plain Show results as text/plain, not as HTML",
25249 #endif
25250 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25251
25252 /*
25253 ** Output help text for commands that match zPattern.
25254 **
25255 ** * If zPattern is NULL, then show all documented commands, but
@@ -25276,10 +26561,11 @@
25276 static int showHelp(FILE *out, const char *zPattern){
25277 int i = 0;
25278 int j = 0;
25279 int n = 0;
25280 char *zPat;
 
25281 if( zPattern==0 ){
25282 /* Show just the first line for all help topics */
25283 zPattern = "[a-z]";
25284 }else if( cli_strcmp(zPattern,"-a")==0
25285 || cli_strcmp(zPattern,"-all")==0
@@ -25293,41 +26579,50 @@
25293 for(i=0; i<ArraySize(azHelp); i++){
25294 if( azHelp[i][0]=='.' ){
25295 show = 0;
25296 }else if( azHelp[i][0]==',' ){
25297 show = 1;
25298 sqlite3_fprintf(out, ".%s\n", &azHelp[i][1]);
25299 n++;
25300 }else if( show ){
25301 sqlite3_fprintf(out, "%s\n", azHelp[i]);
25302 }
25303 }
25304 return n;
25305 }
25306
25307 /* Seek documented commands for which zPattern is an exact prefix */
25308 zPat = sqlite3_mprintf(".%s*", zPattern);
25309 shell_check_oom(zPat);
25310 for(i=0; i<ArraySize(azHelp); i++){
25311 if( sqlite3_strglob(zPat, azHelp[i])==0 ){
25312 sqlite3_fprintf(out, "%s\n", azHelp[i]);
 
25313 j = i+1;
25314 n++;
25315 }
25316 }
25317 sqlite3_free(zPat);
25318 if( n ){
25319 if( n==1 ){
25320 /* when zPattern is a prefix of exactly one command, then include
25321 ** the details of that command, which should begin at offset j */
25322 while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
25323 sqlite3_fprintf(out, "%s\n", azHelp[j]);
25324 j++;
25325 }
25326 }
25327 return n;
25328 }
 
 
 
 
 
 
 
 
 
25329
25330 /* Look for documented commands that contain zPattern anywhere.
25331 ** Show complete text of all documented commands that match. */
25332 zPat = sqlite3_mprintf("%%%s%%", zPattern);
25333 shell_check_oom(zPat);
@@ -25336,14 +26631,14 @@
25336 while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
25337 continue;
25338 }
25339 if( azHelp[i][0]=='.' ) j = i;
25340 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
25341 sqlite3_fprintf(out, "%s\n", azHelp[j]);
25342 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
25343 j++;
25344 sqlite3_fprintf(out, "%s\n", azHelp[j]);
25345 }
25346 i = j;
25347 n++;
25348 }
25349 }
@@ -25376,27 +26671,27 @@
25376 char *pBuf;
25377 int rc;
25378 if( in==0 ) return 0;
25379 rc = fseek(in, 0, SEEK_END);
25380 if( rc!=0 ){
25381 sqlite3_fprintf(stderr,"Error: '%s' not seekable\n", zName);
25382 fclose(in);
25383 return 0;
25384 }
25385 nIn = ftell(in);
25386 rewind(in);
25387 pBuf = sqlite3_malloc64( nIn+1 );
25388 if( pBuf==0 ){
25389 sqlite3_fputs("Error: out of memory\n", stderr);
25390 fclose(in);
25391 return 0;
25392 }
25393 nRead = fread(pBuf, nIn, 1, in);
25394 fclose(in);
25395 if( nRead!=1 ){
25396 sqlite3_free(pBuf);
25397 sqlite3_fprintf(stderr,"Error: cannot read '%s'\n", zName);
25398 return 0;
25399 }
25400 pBuf[nIn] = 0;
25401 if( pnByte ) *pnByte = nIn;
25402 return pBuf;
@@ -25529,11 +26824,11 @@
25529 unsigned int x[16];
25530 char zLine[1000];
25531 if( zDbFilename ){
25532 in = sqlite3_fopen(zDbFilename, "r");
25533 if( in==0 ){
25534 sqlite3_fprintf(stderr,"cannot open \"%s\" for reading\n", zDbFilename);
25535 return 0;
25536 }
25537 nLine = 0;
25538 }else{
25539 in = p->in;
@@ -25545,11 +26840,11 @@
25545 if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
25546 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
25547 if( rc!=2 ) goto readHexDb_error;
25548 if( n<0 ) goto readHexDb_error;
25549 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
25550 sqlite3_fputs("invalid pagesize\n", stderr);
25551 goto readHexDb_error;
25552 }
25553 sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
25554 a = sqlite3_malloc64( sz ? sz : 1 );
25555 shell_check_oom(a);
@@ -25556,11 +26851,11 @@
25556 memset(a, 0, sz);
25557 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
25558 int j = 0; /* Page number from "| page" line */
25559 int k = 0; /* Offset from "| page" line */
25560 if( nLine>=2000000000 ){
25561 sqlite3_fprintf(stderr, "input too big\n");
25562 goto readHexDb_error;
25563 }
25564 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
25565 if( rc==2 ){
25566 iOffset = k;
@@ -25597,11 +26892,11 @@
25597 if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
25598 }
25599 p->lineno = nLine;
25600 }
25601 sqlite3_free(a);
25602 sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine);
25603 return 0;
25604 }
25605 #endif /* SQLITE_OMIT_DESERIALIZE */
25606
25607 /*
@@ -25702,23 +26997,23 @@
25702 sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0);
25703 break;
25704 }
25705 }
25706 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
25707 sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
25708 zDbFilename, sqlite3_errmsg(p->db));
25709 if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
25710 exit(1);
25711 }
25712 sqlite3_close(p->db);
25713 sqlite3_open(":memory:", &p->db);
25714 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
25715 sqlite3_fputs("Also: unable to open substitute in-memory database.\n",
25716 stderr);
25717 exit(1);
25718 }else{
25719 sqlite3_fprintf(stderr,
25720 "Notice: using substitute in-memory database instead of \"%s\"\n",
25721 zDbFilename);
25722 }
25723 }
25724 globalDb = p->db;
@@ -25792,10 +27087,12 @@
25792 shellAddSchemaName, 0, 0);
25793 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, p,
25794 shellModuleSchema, 0, 0);
25795 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
25796 shellPutsFunc, 0, 0);
 
 
25797 sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
25798 shellUSleepFunc, 0, 0);
25799 #ifndef SQLITE_NOHAVE_SYSTEM
25800 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
25801 editFunc, 0, 0);
@@ -25826,11 +27123,11 @@
25826 }
25827 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
25828 SQLITE_DESERIALIZE_RESIZEABLE |
25829 SQLITE_DESERIALIZE_FREEONCLOSE);
25830 if( rc ){
25831 sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc);
25832 }
25833 if( p->szMax>0 ){
25834 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
25835 }
25836 }
@@ -25841,11 +27138,11 @@
25841 if( p->bSafeModePersist ){
25842 sqlite3_set_authorizer(p->db, safeModeAuth, p);
25843 }
25844 #endif
25845 sqlite3_db_config(
25846 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
25847 );
25848 }
25849 }
25850
25851 /*
@@ -25852,11 +27149,11 @@
25852 ** Attempt to close the database connection. Report errors.
25853 */
25854 void close_db(sqlite3 *db){
25855 int rc = sqlite3_close(db);
25856 if( rc ){
25857 sqlite3_fprintf(stderr,
25858 "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
25859 }
25860 }
25861
25862 #if (HAVE_READLINE || HAVE_EDITLINE) \
@@ -26025,11 +27322,11 @@
26025 return 1;
26026 }
26027 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
26028 return 0;
26029 }
26030 sqlite3_fprintf(stderr,
26031 "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
26032 return 0;
26033 }
26034
26035 /*
@@ -26053,22 +27350,22 @@
26053 /*
26054 ** Try to open an output file. The names "stdout" and "stderr" are
26055 ** recognized and do the right thing. NULL is returned if the output
26056 ** filename is "off".
26057 */
26058 static FILE *output_file_open(const char *zFile){
26059 FILE *f;
26060 if( cli_strcmp(zFile,"stdout")==0 ){
26061 f = stdout;
26062 }else if( cli_strcmp(zFile, "stderr")==0 ){
26063 f = stderr;
26064 }else if( cli_strcmp(zFile, "off")==0 ){
26065 f = 0;
26066 }else{
26067 f = sqlite3_fopen(zFile, "w");
26068 if( f==0 ){
26069 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
26070 }
26071 }
26072 return f;
26073 }
26074
@@ -26117,16 +27414,16 @@
26117 if( nSql>1000000000 ) nSql = 1000000000;
26118 while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
26119 switch( mType ){
26120 case SQLITE_TRACE_ROW:
26121 case SQLITE_TRACE_STMT: {
26122 sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
26123 break;
26124 }
26125 case SQLITE_TRACE_PROFILE: {
26126 sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
26127 sqlite3_fprintf(p->traceOut,
26128 "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
26129 break;
26130 }
26131 }
26132 return 0;
@@ -26230,15 +27527,15 @@
26230 do{ p->n--; }while( p->z[p->n]!=cQuote );
26231 p->cTerm = c;
26232 break;
26233 }
26234 if( pc==cQuote && c!='\r' ){
26235 sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n",
26236 p->zFile, p->nLine, cQuote);
26237 }
26238 if( c==EOF ){
26239 sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n",
26240 p->zFile, startLine, cQuote);
26241 p->cTerm = c;
26242 break;
26243 }
26244 import_append_char(p, c);
@@ -26333,11 +27630,11 @@
26333
26334 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
26335 shell_check_oom(zQuery);
26336 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
26337 if( rc ){
26338 sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
26339 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
26340 goto end_data_xfer;
26341 }
26342 n = sqlite3_column_count(pQuery);
26343 zInsert = sqlite3_malloc64(200 + nTable + n*3);
@@ -26350,11 +27647,11 @@
26350 i += 2;
26351 }
26352 memcpy(zInsert+i, ");", 3);
26353 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
26354 if( rc ){
26355 sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
26356 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert);
26357 goto end_data_xfer;
26358 }
26359 for(k=0; k<2; k++){
26360 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
@@ -26386,11 +27683,11 @@
26386 }
26387 }
26388 } /* End for */
26389 rc = sqlite3_step(pInsert);
26390 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
26391 sqlite3_fprintf(stderr,"Error %d: %s\n",
26392 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb));
26393 }
26394 sqlite3_reset(pInsert);
26395 cnt++;
26396 if( (cnt%spinRate)==0 ){
@@ -26404,11 +27701,11 @@
26404 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
26405 zTable);
26406 shell_check_oom(zQuery);
26407 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
26408 if( rc ){
26409 sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable);
26410 break;
26411 }
26412 } /* End for(k=0...) */
26413
26414 end_data_xfer:
@@ -26441,24 +27738,24 @@
26441 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
26442 " WHERE %s ORDER BY rowid ASC", zWhere);
26443 shell_check_oom(zQuery);
26444 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
26445 if( rc ){
26446 sqlite3_fprintf(stderr,
26447 "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
26448 sqlite3_errmsg(p->db), zQuery);
26449 goto end_schema_xfer;
26450 }
26451 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
26452 zName = sqlite3_column_text(pQuery, 0);
26453 zSql = sqlite3_column_text(pQuery, 1);
26454 if( zName==0 || zSql==0 ) continue;
26455 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
26456 sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
26457 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
26458 if( zErrMsg ){
26459 sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
26460 sqlite3_free(zErrMsg);
26461 zErrMsg = 0;
26462 }
26463 }
26464 if( xForEach ){
@@ -26472,23 +27769,23 @@
26472 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
26473 " WHERE %s ORDER BY rowid DESC", zWhere);
26474 shell_check_oom(zQuery);
26475 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
26476 if( rc ){
26477 sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n",
26478 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
26479 goto end_schema_xfer;
26480 }
26481 while( sqlite3_step(pQuery)==SQLITE_ROW ){
26482 zName = sqlite3_column_text(pQuery, 0);
26483 zSql = sqlite3_column_text(pQuery, 1);
26484 if( zName==0 || zSql==0 ) continue;
26485 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
26486 sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
26487 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
26488 if( zErrMsg ){
26489 sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
26490 sqlite3_free(zErrMsg);
26491 zErrMsg = 0;
26492 }
26493 if( xForEach ){
26494 xForEach(p, newDb, (const char*)zName);
@@ -26508,16 +27805,16 @@
26508 */
26509 static void tryToClone(ShellState *p, const char *zNewDb){
26510 int rc;
26511 sqlite3 *newDb = 0;
26512 if( access(zNewDb,0)==0 ){
26513 sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb);
26514 return;
26515 }
26516 rc = sqlite3_open(zNewDb, &newDb);
26517 if( rc ){
26518 sqlite3_fprintf(stderr,
26519 "Cannot create output database: %s\n", sqlite3_errmsg(newDb));
26520 }else{
26521 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
26522 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
26523 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
@@ -26532,16 +27829,16 @@
26532 /*
26533 ** Change the output stream (file or pipe or console) to something else.
26534 */
26535 static void output_redir(ShellState *p, FILE *pfNew){
26536 if( p->out != stdout ){
26537 sqlite3_fputs("Output already redirected.\n", stderr);
26538 }else{
26539 p->out = pfNew;
26540 setCrlfMode(p);
26541 if( p->mode==MODE_Www ){
26542 sqlite3_fputs(
26543 "<!DOCTYPE html>\n"
26544 "<HTML><BODY><PRE>\n",
26545 p->out
26546 );
26547 }
@@ -26559,12 +27856,12 @@
26559 if( p->outfile[0]=='|' ){
26560 #ifndef SQLITE_OMIT_POPEN
26561 pclose(p->out);
26562 #endif
26563 }else{
26564 if( p->mode==MODE_Www ){
26565 sqlite3_fputs("</PRE></BODY></HTML>\n", p->out);
26566 }
26567 output_file_close(p->out);
26568 #ifndef SQLITE_NOHAVE_SYSTEM
26569 if( p->doXdgOpen ){
26570 const char *zXdgOpenCmd =
@@ -26576,26 +27873,30 @@
26576 "xdg-open";
26577 #endif
26578 char *zCmd;
26579 zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
26580 if( system(zCmd) ){
26581 sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd);
26582 }else{
26583 /* Give the start/open/xdg-open command some time to get
26584 ** going before we continue, and potential delete the
26585 ** p->zTempFile data file out from under it */
26586 sqlite3_sleep(2000);
26587 }
26588 sqlite3_free(zCmd);
26589 outputModePop(p);
26590 p->doXdgOpen = 0;
26591 }
26592 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
26593 }
26594 p->outfile[0] = 0;
26595 p->out = stdout;
26596 setCrlfMode(p);
 
 
 
 
26597 }
26598 #else
26599 # define output_redir(SS,pfO)
26600 # define output_reset(SS)
26601 #endif
@@ -26676,11 +27977,11 @@
26676 if( p->db==0 ) return 1;
26677 rc = sqlite3_prepare_v2(p->db,
26678 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
26679 -1, &pStmt, 0);
26680 if( rc ){
26681 sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db));
26682 sqlite3_finalize(pStmt);
26683 return 1;
26684 }
26685 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
26686 if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -26689,32 +27990,32 @@
26689 const u8 *pb = sqlite3_column_blob(pStmt,0);
26690 shell_check_oom(pb);
26691 memcpy(aHdr, pb, 100);
26692 sqlite3_finalize(pStmt);
26693 }else{
26694 sqlite3_fputs("unable to read database header\n", stderr);
26695 sqlite3_finalize(pStmt);
26696 return 1;
26697 }
26698 i = get2byteInt(aHdr+16);
26699 if( i==1 ) i = 65536;
26700 sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i);
26701 sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
26702 sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
26703 sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
26704 for(i=0; i<ArraySize(aField); i++){
26705 int ofst = aField[i].ofst;
26706 unsigned int val = get4byteInt(aHdr + ofst);
26707 sqlite3_fprintf(p->out, "%-20s %u", aField[i].zName, val);
26708 switch( ofst ){
26709 case 56: {
26710 if( val==1 ) sqlite3_fputs(" (utf8)", p->out);
26711 if( val==2 ) sqlite3_fputs(" (utf16le)", p->out);
26712 if( val==3 ) sqlite3_fputs(" (utf16be)", p->out);
26713 }
26714 }
26715 sqlite3_fputs("\n", p->out);
26716 }
26717 if( zDb==0 ){
26718 zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
26719 }else if( cli_strcmp(zDb,"temp")==0 ){
26720 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
@@ -26721,15 +28022,15 @@
26721 }else{
26722 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
26723 }
26724 for(i=0; i<ArraySize(aQuery); i++){
26725 int val = db_int(p->db, aQuery[i].zSql, zSchemaTab);
26726 sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
26727 }
26728 sqlite3_free(zSchemaTab);
26729 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
26730 sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion);
26731 return 0;
26732 }
26733 #endif /* SQLITE_SHELL_HAVE_RECOVER */
26734
26735 /*
@@ -26785,11 +28086,11 @@
26785 zTail++;
26786 }
26787 }
26788 zName = strdup(zTail);
26789 shell_check_oom(zName);
26790 sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
26791 nPage*pgSz, pgSz, zName);
26792 sqlite3_finalize(pStmt);
26793 pStmt = 0;
26794 rc = sqlite3_prepare_v2(p->db,
26795 "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
@@ -26801,31 +28102,31 @@
26801 for(i=0; i<pgSz; i+=16){
26802 const u8 *aLine = aData+i;
26803 for(j=0; j<16 && aLine[j]==0; j++){}
26804 if( j==16 ) continue;
26805 if( !seenPageLabel ){
26806 sqlite3_fprintf(p->out, "| page %lld offset %lld\n",pgno,(pgno-1)*pgSz);
26807 seenPageLabel = 1;
26808 }
26809 sqlite3_fprintf(p->out, "| %5d:", i);
26810 for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
26811 sqlite3_fprintf(p->out, " ");
26812 for(j=0; j<16; j++){
26813 unsigned char c = (unsigned char)aLine[j];
26814 sqlite3_fprintf(p->out, "%c", bShow[c]);
26815 }
26816 sqlite3_fprintf(p->out, "\n");
26817 }
26818 }
26819 sqlite3_finalize(pStmt);
26820 sqlite3_fprintf(p->out, "| end %s\n", zName);
26821 free(zName);
26822 return 0;
26823
26824 dbtotxt_error:
26825 if( rc ){
26826 sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
26827 }
26828 sqlite3_finalize(pStmt);
26829 free(zName);
26830 return 1;
26831 }
@@ -26832,11 +28133,11 @@
26832
26833 /*
26834 ** Print the given string as an error message.
26835 */
26836 static void shellEmitError(const char *zErr){
26837 sqlite3_fprintf(stderr,"Error: %s\n", zErr);
26838 }
26839 /*
26840 ** Print the current sqlite3_errmsg() value to stderr and return 1.
26841 */
26842 static int shellDatabaseError(sqlite3 *db){
@@ -27015,42 +28316,45 @@
27015 if( shellDeleteFile(p->zTempFile) ) return;
27016 sqlite3_free(p->zTempFile);
27017 p->zTempFile = 0;
27018 }
27019
 
 
 
27020 /*
27021 ** Create a new temp file name with the given suffix.
 
 
 
 
27022 */
27023 static void newTempFile(ShellState *p, const char *zSuffix){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27024 clearTempFile(p);
27025 sqlite3_free(p->zTempFile);
27026 p->zTempFile = 0;
27027 if( p->db ){
27028 sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
27029 }
27030 if( p->zTempFile==0 ){
27031 /* If p->db is an in-memory database then the TEMPFILENAME file-control
27032 ** will not work and we will need to fallback to guessing */
27033 char *zTemp;
27034 sqlite3_uint64 r;
27035 sqlite3_randomness(sizeof(r), &r);
27036 zTemp = getenv("TEMP");
27037 if( zTemp==0 ) zTemp = getenv("TMP");
27038 if( zTemp==0 ){
27039 #ifdef _WIN32
27040 zTemp = "\\tmp";
27041 #else
27042 zTemp = "/tmp";
27043 #endif
27044 }
27045 p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
27046 }else{
27047 p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
27048 }
27049 shell_check_oom(p->zTempFile);
27050 }
27051
27052
27053 /*
27054 ** The implementation of SQL scalar function fkey_collate_clause(), used
27055 ** by the ".lint fkey-indexes" command. This scalar function is always
27056 ** called with four arguments - the parent table name, the parent column name,
@@ -27192,11 +28496,11 @@
27192 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
27193 bGroupByParent = 1;
27194 zIndent = " ";
27195 }
27196 else{
27197 sqlite3_fprintf(stderr,
27198 "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]);
27199 return SQLITE_ERROR;
27200 }
27201 }
27202
@@ -27237,45 +28541,45 @@
27237 }
27238 rc = sqlite3_finalize(pExplain);
27239 if( rc!=SQLITE_OK ) break;
27240
27241 if( res<0 ){
27242 sqlite3_fputs("Error: internal error", stderr);
27243 break;
27244 }else{
27245 if( bGroupByParent
27246 && (bVerbose || res==0)
27247 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
27248 ){
27249 sqlite3_fprintf(out, "-- Parent table %s\n", zParent);
27250 sqlite3_free(zPrev);
27251 zPrev = sqlite3_mprintf("%s", zParent);
27252 }
27253
27254 if( res==0 ){
27255 sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
27256 }else if( bVerbose ){
27257 sqlite3_fprintf(out,
27258 "%s/* no extra indexes required for %s -> %s */\n",
27259 zIndent, zFrom, zTarget
27260 );
27261 }
27262 }
27263 }
27264 sqlite3_free(zPrev);
27265
27266 if( rc!=SQLITE_OK ){
27267 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
27268 }
27269
27270 rc2 = sqlite3_finalize(pSql);
27271 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
27272 rc = rc2;
27273 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
27274 }
27275 }else{
27276 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db));
27277 }
27278
27279 return rc;
27280 }
27281
@@ -27291,13 +28595,13 @@
27291 n = (nArg>=2 ? strlen30(azArg[1]) : 0);
27292 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
27293 return lintFkeyIndexes(pState, azArg, nArg);
27294
27295 usage:
27296 sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]);
27297 sqlite3_fprintf(stderr, "Where sub-commands are:\n");
27298 sqlite3_fprintf(stderr, " fkey-indexes\n");
27299 return SQLITE_ERROR;
27300 }
27301
27302 static void shellPrepare(
27303 sqlite3 *db,
@@ -27307,11 +28611,11 @@
27307 ){
27308 *ppStmt = 0;
27309 if( *pRc==SQLITE_OK ){
27310 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
27311 if( rc!=SQLITE_OK ){
27312 sqlite3_fprintf(stderr,
27313 "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db));
27314 *pRc = rc;
27315 }
27316 }
27317 }
@@ -27352,11 +28656,11 @@
27352 if( pStmt ){
27353 sqlite3 *db = sqlite3_db_handle(pStmt);
27354 int rc = sqlite3_finalize(pStmt);
27355 if( *pRc==SQLITE_OK ){
27356 if( rc!=SQLITE_OK ){
27357 sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
27358 }
27359 *pRc = rc;
27360 }
27361 }
27362 }
@@ -27374,11 +28678,11 @@
27374 ){
27375 int rc = sqlite3_reset(pStmt);
27376 if( *pRc==SQLITE_OK ){
27377 if( rc!=SQLITE_OK ){
27378 sqlite3 *db = sqlite3_db_handle(pStmt);
27379 sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
27380 }
27381 *pRc = rc;
27382 }
27383 }
27384 #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
@@ -27427,13 +28731,13 @@
27427 va_start(ap, zFmt);
27428 z = sqlite3_vmprintf(zFmt, ap);
27429 va_end(ap);
27430 shellEmitError(z);
27431 if( pAr->fromCmdLine ){
27432 sqlite3_fputs("Use \"-A\" for more help\n", stderr);
27433 }else{
27434 sqlite3_fputs("Use \".archive --help\" for more help\n", stderr);
27435 }
27436 sqlite3_free(z);
27437 return SQLITE_ERROR;
27438 }
27439
@@ -27529,11 +28833,11 @@
27529 };
27530 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
27531 struct ArSwitch *pEnd = &aSwitch[nSwitch];
27532
27533 if( nArg<=1 ){
27534 sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n");
27535 return arUsage(stderr);
27536 }else{
27537 char *z = azArg[1];
27538 if( z[0]!='-' ){
27539 /* Traditional style [tar] invocation */
@@ -27635,11 +28939,11 @@
27635 }
27636 }
27637 }
27638 }
27639 if( pAr->eCmd==0 ){
27640 sqlite3_fprintf(stderr, "Required argument missing. Usage:\n");
27641 return arUsage(stderr);
27642 }
27643 return SQLITE_OK;
27644 }
27645
@@ -27678,11 +28982,11 @@
27678 if( SQLITE_ROW==sqlite3_step(pTest) ){
27679 bOk = 1;
27680 }
27681 shellReset(&rc, pTest);
27682 if( rc==SQLITE_OK && bOk==0 ){
27683 sqlite3_fprintf(stderr,"not found in archive: %s\n", z);
27684 rc = SQLITE_ERROR;
27685 }
27686 }
27687 shellFinalize(&rc, pTest);
27688 }
@@ -27761,19 +29065,19 @@
27761 arWhereClause(&rc, pAr, &zWhere);
27762
27763 shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
27764 pAr->zSrcTable, zWhere);
27765 if( pAr->bDryRun ){
27766 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql));
27767 }else{
27768 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
27769 if( pAr->bVerbose ){
27770 sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n",
27771 sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1),
27772 sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3));
27773 }else{
27774 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
27775 }
27776 }
27777 }
27778 shellFinalize(&rc, pSql);
27779 sqlite3_free(zWhere);
@@ -27796,11 +29100,11 @@
27796 }
27797 if( rc==SQLITE_OK ){
27798 zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
27799 pAr->zSrcTable, zWhere);
27800 if( pAr->bDryRun ){
27801 sqlite3_fprintf(pAr->out, "%s\n", zSql);
27802 }else{
27803 char *zErr = 0;
27804 rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
27805 if( rc==SQLITE_OK ){
27806 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
@@ -27809,11 +29113,11 @@
27809 }else{
27810 rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
27811 }
27812 }
27813 if( zErr ){
27814 sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */
27815 sqlite3_free(zErr);
27816 }
27817 }
27818 }
27819 sqlite3_free(zWhere);
@@ -27873,15 +29177,15 @@
27873 ** populating them changes the timestamp). */
27874 for(i=0; i<2; i++){
27875 j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
27876 sqlite3_bind_int(pSql, j, i);
27877 if( pAr->bDryRun ){
27878 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql));
27879 }else{
27880 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
27881 if( i==0 && pAr->bVerbose ){
27882 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
27883 }
27884 }
27885 }
27886 shellReset(&rc, pSql);
27887 }
@@ -27897,17 +29201,17 @@
27897 ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
27898 */
27899 static int arExecSql(ArCommand *pAr, const char *zSql){
27900 int rc;
27901 if( pAr->bDryRun ){
27902 sqlite3_fprintf(pAr->out, "%s\n", zSql);
27903 rc = SQLITE_OK;
27904 }else{
27905 char *zErr = 0;
27906 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
27907 if( zErr ){
27908 sqlite3_fprintf(stdout, "ERROR: %s\n", zErr);
27909 sqlite3_free(zErr);
27910 }
27911 }
27912 return rc;
27913 }
@@ -28079,17 +29383,17 @@
28079 }else{
28080 flags = SQLITE_OPEN_READONLY;
28081 }
28082 cmd.db = 0;
28083 if( cmd.bDryRun ){
28084 sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile,
28085 eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
28086 }
28087 rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
28088 eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
28089 if( rc!=SQLITE_OK ){
28090 sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n",
28091 cmd.zFile, sqlite3_errmsg(cmd.db));
28092 goto end_ar_command;
28093 }
28094 sqlite3_fileio_init(cmd.db, 0, 0);
28095 sqlite3_sqlar_init(cmd.db, 0, 0);
@@ -28099,11 +29403,11 @@
28099 }
28100 if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
28101 if( cmd.eCmd!=AR_CMD_CREATE
28102 && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
28103 ){
28104 sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n");
28105 rc = SQLITE_ERROR;
28106 goto end_ar_command;
28107 }
28108 cmd.zSrcTable = sqlite3_mprintf("sqlar");
28109 }
@@ -28157,11 +29461,11 @@
28157 ** This function is used as a callback by the recover extension. Simply
28158 ** print the supplied SQL statement to stdout.
28159 */
28160 static int recoverSqlCb(void *pCtx, const char *zSql){
28161 ShellState *pState = (ShellState*)pCtx;
28162 sqlite3_fprintf(pState->out, "%s;\n", zSql);
28163 return SQLITE_OK;
28164 }
28165
28166 /*
28167 ** This function is called to recover data from the database. A script
@@ -28200,11 +29504,11 @@
28200 }else
28201 if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
28202 bRowids = 0;
28203 }
28204 else{
28205 sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]);
28206 showHelp(pState->out, azArg[0]);
28207 return 1;
28208 }
28209 }
28210
@@ -28215,16 +29519,16 @@
28215 sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */
28216 sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
28217 sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
28218 sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
28219
28220 sqlite3_fprintf(pState->out, ".dbconfig defensive off\n");
28221 sqlite3_recover_run(p);
28222 if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
28223 const char *zErr = sqlite3_recover_errmsg(p);
28224 int errCode = sqlite3_recover_errcode(p);
28225 sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode);
28226 }
28227 rc = sqlite3_recover_finish(p);
28228 return rc;
28229 }
28230 #endif /* SQLITE_SHELL_HAVE_RECOVER */
@@ -28242,25 +29546,25 @@
28242 i64 nError = 0;
28243 const char *zErr = 0;
28244 while( SQLITE_OK==sqlite3_intck_step(p) ){
28245 const char *zMsg = sqlite3_intck_message(p);
28246 if( zMsg ){
28247 sqlite3_fprintf(pState->out, "%s\n", zMsg);
28248 nError++;
28249 }
28250 nStep++;
28251 if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){
28252 sqlite3_intck_unlock(p);
28253 }
28254 }
28255 rc = sqlite3_intck_error(p, &zErr);
28256 if( zErr ){
28257 sqlite3_fprintf(stderr,"%s\n", zErr);
28258 }
28259 sqlite3_intck_close(p);
28260
28261 sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError);
28262 }
28263
28264 return rc;
28265 }
28266
@@ -28279,11 +29583,11 @@
28279 */
28280 #ifdef SHELL_DEBUG
28281 #define rc_err_oom_die(rc) \
28282 if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
28283 else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
28284 sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0)
28285 #else
28286 static void rc_err_oom_die(int rc){
28287 if( rc==SQLITE_NOMEM ) shell_check_oom(0);
28288 assert(rc==SQLITE_OK||rc==SQLITE_DONE);
28289 }
@@ -28496,11 +29800,11 @@
28496 shellPreparePrintf(p->db, &rc, &pStmt,
28497 "SELECT 1 FROM sqlite_schema o WHERE "
28498 "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true"
28499 );
28500 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
28501 sqlite3_fputs("/* WARNING: "
28502 "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n",
28503 p->out
28504 );
28505 }
28506 shellFinalize(&rc, pStmt);
@@ -28529,69 +29833,1323 @@
28529 return SQLITE_OK;
28530 }
28531 if( faultsim_state.iCnt ){
28532 if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--;
28533 if( faultsim_state.eVerbose>=2 ){
28534 sqlite3_fprintf(stdout,
28535 "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt);
28536 }
28537 return SQLITE_OK;
28538 }
28539 if( faultsim_state.eVerbose>=1 ){
28540 sqlite3_fprintf(stdout,
28541 "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr);
28542 }
28543 faultsim_state.iCnt = faultsim_state.iInterval;
28544 faultsim_state.nHit++;
28545 if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){
28546 faultsim_state.iCnt = -1;
28547 }
28548 return faultsim_state.iErr;
28549 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28550
28551 /*
28552 ** If an input line begins with "." then invoke this routine to
28553 ** process that line.
28554 **
28555 ** Return 1 on error, 2 to exit, and 0 otherwise.
28556 */
28557 static int do_meta_command(char *zLine, ShellState *p){
28558 int h = 1;
28559 int nArg = 0;
28560 int n, c;
28561 int rc = 0;
28562 char *azArg[52];
28563
28564 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
28565 if( p->expert.pExpert ){
28566 expertFinish(p, 1, 0);
28567 }
28568 #endif
28569
28570 /* Parse the input line into tokens.
28571 */
28572 while( zLine[h] && nArg<ArraySize(azArg)-1 ){
28573 while( IsSpace(zLine[h]) ){ h++; }
28574 if( zLine[h]==0 ) break;
28575 if( zLine[h]=='\'' || zLine[h]=='"' ){
28576 int delim = zLine[h++];
28577 azArg[nArg++] = &zLine[h];
28578 while( zLine[h] && zLine[h]!=delim ){
28579 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
28580 h++;
28581 }
28582 if( zLine[h]==delim ){
28583 zLine[h++] = 0;
28584 }
28585 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
28586 }else{
28587 azArg[nArg++] = &zLine[h];
28588 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
28589 if( zLine[h] ) zLine[h++] = 0;
28590 }
28591 }
28592 azArg[nArg] = 0;
28593
28594 /* Process the input line.
28595 */
28596 if( nArg==0 ) return 0; /* no tokens, no error */
28597 n = strlen30(azArg[0]);
@@ -28599,11 +31157,11 @@
28599 clearTempFile(p);
28600
28601 #ifndef SQLITE_OMIT_AUTHORIZATION
28602 if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
28603 if( nArg!=2 ){
28604 sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n");
28605 rc = 1;
28606 goto meta_command_exit;
28607 }
28608 open_db(p, 0);
28609 if( booleanValue(azArg[1]) ){
@@ -28646,32 +31204,32 @@
28646 }else
28647 if( cli_strcmp(z, "-async")==0 ){
28648 bAsync = 1;
28649 }else
28650 {
28651 sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]);
28652 return 1;
28653 }
28654 }else if( zDestFile==0 ){
28655 zDestFile = azArg[j];
28656 }else if( zDb==0 ){
28657 zDb = zDestFile;
28658 zDestFile = azArg[j];
28659 }else{
28660 sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
28661 return 1;
28662 }
28663 }
28664 if( zDestFile==0 ){
28665 sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n");
28666 return 1;
28667 }
28668 if( zDb==0 ) zDb = "main";
28669 rc = sqlite3_open_v2(zDestFile, &pDest,
28670 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
28671 if( rc!=SQLITE_OK ){
28672 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile);
28673 close_db(pDest);
28674 return 1;
28675 }
28676 if( bAsync ){
28677 sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
@@ -28728,11 +31286,11 @@
28728 sqlite3_free(z);
28729 #else
28730 rc = chdir(azArg[1]);
28731 #endif
28732 if( rc ){
28733 sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]);
28734 rc = 1;
28735 }
28736 }else{
28737 eputz("Usage: .cd DIRECTORY\n");
28738 rc = 1;
@@ -28761,16 +31319,16 @@
28761 eputz("Usage: .check GLOB-PATTERN\n");
28762 rc = 2;
28763 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
28764 rc = 2;
28765 }else if( testcase_glob(azArg[1],zRes)==0 ){
28766 sqlite3_fprintf(stderr,
28767 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
28768 p->zTestcase, azArg[1], zRes);
28769 rc = 1;
28770 }else{
28771 sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase);
28772 p->nCheck++;
28773 }
28774 sqlite3_free(zRes);
28775 }else
28776 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28799,13 +31357,13 @@
28799 zFile = "(memory)";
28800 }else if( zFile[0]==0 ){
28801 zFile = "(temporary-file)";
28802 }
28803 if( p->pAuxDb == &p->aAuxDb[i] ){
28804 sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile);
28805 }else if( p->aAuxDb[i].db!=0 ){
28806 sqlite3_fprintf(stdout, " %d: %s\n", i, zFile);
28807 }
28808 }
28809 }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){
28810 int i = azArg[1][0] - '0';
28811 if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){
@@ -28837,16 +31395,21 @@
28837 && (cli_strncmp(azArg[0], "crlf", n)==0
28838 || cli_strncmp(azArg[0], "crnl",n)==0)
28839 ){
28840 if( nArg==2 ){
28841 #ifdef _WIN32
28842 p->crlfMode = booleanValue(azArg[1]);
 
 
 
 
28843 #else
28844 p->crlfMode = 0;
28845 #endif
28846 }
28847 sqlite3_fprintf(stderr, "crlf is %s\n", p->crlfMode ? "ON" : "OFF");
 
28848 }else
28849
28850 if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
28851 char **azName = 0;
28852 int nName = 0;
@@ -28872,11 +31435,11 @@
28872 sqlite3_finalize(pStmt);
28873 for(i=0; i<nName; i++){
28874 int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
28875 int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
28876 const char *z = azName[i*2+1];
28877 sqlite3_fprintf(p->out, "%s: %s %s%s\n",
28878 azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w",
28879 eTxn==SQLITE_TXN_NONE ? "" :
28880 eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
28881 free(azName[i*2]);
28882 free(azName[i*2+1]);
@@ -28917,17 +31480,17 @@
28917 if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
28918 if( nArg>=3 ){
28919 sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
28920 }
28921 sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
28922 sqlite3_fprintf(p->out, "%19s %s\n",
28923 aDbConfig[ii].zName, v ? "on" : "off");
28924 if( nArg>1 ) break;
28925 }
28926 if( nArg>1 && ii==ArraySize(aDbConfig) ){
28927 sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]);
28928 eputz("Enter \".dbconfig\" with no arguments for a list\n");
28929 }
28930 }else
28931
28932 #if SQLITE_SHELL_HAVE_RECOVER
28933 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
@@ -28942,42 +31505,41 @@
28942
28943 if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
28944 char *zLike = 0;
28945 char *zSql;
28946 int i;
28947 int savedShowHeader = p->showHeader;
28948 int savedShellFlags = p->shellFlgs;
 
28949 ShellClearFlag(p,
28950 SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
28951 |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
28952 for(i=1; i<nArg; i++){
28953 if( azArg[i][0]=='-' ){
28954 const char *z = azArg[i]+1;
28955 if( z[0]=='-' ) z++;
28956 if( cli_strcmp(z,"preserve-rowids")==0 ){
28957 #ifdef SQLITE_OMIT_VIRTUALTABLE
28958 eputz("The --preserve-rowids option is not compatible"
28959 " with SQLITE_OMIT_VIRTUALTABLE\n");
 
28960 rc = 1;
28961 sqlite3_free(zLike);
28962 goto meta_command_exit;
28963 #else
28964 ShellSetFlag(p, SHFLG_PreserveRowid);
28965 #endif
28966 }else
28967 if( cli_strcmp(z,"newlines")==0 ){
28968 ShellSetFlag(p, SHFLG_Newlines);
28969 }else
28970 if( cli_strcmp(z,"data-only")==0 ){
28971 ShellSetFlag(p, SHFLG_DumpDataOnly);
28972 }else
28973 if( cli_strcmp(z,"nosys")==0 ){
28974 ShellSetFlag(p, SHFLG_DumpNoSys);
28975 }else
28976 {
28977 sqlite3_fprintf(stderr,
28978 "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
28979 rc = 1;
28980 sqlite3_free(zLike);
28981 goto meta_command_exit;
28982 }
28983 }else{
@@ -29003,20 +31565,21 @@
29003 }
29004 }
29005
29006 open_db(p, 0);
29007
 
29008 outputDumpWarning(p, zLike);
29009 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
29010 /* When playing back a "dump", the content might appear in an order
29011 ** which causes immediate foreign key constraints to be violated.
29012 ** So disable foreign-key constraint enforcement to prevent problems. */
29013 sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out);
29014 sqlite3_fputs("BEGIN TRANSACTION;\n", p->out);
29015 }
29016 p->writableSchema = 0;
29017 p->showHeader = 0;
29018 /* Set writable_schema=ON since doing so forces SQLite to initialize
29019 ** as much of the schema as it can even if the sqlite_schema table is
29020 ** corrupt. */
29021 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
29022 p->nErr = 0;
@@ -29041,25 +31604,31 @@
29041 run_table_dump_query(p, zSql);
29042 sqlite3_free(zSql);
29043 }
29044 sqlite3_free(zLike);
29045 if( p->writableSchema ){
29046 sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out);
29047 p->writableSchema = 0;
29048 }
29049 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
29050 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
29051 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
29052 sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out);
29053 }
29054 p->showHeader = savedShowHeader;
29055 p->shellFlgs = savedShellFlags;
 
 
 
29056 }else
29057
29058 if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
29059 if( nArg==2 ){
29060 setOrClearFlag(p, SHFLG_Echo, azArg[1]);
 
 
 
 
29061 }else{
29062 eputz("Usage: .echo on|off\n");
29063 rc = 1;
29064 }
29065 }else
@@ -29069,74 +31638,58 @@
29069 rc = shell_dbtotxt_command(p, nArg, azArg);
29070 }else
29071
29072 if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
29073 if( nArg==2 ){
29074 p->autoEQPtest = 0;
29075 if( p->autoEQPtrace ){
29076 if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
29077 p->autoEQPtrace = 0;
29078 }
29079 if( cli_strcmp(azArg[1],"full")==0 ){
29080 p->autoEQP = AUTOEQP_full;
29081 }else if( cli_strcmp(azArg[1],"trigger")==0 ){
29082 p->autoEQP = AUTOEQP_trigger;
29083 #ifdef SQLITE_DEBUG
29084 }else if( cli_strcmp(azArg[1],"test")==0 ){
29085 p->autoEQP = AUTOEQP_on;
29086 p->autoEQPtest = 1;
29087 }else if( cli_strcmp(azArg[1],"trace")==0 ){
29088 p->autoEQP = AUTOEQP_full;
29089 p->autoEQPtrace = 1;
29090 open_db(p, 0);
29091 sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
29092 sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
29093 #endif
29094 }else{
29095 p->autoEQP = (u8)booleanValue(azArg[1]);
29096 }
29097 }else{
29098 eputz("Usage: .eqp off|on|trace|trigger|full\n");
29099 rc = 1;
29100 }
29101 }else
29102
29103 #ifndef SQLITE_SHELL_FIDDLE
29104 if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
29105 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
29106 rc = 2;
29107 }else
29108 #endif
29109
29110 /* The ".explain" command is automatic now. It is largely pointless. It
29111 ** retained purely for backwards compatibility */
29112 if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){
29113 int val = 1;
29114 if( nArg>=2 ){
29115 if( cli_strcmp(azArg[1],"auto")==0 ){
29116 val = 99;
29117 }else{
29118 val = booleanValue(azArg[1]);
29119 }
29120 }
29121 if( val==1 && p->mode!=MODE_Explain ){
29122 p->normalMode = p->mode;
29123 p->mode = MODE_Explain;
29124 p->autoExplain = 0;
29125 }else if( val==0 ){
29126 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
29127 p->autoExplain = 0;
29128 }else if( val==99 ){
29129 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
29130 p->autoExplain = 1;
29131 }
29132 }else
29133
29134 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
29135 if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
29136 if( p->bSafeMode ){
29137 sqlite3_fprintf(stderr,
29138 "Cannot run experimental commands such as \"%s\" in safe mode\n",
29139 azArg[0]);
29140 rc = 1;
29141 }else{
29142 open_db(p, 0);
@@ -29190,13 +31743,13 @@
29190 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
29191 }
29192
29193 /* --help lists all file-controls */
29194 if( cli_strcmp(zCmd,"help")==0 ){
29195 sqlite3_fputs("Available file-controls:\n", p->out);
29196 for(i=0; i<ArraySize(aCtrl); i++){
29197 sqlite3_fprintf(p->out,
29198 " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage);
29199 }
29200 rc = 1;
29201 goto meta_command_exit;
29202 }
@@ -29208,19 +31761,19 @@
29208 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
29209 if( filectrl<0 ){
29210 filectrl = aCtrl[i].ctrlCode;
29211 iCtrl = i;
29212 }else{
29213 sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n"
29214 "Use \".filectrl --help\" for help\n", zCmd);
29215 rc = 1;
29216 goto meta_command_exit;
29217 }
29218 }
29219 }
29220 if( filectrl<0 ){
29221 sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n"
29222 "Use \".filectrl --help\" for help\n", zCmd);
29223 }else{
29224 switch(filectrl){
29225 case SQLITE_FCNTL_SIZE_LIMIT: {
29226 if( nArg!=2 && nArg!=3 ) break;
@@ -29260,11 +31813,11 @@
29260 case SQLITE_FCNTL_TEMPFILENAME: {
29261 char *z = 0;
29262 if( nArg!=2 ) break;
29263 sqlite3_file_control(p->db, zSchema, filectrl, &z);
29264 if( z ){
29265 sqlite3_fprintf(p->out, "%s\n", z);
29266 sqlite3_free(z);
29267 }
29268 isOk = 2;
29269 break;
29270 }
@@ -29274,81 +31827,96 @@
29274 x = atoi(azArg[2]);
29275 sqlite3_file_control(p->db, zSchema, filectrl, &x);
29276 }
29277 x = -1;
29278 sqlite3_file_control(p->db, zSchema, filectrl, &x);
29279 sqlite3_fprintf(p->out, "%d\n", x);
29280 isOk = 2;
29281 break;
29282 }
29283 }
29284 }
29285 if( isOk==0 && iCtrl>=0 ){
29286 sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n",
29287 zCmd, aCtrl[iCtrl].zUsage);
29288 rc = 1;
29289 }else if( isOk==1 ){
29290 char zBuf[100];
29291 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
29292 sqlite3_fprintf(p->out, "%s\n", zBuf);
29293 }
29294 }else
29295
29296 if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){
29297 ShellState data;
29298 int doStats = 0;
29299 memcpy(&data, p, sizeof(data));
29300 data.showHeader = 0;
29301 data.cMode = data.mode = MODE_Semi;
29302 if( nArg==2 && optionMatch(azArg[1], "indent") ){
29303 data.cMode = data.mode = MODE_Pretty;
29304 nArg = 1;
29305 }
29306 if( nArg!=1 ){
29307 eputz("Usage: .fullschema ?--indent?\n");
29308 rc = 1;
29309 goto meta_command_exit;
29310 }
29311 open_db(p, 0);
29312 rc = sqlite3_exec(p->db,
29313 "SELECT sql FROM"
29314 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
29315 " FROM sqlite_schema UNION ALL"
29316 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
29317 "WHERE type!='meta' AND sql NOTNULL"
29318 " AND name NOT LIKE 'sqlite__%' ESCAPE '_' "
29319 "ORDER BY x",
29320 callback, &data, 0
29321 );
 
 
 
 
 
 
29322 if( rc==SQLITE_OK ){
 
29323 sqlite3_stmt *pStmt;
29324 rc = sqlite3_prepare_v2(p->db,
29325 "SELECT rowid FROM sqlite_schema"
29326 " WHERE name GLOB 'sqlite_stat[134]'",
29327 -1, &pStmt, 0);
29328 if( rc==SQLITE_OK ){
29329 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
29330 sqlite3_finalize(pStmt);
 
 
 
 
29331 }
 
29332 }
29333 if( doStats==0 ){
29334 sqlite3_fputs("/* No STAT tables available */\n", p->out);
29335 }else{
29336 sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
29337 data.cMode = data.mode = MODE_Insert;
29338 data.zDestTable = "sqlite_stat1";
29339 shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
29340 data.zDestTable = "sqlite_stat4";
29341 shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
29342 sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
 
 
 
 
29343 }
29344 }else
29345
29346 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
29347 if( nArg==2 ){
29348 p->showHeader = booleanValue(azArg[1]);
29349 p->shellFlgs |= SHFLG_HeaderSet;
29350 }else{
29351 eputz("Usage: .headers on|off\n");
29352 rc = 1;
29353 }
29354 }else
@@ -29355,340 +31923,20 @@
29355
29356 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
29357 if( nArg>=2 ){
29358 n = showHelp(p->out, azArg[1]);
29359 if( n==0 ){
29360 sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]);
29361 }
29362 }else{
29363 showHelp(p->out, 0);
29364 }
29365 }else
29366
29367 #ifndef SQLITE_SHELL_FIDDLE
29368 if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
29369 char *zTable = 0; /* Insert data into this table */
29370 char *zSchema = 0; /* Schema of zTable */
29371 char *zFile = 0; /* Name of file to extra content from */
29372 sqlite3_stmt *pStmt = NULL; /* A statement */
29373 int nCol; /* Number of columns in the table */
29374 i64 nByte; /* Number of bytes in an SQL string */
29375 int i, j; /* Loop counters */
29376 int needCommit; /* True to COMMIT or ROLLBACK at end */
29377 int nSep; /* Number of bytes in p->colSeparator[] */
29378 char *zSql = 0; /* An SQL statement */
29379 ImportCtx sCtx; /* Reader context */
29380 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29381 int eVerbose = 0; /* Larger for more console output */
29382 i64 nSkip = 0; /* Initial lines to skip */
29383 int useOutputMode = 1; /* Use output mode to determine separators */
29384 char *zCreate = 0; /* CREATE TABLE statement text */
29385
29386 failIfSafeMode(p, "cannot run .import in safe mode");
29387 memset(&sCtx, 0, sizeof(sCtx));
29388 if( p->mode==MODE_Ascii ){
29389 xRead = ascii_read_one_field;
29390 }else{
29391 xRead = csv_read_one_field;
29392 }
29393 rc = 1;
29394 for(i=1; i<nArg; i++){
29395 char *z = azArg[i];
29396 if( z[0]=='-' && z[1]=='-' ) z++;
29397 if( z[0]!='-' ){
29398 if( zFile==0 ){
29399 zFile = z;
29400 }else if( zTable==0 ){
29401 zTable = z;
29402 }else{
29403 sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z);
29404 showHelp(p->out, "import");
29405 goto meta_command_exit;
29406 }
29407 }else if( cli_strcmp(z,"-v")==0 ){
29408 eVerbose++;
29409 }else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){
29410 zSchema = azArg[++i];
29411 }else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){
29412 nSkip = integerValue(azArg[++i]);
29413 }else if( cli_strcmp(z,"-ascii")==0 ){
29414 sCtx.cColSep = SEP_Unit[0];
29415 sCtx.cRowSep = SEP_Record[0];
29416 xRead = ascii_read_one_field;
29417 useOutputMode = 0;
29418 }else if( cli_strcmp(z,"-csv")==0 ){
29419 sCtx.cColSep = ',';
29420 sCtx.cRowSep = '\n';
29421 xRead = csv_read_one_field;
29422 useOutputMode = 0;
29423 }else{
29424 sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
29425 showHelp(p->out, "import");
29426 goto meta_command_exit;
29427 }
29428 }
29429 if( zTable==0 ){
29430 sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n",
29431 zFile==0 ? "FILE" : "TABLE");
29432 showHelp(p->out, "import");
29433 goto meta_command_exit;
29434 }
29435 seenInterrupt = 0;
29436 open_db(p, 0);
29437 if( useOutputMode ){
29438 /* If neither the --csv or --ascii options are specified, then set
29439 ** the column and row separator characters from the output mode. */
29440 nSep = strlen30(p->colSeparator);
29441 if( nSep==0 ){
29442 eputz("Error: non-null column separator required for import\n");
29443 goto meta_command_exit;
29444 }
29445 if( nSep>1 ){
29446 eputz("Error: multi-character column separators not allowed"
29447 " for import\n");
29448 goto meta_command_exit;
29449 }
29450 nSep = strlen30(p->rowSeparator);
29451 if( nSep==0 ){
29452 eputz("Error: non-null row separator required for import\n");
29453 goto meta_command_exit;
29454 }
29455 if( nSep==2 && p->mode==MODE_Csv
29456 && cli_strcmp(p->rowSeparator,SEP_CrLf)==0
29457 ){
29458 /* When importing CSV (only), if the row separator is set to the
29459 ** default output row separator, change it to the default input
29460 ** row separator. This avoids having to maintain different input
29461 ** and output row separators. */
29462 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
29463 nSep = strlen30(p->rowSeparator);
29464 }
29465 if( nSep>1 ){
29466 eputz("Error: multi-character row separators not allowed"
29467 " for import\n");
29468 goto meta_command_exit;
29469 }
29470 sCtx.cColSep = (u8)p->colSeparator[0];
29471 sCtx.cRowSep = (u8)p->rowSeparator[0];
29472 }
29473 sCtx.zFile = zFile;
29474 sCtx.nLine = 1;
29475 if( sCtx.zFile[0]=='|' ){
29476 #ifdef SQLITE_OMIT_POPEN
29477 eputz("Error: pipes are not supported in this OS\n");
29478 goto meta_command_exit;
29479 #else
29480 sCtx.in = sqlite3_popen(sCtx.zFile+1, "r");
29481 sCtx.zFile = "<pipe>";
29482 sCtx.xCloser = pclose;
29483 #endif
29484 }else{
29485 sCtx.in = sqlite3_fopen(sCtx.zFile, "rb");
29486 sCtx.xCloser = fclose;
29487 }
29488 if( sCtx.in==0 ){
29489 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
29490 goto meta_command_exit;
29491 }
29492 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
29493 char zSep[2];
29494 zSep[1] = 0;
29495 zSep[0] = sCtx.cColSep;
29496 sqlite3_fputs("Column separator ", p->out);
29497 output_c_string(p->out, zSep);
29498 sqlite3_fputs(", row separator ", p->out);
29499 zSep[0] = sCtx.cRowSep;
29500 output_c_string(p->out, zSep);
29501 sqlite3_fputs("\n", p->out);
29502 }
29503 sCtx.z = sqlite3_malloc64(120);
29504 if( sCtx.z==0 ){
29505 import_cleanup(&sCtx);
29506 shell_out_of_memory();
29507 }
29508 /* Below, resources must be freed before exit. */
29509 while( nSkip>0 ){
29510 nSkip--;
29511 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
29512 }
29513 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
29514 if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
29515 && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
29516 " WHERE name=%Q AND type='view'",
29517 zSchema ? zSchema : "main", zTable)
29518 ){
29519 /* Table does not exist. Create it. */
29520 sqlite3 *dbCols = 0;
29521 char *zRenames = 0;
29522 char *zColDefs;
29523 zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
29524 zSchema ? zSchema : "main", zTable);
29525 while( xRead(&sCtx) ){
29526 zAutoColumn(sCtx.z, &dbCols, 0);
29527 if( sCtx.cTerm!=sCtx.cColSep ) break;
29528 }
29529 zColDefs = zAutoColumn(0, &dbCols, &zRenames);
29530 if( zRenames!=0 ){
29531 sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
29532 "Columns renamed during .import %s due to duplicates:\n"
29533 "%s\n", sCtx.zFile, zRenames);
29534 sqlite3_free(zRenames);
29535 }
29536 assert(dbCols==0);
29537 if( zColDefs==0 ){
29538 sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile);
29539 import_cleanup(&sCtx);
29540 rc = 1;
29541 sqlite3_free(zCreate);
29542 goto meta_command_exit;
29543 }
29544 zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
29545 if( zCreate==0 ){
29546 import_cleanup(&sCtx);
29547 shell_out_of_memory();
29548 }
29549 if( eVerbose>=1 ){
29550 sqlite3_fprintf(p->out, "%s\n", zCreate);
29551 }
29552 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
29553 if( rc ){
29554 sqlite3_fprintf(stderr,
29555 "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
29556 }
29557 sqlite3_free(zCreate);
29558 zCreate = 0;
29559 if( rc ){
29560 import_cleanup(&sCtx);
29561 rc = 1;
29562 goto meta_command_exit;
29563 }
29564 }
29565 zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
29566 zTable, zSchema);
29567 if( zSql==0 ){
29568 import_cleanup(&sCtx);
29569 shell_out_of_memory();
29570 }
29571 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
29572 sqlite3_free(zSql);
29573 zSql = 0;
29574 if( rc ){
29575 if (pStmt) sqlite3_finalize(pStmt);
29576 shellDatabaseError(p->db);
29577 import_cleanup(&sCtx);
29578 rc = 1;
29579 goto meta_command_exit;
29580 }
29581 if( sqlite3_step(pStmt)==SQLITE_ROW ){
29582 nCol = sqlite3_column_int(pStmt, 0);
29583 }else{
29584 nCol = 0;
29585 }
29586 sqlite3_finalize(pStmt);
29587 pStmt = 0;
29588 if( nCol==0 ) return 0; /* no columns, no error */
29589
29590 nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */
29591 + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */
29592 + strlen(zTable)*2 + 2 /* Quoted table name */
29593 + nCol*2; /* Space for ",?" for each column */
29594 zSql = sqlite3_malloc64( nByte );
29595 if( zSql==0 ){
29596 import_cleanup(&sCtx);
29597 shell_out_of_memory();
29598 }
29599 if( zSchema ){
29600 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
29601 zSchema, zTable);
29602 }else{
29603 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
29604 }
29605 j = strlen30(zSql);
29606 for(i=1; i<nCol; i++){
29607 zSql[j++] = ',';
29608 zSql[j++] = '?';
29609 }
29610 zSql[j++] = ')';
29611 zSql[j] = 0;
29612 assert( j<nByte );
29613 if( eVerbose>=2 ){
29614 sqlite3_fprintf(p->out, "Insert using: %s\n", zSql);
29615 }
29616 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
29617 sqlite3_free(zSql);
29618 zSql = 0;
29619 if( rc ){
29620 shellDatabaseError(p->db);
29621 if (pStmt) sqlite3_finalize(pStmt);
29622 import_cleanup(&sCtx);
29623 rc = 1;
29624 goto meta_command_exit;
29625 }
29626 needCommit = sqlite3_get_autocommit(p->db);
29627 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
29628 do{
29629 int startLine = sCtx.nLine;
29630 for(i=0; i<nCol; i++){
29631 char *z = xRead(&sCtx);
29632 /*
29633 ** Did we reach end-of-file before finding any columns?
29634 ** If so, stop instead of NULL filling the remaining columns.
29635 */
29636 if( z==0 && i==0 ) break;
29637 /*
29638 ** Did we reach end-of-file OR end-of-line before finding any
29639 ** columns in ASCII mode? If so, stop instead of NULL filling
29640 ** the remaining columns.
29641 */
29642 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
29643 /*
29644 ** For CSV mode, per RFC 4180, accept EOF in lieu of final
29645 ** record terminator but only for last field of multi-field row.
29646 ** (If there are too few fields, it's not valid CSV anyway.)
29647 */
29648 if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
29649 z = "";
29650 }
29651 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
29652 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
29653 sqlite3_fprintf(stderr,"%s:%d: expected %d columns but found %d"
29654 " - filling the rest with NULL\n",
29655 sCtx.zFile, startLine, nCol, i+1);
29656 i += 2;
29657 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
29658 }
29659 }
29660 if( sCtx.cTerm==sCtx.cColSep ){
29661 do{
29662 xRead(&sCtx);
29663 i++;
29664 }while( sCtx.cTerm==sCtx.cColSep );
29665 sqlite3_fprintf(stderr,
29666 "%s:%d: expected %d columns but found %d - extras ignored\n",
29667 sCtx.zFile, startLine, nCol, i);
29668 }
29669 if( i>=nCol ){
29670 sqlite3_step(pStmt);
29671 rc = sqlite3_reset(pStmt);
29672 if( rc!=SQLITE_OK ){
29673 sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n",
29674 sCtx.zFile, startLine, sqlite3_errmsg(p->db));
29675 sCtx.nErr++;
29676 }else{
29677 sCtx.nRow++;
29678 }
29679 }
29680 }while( sCtx.cTerm!=EOF );
29681
29682 import_cleanup(&sCtx);
29683 sqlite3_finalize(pStmt);
29684 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
29685 if( eVerbose>0 ){
29686 sqlite3_fprintf(p->out,
29687 "Added %d rows with %d errors using %d lines of input\n",
29688 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
29689 }
29690 }else
29691 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
29692
29693 #ifndef SQLITE_UNTESTABLE
29694 if( c=='i' && cli_strncmp(azArg[0], "imposter", n)==0 ){
@@ -29758,11 +32006,11 @@
29758 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
29759 }
29760 }
29761 sqlite3_finalize(pStmt);
29762 if( i==0 || tnum==0 ){
29763 sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]);
29764 rc = 1;
29765 sqlite3_free(zCollist);
29766 goto meta_command_exit;
29767 }
29768 if( lenPK==0 ) lenPK = 100000;
@@ -29773,17 +32021,17 @@
29773 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum);
29774 if( rc==SQLITE_OK ){
29775 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
29776 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
29777 if( rc ){
29778 sqlite3_fprintf(stderr,
29779 "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
29780 }else{
29781 sqlite3_fprintf(stdout, "%s;\n", zSql);
29782 }
29783 }else{
29784 sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
29785 rc = 1;
29786 }
29787 sqlite3_free(zSql);
29788 }else
29789 #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
@@ -29793,11 +32041,11 @@
29793 if( nArg==2 ){
29794 iArg = integerValue(azArg[1]);
29795 if( iArg==0 ) iArg = -1;
29796 }
29797 if( (nArg!=1 && nArg!=2) || iArg<0 ){
29798 sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
29799 rc = 1;
29800 goto meta_command_exit;
29801 }
29802 open_db(p, 0);
29803 rc = intckDatabaseCmd(p, iArg);
@@ -29814,11 +32062,11 @@
29814 sqlite3IoTrace = iotracePrintf;
29815 iotrace = stdout;
29816 }else{
29817 iotrace = sqlite3_fopen(azArg[1], "w");
29818 if( iotrace==0 ){
29819 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
29820 sqlite3IoTrace = 0;
29821 rc = 1;
29822 }else{
29823 sqlite3IoTrace = iotracePrintf;
29824 }
@@ -29833,10 +32081,11 @@
29833 } aLimit[] = {
29834 { "length", SQLITE_LIMIT_LENGTH },
29835 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
29836 { "column", SQLITE_LIMIT_COLUMN },
29837 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
 
29838 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
29839 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
29840 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
29841 { "attached", SQLITE_LIMIT_ATTACHED },
29842 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
@@ -29846,11 +32095,11 @@
29846 };
29847 int i, n2;
29848 open_db(p, 0);
29849 if( nArg==1 ){
29850 for(i=0; i<ArraySize(aLimit); i++){
29851 sqlite3_fprintf(stdout, "%20s %d\n", aLimit[i].zLimitName,
29852 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
29853 }
29854 }else if( nArg>3 ){
29855 eputz("Usage: .limit NAME ?NEW-VALUE?\n");
29856 rc = 1;
@@ -29861,28 +32110,28 @@
29861 for(i=0; i<ArraySize(aLimit); i++){
29862 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
29863 if( iLimit<0 ){
29864 iLimit = i;
29865 }else{
29866 sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]);
29867 rc = 1;
29868 goto meta_command_exit;
29869 }
29870 }
29871 }
29872 if( iLimit<0 ){
29873 sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n"
29874 "enter \".limits\" with no arguments for a list.\n",
29875 azArg[1]);
29876 rc = 1;
29877 goto meta_command_exit;
29878 }
29879 if( nArg==3 ){
29880 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
29881 (int)integerValue(azArg[2]));
29882 }
29883 sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName,
29884 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
29885 }
29886 }else
29887
29888 if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){
@@ -29927,189 +32176,27 @@
29927 " than \"on\" or \"off\"\n");
29928 zFile = "off";
29929 }
29930 output_file_close(p->pLog);
29931 if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
29932 p->pLog = output_file_open(zFile);
29933 }
29934 }else
29935
29936 if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){
29937 const char *zMode = 0;
29938 const char *zTabname = 0;
29939 int i, n2;
29940 int chng = 0; /* 0x01: change to cmopts. 0x02: Any other change */
29941 ColModeOpts cmOpts = ColModeOpts_default;
29942 for(i=1; i<nArg; i++){
29943 const char *z = azArg[i];
29944 if( optionMatch(z,"wrap") && i+1<nArg ){
29945 cmOpts.iWrap = integerValue(azArg[++i]);
29946 chng |= 1;
29947 }else if( optionMatch(z,"ww") ){
29948 cmOpts.bWordWrap = 1;
29949 chng |= 1;
29950 }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
29951 cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
29952 chng |= 1;
29953 }else if( optionMatch(z,"quote") ){
29954 cmOpts.bQuote = 1;
29955 chng |= 1;
29956 }else if( optionMatch(z,"noquote") ){
29957 cmOpts.bQuote = 0;
29958 chng |= 1;
29959 }else if( optionMatch(z,"escape") && i+1<nArg ){
29960 /* See similar code at tag-20250224-1 */
29961 const char *zEsc = azArg[++i];
29962 int k;
29963 for(k=0; k<ArraySize(shell_EscModeNames); k++){
29964 if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){
29965 p->eEscMode = k;
29966 chng |= 2;
29967 break;
29968 }
29969 }
29970 if( k>=ArraySize(shell_EscModeNames) ){
29971 sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
29972 " - choices:", zEsc);
29973 for(k=0; k<ArraySize(shell_EscModeNames); k++){
29974 sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
29975 }
29976 sqlite3_fprintf(stderr, "\n");
29977 rc = 1;
29978 goto meta_command_exit;
29979 }
29980 }else if( zMode==0 ){
29981 zMode = z;
29982 /* Apply defaults for qbox pseudo-mode. If that
29983 * overwrites already-set values, user was informed of this.
29984 */
29985 chng |= 1;
29986 if( cli_strcmp(z, "qbox")==0 ){
29987 ColModeOpts cmo = ColModeOpts_default_qbox;
29988 zMode = "box";
29989 cmOpts = cmo;
29990 }
29991 }else if( zTabname==0 ){
29992 zTabname = z;
29993 }else if( z[0]=='-' ){
29994 sqlite3_fprintf(stderr,"unknown option: %s\n", z);
29995 eputz("options:\n"
29996 " --escape MODE\n"
29997 " --noquote\n"
29998 " --quote\n"
29999 " --wordwrap on/off\n"
30000 " --wrap N\n"
30001 " --ww\n");
30002 rc = 1;
30003 goto meta_command_exit;
30004 }else{
30005 sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
30006 rc = 1;
30007 goto meta_command_exit;
30008 }
30009 }
30010 if( !chng ){
30011 if( p->mode==MODE_Column
30012 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
30013 ){
30014 sqlite3_fprintf(p->out,
30015 "current output mode: %s --wrap %d --wordwrap %s "
30016 "--%squote --escape %s\n",
30017 modeDescr[p->mode], p->cmOpts.iWrap,
30018 p->cmOpts.bWordWrap ? "on" : "off",
30019 p->cmOpts.bQuote ? "" : "no",
30020 shell_EscModeNames[p->eEscMode]
30021 );
30022 }else{
30023 sqlite3_fprintf(p->out,
30024 "current output mode: %s --escape %s\n",
30025 modeDescr[p->mode],
30026 shell_EscModeNames[p->eEscMode]
30027 );
30028 }
30029 }
30030 if( zMode==0 ){
30031 zMode = modeDescr[p->mode];
30032 if( (chng&1)==0 ) cmOpts = p->cmOpts;
30033 }
30034 n2 = strlen30(zMode);
30035 if( cli_strncmp(zMode,"lines",n2)==0 ){
30036 p->mode = MODE_Line;
30037 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30038 }else if( cli_strncmp(zMode,"columns",n2)==0 ){
30039 p->mode = MODE_Column;
30040 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
30041 p->showHeader = 1;
30042 }
30043 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30044 p->cmOpts = cmOpts;
30045 }else if( cli_strncmp(zMode,"list",n2)==0 ){
30046 p->mode = MODE_List;
30047 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
30048 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30049 }else if( cli_strncmp(zMode,"html",n2)==0 ){
30050 p->mode = MODE_Html;
30051 }else if( cli_strncmp(zMode,"tcl",n2)==0 ){
30052 p->mode = MODE_Tcl;
30053 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
30054 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30055 }else if( cli_strncmp(zMode,"csv",n2)==0 ){
30056 p->mode = MODE_Csv;
30057 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30058 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
30059 }else if( cli_strncmp(zMode,"tabs",n2)==0 ){
30060 p->mode = MODE_List;
30061 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
30062 }else if( cli_strncmp(zMode,"insert",n2)==0 ){
30063 p->mode = MODE_Insert;
30064 set_table_name(p, zTabname ? zTabname : "table");
30065 if( p->eEscMode==SHELL_ESC_OFF ){
30066 ShellSetFlag(p, SHFLG_Newlines);
30067 }else{
30068 ShellClearFlag(p, SHFLG_Newlines);
30069 }
30070 }else if( cli_strncmp(zMode,"quote",n2)==0 ){
30071 p->mode = MODE_Quote;
30072 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30073 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
30074 }else if( cli_strncmp(zMode,"ascii",n2)==0 ){
30075 p->mode = MODE_Ascii;
30076 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
30077 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
30078 }else if( cli_strncmp(zMode,"markdown",n2)==0 ){
30079 p->mode = MODE_Markdown;
30080 p->cmOpts = cmOpts;
30081 }else if( cli_strncmp(zMode,"table",n2)==0 ){
30082 p->mode = MODE_Table;
30083 p->cmOpts = cmOpts;
30084 }else if( cli_strncmp(zMode,"box",n2)==0 ){
30085 p->mode = MODE_Box;
30086 p->cmOpts = cmOpts;
30087 }else if( cli_strncmp(zMode,"count",n2)==0 ){
30088 p->mode = MODE_Count;
30089 }else if( cli_strncmp(zMode,"off",n2)==0 ){
30090 p->mode = MODE_Off;
30091 }else if( cli_strncmp(zMode,"json",n2)==0 ){
30092 p->mode = MODE_Json;
30093 }else{
30094 eputz("Error: mode should be one of: "
30095 "ascii box column csv html insert json line list markdown "
30096 "qbox quote table tabs tcl\n");
30097 rc = 1;
30098 }
30099 p->cMode = p->mode;
30100 }else
30101
30102 #ifndef SQLITE_SHELL_FIDDLE
30103 if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
30104 if( nArg!=2 ){
30105 eputz("Usage: .nonce NONCE\n");
30106 rc = 1;
30107 }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
30108 sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
30109 p->lineno, azArg[1]);
30110 exit(1);
30111 }else{
30112 p->bSafeMode = 0;
30113 return 0; /* Return immediately to bypass the safe mode reset
30114 ** at the end of this procedure */
30115 }
@@ -30116,12 +32203,11 @@
30116 }else
30117 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
30118
30119 if( c=='n' && cli_strncmp(azArg[0], "nullvalue", n)==0 ){
30120 if( nArg==2 ){
30121 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
30122 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
30123 }else{
30124 eputz("Usage: .nullvalue STRING\n");
30125 rc = 1;
30126 }
30127 }else
@@ -30166,15 +32252,15 @@
30166 p->szMax = integerValue(azArg[++iName]);
30167 #endif /* SQLITE_OMIT_DESERIALIZE */
30168 }else
30169 #endif /* !SQLITE_SHELL_FIDDLE */
30170 if( z[0]=='-' ){
30171 sqlite3_fprintf(stderr,"unknown option: %s\n", z);
30172 rc = 1;
30173 goto meta_command_exit;
30174 }else if( zFN ){
30175 sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
30176 rc = 1;
30177 goto meta_command_exit;
30178 }else{
30179 zFN = z;
30180 }
@@ -30221,11 +32307,11 @@
30221 zNewFilename = 0;
30222 }
30223 p->pAuxDb->zDbFilename = zNewFilename;
30224 open_db(p, OPEN_DB_KEEPALIVE);
30225 if( p->db==0 ){
30226 sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename);
30227 sqlite3_free(zNewFilename);
30228 }else{
30229 p->pAuxDb->zFreeOnClose = zNewFilename;
30230 }
30231 }
@@ -30241,149 +32327,11 @@
30241 && (cli_strncmp(azArg[0], "output", n)==0
30242 || cli_strncmp(azArg[0], "once", n)==0))
30243 || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0)
30244 || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0)
30245 ){
30246 char *zFile = 0;
30247 int i;
30248 int eMode = 0; /* 0: .outout/.once, 'x'=.excel, 'w'=.www */
30249 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */
30250 int bPlain = 0; /* --plain option */
30251 static const char *zBomUtf8 = "\357\273\277";
30252 const char *zBom = 0;
30253
30254 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
30255 if( c=='e' ){
30256 eMode = 'x';
30257 bOnce = 2;
30258 }else if( c=='w' ){
30259 eMode = 'w';
30260 bOnce = 2;
30261 }else if( cli_strncmp(azArg[0],"once",n)==0 ){
30262 bOnce = 1;
30263 }
30264 for(i=1; i<nArg; i++){
30265 char *z = azArg[i];
30266 if( z[0]=='-' ){
30267 if( z[1]=='-' ) z++;
30268 if( cli_strcmp(z,"-bom")==0 ){
30269 zBom = zBomUtf8;
30270 }else if( cli_strcmp(z,"-plain")==0 ){
30271 bPlain = 1;
30272 }else if( c=='o' && cli_strcmp(z,"-x")==0 ){
30273 eMode = 'x'; /* spreadsheet */
30274 }else if( c=='o' && cli_strcmp(z,"-e")==0 ){
30275 eMode = 'e'; /* text editor */
30276 }else if( c=='o' && cli_strcmp(z,"-w")==0 ){
30277 eMode = 'w'; /* Web browser */
30278 }else{
30279 sqlite3_fprintf(p->out,
30280 "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
30281 showHelp(p->out, azArg[0]);
30282 rc = 1;
30283 sqlite3_free(zFile);
30284 goto meta_command_exit;
30285 }
30286 }else if( zFile==0 && eMode==0 ){
30287 if( cli_strcmp(z, "off")==0 ){
30288 #ifdef _WIN32
30289 zFile = sqlite3_mprintf("nul");
30290 #else
30291 zFile = sqlite3_mprintf("/dev/null");
30292 #endif
30293 }else{
30294 zFile = sqlite3_mprintf("%s", z);
30295 }
30296 if( zFile && zFile[0]=='|' ){
30297 while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
30298 break;
30299 }
30300 }else{
30301 sqlite3_fprintf(p->out,
30302 "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]);
30303 showHelp(p->out, azArg[0]);
30304 rc = 1;
30305 sqlite3_free(zFile);
30306 goto meta_command_exit;
30307 }
30308 }
30309 if( zFile==0 ){
30310 zFile = sqlite3_mprintf("stdout");
30311 }
30312 shell_check_oom(zFile);
30313 if( bOnce ){
30314 p->outCount = 2;
30315 }else{
30316 p->outCount = 0;
30317 }
30318 output_reset(p);
30319 #ifndef SQLITE_NOHAVE_SYSTEM
30320 if( eMode=='e' || eMode=='x' || eMode=='w' ){
30321 p->doXdgOpen = 1;
30322 outputModePush(p);
30323 if( eMode=='x' ){
30324 /* spreadsheet mode. Output as CSV. */
30325 newTempFile(p, "csv");
30326 ShellClearFlag(p, SHFLG_Echo);
30327 p->mode = MODE_Csv;
30328 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
30329 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
30330 #ifdef _WIN32
30331 zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does
30332 ** not work without it. */
30333 #endif
30334 }else if( eMode=='w' ){
30335 /* web-browser mode. */
30336 newTempFile(p, "html");
30337 if( !bPlain ) p->mode = MODE_Www;
30338 }else{
30339 /* text editor mode */
30340 newTempFile(p, "txt");
30341 }
30342 sqlite3_free(zFile);
30343 zFile = sqlite3_mprintf("%s", p->zTempFile);
30344 }
30345 #endif /* SQLITE_NOHAVE_SYSTEM */
30346 shell_check_oom(zFile);
30347 if( zFile[0]=='|' ){
30348 #ifdef SQLITE_OMIT_POPEN
30349 eputz("Error: pipes are not supported in this OS\n");
30350 rc = 1;
30351 output_redir(p, stdout);
30352 #else
30353 FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
30354 if( pfPipe==0 ){
30355 assert( stderr!=NULL );
30356 sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
30357 rc = 1;
30358 }else{
30359 output_redir(p, pfPipe);
30360 if( zBom ) sqlite3_fputs(zBom, pfPipe);
30361 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
30362 }
30363 #endif
30364 }else{
30365 FILE *pfFile = output_file_open(zFile);
30366 if( pfFile==0 ){
30367 if( cli_strcmp(zFile,"off")!=0 ){
30368 assert( stderr!=NULL );
30369 sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
30370 }
30371 rc = 1;
30372 } else {
30373 output_redir(p, pfFile);
30374 if( zBom ) sqlite3_fputs(zBom, pfFile);
30375 if( bPlain && eMode=='w' ){
30376 sqlite3_fputs(
30377 "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n",
30378 pfFile
30379 );
30380 }
30381 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
30382 }
30383 }
30384 sqlite3_free(zFile);
30385 }else
30386 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
30387
30388 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "parameter", n)==0 ){
30389 open_db(p,0);
@@ -30416,11 +32364,11 @@
30416 if( len ){
30417 rx = sqlite3_prepare_v2(p->db,
30418 "SELECT key, quote(value) "
30419 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
30420 while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
30421 sqlite3_fprintf(p->out,
30422 "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
30423 sqlite3_column_text(pStmt,1));
30424 }
30425 sqlite3_finalize(pStmt);
30426 }
@@ -30462,11 +32410,11 @@
30462 "VALUES(%Q,%Q);", zKey, zValue);
30463 shell_check_oom(zSql);
30464 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
30465 sqlite3_free(zSql);
30466 if( rx!=SQLITE_OK ){
30467 sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
30468 sqlite3_finalize(pStmt);
30469 pStmt = 0;
30470 rc = 1;
30471 }
30472 }
@@ -30492,14 +32440,14 @@
30492 }else
30493
30494 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
30495 int i;
30496 for(i=1; i<nArg; i++){
30497 if( i>1 ) sqlite3_fputs(" ", p->out);
30498 sqlite3_fputs(azArg[i], p->out);
30499 }
30500 sqlite3_fputs("\n", p->out);
30501 }else
30502
30503 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
30504 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){
30505 int i;
@@ -30532,11 +32480,11 @@
30532 }else{
30533 p->mxProgress = (int)integerValue(azArg[++i]);
30534 }
30535 continue;
30536 }
30537 sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]);
30538 rc = 1;
30539 goto meta_command_exit;
30540 }else{
30541 nn = (int)integerValue(z);
30542 }
@@ -30576,22 +32524,24 @@
30576 eputz("Error: pipes are not supported in this OS\n");
30577 rc = 1;
30578 #else
30579 p->in = sqlite3_popen(azArg[1]+1, "r");
30580 if( p->in==0 ){
30581 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30582 rc = 1;
30583 }else{
30584 rc = process_input(p, "<pipe>");
30585 pclose(p->in);
30586 }
30587 #endif
30588 }else if( (p->in = openChrSource(azArg[1]))==0 ){
30589 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30590 rc = 1;
30591 }else{
30592 rc = process_input(p, azArg[1]);
 
 
30593 fclose(p->in);
30594 }
30595 p->in = inSaved;
30596 p->lineno = savedLineno;
30597 }else
@@ -30617,11 +32567,11 @@
30617 rc = 1;
30618 goto meta_command_exit;
30619 }
30620 rc = sqlite3_open(zSrcFile, &pSrc);
30621 if( rc!=SQLITE_OK ){
30622 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile);
30623 close_db(pSrc);
30624 return 1;
30625 }
30626 open_db(p, 0);
30627 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
@@ -30655,25 +32605,25 @@
30655 (cli_strncmp(azArg[0], "scanstats", n)==0 ||
30656 cli_strncmp(azArg[0], "scanstatus", n)==0)
30657 ){
30658 if( nArg==2 ){
30659 if( cli_strcmp(azArg[1], "vm")==0 ){
30660 p->scanstatsOn = 3;
30661 }else
30662 if( cli_strcmp(azArg[1], "est")==0 ){
30663 p->scanstatsOn = 2;
30664 }else{
30665 p->scanstatsOn = (u8)booleanValue(azArg[1]);
30666 }
30667 open_db(p, 0);
30668 sqlite3_db_config(
30669 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
30670 );
30671 #if !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
30672 eputz("Warning: .scanstats not available in this build.\n");
30673 #elif !defined(SQLITE_ENABLE_BYTECODE_VTAB)
30674 if( p->scanstatsOn==3 ){
30675 eputz("Warning: \".scanstats vm\" not available in this build.\n");
30676 }
30677 #endif
30678 }else{
30679 eputz("Usage: .scanstats on|off|est\n");
@@ -30680,34 +32630,38 @@
30680 rc = 1;
30681 }
30682 }else
30683
30684 if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){
30685 ShellText sSelect;
30686 ShellState data;
30687 char *zErrMsg = 0;
30688 const char *zDiv = "(";
30689 const char *zName = 0;
30690 int iSchema = 0;
30691 int bDebug = 0;
30692 int bNoSystemTabs = 0;
 
30693 int ii;
30694
 
 
30695 open_db(p, 0);
30696 memcpy(&data, p, sizeof(data));
30697 data.showHeader = 0;
30698 data.cMode = data.mode = MODE_Semi;
30699 initText(&sSelect);
 
 
30700 for(ii=1; ii<nArg; ii++){
30701 if( optionMatch(azArg[ii],"indent") ){
30702 data.cMode = data.mode = MODE_Pretty;
30703 }else if( optionMatch(azArg[ii],"debug") ){
30704 bDebug = 1;
30705 }else if( optionMatch(azArg[ii],"nosys") ){
30706 bNoSystemTabs = 1;
30707 }else if( azArg[ii][0]=='-' ){
30708 sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]);
30709 rc = 1;
30710 goto meta_command_exit;
30711 }else if( zName==0 ){
30712 zName = azArg[ii];
30713 }else{
@@ -30720,100 +32674,87 @@
30720 int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
30721 || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
30722 || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
30723 || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
30724 if( isSchema ){
30725 char *new_argv[2], *new_colv[2];
30726 new_argv[0] = sqlite3_mprintf(
30727 "CREATE TABLE %s (\n"
30728 " type text,\n"
30729 " name text,\n"
30730 " tbl_name text,\n"
30731 " rootpage integer,\n"
30732 " sql text\n"
30733 ")", zName);
30734 shell_check_oom(new_argv[0]);
30735 new_argv[1] = 0;
30736 new_colv[0] = "sql";
30737 new_colv[1] = 0;
30738 callback(&data, 1, new_argv, new_colv);
30739 sqlite3_free(new_argv[0]);
30740 }
30741 }
30742 if( zDiv ){
30743 sqlite3_stmt *pStmt = 0;
30744 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
30745 -1, &pStmt, 0);
30746 if( rc ){
30747 shellDatabaseError(p->db);
30748 sqlite3_finalize(pStmt);
30749 rc = 1;
30750 goto meta_command_exit;
30751 }
30752 appendText(&sSelect, "SELECT sql FROM", 0);
30753 iSchema = 0;
30754 while( sqlite3_step(pStmt)==SQLITE_ROW ){
30755 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
30756 char zScNum[30];
30757 sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
30758 appendText(&sSelect, zDiv, 0);
30759 zDiv = " UNION ALL ";
30760 appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
30761 if( sqlite3_stricmp(zDb, "main")!=0 ){
30762 appendText(&sSelect, zDb, '\'');
30763 }else{
30764 appendText(&sSelect, "NULL", 0);
30765 }
30766 appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
30767 appendText(&sSelect, zScNum, 0);
30768 appendText(&sSelect, " AS snum, ", 0);
30769 appendText(&sSelect, zDb, '\'');
30770 appendText(&sSelect, " AS sname FROM ", 0);
30771 appendText(&sSelect, zDb, quoteChar(zDb));
30772 appendText(&sSelect, ".sqlite_schema", 0);
30773 }
30774 sqlite3_finalize(pStmt);
30775 #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
30776 if( zName ){
30777 appendText(&sSelect,
30778 " UNION ALL SELECT shell_module_schema(name),"
30779 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
30780 0);
30781 }
30782 #endif
30783 appendText(&sSelect, ") WHERE ", 0);
30784 if( zName ){
30785 char *zQarg = sqlite3_mprintf("%Q", zName);
30786 int bGlob;
30787 shell_check_oom(zQarg);
30788 bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
30789 strchr(zName, '[') != 0;
30790 if( strchr(zName, '.') ){
30791 appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
30792 }else{
30793 appendText(&sSelect, "lower(tbl_name)", 0);
30794 }
30795 appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
30796 appendText(&sSelect, zQarg, 0);
30797 if( !bGlob ){
30798 appendText(&sSelect, " ESCAPE '\\' ", 0);
30799 }
30800 appendText(&sSelect, " AND ", 0);
30801 sqlite3_free(zQarg);
30802 }
30803 if( bNoSystemTabs ){
30804 appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
30805 }
30806 appendText(&sSelect, "sql IS NOT NULL"
30807 " ORDER BY snum, rowid", 0);
30808 if( bDebug ){
30809 sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
30810 }else{
30811 rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
30812 }
30813 freeText(&sSelect);
30814 }
30815 if( zErrMsg ){
30816 shellEmitError(zErrMsg);
30817 sqlite3_free(zErrMsg);
30818 rc = 1;
30819 }else if( rc != SQLITE_OK ){
@@ -30865,11 +32806,11 @@
30865 session_not_open:
30866 eputz("ERROR: No sessions are open\n");
30867 }else{
30868 rc = sqlite3session_attach(pSession->p, azCmd[1]);
30869 if( rc ){
30870 sqlite3_fprintf(stderr,
30871 "ERROR: sqlite3session_attach() returns %d\n",rc);
30872 rc = 0;
30873 }
30874 }
30875 }else
@@ -30885,11 +32826,11 @@
30885 failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
30886 if( nCmd!=2 ) goto session_syntax_error;
30887 if( pSession->p==0 ) goto session_not_open;
30888 out = sqlite3_fopen(azCmd[1], "wb");
30889 if( out==0 ){
30890 sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n",
30891 azCmd[1]);
30892 }else{
30893 int szChng;
30894 void *pChng;
30895 if( azCmd[0][0]=='c' ){
@@ -30896,16 +32837,16 @@
30896 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
30897 }else{
30898 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
30899 }
30900 if( rc ){
30901 sqlite3_fprintf(stdout, "Error: error code %d\n", rc);
30902 rc = 0;
30903 }
30904 if( pChng
30905 && fwrite(pChng, szChng, 1, out)!=1 ){
30906 sqlite3_fprintf(stderr,
30907 "ERROR: Failed to write entire %d-byte output\n", szChng);
30908 }
30909 sqlite3_free(pChng);
30910 fclose(out);
30911 }
@@ -30929,11 +32870,11 @@
30929 int ii;
30930 if( nCmd>2 ) goto session_syntax_error;
30931 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
30932 if( pAuxDb->nSession ){
30933 ii = sqlite3session_enable(pSession->p, ii);
30934 sqlite3_fprintf(p->out,
30935 "session %s enable flag = %d\n", pSession->zName, ii);
30936 }
30937 }else
30938
30939 /* .session filter GLOB ....
@@ -30966,11 +32907,11 @@
30966 int ii;
30967 if( nCmd>2 ) goto session_syntax_error;
30968 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
30969 if( pAuxDb->nSession ){
30970 ii = sqlite3session_indirect(pSession->p, ii);
30971 sqlite3_fprintf(p->out,
30972 "session %s indirect flag = %d\n", pSession->zName, ii);
30973 }
30974 }else
30975
30976 /* .session isempty
@@ -30979,21 +32920,21 @@
30979 if( cli_strcmp(azCmd[0], "isempty")==0 ){
30980 int ii;
30981 if( nCmd!=1 ) goto session_syntax_error;
30982 if( pAuxDb->nSession ){
30983 ii = sqlite3session_isempty(pSession->p);
30984 sqlite3_fprintf(p->out,
30985 "session %s isempty flag = %d\n", pSession->zName, ii);
30986 }
30987 }else
30988
30989 /* .session list
30990 ** List all currently open sessions
30991 */
30992 if( cli_strcmp(azCmd[0],"list")==0 ){
30993 for(i=0; i<pAuxDb->nSession; i++){
30994 sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName);
30995 }
30996 }else
30997
30998 /* .session open DB NAME
30999 ** Open a new session called NAME on the attached database DB.
@@ -31004,23 +32945,23 @@
31004 if( nCmd!=3 ) goto session_syntax_error;
31005 zName = azCmd[2];
31006 if( zName[0]==0 ) goto session_syntax_error;
31007 for(i=0; i<pAuxDb->nSession; i++){
31008 if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){
31009 sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName);
31010 goto meta_command_exit;
31011 }
31012 }
31013 if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
31014 sqlite3_fprintf(stderr,
31015 "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
31016 goto meta_command_exit;
31017 }
31018 pSession = &pAuxDb->aSession[pAuxDb->nSession];
31019 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
31020 if( rc ){
31021 sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc);
31022 rc = 0;
31023 goto meta_command_exit;
31024 }
31025 pSession->nFilter = 0;
31026 sqlite3session_table_filter(pSession->p, session_filter, pSession);
@@ -31040,20 +32981,20 @@
31040 if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){
31041 if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){
31042 int i, v;
31043 for(i=1; i<nArg; i++){
31044 v = booleanValue(azArg[i]);
31045 sqlite3_fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
31046 }
31047 }
31048 if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){
31049 int i; sqlite3_int64 v;
31050 for(i=1; i<nArg; i++){
31051 char zBuf[200];
31052 v = integerValue(azArg[i]);
31053 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
31054 sqlite3_fputs(zBuf, p->out);
31055 }
31056 }
31057 }else
31058 #endif
31059
@@ -31076,13 +33017,13 @@
31076 }else
31077 if( cli_strcmp(z,"-v")==0 ){
31078 bVerbose++;
31079 }else
31080 {
31081 sqlite3_fprintf(stderr,
31082 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
31083 sqlite3_fputs("Should be one of: --init -v\n", stderr);
31084 rc = 1;
31085 goto meta_command_exit;
31086 }
31087 }
31088 if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
@@ -31123,61 +33064,59 @@
31123 if( zOp==0 ) continue;
31124 if( zSql==0 ) continue;
31125 if( zAns==0 ) continue;
31126 k = 0;
31127 if( bVerbose>0 ){
31128 sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql);
31129 }
31130 if( cli_strcmp(zOp,"memo")==0 ){
31131 sqlite3_fprintf(p->out, "%s\n", zSql);
31132 }else
31133 if( cli_strcmp(zOp,"run")==0 ){
31134 char *zErrMsg = 0;
31135 str.n = 0;
31136 str.zTxt[0] = 0;
31137 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
31138 nTest++;
31139 if( bVerbose ){
31140 sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt);
31141 }
31142 if( rc || zErrMsg ){
31143 nErr++;
31144 rc = 1;
31145 sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
31146 sqlite3_free(zErrMsg);
31147 }else if( cli_strcmp(zAns,str.zTxt)!=0 ){
31148 nErr++;
31149 rc = 1;
31150 sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
31151 sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
31152 }
31153 }
31154 else{
31155 sqlite3_fprintf(stderr,
31156 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
31157 rc = 1;
31158 break;
31159 }
31160 } /* End loop over rows of content from SELFTEST */
31161 sqlite3_finalize(pStmt);
31162 } /* End loop over k */
31163 freeText(&str);
31164 sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest);
31165 }else
31166
31167 if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){
31168 if( nArg<2 || nArg>3 ){
31169 eputz("Usage: .separator COL ?ROW?\n");
31170 rc = 1;
31171 }
31172 if( nArg>=2 ){
31173 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
31174 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
31175 }
31176 if( nArg>=3 ){
31177 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
31178 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
31179 }
31180 }else
31181
31182 if( c=='s' && n>=4 && cli_strncmp(azArg[0],"sha3sum",n)==0 ){
31183 const char *zLike = 0; /* Which table to checksum. 0 means everything */
@@ -31207,11 +33146,11 @@
31207 }else
31208 if( cli_strcmp(z,"debug")==0 ){
31209 bDebug = 1;
31210 }else
31211 {
31212 sqlite3_fprintf(stderr,
31213 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
31214 showHelp(p->out, azArg[0]);
31215 rc = 1;
31216 goto meta_command_exit;
31217 }
@@ -31286,11 +33225,11 @@
31286 }
31287 shell_check_oom(zSql);
31288 freeText(&sQuery);
31289 freeText(&sSql);
31290 if( bDebug ){
31291 sqlite3_fprintf(p->out, "%s\n", zSql);
31292 }else{
31293 shell_exec(p, zSql, 0);
31294 }
31295 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
31296 {
@@ -31316,11 +33255,11 @@
31316 "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
31317 "|| ' AND typeof('||cname||')=''text'' ',\n"
31318 "' OR ') as query, tname from tabcols group by tname)"
31319 , zRevText);
31320 shell_check_oom(zRevText);
31321 if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText);
31322 lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
31323 if( lrc!=SQLITE_OK ){
31324 /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the
31325 ** user does cruel and unnatural things like ".limit expr_depth 0". */
31326 rc = 1;
@@ -31329,19 +33268,19 @@
31329 lrc = SQLITE_ROW==sqlite3_step(pStmt);
31330 if( lrc ){
31331 const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
31332 sqlite3_stmt *pCheckStmt;
31333 lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
31334 if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery);
31335 if( lrc!=SQLITE_OK ){
31336 rc = 1;
31337 }else{
31338 if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
31339 double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
31340 if( countIrreversible>0 ){
31341 int sz = (int)(countIrreversible + 0.5);
31342 sqlite3_fprintf(stderr,
31343 "Digest includes %d invalidly encoded text field%s.\n",
31344 sz, (sz>1)? "s": "");
31345 }
31346 }
31347 sqlite3_finalize(pCheckStmt);
@@ -31376,11 +33315,11 @@
31376 }
31377 /*consoleRestore();*/
31378 x = zCmd!=0 ? system(zCmd) : 1;
31379 /*consoleRenewSetup();*/
31380 sqlite3_free(zCmd);
31381 if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x);
31382 }else
31383 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */
31384
31385 if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){
31386 static const char *azBool[] = { "off", "on", "trigger", "full"};
@@ -31389,52 +33328,55 @@
31389 if( nArg!=1 ){
31390 eputz("Usage: .show\n");
31391 rc = 1;
31392 goto meta_command_exit;
31393 }
31394 sqlite3_fprintf(p->out, "%12.12s: %s\n","echo",
31395 azBool[ShellHasFlag(p, SHFLG_Echo)]);
31396 sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
31397 sqlite3_fprintf(p->out, "%12.12s: %s\n","explain",
31398 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
31399 sqlite3_fprintf(p->out, "%12.12s: %s\n","headers",
31400 azBool[p->showHeader!=0]);
31401 if( p->mode==MODE_Column
31402 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
 
 
31403 ){
31404 sqlite3_fprintf(p->out,
31405 "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
31406 modeDescr[p->mode], p->cmOpts.iWrap,
31407 p->cmOpts.bWordWrap ? "on" : "off",
31408 p->cmOpts.bQuote ? "" : "no");
31409 }else{
31410 sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
 
31411 }
31412 sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue");
31413 output_c_string(p->out, p->nullValue);
31414 sqlite3_fputs("\n", p->out);
31415 sqlite3_fprintf(p->out, "%12.12s: %s\n","output",
31416 strlen30(p->outfile) ? p->outfile : "stdout");
31417 sqlite3_fprintf(p->out, "%12.12s: ", "colseparator");
31418 output_c_string(p->out, p->colSeparator);
31419 sqlite3_fputs("\n", p->out);
31420 sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator");
31421 output_c_string(p->out, p->rowSeparator);
31422 sqlite3_fputs("\n", p->out);
31423 switch( p->statsOn ){
31424 case 0: zOut = "off"; break;
31425 default: zOut = "on"; break;
31426 case 2: zOut = "stmt"; break;
31427 case 3: zOut = "vmstep"; break;
31428 }
31429 sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut);
31430 sqlite3_fprintf(p->out, "%12.12s: ", "width");
31431 for (i=0;i<p->nWidth;i++) {
31432 sqlite3_fprintf(p->out, "%d ", p->colWidth[i]);
31433 }
31434 sqlite3_fputs("\n", p->out);
31435 sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename",
31436 p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
31437 }else
31438
31439 if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){
31440 if( nArg==2 ){
@@ -31542,20 +33484,20 @@
31542 int nPrintCol, nPrintRow;
31543 for(i=0; i<nRow; i++){
31544 len = strlen30(azResult[i]);
31545 if( len>maxlen ) maxlen = len;
31546 }
31547 nPrintCol = 80/(maxlen+2);
31548 if( nPrintCol<1 ) nPrintCol = 1;
31549 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
31550 for(i=0; i<nPrintRow; i++){
31551 for(j=i; j<nRow; j+=nPrintRow){
31552 char *zSp = j<nPrintRow ? "" : " ";
31553 sqlite3_fprintf(p->out,
31554 "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
31555 }
31556 sqlite3_fputs("\n", p->out);
31557 }
31558 }
31559
31560 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
31561 sqlite3_free(azResult);
@@ -31563,11 +33505,11 @@
31563
31564 #ifndef SQLITE_SHELL_FIDDLE
31565 /* Begin redirecting output to the file "testcase-out.txt" */
31566 if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){
31567 output_reset(p);
31568 p->out = output_file_open("testcase-out.txt");
31569 if( p->out==0 ){
31570 eputz("Error: cannot open 'testcase-out.txt'\n");
31571 }
31572 if( nArg>=2 ){
31573 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
@@ -31626,14 +33568,14 @@
31626 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
31627 }
31628
31629 /* --help lists all test-controls */
31630 if( cli_strcmp(zCmd,"help")==0 ){
31631 sqlite3_fputs("Available test-controls:\n", p->out);
31632 for(i=0; i<ArraySize(aCtrl); i++){
31633 if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue;
31634 sqlite3_fprintf(p->out, " .testctrl %s %s\n",
31635 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
31636 }
31637 rc = 1;
31638 goto meta_command_exit;
31639 }
@@ -31646,19 +33588,19 @@
31646 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
31647 if( testctrl<0 ){
31648 testctrl = aCtrl[i].ctrlCode;
31649 iCtrl = i;
31650 }else{
31651 sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n"
31652 "Use \".testctrl --help\" for help\n", zCmd);
31653 rc = 1;
31654 goto meta_command_exit;
31655 }
31656 }
31657 }
31658 if( testctrl<0 ){
31659 sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n"
31660 "Use \".testctrl --help\" for help\n", zCmd);
31661 }else{
31662 switch(testctrl){
31663
31664 /* Special processing for .testctrl opt MASK ...
@@ -31734,17 +33676,17 @@
31734 int jj;
31735 for(jj=0; jj<ArraySize(aLabel); jj++){
31736 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
31737 }
31738 if( jj>=ArraySize(aLabel) ){
31739 sqlite3_fprintf(stderr,
31740 "Error: no such optimization: \"%s\"\n", zLabel);
31741 sqlite3_fputs("Should be one of:", stderr);
31742 for(jj=0; jj<ArraySize(aLabel); jj++){
31743 sqlite3_fprintf(stderr," %s", aLabel[jj].zLabel);
31744 }
31745 sqlite3_fputs("\n", stderr);
31746 rc = 1;
31747 goto meta_command_exit;
31748 }
31749 if( useLabel=='+' ){
31750 newOpt &= ~aLabel[jj].mask;
@@ -31758,27 +33700,27 @@
31758 }
31759 for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){
31760 if( m & newOpt ) nOff++;
31761 }
31762 if( nOff<12 ){
31763 sqlite3_fputs("+All", p->out);
31764 for(ii=0; ii<ArraySize(aLabel); ii++){
31765 if( !aLabel[ii].bDsply ) continue;
31766 if( (newOpt & aLabel[ii].mask)!=0 ){
31767 sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel);
31768 }
31769 }
31770 }else{
31771 sqlite3_fputs("-All", p->out);
31772 for(ii=0; ii<ArraySize(aLabel); ii++){
31773 if( !aLabel[ii].bDsply ) continue;
31774 if( (newOpt & aLabel[ii].mask)==0 ){
31775 sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel);
31776 }
31777 }
31778 }
31779 sqlite3_fputs("\n", p->out);
31780 rc2 = isOk = 3;
31781 break;
31782 }
31783
31784 /* sqlite3_test_control(int, db, int) */
@@ -31814,11 +33756,11 @@
31814 if( nArg==3 || nArg==4 ){
31815 int ii = (int)integerValue(azArg[2]);
31816 sqlite3 *db;
31817 if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){
31818 sqlite3_randomness(sizeof(ii),&ii);
31819 sqlite3_fprintf(stdout, "-- random seed: %d\n", ii);
31820 }
31821 if( nArg==3 ){
31822 db = 0;
31823 }else{
31824 db = p->db;
@@ -31867,11 +33809,11 @@
31867 break;
31868
31869 case SQLITE_TESTCTRL_SEEK_COUNT: {
31870 u64 x = 0;
31871 rc2 = sqlite3_test_control(testctrl, p->db, &x);
31872 sqlite3_fprintf(p->out, "%llu\n", x);
31873 isOk = 3;
31874 break;
31875 }
31876
31877 #ifdef YYCOVERAGE
@@ -31898,15 +33840,15 @@
31898 int id = 1;
31899 while(1){
31900 int val = 0;
31901 rc2 = sqlite3_test_control(testctrl, -id, &val);
31902 if( rc2!=SQLITE_OK ) break;
31903 if( id>1 ) sqlite3_fputs(" ", p->out);
31904 sqlite3_fprintf(p->out, "%d: %d", id, val);
31905 id++;
31906 }
31907 if( id>1 ) sqlite3_fputs("\n", p->out);
31908 isOk = 3;
31909 }
31910 break;
31911 }
31912 #endif
@@ -31941,11 +33883,11 @@
31941 const char *zTestArg;
31942 int nOp;
31943 int ii, jj, x;
31944 int *aOp;
31945 if( nArg!=4 ){
31946 sqlite3_fprintf(stderr,
31947 "ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n"
31948 );
31949 rc = 1;
31950 goto meta_command_exit;
31951 }
@@ -31964,11 +33906,11 @@
31964 x = 0;
31965 }
31966 }
31967 aOp[jj] = x;
31968 x = sqlite3_test_control(testctrl, iSize, aOp);
31969 sqlite3_fprintf(p->out, "result: %d\n", x);
31970 free(aOp);
31971 break;
31972 }
31973 case SQLITE_TESTCTRL_FAULT_INSTALL: {
31974 int kk;
@@ -31987,25 +33929,25 @@
31987 }else if( cli_strcmp(z,"reset")==0 ){
31988 faultsim_state.iCnt = faultsim_state.nSkip;
31989 faultsim_state.nHit = 0;
31990 sqlite3_test_control(testctrl, faultsim_callback);
31991 }else if( cli_strcmp(z,"status")==0 ){
31992 sqlite3_fprintf(p->out, "faultsim.iId: %d\n",
31993 faultsim_state.iId);
31994 sqlite3_fprintf(p->out, "faultsim.iErr: %d\n",
31995 faultsim_state.iErr);
31996 sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n",
31997 faultsim_state.iCnt);
31998 sqlite3_fprintf(p->out, "faultsim.nHit: %d\n",
31999 faultsim_state.nHit);
32000 sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n",
32001 faultsim_state.iInterval);
32002 sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n",
32003 faultsim_state.eVerbose);
32004 sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n",
32005 faultsim_state.nRepeat);
32006 sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n",
32007 faultsim_state.nSkip);
32008 }else if( cli_strcmp(z,"-v")==0 ){
32009 if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++;
32010 }else if( cli_strcmp(z,"-q")==0 ){
32011 if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--;
@@ -32020,20 +33962,20 @@
32020 }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){
32021 faultsim_state.nSkip = atoi(azArg[++kk]);
32022 }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){
32023 bShowHelp = 1;
32024 }else{
32025 sqlite3_fprintf(stderr,
32026 "Unrecognized fault_install argument: \"%s\"\n",
32027 azArg[kk]);
32028 rc = 1;
32029 bShowHelp = 1;
32030 break;
32031 }
32032 }
32033 if( bShowHelp ){
32034 sqlite3_fputs(
32035 "Usage: .testctrl fault_install ARGS\n"
32036 "Possible arguments:\n"
32037 " off Disable faultsim\n"
32038 " on Activate faultsim\n"
32039 " reset Reset the trigger counter\n"
@@ -32051,17 +33993,17 @@
32051 break;
32052 }
32053 }
32054 }
32055 if( isOk==0 && iCtrl>=0 ){
32056 sqlite3_fprintf(p->out,
32057 "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
32058 rc = 1;
32059 }else if( isOk==1 ){
32060 sqlite3_fprintf(p->out, "%d\n", rc2);
32061 }else if( isOk==2 ){
32062 sqlite3_fprintf(p->out, "0x%08x\n", rc2);
32063 }
32064 }else
32065 #endif /* !defined(SQLITE_UNTESTABLE) */
32066
32067 if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){
@@ -32112,17 +34054,17 @@
32112 }
32113 else if( optionMatch(z, "close") ){
32114 mType |= SQLITE_TRACE_CLOSE;
32115 }
32116 else {
32117 sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".trace\"\n", z);
32118 rc = 1;
32119 goto meta_command_exit;
32120 }
32121 }else{
32122 output_file_close(p->traceOut);
32123 p->traceOut = output_file_open(z);
32124 }
32125 }
32126 if( p->traceOut==0 ){
32127 sqlite3_trace_v2(p->db, 0, 0, 0);
32128 }else{
@@ -32157,38 +34099,38 @@
32157 }else
32158 #endif
32159
32160 if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
32161 char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
32162 sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
32163 sqlite3_libversion(), sqlite3_sourceid());
32164 #if SQLITE_HAVE_ZLIB
32165 sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion());
32166 #endif
32167 #define CTIMEOPT_VAL_(opt) #opt
32168 #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
32169 #if defined(__clang__) && defined(__clang_major__)
32170 sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
32171 CTIMEOPT_VAL(__clang_minor__) "."
32172 CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz);
32173 #elif defined(_MSC_VER)
32174 sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
32175 #elif defined(__GNUC__) && defined(__VERSION__)
32176 sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz);
32177 #endif
32178 }else
32179
32180 if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){
32181 const char *zDbName = nArg==2 ? azArg[1] : "main";
32182 sqlite3_vfs *pVfs = 0;
32183 if( p->db ){
32184 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
32185 if( pVfs ){
32186 sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
32187 sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
32188 sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
32189 sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
32190 }
32191 }
32192 }else
32193
32194 if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){
@@ -32196,17 +34138,17 @@
32196 sqlite3_vfs *pCurrent = 0;
32197 if( p->db ){
32198 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
32199 }
32200 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
32201 sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
32202 pVfs==pCurrent ? " <--- CURRENT" : "");
32203 sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
32204 sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
32205 sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
32206 if( pVfs->pNext ){
32207 sqlite3_fputs("-----------------------------------\n", p->out);
32208 }
32209 }
32210 }else
32211
32212 if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){
@@ -32213,11 +34155,11 @@
32213 const char *zDbName = nArg==2 ? azArg[1] : "main";
32214 char *zVfsName = 0;
32215 if( p->db ){
32216 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
32217 if( zVfsName ){
32218 sqlite3_fprintf(p->out, "%s\n", zVfsName);
32219 sqlite3_free(zVfsName);
32220 }
32221 }
32222 }else
32223
@@ -32226,33 +34168,32 @@
32226 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
32227 }else
32228
32229 if( c=='w' && cli_strncmp(azArg[0], "width", n)==0 ){
32230 int j;
32231 assert( nArg<=ArraySize(azArg) );
32232 p->nWidth = nArg-1;
32233 p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2);
32234 if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
32235 if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
32236 for(j=1; j<nArg; j++){
32237 i64 w = integerValue(azArg[j]);
32238 if( w < -30000 ) w = -30000;
32239 if( w > +30000 ) w = +30000;
32240 p->colWidth[j-1] = (int)w;
32241 }
32242 }else
32243
32244 {
32245 sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: "
32246 " \"%s\". Enter \".help\" for help\n", azArg[0]);
32247 rc = 1;
32248 }
32249
32250 meta_command_exit:
32251 if( p->outCount ){
32252 p->outCount--;
32253 if( p->outCount==0 ) output_reset(p);
32254 }
32255 p->bSafeMode = p->bSafeModePersist;
32256 return rc;
32257 }
32258
@@ -32513,29 +34454,29 @@
32513 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
32514 "%s near line %d:", zErrorType, startline);
32515 }else{
32516 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
32517 }
32518 sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail);
32519 sqlite3_free(zErrMsg);
32520 zErrMsg = 0;
32521 return 1;
32522 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
32523 char zLineBuf[2000];
32524 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
32525 "changes: %lld total_changes: %lld",
32526 sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
32527 sqlite3_fprintf(p->out, "%s\n", zLineBuf);
32528 }
32529
32530 if( doAutoDetectRestore(p, zSql) ) return 1;
32531 return 0;
32532 }
32533
32534 static void echo_group_input(ShellState *p, const char *zDo){
32535 if( ShellHasFlag(p, SHFLG_Echo) ){
32536 sqlite3_fprintf(p->out, "%s\n", zDo);
32537 fflush(p->out);
32538 }
32539 }
32540
32541 #ifdef SQLITE_SHELL_FIDDLE
@@ -32588,26 +34529,31 @@
32588 i64 nAlloc = 0; /* Allocated zSql[] space */
32589 int rc; /* Error code */
32590 int errCnt = 0; /* Number of errors seen */
32591 i64 startline = 0; /* Line number for start of current input */
32592 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
 
 
32593
32594 if( p->inputNesting==MAX_INPUT_NESTING ){
32595 /* This will be more informative in a later version. */
32596 sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
32597 " Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
32598 return 1;
32599 }
32600 ++p->inputNesting;
 
 
 
32601 p->lineno = 0;
32602 CONTINUE_PROMPT_RESET;
32603 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
32604 fflush(p->out);
32605 zLine = one_input_line(p->in, zLine, nSql>0);
32606 if( zLine==0 ){
32607 /* End of input */
32608 if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out);
32609 break;
32610 }
32611 if( seenInterrupt ){
32612 if( p->in!=0 ) break;
32613 seenInterrupt = 0;
@@ -32660,25 +34606,29 @@
32660 nSql += nLine;
32661 }
32662 if( nSql>0x7fff0000 ){
32663 char zSize[100];
32664 sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
32665 sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
32666 zSrc, startline, zSize);
32667 nSql = 0;
32668 errCnt++;
32669 break;
32670 }else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
32671 echo_group_input(p, zSql);
32672 errCnt += runOneSqlLine(p, zSql, p->in, startline);
32673 CONTINUE_PROMPT_RESET;
32674 nSql = 0;
32675 if( p->outCount ){
32676 output_reset(p);
32677 p->outCount = 0;
32678 }else{
32679 clearTempFile(p);
 
 
 
 
32680 }
32681 p->bSafeMode = p->bSafeModePersist;
32682 qss = QSS_Start;
32683 }else if( nSql && QSS_PLAINWHITE(qss) ){
32684 echo_group_input(p, zSql);
@@ -32693,10 +34643,12 @@
32693 CONTINUE_PROMPT_RESET;
32694 }
32695 free(zSql);
32696 free(zLine);
32697 --p->inputNesting;
 
 
32698 return errCnt>0;
32699 }
32700
32701 /*
32702 ** Return a pathname which is the user's home directory. A
@@ -32853,17 +34805,17 @@
32853 shell_check_oom(sqliterc);
32854 }
32855 p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
32856 if( p->in ){
32857 if( stdin_is_interactive ){
32858 sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
32859 }
32860 if( process_input(p, sqliterc) && bail_on_error ) exit(1);
32861 fclose(p->in);
32862 }else if( sqliterc_override!=0 ){
32863 sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
32864 if( bail_on_error ) exit(1);
32865 }
32866 p->in = inSaved;
32867 p->lineno = savedLineno;
32868 if( sqliterc != sqliterc_override ){
32869 sqlite3_free(sqliterc);
@@ -32881,12 +34833,13 @@
32881 " -append append the database to the end of the file\n"
32882 " -ascii set output mode to 'ascii'\n"
32883 " -bail stop after hitting an error\n"
32884 " -batch force batch I/O\n"
32885 " -box set output mode to 'box'\n"
32886 " -column set output mode to 'column'\n"
32887 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
 
 
32888 " -csv set output mode to 'csv'\n"
32889 #if !defined(SQLITE_OMIT_DESERIALIZE)
32890 " -deserialize open the database using sqlite3_deserialize()\n"
32891 #endif
32892 " -echo print inputs before execution\n"
@@ -32913,18 +34866,20 @@
32913 #ifdef SQLITE_ENABLE_MULTIPLEX
32914 " -multiplex enable the multiplexor VFS\n"
32915 #endif
32916 " -newline SEP set output row separator. Default: '\\n'\n"
32917 " -nofollow refuse to open symbolic links to database files\n"
 
32918 " -nonce STRING set the safe-mode escape nonce\n"
32919 " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
32920 " -nullvalue TEXT set text string for NULL values. Default ''\n"
32921 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
32922 " -pcachetrace trace all page cache operations\n"
32923 " -quote set output mode to 'quote'\n"
32924 " -readonly open the database read-only\n"
32925 " -safe enable safe-mode\n"
 
32926 " -separator SEP set output column separator. Default: '|'\n"
32927 #ifdef SQLITE_ENABLE_SORTER_REFERENCES
32928 " -sorterref SIZE sorter references threshold size\n"
32929 #endif
32930 " -stats print memory stats before each finalize\n"
@@ -32937,15 +34892,15 @@
32937 #ifdef SQLITE_HAVE_ZLIB
32938 " -zip open the file as a ZIP Archive\n"
32939 #endif
32940 ;
32941 static void usage(int showDetail){
32942 sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL...]]\n"
32943 "FILENAME is the name of an SQLite database. A new database is created\n"
32944 "if the file does not previously exist. Defaults to :memory:.\n", Argv0);
32945 if( showDetail ){
32946 sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions);
32947 }else{
32948 eputz("Use the -help option for additional information\n");
32949 }
32950 exit(0);
32951 }
@@ -32962,23 +34917,20 @@
32962 }
32963
32964 /*
32965 ** Initialize the state information in data
32966 */
32967 static void main_init(ShellState *data) {
32968 memset(data, 0, sizeof(*data));
32969 data->normalMode = data->cMode = data->mode = MODE_List;
32970 data->autoExplain = 1;
32971 #ifdef _WIN32
32972 data->crlfMode = 1;
32973 #endif
32974 data->pAuxDb = &data->aAuxDb[0];
32975 memcpy(data->colSeparator,SEP_Column, 2);
32976 memcpy(data->rowSeparator,SEP_Row, 2);
32977 data->showHeader = 0;
32978 data->shellFlgs = SHFLG_Lookaside;
32979 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
32980 #if !defined(SQLITE_SHELL_FIDDLE)
32981 verify_uninitialized();
32982 #endif
32983 sqlite3_config(SQLITE_CONFIG_URI, 1);
32984 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
@@ -33004,23 +34956,23 @@
33004 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
33005 #endif
33006 }
33007 #else
33008 static void printBold(const char *zText){
33009 sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText);
33010 }
33011 #endif
33012
33013 /*
33014 ** Get the argument to an --option. Throw an error and die if no argument
33015 ** is available.
33016 */
33017 static char *cmdline_option_value(int argc, char **argv, int i){
33018 if( i==argc ){
33019 sqlite3_fprintf(stderr,
33020 "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
33021 exit(1);
33022 }
33023 return argv[i];
33024 }
33025
33026 static void sayAbnormalExit(void){
@@ -33029,11 +34981,11 @@
33029
33030 /* Routine to output from vfstrace
33031 */
33032 static int vfstraceOut(const char *z, void *pArg){
33033 ShellState *p = (ShellState*)pArg;
33034 sqlite3_fputs(z, p->out);
33035 fflush(p->out);
33036 return 1;
33037 }
33038
33039 #ifndef SQLITE_SHELL_IS_UTF8
@@ -33067,14 +35019,16 @@
33067 const char *zInitFile = 0;
33068 int i;
33069 int rc = 0;
33070 int warnInmemoryDb = 0;
33071 int readStdin = 1;
 
33072 int nCmd = 0;
33073 int nOptsEnd = argc;
33074 int bEnableVfstrace = 0;
33075 char **azCmd = 0;
 
33076 const char *zVfs = 0; /* Value of -vfs command-line option */
33077 #if !SQLITE_SHELL_IS_UTF8
33078 char **argvToFree = 0;
33079 int argcToFree = 0;
33080 #endif
@@ -33094,11 +35048,11 @@
33094 #endif
33095 #if !defined(_WIN32_WCE)
33096 if( getenv("SQLITE_DEBUG_BREAK") ){
33097 if( isatty(0) && isatty(2) ){
33098 char zLine[100];
33099 sqlite3_fprintf(stderr,
33100 "attach debugger to process %d and press ENTER to continue...",
33101 GETPID());
33102 if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0
33103 && cli_strcmp(zLine,"stop")==0
33104 ){
@@ -33126,11 +35080,11 @@
33126 }
33127 #endif
33128
33129 #if USE_SYSTEM_SQLITE+0!=1
33130 if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
33131 sqlite3_fprintf(stderr,
33132 "SQLite header and source version mismatch\n%s\n%s\n",
33133 sqlite3_sourceid(), SQLITE_SOURCE_ID);
33134 exit(1);
33135 }
33136 #endif
@@ -33193,14 +35147,18 @@
33193 data.aAuxDb->zDbFilename = z;
33194 }else{
33195 /* Excess arguments are interpreted as SQL (or dot-commands) and
33196 ** mean that nothing is read from stdin */
33197 readStdin = 0;
 
33198 nCmd++;
33199 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
33200 shell_check_oom(azCmd);
 
 
33201 azCmd[nCmd-1] = z;
 
33202 }
33203 continue;
33204 }
33205 if( z[1]=='-' ) z++;
33206 if( cli_strcmp(z, "-")==0 ){
@@ -33219,10 +35177,24 @@
33219 /* Need to check for batch mode here to so we can avoid printing
33220 ** informational messages (like from process_sqliterc) before
33221 ** we do the actual processing of arguments later in a second pass.
33222 */
33223 stdin_is_interactive = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33224 }else if( cli_strcmp(z,"-utf8")==0 ){
33225 }else if( cli_strcmp(z,"-no-utf8")==0 ){
33226 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
33227 int val = 0;
33228 sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val);
@@ -33252,11 +35224,11 @@
33252 if( sz>0 && (sz & (sz-1))==0 ){
33253 /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */
33254 int szHdr = 0;
33255 sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr);
33256 sz += szHdr;
33257 sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate"
33258 " the %d-byte headers\n", (int)sz, szHdr);
33259 }
33260 verify_uninitialized();
33261 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
33262 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
@@ -33313,10 +35285,12 @@
33313 }else if( cli_strcmp(z,"-readonly")==0 ){
33314 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
33315 data.openFlags |= SQLITE_OPEN_READONLY;
33316 }else if( cli_strcmp(z,"-nofollow")==0 ){
33317 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
 
 
33318 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
33319 data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
33320 }else if( cli_strcmp(z,"-ifexists")==0 ){
33321 data.openFlags &= ~(SQLITE_OPEN_CREATE);
33322 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
@@ -33367,21 +35341,21 @@
33367 if( zVfs ){
33368 sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
33369 if( pVfs ){
33370 sqlite3_vfs_register(pVfs, 1);
33371 }else{
33372 sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs);
33373 exit(1);
33374 }
33375 }
33376
33377 if( data.pAuxDb->zDbFilename==0 ){
33378 #ifndef SQLITE_OMIT_MEMORYDB
33379 data.pAuxDb->zDbFilename = ":memory:";
33380 warnInmemoryDb = argc==1;
33381 #else
33382 sqlite3_fprintf(stderr,
33383 "%s: Error: no database filename specified\n", Argv0);
33384 return 1;
33385 #endif
33386 }
33387 data.out = stdout;
@@ -33389,10 +35363,11 @@
33389 vfstrace_register("trace",0,vfstraceOut, &data, 1);
33390 }
33391 #ifndef SQLITE_SHELL_FIDDLE
33392 sqlite3_appendvfs_init(0,0,0);
33393 #endif
 
33394
33395 /* Go ahead and open the database file if it already exists. If the
33396 ** file does not exist, delay opening it. This prevents empty database
33397 ** files from being created if a user mistypes the database name argument
33398 ** to the sqlite command-line tool.
@@ -33403,11 +35378,11 @@
33403
33404 /* Process the initialization file if there is one. If no -init option
33405 ** is given on the command line, look for a file named ~/.sqliterc and
33406 ** try to process it.
33407 */
33408 process_sqliterc(&data,zInitFile);
33409
33410 /* Make a second pass through the command-line argument and set
33411 ** options. This second pass is delayed until after the initialization
33412 ** file is processed so that the command-line arguments will override
33413 ** settings in the initialization file.
@@ -33417,49 +35392,46 @@
33417 if( z[0]!='-' || i>=nOptsEnd ) continue;
33418 if( z[1]=='-' ){ z++; }
33419 if( cli_strcmp(z,"-init")==0 ){
33420 i++;
33421 }else if( cli_strcmp(z,"-html")==0 ){
33422 data.mode = MODE_Html;
33423 }else if( cli_strcmp(z,"-list")==0 ){
33424 data.mode = MODE_List;
33425 }else if( cli_strcmp(z,"-quote")==0 ){
33426 data.mode = MODE_Quote;
33427 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
33428 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
33429 }else if( cli_strcmp(z,"-line")==0 ){
33430 data.mode = MODE_Line;
33431 }else if( cli_strcmp(z,"-column")==0 ){
33432 data.mode = MODE_Column;
33433 }else if( cli_strcmp(z,"-json")==0 ){
33434 data.mode = MODE_Json;
33435 }else if( cli_strcmp(z,"-markdown")==0 ){
33436 data.mode = MODE_Markdown;
33437 }else if( cli_strcmp(z,"-table")==0 ){
33438 data.mode = MODE_Table;
33439 }else if( cli_strcmp(z,"-box")==0 ){
33440 data.mode = MODE_Box;
33441 }else if( cli_strcmp(z,"-csv")==0 ){
33442 data.mode = MODE_Csv;
33443 memcpy(data.colSeparator,",",2);
33444 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
33445 /* See similar code at tag-20250224-1 */
33446 const char *zEsc = argv[++i];
33447 int k;
33448 for(k=0; k<ArraySize(shell_EscModeNames); k++){
33449 if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){
33450 data.eEscMode = k;
33451 break;
33452 }
33453 }
33454 if( k>=ArraySize(shell_EscModeNames) ){
33455 sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
33456 " - choices:", zEsc);
33457 for(k=0; k<ArraySize(shell_EscModeNames); k++){
33458 sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
33459 }
33460 sqlite3_fprintf(stderr, "\n");
33461 exit(1);
33462 }
33463 #ifdef SQLITE_HAVE_ZLIB
33464 }else if( cli_strcmp(z,"-zip")==0 ){
33465 data.openMode = SHELL_OPEN_ZIPFILE;
@@ -33475,48 +35447,44 @@
33475 }else if( cli_strcmp(z,"-readonly")==0 ){
33476 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
33477 data.openFlags |= SQLITE_OPEN_READONLY;
33478 }else if( cli_strcmp(z,"-nofollow")==0 ){
33479 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
 
 
33480 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
33481 data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
33482 }else if( cli_strcmp(z,"-ifexists")==0 ){
33483 data.openFlags &= ~(SQLITE_OPEN_CREATE);
33484 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
33485 }else if( cli_strcmp(z,"-ascii")==0 ){
33486 data.mode = MODE_Ascii;
33487 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit);
33488 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record);
33489 }else if( cli_strcmp(z,"-tabs")==0 ){
33490 data.mode = MODE_List;
33491 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab);
33492 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row);
33493 }else if( cli_strcmp(z,"-separator")==0 ){
33494 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
33495 "%s",cmdline_option_value(argc,argv,++i));
33496 }else if( cli_strcmp(z,"-newline")==0 ){
33497 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
33498 "%s",cmdline_option_value(argc,argv,++i));
33499 }else if( cli_strcmp(z,"-nullvalue")==0 ){
33500 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
33501 "%s",cmdline_option_value(argc,argv,++i));
33502 }else if( cli_strcmp(z,"-header")==0 ){
33503 data.showHeader = 1;
33504 ShellSetFlag(&data, SHFLG_HeaderSet);
33505 }else if( cli_strcmp(z,"-noheader")==0 ){
33506 data.showHeader = 0;
33507 ShellSetFlag(&data, SHFLG_HeaderSet);
33508 }else if( cli_strcmp(z,"-echo")==0 ){
33509 ShellSetFlag(&data, SHFLG_Echo);
33510 }else if( cli_strcmp(z,"-eqp")==0 ){
33511 data.autoEQP = AUTOEQP_on;
33512 }else if( cli_strcmp(z,"-eqpfull")==0 ){
33513 data.autoEQP = AUTOEQP_full;
33514 }else if( cli_strcmp(z,"-stats")==0 ){
33515 data.statsOn = 1;
33516 }else if( cli_strcmp(z,"-scanstats")==0 ){
33517 data.scanstatsOn = 1;
33518 }else if( cli_strcmp(z,"-backslash")==0 ){
33519 /* Undocumented command-line option: -backslash
33520 ** Causes C-style backslash escapes to be evaluated in SQL statements
33521 ** prior to sending the SQL into SQLite. Useful for injecting
33522 ** crazy bytes in the middle of SQL statements for testing and debugging.
@@ -33523,20 +35491,24 @@
33523 */
33524 ShellSetFlag(&data, SHFLG_Backslash);
33525 }else if( cli_strcmp(z,"-bail")==0 ){
33526 /* No-op. The bail_on_error flag should already be set. */
33527 }else if( cli_strcmp(z,"-version")==0 ){
33528 sqlite3_fprintf(stdout, "%s %s (%d-bit)\n",
33529 sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
33530 return 0;
33531 }else if( cli_strcmp(z,"-interactive")==0 ){
33532 /* Need to check for interactive override here to so that it can
33533 ** affect console setup (for Windows only) and testing thereof.
33534 */
33535 stdin_is_interactive = 1;
33536 }else if( cli_strcmp(z,"-batch")==0 ){
33537 /* already handled */
 
 
 
 
33538 }else if( cli_strcmp(z,"-utf8")==0 ){
33539 /* already handled */
33540 }else if( cli_strcmp(z,"-no-utf8")==0 ){
33541 /* already handled */
33542 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
@@ -33584,20 +35556,21 @@
33584 }else{
33585 open_db(&data, 0);
33586 rc = shell_exec(&data, z, &zErrMsg);
33587 if( zErrMsg!=0 ){
33588 shellEmitError(zErrMsg);
 
33589 if( bail_on_error ) return rc!=0 ? rc : 1;
33590 }else if( rc!=0 ){
33591 sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
33592 if( bail_on_error ) return rc;
33593 }
33594 }
33595 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
33596 }else if( cli_strncmp(z, "-A", 2)==0 ){
33597 if( nCmd>0 ){
33598 sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands"
33599 " with \"%s\"\n", z);
33600 return 1;
33601 }
33602 open_db(&data, OPEN_DB_ZIPFILE);
33603 if( z[2] ){
@@ -33605,22 +35578,22 @@
33605 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
33606 }else{
33607 arDotCommand(&data, 1, argv+i, argc-i);
33608 }
33609 readStdin = 0;
 
33610 break;
33611 #endif
33612 }else if( cli_strcmp(z,"-safe")==0 ){
33613 data.bSafeMode = data.bSafeModePersist = 1;
33614 }else if( cli_strcmp(z,"-unsafe-testing")==0 ){
33615 /* Acted upon in first pass. */
33616 }else{
33617 sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
33618 eputz("Use -help for a list of options.\n");
33619 return 1;
33620 }
33621 data.cMode = data.mode;
33622 }
33623
33624 if( !readStdin ){
33625 /* Run all arguments that do not begin with '-' as if they were separate
33626 ** command-line inputs, except for the argToSkip argument which contains
@@ -33627,11 +35600,18 @@
33627 ** the database filename.
33628 */
33629 for(i=0; i<nCmd; i++){
33630 echo_group_input(&data, azCmd[i]);
33631 if( azCmd[i][0]=='.' ){
 
 
 
 
 
33632 rc = do_meta_command(azCmd[i], &data);
 
 
33633 if( rc ){
33634 if( rc==2 ) rc = 0;
33635 goto shell_main_exit;
33636 }
33637 }else{
@@ -33639,11 +35619,11 @@
33639 rc = shell_exec(&data, azCmd[i], &zErrMsg);
33640 if( zErrMsg || rc ){
33641 if( zErrMsg!=0 ){
33642 shellEmitError(zErrMsg);
33643 }else{
33644 sqlite3_fprintf(stderr,
33645 "Error: unable to process SQL: %s\n", azCmd[i]);
33646 }
33647 sqlite3_free(zErrMsg);
33648 if( rc==0 ) rc = 1;
33649 goto shell_main_exit;
@@ -33654,11 +35634,11 @@
33654 /* Run commands received from standard input
33655 */
33656 if( stdin_is_interactive ){
33657 char *zHome;
33658 char *zHistory;
33659 sqlite3_fprintf(stdout,
33660 "SQLite version %s %.19s\n" /*extra-version-info*/
33661 "Enter \".help\" for usage hints.\n",
33662 sqlite3_libversion(), sqlite3_sourceid());
33663 if( warnInmemoryDb ){
33664 sputz(stdout, "Connected to a ");
@@ -33707,10 +35687,11 @@
33707 expertFinish(&data, 1, 0);
33708 }
33709 #endif
33710 shell_main_exit:
33711 free(azCmd);
 
33712 set_table_name(&data, 0);
33713 if( data.db ){
33714 session_close_all(&data, -1);
33715 close_db(data.db);
33716 }
@@ -33727,21 +35708,41 @@
33727 clearTempFile(&data);
33728 #if !SQLITE_SHELL_IS_UTF8
33729 for(i=0; i<argcToFree; i++) free(argvToFree[i]);
33730 free(argvToFree);
33731 #endif
33732 free(data.colWidth);
 
 
 
 
 
 
 
 
 
33733 free(data.zNonce);
 
 
 
 
 
 
 
 
 
 
 
33734 /* Clear the global data structure so that valgrind will detect memory
33735 ** leaks */
33736 memset(&data, 0, sizeof(data));
33737 if( bEnableVfstrace ){
33738 vfstrace_unregister("trace");
33739 }
33740 #ifdef SQLITE_DEBUG
33741 if( sqlite3_memory_used()>mem_main_enter ){
33742 sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n",
33743 (unsigned int)(sqlite3_memory_used()-mem_main_enter));
33744 }
33745 #endif
33746 #else /* SQLITE_SHELL_FIDDLE... */
33747 shell_main_exit:
@@ -33777,11 +35778,11 @@
33777 return pVfs;
33778 }
33779
33780 /* Only for emcc experimentation purposes. */
33781 sqlite3 * fiddle_db_arg(sqlite3 *arg){
33782 sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg);
33783 return arg;
33784 }
33785
33786 /*
33787 ** Intended to be called via a SharedWorker() while a separate
@@ -33814,11 +35815,11 @@
33814 while( sqlite3_txn_state(globalDb,0)>0 ){
33815 /*
33816 ** Resolve problem reported in
33817 ** https://sqlite.org/forum/forumpost/0b41a25d65
33818 */
33819 sqlite3_fputs("Rolling back in-progress transaction.\n", stdout);
33820 sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0);
33821 }
33822 rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
33823 if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0);
33824 sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
@@ -33881,5 +35882,6 @@
33881 process_input(&shellState, "<stdin>");
33882 shellState.wasm.zInput = shellState.wasm.zPos = 0;
33883 }
33884 }
33885 #endif /* SQLITE_SHELL_FIDDLE */
 
33886
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1,23 +1,47 @@
1 /*
2 ** This is the amalgamated source code to the "sqlite3" or "sqlite3.exe"
3 ** command-line shell (CLI) for SQLite. This file is automatically
4 ** generated by the tool/mkshellc.tcl script from the following sources:
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/fileio.c
16 ** ext/misc/ieee754.c
17 ** ext/misc/memtrace.c
18 ** ext/misc/pcachetrace.c
19 ** ext/misc/regexp.c
20 ** ext/misc/series.c
21 ** ext/misc/sha1.c
22 ** ext/misc/shathree.c
23 ** ext/misc/sqlar.c
24 ** ext/misc/sqlite3_stdio.c
25 ** ext/misc/sqlite3_stdio.h
26 ** ext/misc/stmtrand.c
27 ** ext/misc/uint.c
28 ** ext/misc/vfstrace.c
29 ** ext/misc/windirent.h
30 ** ext/misc/zipfile.c
31 ** ext/qrf/qrf.c
32 ** ext/qrf/qrf.h
33 ** ext/recover/dbdata.c
34 ** ext/recover/sqlite3recover.c
35 ** ext/recover/sqlite3recover.h
36 ** src/shell.c.in
37 **
38 ** To modify this program, get a copy of the canonical SQLite source tree,
39 ** edit the src/shell.c.in file and/or some of the other files that are
40 ** listed above, then rerun the rerun "make shell.c".
41 */
42 /************************* Begin src/shell.c.in ******************/
43 /*
44 ** 2001 September 15
45 **
46 ** The author disclaims copyright to this source code. In place of
47 ** a legal notice, here is a blessing:
@@ -124,10 +148,11 @@
148 typedef unsigned char u8;
149 #include <ctype.h>
150 #include <stdarg.h>
151 #ifndef _WIN32
152 # include <sys/time.h>
153 # include <sys/ioctl.h>
154 #endif
155
156 #if !defined(_WIN32) && !defined(WIN32)
157 # include <signal.h>
158 # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
@@ -253,11 +278,11 @@
278 /* string conversion routines only needed on Win32 */
279 extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
280 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
281 #endif
282
283 /************************* Begin ext/misc/sqlite3_stdio.h ******************/
284 /*
285 ** 2024-09-24
286 **
287 ** The author disclaims copyright to this source code. In place of
288 ** a legal notice, here is a blessing:
@@ -287,17 +312,19 @@
312 #ifndef _SQLITE3_STDIO_H_
313 #define _SQLITE3_STDIO_H_ 1
314 #ifdef _WIN32
315 /**** Definitions For Windows ****/
316 #include <stdio.h>
317 #include <stdarg.h>
318 #include <windows.h>
319
320 FILE *sqlite3_fopen(const char *zFilename, const char *zMode);
321 FILE *sqlite3_popen(const char *zCommand, const char *type);
322 char *sqlite3_fgets(char *s, int size, FILE *stream);
323 int sqlite3_fputs(const char *s, FILE *stream);
324 int sqlite3_fprintf(FILE *stream, const char *format, ...);
325 int sqlite3_vfprintf(FILE *stream, const char *format, va_list);
326 void sqlite3_fsetmode(FILE *stream, int mode);
327
328
329 #else
330 /**** Definitions For All Other Platforms ****/
@@ -305,17 +332,18 @@
332 #define sqlite3_fopen fopen
333 #define sqlite3_popen popen
334 #define sqlite3_fgets fgets
335 #define sqlite3_fputs fputs
336 #define sqlite3_fprintf fprintf
337 #define sqlite3_vfprintf vfprintf
338 #define sqlite3_fsetmode(F,X) /*no-op*/
339
340 #endif
341 #endif /* _SQLITE3_STDIO_H_ */
342
343 /************************* End ext/misc/sqlite3_stdio.h ********************/
344 /************************* Begin ext/misc/sqlite3_stdio.c ******************/
345 /*
346 ** 2024-09-24
347 **
348 ** The author disclaims copyright to this source code. In place of
349 ** a legal notice, here is a blessing:
@@ -572,11 +600,11 @@
600 }
601 }
602
603
604 /*
605 ** Work-alikes for fprintf() and vfprintf() from the standard C library.
606 */
607 int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
608 int rc;
609 if( UseWtextForOutput(out) ){
610 /* When writing to the command-prompt in Windows, it is necessary
@@ -599,10 +627,28 @@
627 rc = vfprintf(out, zFormat, ap);
628 va_end(ap);
629 }
630 return rc;
631 }
632 int sqlite3_vfprintf(FILE *out, const char *zFormat, va_list ap){
633 int rc;
634 if( UseWtextForOutput(out) ){
635 /* When writing to the command-prompt in Windows, it is necessary
636 ** to use _O_WTEXT input mode and write UTF-16 characters.
637 */
638 char *z;
639 z = sqlite3_vmprintf(zFormat, ap);
640 sqlite3_fputs(z, out);
641 rc = (int)strlen(z);
642 sqlite3_free(z);
643 }else{
644 /* Writing to a file or other destination, just write bytes without
645 ** any translation. */
646 rc = vfprintf(out, zFormat, ap);
647 }
648 return rc;
649 }
650
651 /*
652 ** Set the mode for an output stream. mode argument is typically _O_BINARY or
653 ** _O_TEXT.
654 */
@@ -617,11 +663,2697 @@
663 }
664 }
665
666 #endif /* defined(_WIN32) */
667
668 /************************* End ext/misc/sqlite3_stdio.c ********************/
669 /************************* Begin ext/qrf/qrf.h ******************/
670 /*
671 ** 2025-10-20
672 **
673 ** The author disclaims copyright to this source code. In place of
674 ** a legal notice, here is a blessing:
675 **
676 ** May you do good and not evil.
677 ** May you find forgiveness for yourself and forgive others.
678 ** May you share freely, never taking more than you give.
679 **
680 *************************************************************************
681 ** Header file for the Result-Format or "resfmt" utility library for SQLite.
682 ** See the resfmt.md documentation for additional information.
683 */
684 #ifndef SQLITE_QRF_H
685 #define SQLITE_QRF_H
686 #include <stdlib.h>
687 /* #include "sqlite3.h" */
688
689 /*
690 ** Specification used by clients to define the output format they want
691 */
692 typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
693 struct sqlite3_qrf_spec {
694 unsigned char iVersion; /* Version number of this structure */
695 unsigned char eStyle; /* Formatting style. "box", "csv", etc... */
696 unsigned char eEsc; /* How to escape control characters in text */
697 unsigned char eText; /* Quoting style for text */
698 unsigned char eTitle; /* Quating style for the text of column names */
699 unsigned char eBlob; /* Quoting style for BLOBs */
700 unsigned char bTitles; /* True to show column names */
701 unsigned char bWordWrap; /* Try to wrap on word boundaries */
702 unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
703 unsigned char bTextNull; /* Apply eText encoding to zNull[] */
704 unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
705 unsigned char eTitleAlign; /* Alignment for column headers */
706 short int nWrap; /* Wrap columns wider than this */
707 short int nScreenWidth; /* Maximum overall table width */
708 short int nLineLimit; /* Maximum number of lines for any row */
709 int nCharLimit; /* Maximum number of characters in a cell */
710 int nWidth; /* Number of entries in aWidth[] */
711 int nAlign; /* Number of entries in aAlignment[] */
712 short int *aWidth; /* Column widths */
713 unsigned char *aAlign; /* Column alignments */
714 char *zColumnSep; /* Alternative column separator */
715 char *zRowSep; /* Alternative row separator */
716 char *zTableName; /* Output table name */
717 char *zNull; /* Rendering of NULL */
718 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
719 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
720 void *pRenderArg; /* First argument to the xRender callback */
721 void *pWriteArg; /* First argument to the xWrite callback */
722 char **pzOutput; /* Storage location for output string */
723 /* Additional fields may be added in the future */
724 };
725
726 /*
727 ** Interfaces
728 */
729 int sqlite3_format_query_result(
730 sqlite3_stmt *pStmt, /* SQL statement to run */
731 const sqlite3_qrf_spec *pSpec, /* Result format specification */
732 char **pzErr /* OUT: Write error message here */
733 );
734
735 /*
736 ** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
737 ** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
738 */
739 #define QRF_MAX_WIDTH 10000
740 #define QRF_MIN_WIDTH 0
741
742 /*
743 ** Output styles:
744 */
745 #define QRF_STYLE_Auto 0 /* Choose a style automatically */
746 #define QRF_STYLE_Box 1 /* Unicode box-drawing characters */
747 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
748 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
749 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
750 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
751 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
752 #define QRF_STYLE_Html 7 /* Generate an XHTML table */
753 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
754 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
755 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
756 #define QRF_STYLE_Line 11 /* One column per line. */
757 #define QRF_STYLE_List 12 /* One record per line with a separator */
758 #define QRF_STYLE_Markdown 13 /* Markdown formatting */
759 #define QRF_STYLE_Off 14 /* No query output shown */
760 #define QRF_STYLE_Quote 15 /* SQL-quoted, comma-separated */
761 #define QRF_STYLE_Stats 16 /* EQP-like output but with performance stats */
762 #define QRF_STYLE_StatsEst 17 /* EQP-like output with planner estimates */
763 #define QRF_STYLE_StatsVm 18 /* EXPLAIN-like output with performance stats */
764 #define QRF_STYLE_Table 19 /* MySQL-style table formatting */
765
766 /*
767 ** Quoting styles for text.
768 ** Allowed values for sqlite3_qrf_spec.eText
769 */
770 #define QRF_TEXT_Auto 0 /* Choose text encoding automatically */
771 #define QRF_TEXT_Plain 1 /* Literal text */
772 #define QRF_TEXT_Sql 2 /* Quote as an SQL literal */
773 #define QRF_TEXT_Csv 3 /* CSV-style quoting */
774 #define QRF_TEXT_Html 4 /* HTML-style quoting */
775 #define QRF_TEXT_Tcl 5 /* C/Tcl quoting */
776 #define QRF_TEXT_Json 6 /* JSON quoting */
777
778 /*
779 ** Quoting styles for BLOBs
780 ** Allowed values for sqlite3_qrf_spec.eBlob
781 */
782 #define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eText */
783 #define QRF_BLOB_Text 1 /* Display content exactly as it is */
784 #define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
785 #define QRF_BLOB_Hex 3 /* Hexadecimal representation */
786 #define QRF_BLOB_Tcl 4 /* "\000" notation */
787 #define QRF_BLOB_Json 5 /* A JSON string */
788
789 /*
790 ** Control-character escape modes.
791 ** Allowed values for sqlite3_qrf_spec.eEsc
792 */
793 #define QRF_ESC_Auto 0 /* Choose the ctrl-char escape automatically */
794 #define QRF_ESC_Off 1 /* Do not escape control characters */
795 #define QRF_ESC_Ascii 2 /* Unix-style escapes. Ex: U+0007 shows ^G */
796 #define QRF_ESC_Symbol 3 /* Unicode escapes. Ex: U+0007 shows U+2407 */
797
798 /*
799 ** Allowed values for "boolean" fields, such as "bColumnNames", "bWordWrap",
800 ** and "bTextJsonb". There is an extra "auto" variants so these are actually
801 ** tri-state settings, not booleans.
802 */
803 #define QRF_SW_Auto 0 /* Let QRF choose the best value */
804 #define QRF_SW_Off 1 /* This setting is forced off */
805 #define QRF_SW_On 2 /* This setting is forced on */
806 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
807 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
808 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
809
810 /*
811 ** Possible alignment values alignment settings
812 **
813 ** Horizontal Vertial
814 ** ---------- -------- */
815 #define QRF_ALIGN_Auto 0 /* auto auto */
816 #define QRF_ALIGN_Left 1 /* left auto */
817 #define QRF_ALIGN_Center 2 /* center auto */
818 #define QRF_ALIGN_Right 3 /* right auto */
819 #define QRF_ALIGN_Top 4 /* auto top */
820 #define QRF_ALIGN_NW 5 /* left top */
821 #define QRF_ALIGN_N 6 /* center top */
822 #define QRF_ALIGN_NE 7 /* right top */
823 #define QRF_ALIGN_Middle 8 /* auto middle */
824 #define QRF_ALIGN_W 9 /* left middle */
825 #define QRF_ALIGN_C 10 /* center middle */
826 #define QRF_ALIGN_E 11 /* right middle */
827 #define QRF_ALIGN_Bottom 12 /* auto bottom */
828 #define QRF_ALIGN_SW 13 /* left bottom */
829 #define QRF_ALIGN_S 14 /* center bottom */
830 #define QRF_ALIGN_SE 15 /* right bottom */
831 #define QRF_ALIGN_HMASK 3 /* Horizontal alignment mask */
832 #define QRF_ALIGN_VMASK 12 /* Vertical alignment mask */
833
834 /*
835 ** Auxiliary routines contined within this module that might be useful
836 ** in other contexts, and which are therefore exported.
837 */
838 /*
839 ** Return an estimate of the width, in columns, for the single Unicode
840 ** character c. For normal characters, the answer is always 1. But the
841 ** estimate might be 0 or 2 for zero-width and double-width characters.
842 **
843 ** Different display devices display unicode using different widths. So
844 ** it is impossible to know that true display width with 100% accuracy.
845 ** Inaccuracies in the width estimates might cause columns to be misaligned.
846 ** Unfortunately, there is nothing we can do about that.
847 */
848 int sqlite3_qrf_wcwidth(int c);
849
850
851
852
853 #endif /* !defined(SQLITE_QRF_H) */
854
855 /************************* End ext/qrf/qrf.h ********************/
856 /************************* Begin ext/qrf/qrf.c ******************/
857 /*
858 ** 2025-10-20
859 **
860 ** The author disclaims copyright to this source code. In place of
861 ** a legal notice, here is a blessing:
862 **
863 ** May you do good and not evil.
864 ** May you find forgiveness for yourself and forgive others.
865 ** May you share freely, never taking more than you give.
866 **
867 *************************************************************************
868 ** Implementation of the Result-Format or "qrf" utility library for SQLite.
869 ** See the qrf.md documentation for additional information.
870 */
871 #ifndef SQLITE_QRF_H
872 #include "qrf.h"
873 #endif
874 #include <string.h>
875 #include <assert.h>
876
877 /* typedef sqlite3_int64 i64; */
878
879 /* A single line in the EQP output */
880 typedef struct qrfEQPGraphRow qrfEQPGraphRow;
881 struct qrfEQPGraphRow {
882 int iEqpId; /* ID for this row */
883 int iParentId; /* ID of the parent row */
884 qrfEQPGraphRow *pNext; /* Next row in sequence */
885 char zText[1]; /* Text to display for this row */
886 };
887
888 /* All EQP output is collected into an instance of the following */
889 typedef struct qrfEQPGraph qrfEQPGraph;
890 struct qrfEQPGraph {
891 qrfEQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
892 qrfEQPGraphRow *pLast; /* Last element of the pRow list */
893 char zPrefix[100]; /* Graph prefix */
894 };
895
896 /*
897 ** Private state information. Subject to change from one release to the
898 ** next.
899 */
900 typedef struct Qrf Qrf;
901 struct Qrf {
902 sqlite3_stmt *pStmt; /* The statement whose output is to be rendered */
903 sqlite3 *db; /* The corresponding database connection */
904 sqlite3_stmt *pJTrans; /* JSONB to JSON translator statement */
905 char **pzErr; /* Write error message here, if not NULL */
906 sqlite3_str *pOut; /* Accumulated output */
907 int iErr; /* Error code */
908 int nCol; /* Number of output columns */
909 int expMode; /* Original sqlite3_stmt_isexplain() plus 1 */
910 int mxWidth; /* Screen width */
911 int mxHeight; /* nLineLimit */
912 union {
913 struct { /* Content for QRF_STYLE_Line */
914 int mxColWth; /* Maximum display width of any column */
915 const char **azCol; /* Names of output columns (MODE_Line) */
916 } sLine;
917 qrfEQPGraph *pGraph; /* EQP graph (Eqp, Stats, and StatsEst) */
918 struct { /* Content for QRF_STYLE_Explain */
919 int nIndent; /* Slots allocated for aiIndent */
920 int iIndent; /* Current slot */
921 int *aiIndent; /* Indentation for each opcode */
922 } sExpln;
923 } u;
924 sqlite3_int64 nRow; /* Number of rows handled so far */
925 int *actualWidth; /* Actual width of each column */
926 sqlite3_qrf_spec spec; /* Copy of the original spec */
927 };
928
929 /*
930 ** Data for substitute ctype.h functions. Used for x-platform
931 ** consistency and so that '_' is counted as an alphabetic
932 ** character.
933 **
934 ** 0x01 - space
935 ** 0x02 - digit
936 ** 0x04 - alphabetic, including '_'
937 */
938 static const char qrfCType[] = {
939 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
940 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
942 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
943 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
944 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4,
945 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
946 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
947 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
952 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
953 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
954 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
955 };
956 #define qrfSpace(x) ((qrfCType[(unsigned char)x]&1)!=0)
957 #define qrfDigit(x) ((qrfCType[(unsigned char)x]&2)!=0)
958 #define qrfAlpha(x) ((qrfCType[(unsigned char)x]&4)!=0)
959 #define qrfAlnum(x) ((qrfCType[(unsigned char)x]&6)!=0)
960
961 /*
962 ** Set an error code and error message.
963 */
964 static void qrfError(
965 Qrf *p, /* Query result state */
966 int iCode, /* Error code */
967 const char *zFormat, /* Message format (or NULL) */
968 ...
969 ){
970 p->iErr = iCode;
971 if( p->pzErr!=0 ){
972 sqlite3_free(*p->pzErr);
973 *p->pzErr = 0;
974 if( zFormat ){
975 va_list ap;
976 va_start(ap, zFormat);
977 *p->pzErr = sqlite3_vmprintf(zFormat, ap);
978 va_end(ap);
979 }
980 }
981 }
982
983 /*
984 ** Out-of-memory error.
985 */
986 static void qrfOom(Qrf *p){
987 qrfError(p, SQLITE_NOMEM, "out of memory");
988 }
989
990
991
992 /*
993 ** Add a new entry to the EXPLAIN QUERY PLAN data
994 */
995 static void qrfEqpAppend(Qrf *p, int iEqpId, int p2, const char *zText){
996 qrfEQPGraphRow *pNew;
997 sqlite3_int64 nText;
998 if( zText==0 ) return;
999 if( p->u.pGraph==0 ){
1000 p->u.pGraph = sqlite3_malloc64( sizeof(qrfEQPGraph) );
1001 if( p->u.pGraph==0 ){
1002 qrfOom(p);
1003 return;
1004 }
1005 memset(p->u.pGraph, 0, sizeof(qrfEQPGraph) );
1006 }
1007 nText = strlen(zText);
1008 pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
1009 if( pNew==0 ){
1010 qrfOom(p);
1011 return;
1012 }
1013 pNew->iEqpId = iEqpId;
1014 pNew->iParentId = p2;
1015 memcpy(pNew->zText, zText, nText+1);
1016 pNew->pNext = 0;
1017 if( p->u.pGraph->pLast ){
1018 p->u.pGraph->pLast->pNext = pNew;
1019 }else{
1020 p->u.pGraph->pRow = pNew;
1021 }
1022 p->u.pGraph->pLast = pNew;
1023 }
1024
1025 /*
1026 ** Free and reset the EXPLAIN QUERY PLAN data that has been collected
1027 ** in p->u.pGraph.
1028 */
1029 static void qrfEqpReset(Qrf *p){
1030 qrfEQPGraphRow *pRow, *pNext;
1031 if( p->u.pGraph ){
1032 for(pRow = p->u.pGraph->pRow; pRow; pRow = pNext){
1033 pNext = pRow->pNext;
1034 sqlite3_free(pRow);
1035 }
1036 sqlite3_free(p->u.pGraph);
1037 p->u.pGraph = 0;
1038 }
1039 }
1040
1041 /* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
1042 ** pOld, or return the first such line if pOld is NULL
1043 */
1044 static qrfEQPGraphRow *qrfEqpNextRow(Qrf *p, int iEqpId, qrfEQPGraphRow *pOld){
1045 qrfEQPGraphRow *pRow = pOld ? pOld->pNext : p->u.pGraph->pRow;
1046 while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
1047 return pRow;
1048 }
1049
1050 /* Render a single level of the graph that has iEqpId as its parent. Called
1051 ** recursively to render sublevels.
1052 */
1053 static void qrfEqpRenderLevel(Qrf *p, int iEqpId){
1054 qrfEQPGraphRow *pRow, *pNext;
1055 i64 n = strlen(p->u.pGraph->zPrefix);
1056 char *z;
1057 for(pRow = qrfEqpNextRow(p, iEqpId, 0); pRow; pRow = pNext){
1058 pNext = qrfEqpNextRow(p, iEqpId, pRow);
1059 z = pRow->zText;
1060 sqlite3_str_appendf(p->pOut, "%s%s%s\n", p->u.pGraph->zPrefix,
1061 pNext ? "|--" : "`--", z);
1062 if( n<(i64)sizeof(p->u.pGraph->zPrefix)-7 ){
1063 memcpy(&p->u.pGraph->zPrefix[n], pNext ? "| " : " ", 4);
1064 qrfEqpRenderLevel(p, pRow->iEqpId);
1065 p->u.pGraph->zPrefix[n] = 0;
1066 }
1067 }
1068 }
1069
1070 /*
1071 ** Display and reset the EXPLAIN QUERY PLAN data
1072 */
1073 static void qrfEqpRender(Qrf *p, i64 nCycle){
1074 qrfEQPGraphRow *pRow;
1075 if( p->u.pGraph!=0 && (pRow = p->u.pGraph->pRow)!=0 ){
1076 if( pRow->zText[0]=='-' ){
1077 if( pRow->pNext==0 ){
1078 qrfEqpReset(p);
1079 return;
1080 }
1081 sqlite3_str_appendf(p->pOut, "%s\n", pRow->zText+3);
1082 p->u.pGraph->pRow = pRow->pNext;
1083 sqlite3_free(pRow);
1084 }else if( nCycle>0 ){
1085 sqlite3_str_appendf(p->pOut, "QUERY PLAN (cycles=%lld [100%%])\n",nCycle);
1086 }else{
1087 sqlite3_str_appendall(p->pOut, "QUERY PLAN\n");
1088 }
1089 p->u.pGraph->zPrefix[0] = 0;
1090 qrfEqpRenderLevel(p, 0);
1091 qrfEqpReset(p);
1092 }
1093 }
1094
1095 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
1096 /*
1097 ** Helper function for qrfExpStats().
1098 **
1099 */
1100 static int qrfStatsHeight(sqlite3_stmt *p, int iEntry){
1101 int iPid = 0;
1102 int ret = 1;
1103 sqlite3_stmt_scanstatus_v2(p, iEntry,
1104 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
1105 );
1106 while( iPid!=0 ){
1107 int ii;
1108 for(ii=0; 1; ii++){
1109 int iId;
1110 int res;
1111 res = sqlite3_stmt_scanstatus_v2(p, ii,
1112 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
1113 );
1114 if( res ) break;
1115 if( iId==iPid ){
1116 sqlite3_stmt_scanstatus_v2(p, ii,
1117 SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
1118 );
1119 }
1120 }
1121 ret++;
1122 }
1123 return ret;
1124 }
1125 #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
1126
1127
1128 /*
1129 ** Generate ".scanstatus est" style of EQP output.
1130 */
1131 static void qrfEqpStats(Qrf *p){
1132 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1133 qrfError(p, SQLITE_ERROR, "not available in this build");
1134 #else
1135 static const int f = SQLITE_SCANSTAT_COMPLEX;
1136 sqlite3_stmt *pS = p->pStmt;
1137 int i = 0;
1138 i64 nTotal = 0;
1139 int nWidth = 0;
1140 sqlite3_str *pLine = sqlite3_str_new(p->db);
1141 sqlite3_str *pStats = sqlite3_str_new(p->db);
1142 qrfEqpReset(p);
1143
1144 for(i=0; 1; i++){
1145 const char *z = 0;
1146 int n = 0;
1147 if( sqlite3_stmt_scanstatus_v2(pS,i,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
1148 break;
1149 }
1150 n = (int)strlen(z) + qrfStatsHeight(pS,i)*3;
1151 if( n>nWidth ) nWidth = n;
1152 }
1153 nWidth += 4;
1154
1155 sqlite3_stmt_scanstatus_v2(pS,-1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal);
1156 for(i=0; 1; i++){
1157 i64 nLoop = 0;
1158 i64 nRow = 0;
1159 i64 nCycle = 0;
1160 int iId = 0;
1161 int iPid = 0;
1162 const char *zo = 0;
1163 const char *zName = 0;
1164 double rEst = 0.0;
1165
1166 if( sqlite3_stmt_scanstatus_v2(pS,i,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){
1167 break;
1168 }
1169 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_EST,f,(void*)&rEst);
1170 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop);
1171 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow);
1172 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle);
1173 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId);
1174 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid);
1175 sqlite3_stmt_scanstatus_v2(pS,i, SQLITE_SCANSTAT_NAME,f,(void*)&zName);
1176
1177 if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
1178 const char *zSp = "";
1179 double rpl;
1180 sqlite3_str_reset(pStats);
1181 if( nCycle>=0 && nTotal>0 ){
1182 sqlite3_str_appendf(pStats, "cycles=%lld [%d%%]",
1183 nCycle, ((nCycle*100)+nTotal/2) / nTotal
1184 );
1185 zSp = " ";
1186 }
1187 if( nLoop>=0 ){
1188 sqlite3_str_appendf(pStats, "%sloops=%lld", zSp, nLoop);
1189 zSp = " ";
1190 }
1191 if( nRow>=0 ){
1192 sqlite3_str_appendf(pStats, "%srows=%lld", zSp, nRow);
1193 zSp = " ";
1194 }
1195
1196 if( p->spec.eStyle==QRF_STYLE_StatsEst ){
1197 rpl = (double)nRow / (double)nLoop;
1198 sqlite3_str_appendf(pStats, "%srpl=%.1f est=%.1f", zSp, rpl, rEst);
1199 }
1200
1201 sqlite3_str_appendf(pLine,
1202 "% *s (%s)", -1*(nWidth-qrfStatsHeight(pS,i)*3), zo,
1203 sqlite3_str_value(pStats)
1204 );
1205 sqlite3_str_reset(pStats);
1206 qrfEqpAppend(p, iId, iPid, sqlite3_str_value(pLine));
1207 sqlite3_str_reset(pLine);
1208 }else{
1209 qrfEqpAppend(p, iId, iPid, zo);
1210 }
1211 }
1212 sqlite3_free(sqlite3_str_finish(pLine));
1213 sqlite3_free(sqlite3_str_finish(pStats));
1214 #endif
1215 }
1216
1217
1218 /*
1219 ** Reset the prepared statement.
1220 */
1221 static void qrfResetStmt(Qrf *p){
1222 int rc = sqlite3_reset(p->pStmt);
1223 if( rc!=SQLITE_OK && p->iErr==SQLITE_OK ){
1224 qrfError(p, rc, "%s", sqlite3_errmsg(p->db));
1225 }
1226 }
1227
1228 /*
1229 ** If xWrite is defined, send all content of pOut to xWrite and
1230 ** reset pOut.
1231 */
1232 static void qrfWrite(Qrf *p){
1233 int n;
1234 if( p->spec.xWrite && (n = sqlite3_str_length(p->pOut))>0 ){
1235 int rc = p->spec.xWrite(p->spec.pWriteArg,
1236 sqlite3_str_value(p->pOut),
1237 (sqlite3_int64)n);
1238 sqlite3_str_reset(p->pOut);
1239 if( rc ){
1240 qrfError(p, rc, "Failed to write %d bytes of output", n);
1241 }
1242 }
1243 }
1244
1245 /* Lookup table to estimate the number of columns consumed by a Unicode
1246 ** character.
1247 */
1248 static const struct {
1249 unsigned char w; /* Width of the character in columns */
1250 int iFirst; /* First character in a span having this width */
1251 } aQrfUWidth[] = {
1252 /* {1, 0x00000}, */
1253 {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488},
1254 {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0},
1255 {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7},
1256 {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616},
1257 {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6},
1258 {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee},
1259 {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730},
1260 {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4},
1261 {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941},
1262 {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955},
1263 {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc},
1264 {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce},
1265 {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c},
1266 {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49},
1267 {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81},
1268 {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6},
1269 {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2},
1270 {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d},
1271 {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d},
1272 {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83},
1273 {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e},
1274 {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e},
1275 {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf},
1276 {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce},
1277 {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d},
1278 {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5},
1279 {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34},
1280 {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2},
1281 {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8},
1282 {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36},
1283 {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71},
1284 {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88},
1285 {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6},
1286 {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033},
1287 {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058},
1288 {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f},
1289 {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735},
1290 {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4},
1291 {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7},
1292 {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b},
1293 {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923},
1294 {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939},
1295 {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04},
1296 {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c},
1297 {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74},
1298 {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b},
1299 {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064},
1300 {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329},
1301 {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f},
1302 {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806},
1303 {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827},
1304 {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e},
1305 {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20},
1306 {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00},
1307 {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc},
1308 {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c},
1309 {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40},
1310 {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185},
1311 {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245},
1312 {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001},
1313 {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0}
1314 };
1315
1316 /*
1317 ** Return an estimate of the width, in columns, for the single Unicode
1318 ** character c. For normal characters, the answer is always 1. But the
1319 ** estimate might be 0 or 2 for zero-width and double-width characters.
1320 **
1321 ** Different display devices display unicode using different widths. So
1322 ** it is impossible to know that true display width with 100% accuracy.
1323 ** Inaccuracies in the width estimates might cause columns to be misaligned.
1324 ** Unfortunately, there is nothing we can do about that.
1325 */
1326 int sqlite3_qrf_wcwidth(int c){
1327 int iFirst, iLast;
1328
1329 /* Fast path for common characters */
1330 if( c<=0x300 ) return 1;
1331
1332 /* The general case */
1333 iFirst = 0;
1334 iLast = sizeof(aQrfUWidth)/sizeof(aQrfUWidth[0]) - 1;
1335 while( iFirst<iLast-1 ){
1336 int iMid = (iFirst+iLast)/2;
1337 int cMid = aQrfUWidth[iMid].iFirst;
1338 if( cMid < c ){
1339 iFirst = iMid;
1340 }else if( cMid > c ){
1341 iLast = iMid - 1;
1342 }else{
1343 return aQrfUWidth[iMid].w;
1344 }
1345 }
1346 if( aQrfUWidth[iLast].iFirst > c ) return aQrfUWidth[iFirst].w;
1347 return aQrfUWidth[iLast].w;
1348 }
1349
1350 /*
1351 ** Compute the value and length of a multi-byte UTF-8 character that
1352 ** begins at z[0]. Return the length. Write the Unicode value into *pU.
1353 **
1354 ** This routine only works for *multi-byte* UTF-8 characters. It does
1355 ** not attempt to detect illegal characters.
1356 */
1357 int sqlite3_qrf_decode_utf8(const unsigned char *z, int *pU){
1358 if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){
1359 *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f);
1360 return 2;
1361 }
1362 if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){
1363 *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f);
1364 return 3;
1365 }
1366 if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1367 && (z[3] & 0xc0)==0x80
1368 ){
1369 *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1370 | (z[3] & 0x3f);
1371 return 4;
1372 }
1373 *pU = 0;
1374 return 1;
1375 }
1376
1377 /*
1378 ** Check to see if z[] is a valid VT100 escape. If it is, then
1379 ** return the number of bytes in the escape sequence. Return 0 if
1380 ** z[] is not a VT100 escape.
1381 **
1382 ** This routine assumes that z[0] is \033 (ESC).
1383 */
1384 static int qrfIsVt100(const unsigned char *z){
1385 int i;
1386 if( z[1]!='[' ) return 0;
1387 i = 2;
1388 while( z[i]>=0x30 && z[i]<=0x3f ){ i++; }
1389 while( z[i]>=0x20 && z[i]<=0x2f ){ i++; }
1390 if( z[i]<0x40 || z[i]>0x7e ) return 0;
1391 return i+1;
1392 }
1393
1394 /*
1395 ** Return the length of a string in display characters.
1396 ** Multibyte UTF8 characters count as a single character
1397 ** for single-width characters, or as two characters for
1398 ** double-width characters.
1399 */
1400 static int qrfDisplayLength(const char *zIn){
1401 const unsigned char *z = (const unsigned char*)zIn;
1402 int n = 0;
1403 while( *z ){
1404 if( z[0]<' ' ){
1405 int k;
1406 if( z[0]=='\033' && (k = qrfIsVt100(z))>0 ){
1407 z += k;
1408 }else{
1409 z++;
1410 }
1411 }else if( (0x80&z[0])==0 ){
1412 n++;
1413 z++;
1414 }else{
1415 int u = 0;
1416 int len = sqlite3_qrf_decode_utf8(z, &u);
1417 z += len;
1418 n += sqlite3_qrf_wcwidth(u);
1419 }
1420 }
1421 return n;
1422 }
1423
1424 /*
1425 ** Return the display width of the longest line of text
1426 ** in the (possibly) multi-line input string zIn[0..nByte].
1427 ** zIn[] is not necessarily zero-terminated. Take
1428 ** into account tab characters, zero- and double-width
1429 ** characters, CR and NL, and VT100 escape codes.
1430 **
1431 ** Write the number of newlines into *pnNL. So, *pnNL will
1432 ** return 0 if everything fits on one line, or positive it
1433 ** it will need to be split.
1434 */
1435 static int qrfDisplayWidth(const char *zIn, sqlite3_int64 nByte, int *pnNL){
1436 const unsigned char *z = (const unsigned char*)zIn;
1437 const unsigned char *zEnd = &z[nByte];
1438 int mx = 0;
1439 int n = 0;
1440 int nNL = 0;
1441 while( z<zEnd ){
1442 if( z[0]<' ' ){
1443 int k;
1444 if( z[0]=='\033' && (k = qrfIsVt100(z))>0 ){
1445 z += k;
1446 }else{
1447 if( z[0]=='\t' ){
1448 n = (n+8)&~7;
1449 }else if( z[0]=='\n' || z[0]=='\r' ){
1450 nNL++;
1451 if( n>mx ) mx = n;
1452 n = 0;
1453 }
1454 z++;
1455 }
1456 }else if( (0x80&z[0])==0 ){
1457 n++;
1458 z++;
1459 }else{
1460 int u = 0;
1461 int len = sqlite3_qrf_decode_utf8(z, &u);
1462 z += len;
1463 n += sqlite3_qrf_wcwidth(u);
1464 }
1465 }
1466 if( mx>n ) n = mx;
1467 if( pnNL ) *pnNL = nNL;
1468 return n;
1469 }
1470
1471 /*
1472 ** Escape the input string if it is needed and in accordance with
1473 ** eEsc, which is either QRF_ESC_Ascii or QRF_ESC_Symbol.
1474 **
1475 ** Escaping is needed if the string contains any control characters
1476 ** other than \t, \n, and \r\n
1477 **
1478 ** If no escaping is needed (the common case) then set *ppOut to NULL
1479 ** and return 0. If escaping is needed, write the escaped string into
1480 ** memory obtained from sqlite3_malloc64() and make *ppOut point to that
1481 ** memory and return 0. If an error occurs, return non-zero.
1482 **
1483 ** The caller is responsible for freeing *ppFree if it is non-NULL in order
1484 ** to reclaim memory.
1485 */
1486 static void qrfEscape(
1487 int eEsc, /* QRF_ESC_Ascii or QRF_ESC_Symbol */
1488 sqlite3_str *pStr, /* String to be escaped */
1489 int iStart /* Begin escapding on this byte of pStr */
1490 ){
1491 sqlite3_int64 i, j; /* Loop counters */
1492 sqlite3_int64 sz; /* Size of the string prior to escaping */
1493 sqlite3_int64 nCtrl = 0;/* Number of control characters to escape */
1494 unsigned char *zIn; /* Text to be escaped */
1495 unsigned char c; /* A single character of the text */
1496 unsigned char *zOut; /* Where to write the results */
1497
1498 /* Find the text to be escaped */
1499 zIn = (unsigned char*)sqlite3_str_value(pStr);
1500 if( zIn==0 ) return;
1501 zIn += iStart;
1502
1503 /* Count the control characters */
1504 for(i=0; (c = zIn[i])!=0; i++){
1505 if( c<=0x1f
1506 && c!='\t'
1507 && c!='\n'
1508 && (c!='\r' || zIn[i+1]!='\n')
1509 ){
1510 nCtrl++;
1511 }
1512 }
1513 if( nCtrl==0 ) return; /* Early out if no control characters */
1514
1515 /* Make space to hold the escapes. Copy the original text to the end
1516 ** of the available space. */
1517 sz = sqlite3_str_length(pStr) - iStart;
1518 if( eEsc==QRF_ESC_Symbol ) nCtrl *= 2;
1519 sqlite3_str_appendchar(pStr, nCtrl, ' ');
1520 zOut = (unsigned char*)sqlite3_str_value(pStr);
1521 if( zOut==0 ) return;
1522 zOut += iStart;
1523 zIn = zOut + nCtrl;
1524 memmove(zIn,zOut,sz);
1525
1526 /* Convert the control characters */
1527 for(i=j=0; (c = zIn[i])!=0; i++){
1528 if( c>0x1f
1529 || c=='\t'
1530 || c=='\n'
1531 || (c=='\r' && zIn[i+1]=='\n')
1532 ){
1533 continue;
1534 }
1535 if( i>0 ){
1536 memmove(&zOut[j], zIn, i);
1537 j += i;
1538 }
1539 zIn += i+1;
1540 i = -1;
1541 if( eEsc==QRF_ESC_Symbol ){
1542 zOut[j++] = 0xe2;
1543 zOut[j++] = 0x90;
1544 zOut[j++] = 0x80+c;
1545 }else{
1546 zOut[j++] = '^';
1547 zOut[j++] = 0x40+c;
1548 }
1549 }
1550 }
1551
1552 /*
1553 ** If a field contains any character identified by a 1 in the following
1554 ** array, then the string must be quoted for CSV.
1555 */
1556 static const char qrfCsvQuote[] = {
1557 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1558 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1559 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1561 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1565 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1566 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1567 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1568 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1569 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1570 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1571 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1572 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1573 };
1574
1575 /*
1576 ** Encode text appropriately and append it to pOut.
1577 */
1578 static void qrfEncodeText(Qrf *p, sqlite3_str *pOut, const char *zTxt){
1579 int iStart = sqlite3_str_length(pOut);
1580 switch( p->spec.eText ){
1581 case QRF_TEXT_Sql: {
1582 if( p->spec.eEsc==QRF_ESC_Off ){
1583 sqlite3_str_appendf(pOut, "%Q", zTxt);
1584 }else{
1585 sqlite3_str_appendf(pOut, "%#Q", zTxt);
1586 }
1587 break;
1588 }
1589 case QRF_TEXT_Csv: {
1590 unsigned int i;
1591 for(i=0; zTxt[i]; i++){
1592 if( qrfCsvQuote[((const unsigned char*)zTxt)[i]] ){
1593 i = 0;
1594 break;
1595 }
1596 }
1597 if( i==0 || strstr(zTxt, p->spec.zColumnSep)!=0 ){
1598 sqlite3_str_appendf(pOut, "\"%w\"", zTxt);
1599 }else{
1600 sqlite3_str_appendall(pOut, zTxt);
1601 }
1602 break;
1603 }
1604 case QRF_TEXT_Html: {
1605 const unsigned char *z = (const unsigned char*)zTxt;
1606 while( *z ){
1607 unsigned int i = 0;
1608 unsigned char c;
1609 while( (c=z[i])>'>'
1610 || (c && c!='<' && c!='>' && c!='&' && c!='\"' && c!='\'')
1611 ){
1612 i++;
1613 }
1614 if( i>0 ){
1615 sqlite3_str_append(pOut, (const char*)z, i);
1616 }
1617 switch( z[i] ){
1618 case '>': sqlite3_str_append(pOut, "&lt;", 4); break;
1619 case '&': sqlite3_str_append(pOut, "&amp;", 5); break;
1620 case '<': sqlite3_str_append(pOut, "&lt;", 4); break;
1621 case '"': sqlite3_str_append(pOut, "&quot;", 6); break;
1622 case '\'': sqlite3_str_append(pOut, "&#39;", 5); break;
1623 default: i--;
1624 }
1625 z += i + 1;
1626 }
1627 break;
1628 }
1629 case QRF_TEXT_Tcl:
1630 case QRF_TEXT_Json: {
1631 const unsigned char *z = (const unsigned char*)zTxt;
1632 sqlite3_str_append(pOut, "\"", 1);
1633 while( *z ){
1634 unsigned int i;
1635 for(i=0; z[i]>=0x20 && z[i]!='\\' && z[i]!='"'; i++){}
1636 if( i>0 ){
1637 sqlite3_str_append(pOut, (const char*)z, i);
1638 }
1639 if( z[i]==0 ) break;
1640 switch( z[i] ){
1641 case '"': sqlite3_str_append(pOut, "\\\"", 2); break;
1642 case '\\': sqlite3_str_append(pOut, "\\\\", 2); break;
1643 case '\b': sqlite3_str_append(pOut, "\\b", 2); break;
1644 case '\f': sqlite3_str_append(pOut, "\\f", 2); break;
1645 case '\n': sqlite3_str_append(pOut, "\\n", 2); break;
1646 case '\r': sqlite3_str_append(pOut, "\\r", 2); break;
1647 case '\t': sqlite3_str_append(pOut, "\\t", 2); break;
1648 default: {
1649 if( p->spec.eText==QRF_TEXT_Json ){
1650 sqlite3_str_appendf(pOut, "\\u%04x", z[i]);
1651 }else{
1652 sqlite3_str_appendf(pOut, "\\%03o", z[i]);
1653 }
1654 break;
1655 }
1656 }
1657 z += i + 1;
1658 }
1659 sqlite3_str_append(pOut, "\"", 1);
1660 break;
1661 }
1662 default: {
1663 sqlite3_str_appendall(pOut, zTxt);
1664 break;
1665 }
1666 }
1667 if( p->spec.eEsc!=QRF_ESC_Off ){
1668 qrfEscape(p->spec.eEsc, pOut, iStart);
1669 }
1670 }
1671
1672 /*
1673 ** Do a quick sanity check to see aBlob[0..nBlob-1] is valid JSONB
1674 ** return true if it is and false if it is not.
1675 **
1676 ** False positives are possible, but not false negatives.
1677 */
1678 static int qrfJsonbQuickCheck(unsigned char *aBlob, int nBlob){
1679 unsigned char x; /* Payload size half-byte */
1680 int i; /* Loop counter */
1681 int n; /* Bytes in the payload size integer */
1682 sqlite3_uint64 sz; /* value of the payload size integer */
1683
1684 if( nBlob==0 ) return 0;
1685 x = aBlob[0]>>4;
1686 if( x<=11 ) return nBlob==(1+x);
1687 n = x<14 ? x-11 : 4*(x-13);
1688 if( nBlob<1+n ) return 0;
1689 sz = aBlob[1];
1690 for(i=1; i<n; i++) sz = (sz<<8) + aBlob[i+1];
1691 return sz+n+1==(sqlite3_uint64)nBlob;
1692 }
1693
1694 /*
1695 ** The current iCol-th column of p->pStmt is known to be a BLOB. Check
1696 ** to see if that BLOB is really a JSONB blob. If it is, then translate
1697 ** it into a text JSON representation and return a pointer to that text JSON.
1698 ** If the BLOB is not JSONB, then return a NULL pointer.
1699 **
1700 ** The memory used to hold the JSON text is managed internally by the
1701 ** "p" object and is overwritten and/or deallocated upon the next call
1702 ** to this routine (with the same p argument) or when the p object is
1703 ** finailized.
1704 */
1705 static const char *qrfJsonbToJson(Qrf *p, int iCol){
1706 int nByte;
1707 const void *pBlob;
1708 int rc;
1709 nByte = sqlite3_column_bytes(p->pStmt, iCol);
1710 pBlob = sqlite3_column_blob(p->pStmt, iCol);
1711 if( qrfJsonbQuickCheck((unsigned char*)pBlob, nByte)==0 ){
1712 return 0;
1713 }
1714 if( p->pJTrans==0 ){
1715 sqlite3 *db;
1716 rc = sqlite3_open(":memory:",&db);
1717 if( rc ){
1718 sqlite3_close(db);
1719 return 0;
1720 }
1721 rc = sqlite3_prepare_v2(db, "SELECT json(?1)", -1, &p->pJTrans, 0);
1722 if( rc ){
1723 sqlite3_finalize(p->pJTrans);
1724 p->pJTrans = 0;
1725 sqlite3_close(db);
1726 return 0;
1727 }
1728 }else{
1729 sqlite3_reset(p->pJTrans);
1730 }
1731 sqlite3_bind_blob(p->pJTrans, 1, (void*)pBlob, nByte, SQLITE_STATIC);
1732 rc = sqlite3_step(p->pJTrans);
1733 if( rc==SQLITE_ROW ){
1734 return (const char*)sqlite3_column_text(p->pJTrans, 0);
1735 }else{
1736 return 0;
1737 }
1738 }
1739
1740 /*
1741 ** Render value pVal into pOut
1742 */
1743 static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
1744 #if SQLITE_VERSION_NUMBER>=3052000
1745 int iStartLen = sqlite3_str_length(pOut);
1746 #endif
1747 if( p->spec.xRender ){
1748 sqlite3_value *pVal;
1749 char *z;
1750 pVal = sqlite3_value_dup(sqlite3_column_value(p->pStmt,iCol));
1751 z = p->spec.xRender(p->spec.pRenderArg, pVal);
1752 sqlite3_value_free(pVal);
1753 if( z ){
1754 sqlite3_str_appendall(pOut, z);
1755 sqlite3_free(z);
1756 return;
1757 }
1758 }
1759 switch( sqlite3_column_type(p->pStmt,iCol) ){
1760 case SQLITE_INTEGER: {
1761 sqlite3_str_appendf(pOut, "%lld", sqlite3_column_int64(p->pStmt,iCol));
1762 break;
1763 }
1764 case SQLITE_FLOAT: {
1765 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1766 sqlite3_str_appendall(pOut, zTxt);
1767 break;
1768 }
1769 case SQLITE_BLOB: {
1770 if( p->spec.bTextJsonb==QRF_Yes ){
1771 const char *zJson = qrfJsonbToJson(p, iCol);
1772 if( zJson ){
1773 if( p->spec.eText==QRF_TEXT_Sql ){
1774 sqlite3_str_append(pOut,"jsonb(",6);
1775 qrfEncodeText(p, pOut, zJson);
1776 sqlite3_str_append(pOut,")",1);
1777 }else{
1778 qrfEncodeText(p, pOut, zJson);
1779 }
1780 break;
1781 }
1782 }
1783 switch( p->spec.eBlob ){
1784 case QRF_BLOB_Hex:
1785 case QRF_BLOB_Sql: {
1786 int iStart;
1787 int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1788 int i, j;
1789 char *zVal;
1790 const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
1791 if( p->spec.eBlob==QRF_BLOB_Sql ){
1792 sqlite3_str_append(pOut, "x'", 2);
1793 }
1794 iStart = sqlite3_str_length(pOut);
1795 sqlite3_str_appendchar(pOut, nBlob, ' ');
1796 sqlite3_str_appendchar(pOut, nBlob, ' ');
1797 if( p->spec.eBlob==QRF_BLOB_Sql ){
1798 sqlite3_str_appendchar(pOut, 1, '\'');
1799 }
1800 if( sqlite3_str_errcode(pOut) ) return;
1801 zVal = sqlite3_str_value(pOut);
1802 for(i=0, j=iStart; i<nBlob; i++, j+=2){
1803 unsigned char c = a[i];
1804 zVal[j] = "0123456789abcdef"[(c>>4)&0xf];
1805 zVal[j+1] = "0123456789abcdef"[(c)&0xf];
1806 }
1807 break;
1808 }
1809 case QRF_BLOB_Tcl:
1810 case QRF_BLOB_Json: {
1811 int iStart;
1812 int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1813 int i, j;
1814 char *zVal;
1815 const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
1816 int szC = p->spec.eBlob==QRF_BLOB_Json ? 6 : 4;
1817 sqlite3_str_append(pOut, "\"", 1);
1818 iStart = sqlite3_str_length(pOut);
1819 for(i=szC; i>0; i--){
1820 sqlite3_str_appendchar(pOut, nBlob, ' ');
1821 }
1822 sqlite3_str_appendchar(pOut, 1, '"');
1823 if( sqlite3_str_errcode(pOut) ) return;
1824 zVal = sqlite3_str_value(pOut);
1825 for(i=0, j=iStart; i<nBlob; i++, j+=szC){
1826 unsigned char c = a[i];
1827 zVal[j] = '\\';
1828 if( szC==4 ){
1829 zVal[j+1] = '0' + ((c>>6)&3);
1830 zVal[j+2] = '0' + ((c>>3)&7);
1831 zVal[j+3] = '0' + (c&7);
1832 }else{
1833 zVal[j+1] = 'u';
1834 zVal[j+2] = '0';
1835 zVal[j+3] = '0';
1836 zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf];
1837 zVal[j+5] = "0123456789abcdef"[(c)&0xf];
1838 }
1839 }
1840 break;
1841 }
1842 default: {
1843 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1844 qrfEncodeText(p, pOut, zTxt);
1845 }
1846 }
1847 break;
1848 }
1849 case SQLITE_NULL: {
1850 if( p->spec.bTextNull==QRF_Yes ){
1851 qrfEncodeText(p, pOut, p->spec.zNull);
1852 }else{
1853 sqlite3_str_appendall(pOut, p->spec.zNull);
1854 }
1855 break;
1856 }
1857 case SQLITE_TEXT: {
1858 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1859 qrfEncodeText(p, pOut, zTxt);
1860 break;
1861 }
1862 }
1863 #if SQLITE_VERSION_NUMBER>=3052000
1864 if( p->spec.nCharLimit>0
1865 && (sqlite3_str_length(pOut) - iStartLen) > p->spec.nCharLimit
1866 ){
1867 const unsigned char *z;
1868 int ii = 0, w = 0, limit = p->spec.nCharLimit;
1869 z = (const unsigned char*)sqlite3_str_value(pOut) + iStartLen;
1870 if( limit<4 ) limit = 4;
1871 while( 1 ){
1872 if( z[ii]<' ' ){
1873 int k;
1874 if( z[ii]=='\033' && (k = qrfIsVt100(z+ii))>0 ){
1875 ii += k;
1876 }else if( z[ii]==0 ){
1877 break;
1878 }else{
1879 ii++;
1880 }
1881 }else if( (0x80&z[ii])==0 ){
1882 w++;
1883 if( w>limit ) break;
1884 ii++;
1885 }else{
1886 int u = 0;
1887 int len = sqlite3_qrf_decode_utf8(&z[ii], &u);
1888 w += sqlite3_qrf_wcwidth(u);
1889 if( w>limit ) break;
1890 ii += len;
1891 }
1892 }
1893 if( w>limit ){
1894 sqlite3_str_truncate(pOut, iStartLen+ii);
1895 sqlite3_str_append(pOut, "...", 3);
1896 }
1897 }
1898 #endif
1899 }
1900
1901 /*
1902 ** Store string zUtf to pOut as w characters. If w is negative,
1903 ** then right-justify the text. W is the width in display characters, not
1904 ** in bytes. Double-width unicode characters count as two characters.
1905 ** VT100 escape sequences count as zero. And so forth.
1906 */
1907 static void qrfWidthPrint(Qrf *p, sqlite3_str *pOut, int w, const char *zUtf){
1908 const unsigned char *a = (const unsigned char*)zUtf;
1909 static const int mxW = 10000000;
1910 unsigned char c;
1911 int i = 0;
1912 int n = 0;
1913 int k;
1914 int aw;
1915 (void)p;
1916 if( w<-mxW ){
1917 w = -mxW;
1918 }else if( w>mxW ){
1919 w= mxW;
1920 }
1921 aw = w<0 ? -w : w;
1922 if( a==0 ) a = (const unsigned char*)"";
1923 while( (c = a[i])!=0 ){
1924 if( (c&0xc0)==0xc0 ){
1925 int u;
1926 int len = sqlite3_qrf_decode_utf8(a+i, &u);
1927 int x = sqlite3_qrf_wcwidth(u);
1928 if( x+n>aw ){
1929 break;
1930 }
1931 i += len;
1932 n += x;
1933 }else if( c==0x1b && (k = qrfIsVt100(&a[i]))>0 ){
1934 i += k;
1935 }else if( n>=aw ){
1936 break;
1937 }else{
1938 n++;
1939 i++;
1940 }
1941 }
1942 if( n>=aw ){
1943 sqlite3_str_append(pOut, zUtf, i);
1944 }else if( w<0 ){
1945 if( aw>n ) sqlite3_str_appendchar(pOut, aw-n, ' ');
1946 sqlite3_str_append(pOut, zUtf, i);
1947 }else{
1948 sqlite3_str_append(pOut, zUtf, i);
1949 if( aw>n ) sqlite3_str_appendchar(pOut, aw-n, ' ');
1950 }
1951 }
1952
1953 /*
1954 ** (*pz)[] is a line of text that is to be displayed the box or table or
1955 ** similar tabular formats. z[] contain newlines or might be too wide
1956 ** to fit in the columns so will need to be split into multiple line.
1957 **
1958 ** This routine determines:
1959 **
1960 ** * How many bytes of z[] should be shown on the current line.
1961 ** * How many character positions those bytes will cover.
1962 ** * The byte offset to the start of the next line.
1963 */
1964 static void qrfWrapLine(
1965 const char *zIn, /* Input text to be displayed */
1966 int w, /* Column width in characters (not bytes) */
1967 int bWrap, /* True if we should do word-wrapping */
1968 int *pnThis, /* OUT: How many bytes of z[] for the current line */
1969 int *pnWide, /* OUT: How wide is the text of this line */
1970 int *piNext /* OUT: Offset into z[] to start of the next line */
1971 ){
1972 int i; /* Input bytes consumed */
1973 int k; /* Bytes in a VT100 code */
1974 int n; /* Output column number */
1975 const unsigned char *z = (const unsigned char*)zIn;
1976 unsigned char c = 0;
1977
1978 if( zIn[0]==0 ){
1979 *pnThis = 0;
1980 *pnWide = 0;
1981 *piNext = 0;
1982 return;
1983 }
1984 n = 0;
1985 for(i=0; n<w; i++){
1986 c = zIn[i];
1987 if( c>=0xc0 ){
1988 int u;
1989 int len = sqlite3_qrf_decode_utf8(&z[i], &u);
1990 int wcw = sqlite3_qrf_wcwidth(u);
1991 if( wcw+n>w ) break;
1992 i += len-1;
1993 n += wcw;
1994 continue;
1995 }
1996 if( c>=' ' ){
1997 n++;
1998 continue;
1999 }
2000 if( c==0 || c=='\n' ) break;
2001 if( c=='\r' && zIn[i+1]=='\n' ){ c = zIn[++i]; break; }
2002 if( c=='\t' ){
2003 int wcw = 8 - (n&7);
2004 if( n+wcw>w ) break;
2005 n += wcw;
2006 continue;
2007 }
2008 if( c==0x1b && (k = qrfIsVt100(&z[i]))>0 ){
2009 i += k-1;
2010 }else{
2011 n++;
2012 }
2013 }
2014 if( c==0 ){
2015 *pnThis = i;
2016 *pnWide = n;
2017 *piNext = i;
2018 return;
2019 }
2020 if( c=='\n' ){
2021 *pnThis = i;
2022 *pnWide = n;
2023 *piNext = i+1;
2024 return;
2025 }
2026
2027 /* If we get this far, that means the current line will end at some
2028 ** point that is neither a "\n" or a 0x00. Figure out where that
2029 ** split should occur
2030 */
2031 if( bWrap && z[i]!=0 && !qrfSpace(z[i]) && qrfAlnum(c)==qrfAlnum(z[i]) ){
2032 /* Perhaps try to back up to a better place to break the line */
2033 for(k=i-1; k>=i/2; k--){
2034 if( qrfSpace(z[k]) ) break;
2035 }
2036 if( k<i/2 ){
2037 for(k=i; k>=i/2; k--){
2038 if( qrfAlnum(z[k-1])!=qrfAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
2039 }
2040 }
2041 if( k>=i/2 ){
2042 i = k;
2043 n = qrfDisplayWidth((const char*)z, k, 0);
2044 }
2045 }
2046 *pnThis = i;
2047 *pnWide = n;
2048 while( zIn[i]==' ' || zIn[i]=='\t' || zIn[i]=='\r' ){ i++; }
2049 *piNext = i;
2050 }
2051
2052 /*
2053 ** Append nVal bytes of text from zVal onto the end of pOut.
2054 ** Convert tab characters in zVal to the appropriate number of
2055 ** spaces.
2056 */
2057 static void qrfAppendWithTabs(
2058 sqlite3_str *pOut, /* Append text here */
2059 const char *zVal, /* Text to append */
2060 int nVal /* Use only the first nVal bytes of zVal[] */
2061 ){
2062 int i = 0;
2063 unsigned int col = 0;
2064 unsigned char *z = (unsigned char *)zVal;
2065 while( i<nVal ){
2066 unsigned char c = z[i];
2067 if( c<' ' ){
2068 int k;
2069 sqlite3_str_append(pOut, (const char*)z, i);
2070 nVal -= i;
2071 z += i;
2072 i = 0;
2073 if( c=='\033' && (k = qrfIsVt100(z))>0 ){
2074 sqlite3_str_append(pOut, (const char*)z, k);
2075 z += k;
2076 nVal -= k;
2077 }else if( c=='\t' ){
2078 k = 8 - (col&7);
2079 sqlite3_str_appendchar(pOut, k, ' ');
2080 col += k;
2081 z++;
2082 nVal--;
2083 }else if( c=='\r' && nVal==1 ){
2084 z++;
2085 nVal--;
2086 }else{
2087 char zCtrlPik[4];
2088 col++;
2089 zCtrlPik[0] = 0xe2;
2090 zCtrlPik[1] = 0x90;
2091 zCtrlPik[2] = 0x80+c;
2092 sqlite3_str_append(pOut, zCtrlPik, 3);
2093 z++;
2094 nVal--;
2095 }
2096 }else if( (0x80&c)==0 ){
2097 i++;
2098 col++;
2099 }else{
2100 int u = 0;
2101 int len = sqlite3_qrf_decode_utf8(&z[i], &u);
2102 i += len;
2103 col += sqlite3_qrf_wcwidth(u);
2104 }
2105 }
2106 sqlite3_str_append(pOut, (const char*)z, i);
2107 }
2108
2109 /*
2110 ** Output horizontally justified text into pOut. The text is the
2111 ** first nVal bytes of zVal. Include nWS bytes of whitespace, either
2112 ** split between both sides, or on the left, or on the right, depending
2113 ** on eAlign.
2114 */
2115 static void qrfPrintAligned(
2116 sqlite3_str *pOut, /* Append text here */
2117 const char *zVal, /* Text to append */
2118 int nVal, /* Use only the first nVal bytes of zVal[] */
2119 int nWS, /* Whitespace for horizonal alignment */
2120 unsigned char eAlign /* Alignment type */
2121 ){
2122 eAlign &= QRF_ALIGN_HMASK;
2123 if( eAlign==QRF_ALIGN_Center ){
2124 /* Center the text */
2125 sqlite3_str_appendchar(pOut, nWS/2, ' ');
2126 qrfAppendWithTabs(pOut, zVal, nVal);
2127 sqlite3_str_appendchar(pOut, nWS - nWS/2, ' ');
2128 }else if( eAlign==QRF_ALIGN_Right){
2129 /* Right justify the text */
2130 sqlite3_str_appendchar(pOut, nWS, ' ');
2131 qrfAppendWithTabs(pOut, zVal, nVal);
2132 }else{
2133 /* Left justify the next */
2134 qrfAppendWithTabs(pOut, zVal, nVal);
2135 sqlite3_str_appendchar(pOut, nWS, ' ');
2136 }
2137 }
2138
2139 /*
2140 ** GCC does not define the offsetof() macro so we'll have to do it
2141 ** ourselves.
2142 */
2143 #ifndef offsetof
2144 # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0))
2145 #endif
2146
2147 /*
2148 ** Data for columnar layout, collected into a single object so
2149 ** that it can be more easily passed into subroutines.
2150 */
2151 typedef struct qrfColData qrfColData;
2152 struct qrfColData {
2153 Qrf *p; /* The QRF instance */
2154 int nCol; /* Number of columns in the table */
2155 unsigned char bMultiRow; /* One or more cells will span multiple lines */
2156 unsigned char nMargin; /* Width of column margins */
2157 sqlite3_int64 nRow; /* Number of rows */
2158 sqlite3_int64 nAlloc; /* Number of cells allocated */
2159 sqlite3_int64 n; /* Number of cells. nCol*nRow */
2160 char **az; /* Content of all cells */
2161 int *aiWth; /* Width of each cell */
2162 struct qrfPerCol { /* Per-column data */
2163 char *z; /* Cache of text for current row */
2164 int w; /* Computed width of this column */
2165 int mxW; /* Maximum natural (unwrapped) width */
2166 unsigned char e; /* Alignment */
2167 unsigned char fx; /* Width is fixed */
2168 } *a; /* One per column */
2169 };
2170
2171 /*
2172 ** Free all the memory allocates in the qrfColData object
2173 */
2174 static void qrfColDataFree(qrfColData *p){
2175 sqlite3_int64 i;
2176 for(i=0; i<p->n; i++) sqlite3_free(p->az[i]);
2177 sqlite3_free(p->az);
2178 sqlite3_free(p->aiWth);
2179 sqlite3_free(p->a);
2180 memset(p, 0, sizeof(*p));
2181 }
2182
2183 /*
2184 ** Allocate space for more cells in the qrfColData object.
2185 ** Return non-zero if a memory allocation fails.
2186 */
2187 static int qrfColDataEnlarge(qrfColData *p){
2188 char **azData;
2189 int *aiWth;
2190 p->nAlloc = 2*p->nAlloc + 10*p->nCol;
2191 azData = sqlite3_realloc64(p->az, p->nAlloc*sizeof(char*));
2192 if( azData==0 ){
2193 qrfOom(p->p);
2194 qrfColDataFree(p);
2195 return 1;
2196 }
2197 p->az = azData;
2198 aiWth = sqlite3_realloc64(p->aiWth, p->nAlloc*sizeof(int));
2199 if( aiWth==0 ){
2200 qrfOom(p->p);
2201 qrfColDataFree(p);
2202 return 1;
2203 }
2204 p->aiWth = aiWth;
2205 return 0;
2206 }
2207
2208 /*
2209 ** Print a markdown or table-style row separator using ascii-art
2210 */
2211 static void qrfRowSeparator(sqlite3_str *pOut, qrfColData *p, char cSep){
2212 int i;
2213 if( p->nCol>0 ){
2214 sqlite3_str_append(pOut, &cSep, 1);
2215 sqlite3_str_appendchar(pOut, p->a[0].w+p->nMargin, '-');
2216 for(i=1; i<p->nCol; i++){
2217 sqlite3_str_append(pOut, &cSep, 1);
2218 sqlite3_str_appendchar(pOut, p->a[i].w+p->nMargin, '-');
2219 }
2220 sqlite3_str_append(pOut, &cSep, 1);
2221 }
2222 sqlite3_str_append(pOut, "\n", 1);
2223 }
2224
2225 /*
2226 ** UTF8 box-drawing characters. Imagine box lines like this:
2227 **
2228 ** 1
2229 ** |
2230 ** 4 --+-- 2
2231 ** |
2232 ** 3
2233 **
2234 ** Each box characters has between 2 and 4 of the lines leading from
2235 ** the center. The characters are here identified by the numbers of
2236 ** their corresponding lines.
2237 */
2238 #define BOX_24 "\342\224\200" /* U+2500 --- */
2239 #define BOX_13 "\342\224\202" /* U+2502 | */
2240 #define BOX_23 "\342\224\214" /* U+250c ,- */
2241 #define BOX_34 "\342\224\220" /* U+2510 -, */
2242 #define BOX_12 "\342\224\224" /* U+2514 '- */
2243 #define BOX_14 "\342\224\230" /* U+2518 -' */
2244 #define BOX_123 "\342\224\234" /* U+251c |- */
2245 #define BOX_134 "\342\224\244" /* U+2524 -| */
2246 #define BOX_234 "\342\224\254" /* U+252c -,- */
2247 #define BOX_124 "\342\224\264" /* U+2534 -'- */
2248 #define BOX_1234 "\342\224\274" /* U+253c -|- */
2249
2250 /* Draw horizontal line N characters long using unicode box
2251 ** characters
2252 */
2253 static void qrfBoxLine(sqlite3_str *pOut, int N){
2254 const char zDash[] =
2255 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
2256 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
2257 const int nDash = sizeof(zDash) - 1;
2258 N *= 3;
2259 while( N>nDash ){
2260 sqlite3_str_append(pOut, zDash, nDash);
2261 N -= nDash;
2262 }
2263 sqlite3_str_append(pOut, zDash, N);
2264 }
2265
2266 /*
2267 ** Draw a horizontal separator for a QRF_STYLE_Box table.
2268 */
2269 static void qrfBoxSeparator(
2270 sqlite3_str *pOut,
2271 qrfColData *p,
2272 const char *zSep1,
2273 const char *zSep2,
2274 const char *zSep3
2275 ){
2276 int i;
2277 if( p->nCol>0 ){
2278 sqlite3_str_appendall(pOut, zSep1);
2279 qrfBoxLine(pOut, p->a[0].w+p->nMargin);
2280 for(i=1; i<p->nCol; i++){
2281 sqlite3_str_appendall(pOut, zSep2);
2282 qrfBoxLine(pOut, p->a[i].w+p->nMargin);
2283 }
2284 sqlite3_str_appendall(pOut, zSep3);
2285 }
2286 sqlite3_str_append(pOut, "\n", 1);
2287 }
2288
2289 /*
2290 ** Load into pData the default alignment for the body of a table.
2291 */
2292 static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
2293 sqlite3_int64 i;
2294 for(i=0; i<pData->nCol; i++){
2295 pData->a[i].e = p->spec.eDfltAlign;
2296 if( i<p->spec.nAlign ){
2297 unsigned char ax = p->spec.aAlign[i];
2298 if( (ax & QRF_ALIGN_HMASK)!=0 ){
2299 pData->a[i].e = (ax & QRF_ALIGN_HMASK) |
2300 (pData->a[i].e & QRF_ALIGN_VMASK);
2301 }
2302 }else if( i<p->spec.nWidth ){
2303 if( p->spec.aWidth[i]<0 ){
2304 pData->a[i].e = QRF_ALIGN_Right |
2305 (pData->a[i].e & QRF_ALIGN_VMASK);
2306 }
2307 }
2308 }
2309 }
2310
2311 /*
2312 ** Adjust the layout for the screen width restriction
2313 */
2314 static void qrfRestrictScreenWidth(qrfColData *pData, Qrf *p){
2315 int sepW; /* Width of all box separators and margins */
2316 int sumW; /* Total width of data area over all columns */
2317 int targetW; /* Desired total data area */
2318 int i; /* Loop counters */
2319 int nCol; /* Number of columns */
2320
2321 pData->nMargin = 2; /* Default to normal margins */
2322 if( p->spec.nScreenWidth==0 ) return;
2323 if( p->spec.eStyle==QRF_STYLE_Column ){
2324 sepW = pData->nCol*2 - 2;
2325 }else{
2326 sepW = pData->nCol*3 + 1;
2327 }
2328 nCol = pData->nCol;
2329 for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
2330 if( p->spec.nScreenWidth >= sumW+sepW ) return;
2331
2332 /* First thing to do is reduce the separation between columns */
2333 pData->nMargin = 0;
2334 if( p->spec.eStyle==QRF_STYLE_Column ){
2335 sepW = pData->nCol - 1;
2336 }else{
2337 sepW = pData->nCol + 1;
2338 }
2339 targetW = p->spec.nScreenWidth - sepW;
2340
2341 #define MIN_SQUOZE 8
2342 #define MIN_EX_SQUOZE 16
2343 /* Reduce the width of the widest eligible column. A column is
2344 ** eligible for narrowing if:
2345 **
2346 ** * It is not a fixed-width column (a[0].fx is false)
2347 ** * The current width is more than MIN_SQUOZE
2348 ** * Either:
2349 ** + The current width is more then MIN_EX_SQUOZE, or
2350 ** + The current width is more than half the max width (a[].mxW)
2351 **
2352 ** Keep making reductions until either no more reductions are
2353 ** possible or until the size target is reached.
2354 */
2355 while( sumW > targetW ){
2356 int gain, w;
2357 int ix = -1;
2358 int mx = 0;
2359 for(i=0; i<nCol; i++){
2360 if( pData->a[i].fx==0
2361 && (w = pData->a[i].w)>mx
2362 && w>MIN_SQUOZE
2363 && (w>MIN_EX_SQUOZE || w*2>pData->a[i].mxW)
2364 ){
2365 ix = i;
2366 mx = w;
2367 }
2368 }
2369 if( ix<0 ) break;
2370 if( mx>=MIN_SQUOZE*2 ){
2371 gain = mx/2;
2372 }else{
2373 gain = mx - MIN_SQUOZE;
2374 }
2375 if( sumW - gain < targetW ){
2376 gain = sumW - targetW;
2377 }
2378 sumW -= gain;
2379 pData->a[ix].w -= gain;
2380 pData->bMultiRow = 1;
2381 }
2382 }
2383
2384 /*
2385 ** Columnar modes require that the entire query be evaluated first, with
2386 ** results written into memory, so that we can compute appropriate column
2387 ** widths.
2388 */
2389 static void qrfColumnar(Qrf *p){
2390 sqlite3_int64 i, j; /* Loop counters */
2391 const char *colSep = 0; /* Column separator text */
2392 const char *rowSep = 0; /* Row terminator text */
2393 const char *rowStart = 0; /* Row start text */
2394 int szColSep, szRowSep, szRowStart; /* Size in bytes of previous 3 */
2395 int rc; /* Result code */
2396 int nColumn = p->nCol; /* Number of columns */
2397 int bWW; /* True to do word-wrap */
2398 sqlite3_str *pStr; /* Temporary rendering */
2399 qrfColData data; /* Columnar layout data */
2400
2401 rc = sqlite3_step(p->pStmt);
2402 if( rc!=SQLITE_ROW || nColumn==0 ){
2403 return; /* No output */
2404 }
2405
2406 /* Initialize the data container */
2407 memset(&data, 0, sizeof(data));
2408 data.nCol = p->nCol;
2409 data.a = sqlite3_malloc64( nColumn*sizeof(struct qrfPerCol) );
2410 if( data.a==0 ){
2411 qrfOom(p);
2412 return;
2413 }
2414 memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2415 if( qrfColDataEnlarge(&data) ) return;
2416 assert( data.az!=0 );
2417
2418 /* Load the column header names and all cell content into data */
2419 if( p->spec.bTitles==QRF_Yes ){
2420 unsigned char saved_eText = p->spec.eText;
2421 p->spec.eText = p->spec.eTitle;
2422 for(i=0; i<nColumn; i++){
2423 const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
2424 int nNL = 0;
2425 int n, w;
2426 pStr = sqlite3_str_new(p->db);
2427 qrfEncodeText(p, pStr, z ? z : "");
2428 n = sqlite3_str_length(pStr);
2429 z = data.az[data.n] = sqlite3_str_finish(pStr);
2430 data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL);
2431 data.n++;
2432 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2433 if( nNL ) data.bMultiRow = 1;
2434 }
2435 p->spec.eText = saved_eText;
2436 p->nRow++;
2437 }
2438 do{
2439 if( data.n+nColumn > data.nAlloc ){
2440 if( qrfColDataEnlarge(&data) ) return;
2441 }
2442 for(i=0; i<nColumn; i++){
2443 char *z;
2444 int nNL = 0;
2445 int n, w;
2446 pStr = sqlite3_str_new(p->db);
2447 qrfRenderValue(p, pStr, i);
2448 n = sqlite3_str_length(pStr);
2449 z = data.az[data.n] = sqlite3_str_finish(pStr);
2450 data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL);
2451 data.n++;
2452 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2453 if( nNL ) data.bMultiRow = 1;
2454 }
2455 p->nRow++;
2456 }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
2457 if( p->iErr ){
2458 qrfColDataFree(&data);
2459 return;
2460 }
2461
2462 /* Compute the width and alignment of every column */
2463 if( p->spec.bTitles==QRF_No ){
2464 qrfLoadAlignment(&data, p);
2465 }else{
2466 unsigned char e;
2467 if( p->spec.eTitleAlign==QRF_Auto ){
2468 e = QRF_ALIGN_Center;
2469 }else{
2470 e = p->spec.eTitleAlign;
2471 }
2472 for(i=0; i<nColumn; i++) data.a[i].e = e;
2473 }
2474
2475 for(i=0; i<nColumn; i++){
2476 int w = 0;
2477 if( i<p->spec.nWidth ){
2478 w = p->spec.aWidth[i];
2479 if( w==(-32768) ){
2480 w = 0;
2481 if( p->spec.nAlign>i && (p->spec.aAlign[i] & QRF_ALIGN_HMASK)==0 ){
2482 data.a[i].e |= QRF_ALIGN_Right;
2483 }
2484 }else if( w<0 ){
2485 w = -w;
2486 if( p->spec.nAlign>i && (p->spec.aAlign[i] & QRF_ALIGN_HMASK)==0 ){
2487 data.a[i].e |= QRF_ALIGN_Right;
2488 }
2489 }
2490 if( w ) data.a[i].fx = 1;
2491 }
2492 if( w==0 ){
2493 w = data.a[i].mxW;
2494 if( p->spec.nWrap>0 && w>p->spec.nWrap ){
2495 w = p->spec.nWrap;
2496 data.bMultiRow = 1;
2497 }
2498 }else if( (data.bMultiRow==0 || w==1) && data.a[i].mxW>w ){
2499 data.bMultiRow = 1;
2500 if( w==1 ){
2501 /* If aiWth[j] is 2 or more, then there might be a double-wide
2502 ** character somewhere. So make the column width at least 2. */
2503 w = 2;
2504 }
2505 }
2506 data.a[i].w = w;
2507 }
2508
2509 /* Adjust the column widths due to screen width restrictions */
2510 qrfRestrictScreenWidth(&data, p);
2511
2512 /* Draw the line across the top of the table. Also initialize
2513 ** the row boundary and column separator texts. */
2514 switch( p->spec.eStyle ){
2515 case QRF_STYLE_Box:
2516 if( data.nMargin ){
2517 rowStart = BOX_13 " ";
2518 colSep = " " BOX_13 " ";
2519 rowSep = " " BOX_13 "\n";
2520 }else{
2521 rowStart = BOX_13;
2522 colSep = BOX_13;
2523 rowSep = BOX_13 "\n";
2524 }
2525 qrfBoxSeparator(p->pOut, &data, BOX_23, BOX_234, BOX_34);
2526 break;
2527 case QRF_STYLE_Table:
2528 if( data.nMargin ){
2529 rowStart = "| ";
2530 colSep = " | ";
2531 rowSep = " |\n";
2532 }else{
2533 rowStart = "|";
2534 colSep = "|";
2535 rowSep = "|\n";
2536 }
2537 qrfRowSeparator(p->pOut, &data, '+');
2538 break;
2539 case QRF_STYLE_Column:
2540 rowStart = "";
2541 colSep = data.nMargin ? " " : " ";
2542 rowSep = "\n";
2543 break;
2544 default: /*case QRF_STYLE_Markdown:*/
2545 if( data.nMargin ){
2546 rowStart = "| ";
2547 colSep = " | ";
2548 rowSep = " |\n";
2549 }else{
2550 rowStart = "|";
2551 colSep = "|";
2552 rowSep = "|\n";
2553 }
2554 break;
2555 }
2556 szRowStart = (int)strlen(rowStart);
2557 szRowSep = (int)strlen(rowSep);
2558 szColSep = (int)strlen(colSep);
2559
2560 bWW = (p->spec.bWordWrap==QRF_Yes && data.bMultiRow);
2561 for(i=0; i<data.n; i+=nColumn){
2562 int bMore;
2563 int nRow = 0;
2564
2565 /* Draw a single row of the table. This might be the title line
2566 ** (if there is a title line) or a row in the body of the table.
2567 ** The column number will be j. The row number is i/nColumn.
2568 */
2569 for(j=0; j<nColumn; j++){ data.a[j].z = data.az[i+j]; }
2570 do{
2571 sqlite3_str_append(p->pOut, rowStart, szRowStart);
2572 bMore = 0;
2573 for(j=0; j<nColumn; j++){
2574 int nThis = 0;
2575 int nWide = 0;
2576 int iNext = 0;
2577 int nWS;
2578 qrfWrapLine(data.a[j].z, data.a[j].w, bWW, &nThis, &nWide, &iNext);
2579 nWS = data.a[j].w - nWide;
2580 qrfPrintAligned(p->pOut, data.a[j].z, nThis, nWS, data.a[j].e);
2581 data.a[j].z += iNext;
2582 if( data.a[j].z[0]!=0 ) bMore = 1;
2583 if( j<nColumn-1 ){
2584 sqlite3_str_append(p->pOut, colSep, szColSep);
2585 }else{
2586 sqlite3_str_append(p->pOut, rowSep, szRowSep);
2587 }
2588 }
2589 }while( bMore && ++nRow < p->mxHeight );
2590 if( bMore ){
2591 /* This row was terminated by nLineLimit. Show ellipsis. */
2592 sqlite3_str_append(p->pOut, rowStart, szRowStart);
2593 for(j=0; j<nColumn; j++){
2594 if( data.a[j].z[0]==0 ){
2595 sqlite3_str_appendchar(p->pOut, data.a[j].w, ' ');
2596 }else{
2597 int nE = 3;
2598 if( nE>data.a[j].w ) nE = data.a[j].w;
2599 qrfPrintAligned(p->pOut, "...", nE, data.a[j].w-nE, data.a[j].e);
2600 }
2601 if( j<nColumn-1 ){
2602 sqlite3_str_append(p->pOut, colSep, szColSep);
2603 }else{
2604 sqlite3_str_append(p->pOut, rowSep, szRowSep);
2605 }
2606 }
2607 }
2608
2609 /* Draw either (1) the separator between the title line and the body
2610 ** of the table, or (2) separators between individual rows of the table
2611 ** body. isTitleDataSeparator will be true if we are doing (1).
2612 */
2613 if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
2614 int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
2615 if( isTitleDataSeparator ){
2616 qrfLoadAlignment(&data, p);
2617 }
2618 switch( p->spec.eStyle ){
2619 case QRF_STYLE_Table: {
2620 if( isTitleDataSeparator || data.bMultiRow ){
2621 qrfRowSeparator(p->pOut, &data, '+');
2622 }
2623 break;
2624 }
2625 case QRF_STYLE_Box: {
2626 if( isTitleDataSeparator || data.bMultiRow ){
2627 qrfBoxSeparator(p->pOut, &data, BOX_123, BOX_1234, BOX_134);
2628 }
2629 break;
2630 }
2631 case QRF_STYLE_Markdown: {
2632 if( isTitleDataSeparator ){
2633 qrfRowSeparator(p->pOut, &data, '|');
2634 }
2635 break;
2636 }
2637 case QRF_STYLE_Column: {
2638 if( isTitleDataSeparator ){
2639 for(j=0; j<nColumn; j++){
2640 sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
2641 if( j<nColumn-1 ){
2642 sqlite3_str_append(p->pOut, colSep, szColSep);
2643 }else{
2644 sqlite3_str_append(p->pOut, rowSep, szRowSep);
2645 }
2646 }
2647 }else if( data.bMultiRow ){
2648 sqlite3_str_append(p->pOut, "\n", 1);
2649 }
2650 break;
2651 }
2652 }
2653 }
2654 }
2655
2656 /* Draw the line across the bottom of the table */
2657 switch( p->spec.eStyle ){
2658 case QRF_STYLE_Box:
2659 qrfBoxSeparator(p->pOut, &data, BOX_12, BOX_124, BOX_14);
2660 break;
2661 case QRF_STYLE_Table:
2662 qrfRowSeparator(p->pOut, &data, '+');
2663 break;
2664 }
2665 qrfWrite(p);
2666
2667 qrfColDataFree(&data);
2668 return;
2669 }
2670
2671 /*
2672 ** Parameter azArray points to a zero-terminated array of strings. zStr
2673 ** points to a single nul-terminated string. Return non-zero if zStr
2674 ** is equal, according to strcmp(), to any of the strings in the array.
2675 ** Otherwise, return zero.
2676 */
2677 static int qrfStringInArray(const char *zStr, const char **azArray){
2678 int i;
2679 if( zStr==0 ) return 0;
2680 for(i=0; azArray[i]; i++){
2681 if( 0==strcmp(zStr, azArray[i]) ) return 1;
2682 }
2683 return 0;
2684 }
2685
2686 /*
2687 ** Print out an EXPLAIN with indentation. This is a two-pass algorithm.
2688 **
2689 ** On the first pass, we compute aiIndent[iOp] which is the amount of
2690 ** indentation to apply to the iOp-th opcode. The output actually occurs
2691 ** on the second pass.
2692 **
2693 ** The indenting rules are:
2694 **
2695 ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
2696 ** all opcodes that occur between the p2 jump destination and the opcode
2697 ** itself by 2 spaces.
2698 **
2699 ** * Do the previous for "Return" instructions for when P2 is positive.
2700 ** See tag-20220407a in wherecode.c and vdbe.c.
2701 **
2702 ** * For each "Goto", if the jump destination is earlier in the program
2703 ** and ends on one of:
2704 ** Yield SeekGt SeekLt RowSetRead Rewind
2705 ** or if the P1 parameter is one instead of zero,
2706 ** then indent all opcodes between the earlier instruction
2707 ** and "Goto" by 2 spaces.
2708 */
2709 static void qrfExplain(Qrf *p){
2710 int *abYield = 0; /* abYield[iOp] is rue if opcode iOp is an OP_Yield */
2711 int *aiIndent = 0; /* Indent the iOp-th opcode by aiIndent[iOp] */
2712 i64 nAlloc = 0; /* Allocated size of aiIndent[], abYield */
2713 int nIndent = 0; /* Number of entries in aiIndent[] */
2714 int iOp; /* Opcode number */
2715 int i; /* Column loop counter */
2716
2717 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
2718 "Return", 0 };
2719 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
2720 "Rewind", 0 };
2721 const char *azGoto[] = { "Goto", 0 };
2722
2723 /* The caller guarantees that the leftmost 4 columns of the statement
2724 ** passed to this function are equivalent to the leftmost 4 columns
2725 ** of EXPLAIN statement output. In practice the statement may be
2726 ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
2727 assert( sqlite3_column_count(p->pStmt)>=4 );
2728 assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 0), "addr" ) );
2729 assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 1), "opcode" ) );
2730 assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 2), "p1" ) );
2731 assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 3), "p2" ) );
2732
2733 for(iOp=0; SQLITE_ROW==sqlite3_step(p->pStmt); iOp++){
2734 int iAddr = sqlite3_column_int(p->pStmt, 0);
2735 const char *zOp = (const char*)sqlite3_column_text(p->pStmt, 1);
2736 int p1 = sqlite3_column_int(p->pStmt, 2);
2737 int p2 = sqlite3_column_int(p->pStmt, 3);
2738
2739 /* Assuming that p2 is an instruction address, set variable p2op to the
2740 ** index of that instruction in the aiIndent[] array. p2 and p2op may be
2741 ** different if the current instruction is part of a sub-program generated
2742 ** by an SQL trigger or foreign key. */
2743 int p2op = (p2 + (iOp-iAddr));
2744
2745 /* Grow the aiIndent array as required */
2746 if( iOp>=nAlloc ){
2747 nAlloc += 100;
2748 aiIndent = (int*)sqlite3_realloc64(aiIndent, nAlloc*sizeof(int));
2749 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
2750 if( aiIndent==0 || abYield==0 ){
2751 qrfOom(p);
2752 sqlite3_free(aiIndent);
2753 sqlite3_free(abYield);
2754 return;
2755 }
2756 }
2757
2758 abYield[iOp] = qrfStringInArray(zOp, azYield);
2759 aiIndent[iOp] = 0;
2760 nIndent = iOp+1;
2761 if( qrfStringInArray(zOp, azNext) && p2op>0 ){
2762 for(i=p2op; i<iOp; i++) aiIndent[i] += 2;
2763 }
2764 if( qrfStringInArray(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
2765 for(i=p2op; i<iOp; i++) aiIndent[i] += 2;
2766 }
2767 }
2768 sqlite3_free(abYield);
2769
2770 /* Second pass. Actually generate output */
2771 sqlite3_reset(p->pStmt);
2772 if( p->iErr==SQLITE_OK ){
2773 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
2774 static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
2775 static const int aScanExpWidth[] = {4,15, 6, 13, 4, 4, 4, 13, 2, 13};
2776 static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
2777 const int *aWidth = aExplainWidth;
2778 const int *aMap = aExplainMap;
2779 int nWidth = sizeof(aExplainWidth)/sizeof(int);
2780 int iIndent = 1;
2781 int nArg = p->nCol;
2782 if( p->spec.eStyle==QRF_STYLE_StatsVm ){
2783 aWidth = aScanExpWidth;
2784 aMap = aScanExpMap;
2785 nWidth = sizeof(aScanExpWidth)/sizeof(int);
2786 iIndent = 3;
2787 }
2788 if( nArg>nWidth ) nArg = nWidth;
2789
2790 for(iOp=0; sqlite3_step(p->pStmt)==SQLITE_ROW; iOp++){
2791 /* If this is the first row seen, print out the headers */
2792 if( iOp==0 ){
2793 for(i=0; i<nArg; i++){
2794 const char *zCol = sqlite3_column_name(p->pStmt, aMap[i]);
2795 qrfWidthPrint(p,p->pOut, aWidth[i], zCol);
2796 if( i==nArg-1 ){
2797 sqlite3_str_append(p->pOut, "\n", 1);
2798 }else{
2799 sqlite3_str_append(p->pOut, " ", 2);
2800 }
2801 }
2802 for(i=0; i<nArg; i++){
2803 sqlite3_str_appendf(p->pOut, "%.*c", aWidth[i], '-');
2804 if( i==nArg-1 ){
2805 sqlite3_str_append(p->pOut, "\n", 1);
2806 }else{
2807 sqlite3_str_append(p->pOut, " ", 2);
2808 }
2809 }
2810 }
2811
2812 for(i=0; i<nArg; i++){
2813 const char *zSep = " ";
2814 int w = aWidth[i];
2815 const char *zVal = (const char*)sqlite3_column_text(p->pStmt, aMap[i]);
2816 int len;
2817 if( i==nArg-1 ) w = 0;
2818 if( zVal==0 ) zVal = "";
2819 len = qrfDisplayLength(zVal);
2820 if( len>w ){
2821 w = len;
2822 zSep = " ";
2823 }
2824 if( i==iIndent && aiIndent && iOp<nIndent ){
2825 sqlite3_str_appendchar(p->pOut, aiIndent[iOp], ' ');
2826 }
2827 qrfWidthPrint(p, p->pOut, w, zVal);
2828 if( i==nArg-1 ){
2829 sqlite3_str_append(p->pOut, "\n", 1);
2830 }else{
2831 sqlite3_str_appendall(p->pOut, zSep);
2832 }
2833 }
2834 p->nRow++;
2835 }
2836 qrfWrite(p);
2837 }
2838 sqlite3_free(aiIndent);
2839 }
2840
2841 /*
2842 ** Do a "scanstatus vm" style EXPLAIN listing on p->pStmt.
2843 **
2844 ** p->pStmt is probably not an EXPLAIN query. Instead, construct a
2845 ** new query that is a bytecode() rendering of p->pStmt with extra
2846 ** columns for the "scanstatus vm" outputs, and run the results of
2847 ** that new query through the normal EXPLAIN formatting.
2848 */
2849 static void qrfScanStatusVm(Qrf *p){
2850 sqlite3_stmt *pOrigStmt = p->pStmt;
2851 sqlite3_stmt *pExplain;
2852 int rc;
2853 static const char *zSql =
2854 " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
2855 " format('% 6s (%.2f%%)',"
2856 " CASE WHEN ncycle<100_000 THEN ncycle || ' '"
2857 " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'"
2858 " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'"
2859 " ELSE (ncycle/1000_000_000) || 'G' END,"
2860 " ncycle*100.0/(sum(ncycle) OVER ())"
2861 " ) AS cycles"
2862 " FROM bytecode(?1)";
2863 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pExplain, 0);
2864 if( rc ){
2865 qrfError(p, rc, "%s", sqlite3_errmsg(p->db));
2866 sqlite3_finalize(pExplain);
2867 return;
2868 }
2869 sqlite3_bind_pointer(pExplain, 1, pOrigStmt, "stmt-pointer", 0);
2870 p->pStmt = pExplain;
2871 p->nCol = 10;
2872 qrfExplain(p);
2873 sqlite3_finalize(pExplain);
2874 p->pStmt = pOrigStmt;
2875 }
2876
2877 /*
2878 ** Attempt to determine if identifier zName needs to be quoted, either
2879 ** because it contains non-alphanumeric characters, or because it is an
2880 ** SQLite keyword. Be conservative in this estimate: When in doubt assume
2881 ** that quoting is required.
2882 **
2883 ** Return 1 if quoting is required. Return 0 if no quoting is required.
2884 */
2885
2886 static int qrf_need_quote(const char *zName){
2887 int i;
2888 const unsigned char *z = (const unsigned char*)zName;
2889 if( z==0 ) return 1;
2890 if( !qrfAlpha(z[0]) ) return 1;
2891 for(i=0; z[i]; i++){
2892 if( !qrfAlnum(z[i]) ) return 1;
2893 }
2894 return sqlite3_keyword_check(zName, i)!=0;
2895 }
2896
2897 /*
2898 ** Helper function for QRF_STYLE_Json and QRF_STYLE_JObject.
2899 ** The initial "{" for a JSON object that will contain row content
2900 ** has been output. Now output all the content.
2901 */
2902 static void qrfOneJsonRow(Qrf *p){
2903 int i, nItem;
2904 for(nItem=i=0; i<p->nCol; i++){
2905 const char *zCName;
2906 zCName = sqlite3_column_name(p->pStmt, i);
2907 if( nItem>0 ) sqlite3_str_append(p->pOut, ",", 1);
2908 nItem++;
2909 qrfEncodeText(p, p->pOut, zCName);
2910 sqlite3_str_append(p->pOut, ":", 1);
2911 qrfRenderValue(p, p->pOut, i);
2912 }
2913 qrfWrite(p);
2914 }
2915
2916 /*
2917 ** Render a single row of output for non-columnar styles - any
2918 ** style that lets us render row by row as the content is received
2919 ** from the query.
2920 */
2921 static void qrfOneSimpleRow(Qrf *p){
2922 int i;
2923 switch( p->spec.eStyle ){
2924 case QRF_STYLE_Off:
2925 case QRF_STYLE_Count: {
2926 /* No-op */
2927 break;
2928 }
2929 case QRF_STYLE_Json: {
2930 if( p->nRow==0 ){
2931 sqlite3_str_append(p->pOut, "[{", 2);
2932 }else{
2933 sqlite3_str_append(p->pOut, "},\n{", 4);
2934 }
2935 qrfOneJsonRow(p);
2936 break;
2937 }
2938 case QRF_STYLE_JObject: {
2939 if( p->nRow==0 ){
2940 sqlite3_str_append(p->pOut, "{", 1);
2941 }else{
2942 sqlite3_str_append(p->pOut, "}\n{", 3);
2943 }
2944 qrfOneJsonRow(p);
2945 break;
2946 }
2947 case QRF_STYLE_Html: {
2948 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
2949 sqlite3_str_append(p->pOut, "<TR>", 4);
2950 for(i=0; i<p->nCol; i++){
2951 const char *zCName = sqlite3_column_name(p->pStmt, i);
2952 sqlite3_str_append(p->pOut, "\n<TH>", 5);
2953 qrfEncodeText(p, p->pOut, zCName);
2954 }
2955 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
2956 }
2957 sqlite3_str_append(p->pOut, "<TR>", 4);
2958 for(i=0; i<p->nCol; i++){
2959 sqlite3_str_append(p->pOut, "\n<TD>", 5);
2960 qrfRenderValue(p, p->pOut, i);
2961 }
2962 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
2963 qrfWrite(p);
2964 break;
2965 }
2966 case QRF_STYLE_Insert: {
2967 if( qrf_need_quote(p->spec.zTableName) ){
2968 sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
2969 }else{
2970 sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
2971 }
2972 if( p->spec.bTitles==QRF_Yes ){
2973 for(i=0; i<p->nCol; i++){
2974 const char *zCName = sqlite3_column_name(p->pStmt, i);
2975 if( qrf_need_quote(zCName) ){
2976 sqlite3_str_appendf(p->pOut, "%c\"%w\"",
2977 i==0 ? '(' : ',', zCName);
2978 }else{
2979 sqlite3_str_appendf(p->pOut, "%c%s",
2980 i==0 ? '(' : ',', zCName);
2981 }
2982 }
2983 sqlite3_str_append(p->pOut, ")", 1);
2984 }
2985 sqlite3_str_append(p->pOut," VALUES(", 8);
2986 for(i=0; i<p->nCol; i++){
2987 if( i>0 ) sqlite3_str_append(p->pOut, ",", 1);
2988 qrfRenderValue(p, p->pOut, i);
2989 }
2990 sqlite3_str_append(p->pOut, ");\n", 3);
2991 qrfWrite(p);
2992 break;
2993 }
2994 case QRF_STYLE_Line: {
2995 sqlite3_str *pVal;
2996 int mxW;
2997 int bWW;
2998 if( p->u.sLine.azCol==0 ){
2999 p->u.sLine.azCol = sqlite3_malloc64( p->nCol*sizeof(char*) );
3000 if( p->u.sLine.azCol==0 ){
3001 qrfOom(p);
3002 break;
3003 }
3004 p->u.sLine.mxColWth = 0;
3005 for(i=0; i<p->nCol; i++){
3006 int sz;
3007 p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i);
3008 if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown";
3009 sz = qrfDisplayLength(p->u.sLine.azCol[i]);
3010 if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz;
3011 }
3012 }
3013 if( p->nRow ) sqlite3_str_append(p->pOut, "\n", 1);
3014 pVal = sqlite3_str_new(p->db);
3015 mxW = p->mxWidth - (3 + p->u.sLine.mxColWth);
3016 bWW = p->spec.bWordWrap==QRF_Yes;
3017 for(i=0; i<p->nCol; i++){
3018 const char *zVal;
3019 int cnt = 0;
3020 qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth, p->u.sLine.azCol[i]);
3021 sqlite3_str_append(p->pOut, " = ", 3);
3022 qrfRenderValue(p, pVal, i);
3023 zVal = sqlite3_str_value(pVal);
3024 if( zVal==0 ) zVal = "";
3025 do{
3026 int nThis, nWide, iNext;
3027 qrfWrapLine(zVal, mxW, bWW, &nThis, &nWide, &iNext);
3028 if( cnt ) sqlite3_str_appendchar(p->pOut,p->u.sLine.mxColWth+3,' ');
3029 cnt++;
3030 if( cnt>p->mxHeight ){
3031 zVal = "...";
3032 nThis = iNext = 3;
3033 }
3034 sqlite3_str_append(p->pOut, zVal, nThis);
3035 sqlite3_str_append(p->pOut, "\n", 1);
3036 zVal += iNext;
3037 }while( zVal[0] );
3038 sqlite3_str_reset(pVal);
3039 }
3040 sqlite3_free(sqlite3_str_finish(pVal));
3041 qrfWrite(p);
3042 break;
3043 }
3044 case QRF_STYLE_Eqp: {
3045 const char *zEqpLine = (const char*)sqlite3_column_text(p->pStmt,3);
3046 int iEqpId = sqlite3_column_int(p->pStmt, 0);
3047 int iParentId = sqlite3_column_int(p->pStmt, 1);
3048 if( zEqpLine==0 ) zEqpLine = "";
3049 if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3050 qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3051 break;
3052 }
3053 default: { /* QRF_STYLE_List */
3054 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3055 int saved_eText = p->spec.eText;
3056 p->spec.eText = p->spec.eTitle;
3057 for(i=0; i<p->nCol; i++){
3058 const char *zCName = sqlite3_column_name(p->pStmt, i);
3059 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3060 qrfEncodeText(p, p->pOut, zCName);
3061 }
3062 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3063 qrfWrite(p);
3064 p->spec.eText = saved_eText;
3065 }
3066 for(i=0; i<p->nCol; i++){
3067 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3068 qrfRenderValue(p, p->pOut, i);
3069 }
3070 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3071 qrfWrite(p);
3072 break;
3073 }
3074 }
3075 p->nRow++;
3076 }
3077
3078 /*
3079 ** Initialize the internal Qrf object.
3080 */
3081 static void qrfInitialize(
3082 Qrf *p, /* State object to be initialized */
3083 sqlite3_stmt *pStmt, /* Query whose output to be formatted */
3084 const sqlite3_qrf_spec *pSpec, /* Format specification */
3085 char **pzErr /* Write errors here */
3086 ){
3087 size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3088 memset(p, 0, sizeof(*p));
3089 p->pzErr = pzErr;
3090 if( pSpec->iVersion!=1 ){
3091 qrfError(p, SQLITE_ERROR,
3092 "unusable sqlite3_qrf_spec.iVersion (%d)",
3093 pSpec->iVersion);
3094 return;
3095 }
3096 p->pStmt = pStmt;
3097 p->db = sqlite3_db_handle(pStmt);
3098 p->pOut = sqlite3_str_new(p->db);
3099 if( p->pOut==0 ){
3100 qrfOom(p);
3101 return;
3102 }
3103 p->iErr = 0;
3104 p->nCol = sqlite3_column_count(p->pStmt);
3105 p->nRow = 0;
3106 sz = sizeof(sqlite3_qrf_spec);
3107 memcpy(&p->spec, pSpec, sz);
3108 if( p->spec.zNull==0 ) p->spec.zNull = "";
3109 p->mxWidth = p->spec.nScreenWidth;
3110 if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3111 p->mxHeight = p->spec.nLineLimit;
3112 if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3113 qrf_reinit:
3114 switch( p->spec.eStyle ){
3115 case QRF_Auto: {
3116 switch( sqlite3_stmt_isexplain(pStmt) ){
3117 case 0: p->spec.eStyle = QRF_STYLE_Box; break;
3118 case 1: p->spec.eStyle = QRF_STYLE_Explain; break;
3119 default: p->spec.eStyle = QRF_STYLE_Eqp; break;
3120 }
3121 goto qrf_reinit;
3122 }
3123 case QRF_STYLE_List: {
3124 if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = "|";
3125 if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3126 break;
3127 }
3128 case QRF_STYLE_JObject:
3129 case QRF_STYLE_Json: {
3130 p->spec.eText = QRF_TEXT_Json;
3131 p->spec.eBlob = QRF_BLOB_Json;
3132 p->spec.zNull = "null";
3133 break;
3134 }
3135 case QRF_STYLE_Html: {
3136 p->spec.eText = QRF_TEXT_Html;
3137 p->spec.zNull = "null";
3138 break;
3139 }
3140 case QRF_STYLE_Insert: {
3141 p->spec.eText = QRF_TEXT_Sql;
3142 p->spec.eBlob = QRF_BLOB_Sql;
3143 p->spec.zNull = "NULL";
3144 if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){
3145 p->spec.zTableName = "tab";
3146 }
3147 break;
3148 }
3149 case QRF_STYLE_Csv: {
3150 p->spec.eStyle = QRF_STYLE_List;
3151 p->spec.eText = QRF_TEXT_Csv;
3152 p->spec.eBlob = QRF_BLOB_Text;
3153 p->spec.zColumnSep = ",";
3154 p->spec.zRowSep = "\r\n";
3155 p->spec.zNull = "";
3156 break;
3157 }
3158 case QRF_STYLE_Quote: {
3159 p->spec.eText = QRF_TEXT_Sql;
3160 p->spec.eBlob = QRF_BLOB_Sql;
3161 p->spec.zNull = "NULL";
3162 p->spec.zColumnSep = ",";
3163 p->spec.zRowSep = "\n";
3164 break;
3165 }
3166 case QRF_STYLE_Eqp: {
3167 int expMode = sqlite3_stmt_isexplain(p->pStmt);
3168 if( expMode!=2 ){
3169 sqlite3_stmt_explain(p->pStmt, 2);
3170 p->expMode = expMode+1;
3171 }
3172 break;
3173 }
3174 case QRF_STYLE_Explain: {
3175 int expMode = sqlite3_stmt_isexplain(p->pStmt);
3176 if( expMode!=1 ){
3177 sqlite3_stmt_explain(p->pStmt, 1);
3178 p->expMode = expMode+1;
3179 }
3180 break;
3181 }
3182 }
3183 if( p->spec.eEsc==QRF_Auto ){
3184 p->spec.eEsc = QRF_ESC_Ascii;
3185 }
3186 if( p->spec.eText==QRF_Auto ){
3187 p->spec.eText = QRF_TEXT_Plain;
3188 }
3189 if( p->spec.eTitle==QRF_Auto ){
3190 switch( p->spec.eStyle ){
3191 case QRF_STYLE_Box:
3192 case QRF_STYLE_Column:
3193 case QRF_STYLE_Table:
3194 p->spec.eTitle = QRF_TEXT_Plain;
3195 break;
3196 default:
3197 p->spec.eTitle = p->spec.eText;
3198 break;
3199 }
3200 }
3201 if( p->spec.eBlob==QRF_Auto ){
3202 switch( p->spec.eText ){
3203 case QRF_TEXT_Sql: p->spec.eBlob = QRF_BLOB_Sql; break;
3204 case QRF_TEXT_Csv: p->spec.eBlob = QRF_BLOB_Tcl; break;
3205 case QRF_TEXT_Tcl: p->spec.eBlob = QRF_BLOB_Tcl; break;
3206 case QRF_TEXT_Json: p->spec.eBlob = QRF_BLOB_Json; break;
3207 default: p->spec.eBlob = QRF_BLOB_Text; break;
3208 }
3209 }
3210 if( p->spec.bTitles==QRF_Auto ){
3211 switch( p->spec.eStyle ){
3212 case QRF_STYLE_Box:
3213 case QRF_STYLE_Csv:
3214 case QRF_STYLE_Column:
3215 case QRF_STYLE_Table:
3216 case QRF_STYLE_Markdown:
3217 p->spec.bTitles = QRF_Yes;
3218 break;
3219 default:
3220 p->spec.bTitles = QRF_No;
3221 break;
3222 }
3223 }
3224 if( p->spec.bWordWrap==QRF_Auto ){
3225 p->spec.bWordWrap = QRF_Yes;
3226 }
3227 if( p->spec.bTextJsonb==QRF_Auto ){
3228 p->spec.bTextJsonb = QRF_No;
3229 }
3230 if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = ",";
3231 if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
3232 }
3233
3234 /*
3235 ** Finish rendering the results
3236 */
3237 static void qrfFinalize(Qrf *p){
3238 switch( p->spec.eStyle ){
3239 case QRF_STYLE_Count: {
3240 sqlite3_str_appendf(p->pOut, "%lld\n", p->nRow);
3241 qrfWrite(p);
3242 break;
3243 }
3244 case QRF_STYLE_Json: {
3245 sqlite3_str_append(p->pOut, "}]\n", 3);
3246 qrfWrite(p);
3247 break;
3248 }
3249 case QRF_STYLE_JObject: {
3250 sqlite3_str_append(p->pOut, "}\n", 2);
3251 qrfWrite(p);
3252 break;
3253 }
3254 case QRF_STYLE_Line: {
3255 if( p->u.sLine.azCol ) sqlite3_free(p->u.sLine.azCol);
3256 break;
3257 }
3258 case QRF_STYLE_Stats:
3259 case QRF_STYLE_StatsEst:
3260 case QRF_STYLE_Eqp: {
3261 qrfEqpRender(p, 0);
3262 qrfWrite(p);
3263 break;
3264 }
3265 }
3266 if( p->spec.pzOutput ){
3267 if( p->spec.pzOutput[0] ){
3268 sqlite3_int64 n, sz;
3269 char *zCombined;
3270 sz = strlen(p->spec.pzOutput[0]);
3271 n = sqlite3_str_length(p->pOut);
3272 zCombined = sqlite3_realloc(p->spec.pzOutput[0], sz+n+1);
3273 if( zCombined==0 ){
3274 sqlite3_free(p->spec.pzOutput[0]);
3275 p->spec.pzOutput[0] = 0;
3276 qrfOom(p);
3277 }else{
3278 p->spec.pzOutput[0] = zCombined;
3279 memcpy(zCombined+sz, sqlite3_str_value(p->pOut), n+1);
3280 }
3281 sqlite3_free(sqlite3_str_finish(p->pOut));
3282 }else{
3283 p->spec.pzOutput[0] = sqlite3_str_finish(p->pOut);
3284 }
3285 }else if( p->pOut ){
3286 sqlite3_free(sqlite3_str_finish(p->pOut));
3287 }
3288 if( p->expMode>0 ){
3289 sqlite3_stmt_explain(p->pStmt, p->expMode-1);
3290 }
3291 if( p->actualWidth ){
3292 sqlite3_free(p->actualWidth);
3293 }
3294 if( p->pJTrans ){
3295 sqlite3 *db = sqlite3_db_handle(p->pJTrans);
3296 sqlite3_finalize(p->pJTrans);
3297 sqlite3_close(db);
3298 }
3299 }
3300
3301 /*
3302 ** Run the prepared statement pStmt and format the results according
3303 ** to the specification provided in pSpec. Return an error code.
3304 ** If pzErr is not NULL and if an error occurs, write an error message
3305 ** into *pzErr.
3306 */
3307 int sqlite3_format_query_result(
3308 sqlite3_stmt *pStmt, /* Statement to evaluate */
3309 const sqlite3_qrf_spec *pSpec, /* Format specification */
3310 char **pzErr /* Write error message here */
3311 ){
3312 Qrf qrf; /* The new Qrf being created */
3313
3314 if( pStmt==0 ) return SQLITE_OK; /* No-op */
3315 if( pSpec==0 ) return SQLITE_MISUSE;
3316 qrfInitialize(&qrf, pStmt, pSpec, pzErr);
3317 switch( qrf.spec.eStyle ){
3318 case QRF_STYLE_Box:
3319 case QRF_STYLE_Column:
3320 case QRF_STYLE_Markdown:
3321 case QRF_STYLE_Table: {
3322 /* Columnar modes require that the entire query be evaluated and the
3323 ** results stored in memory, so that we can compute column widths */
3324 qrfColumnar(&qrf);
3325 break;
3326 }
3327 case QRF_STYLE_Explain: {
3328 qrfExplain(&qrf);
3329 break;
3330 }
3331 case QRF_STYLE_StatsVm: {
3332 qrfScanStatusVm(&qrf);
3333 break;
3334 }
3335 case QRF_STYLE_Stats:
3336 case QRF_STYLE_StatsEst: {
3337 qrfEqpStats(&qrf);
3338 break;
3339 }
3340 default: {
3341 /* Non-columnar modes where the output can occur after each row
3342 ** of result is received */
3343 while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
3344 qrfOneSimpleRow(&qrf);
3345 }
3346 break;
3347 }
3348 }
3349 qrfResetStmt(&qrf);
3350 qrfFinalize(&qrf);
3351 return qrf.iErr;
3352 }
3353
3354 /************************* End ext/qrf/qrf.c ********************/
3355
3356 /* Use console I/O package as a direct INCLUDE. */
3357 #define SQLITE_INTERNAL_LINKAGE static
3358
3359 #ifdef SQLITE_SHELL_FIDDLE
@@ -631,12 +3363,71 @@
3363 # define SQLITE_CIO_NO_TRANSLATE
3364 # define SQLITE_CIO_NO_SETMODE
3365 # define SQLITE_CIO_NO_FLUSH
3366 #endif
3367
3368 /*
3369 ** Output routines that are able to redirect to memory rather than
3370 ** doing actually I/O.
3371 ** Works like.
3372 ** --------------
3373 ** cli_printf(FILE*, const char*, ...); fprintf()
3374 ** cli_puts(const char*, FILE*); fputs()
3375 ** cli_vprintf(FILE*, const char*, va_list); vfprintf()
3376 **
3377 ** These are just thin wrappers with the following added semantics:
3378 ** If the file-scope variable cli_output_capture is not NULL, and
3379 ** if the FILE* argument is stdout or stderr, then rather than
3380 ** writing to stdout/stdout, append the text to the cli_output_capture
3381 ** variable.
3382 **
3383 ** The cli_exit(int) routine works like exit() except that it
3384 ** first dumps any capture output to stdout.
3385 */
3386 static sqlite3_str *cli_output_capture = 0;
3387 static int cli_printf(FILE *out, const char *zFormat, ...){
3388 va_list ap;
3389 int rc;
3390 va_start(ap,zFormat);
3391 if( cli_output_capture && (out==stdout || out==stderr) ){
3392 sqlite3_str_vappendf(cli_output_capture, zFormat, ap);
3393 rc = 1;
3394 }else{
3395 rc = sqlite3_vfprintf(out, zFormat, ap);
3396 }
3397 va_end(ap);
3398 return rc;
3399 }
3400 static int cli_puts(const char *zText, FILE *out){
3401 if( cli_output_capture && (out==stdout || out==stderr) ){
3402 sqlite3_str_appendall(cli_output_capture, zText);
3403 return 1;
3404 }
3405 return sqlite3_fputs(zText, out);
3406 }
3407 #if 0 /* Not currently used - available if we need it later */
3408 static int cli_vprintf(FILE *out, const char *zFormat, va_list ap){
3409 if( cli_output_capture && (out==stdout || out==stderr) ){
3410 sqlite3_str_vappendf(cli_output_capture, zFormat, ap);
3411 return 1;
3412 }else{
3413 return sqlite3_vfprintf(out, zFormat, ap);
3414 }
3415 }
3416 #endif
3417 static void cli_exit(int rc){
3418 if( cli_output_capture ){
3419 char *z = sqlite3_str_finish(cli_output_capture);
3420 sqlite3_fputs(z, stdout);
3421 fflush(stdout);
3422 }
3423 exit(rc);
3424 }
3425
3426
3427 #define eputz(z) cli_puts(z,stderr)
3428 #define sputz(fp,z) cli_puts(z,fp)
3429
3430 /* True if the timer is enabled */
3431 static int enableTimer = 0;
3432
3433 /* A version of strcmp() that works with NULL values */
@@ -723,11 +3514,11 @@
3514 static void endTimer(FILE *out){
3515 if( enableTimer ){
3516 sqlite3_int64 iEnd = timeOfDay();
3517 struct rusage sEnd;
3518 getrusage(RUSAGE_SELF, &sEnd);
3519 cli_printf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
3520 (iEnd - iBegin)*0.000001,
3521 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
3522 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
3523 }
3524 }
@@ -804,17 +3595,17 @@
3595 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
3596 sqlite3_int64 ftWallEnd = timeOfDay();
3597 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
3598 #ifdef _WIN64
3599 /* microsecond precision on 64-bit windows */
3600 cli_printf(out, "Run Time: real %.6f user %f sys %f\n",
3601 (ftWallEnd - ftWallBegin)*0.000001,
3602 timeDiff(&ftUserBegin, &ftUserEnd),
3603 timeDiff(&ftKernelBegin, &ftKernelEnd));
3604 #else
3605 /* millisecond precisino on 32-bit windows */
3606 cli_printf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
3607 (ftWallEnd - ftWallBegin)*0.000001,
3608 timeDiff(&ftUserBegin, &ftUserEnd),
3609 timeDiff(&ftKernelBegin, &ftKernelEnd));
3610 #endif
3611 }
@@ -851,16 +3642,21 @@
3642 ** is true. Otherwise, assume stdin is connected to a file or pipe.
3643 */
3644 static int stdin_is_interactive = 1;
3645
3646 /*
3647 ** Treat stdout like a TTY if true.
 
 
3648 */
3649 static int stdout_is_console = 1;
3650
3651 /*
3652 ** Use this value as the width of the output device. Or, figure it
3653 ** out at runtime if the value is negative. Or use a default width
3654 ** if this value is zero.
3655 */
3656 static int stdout_tty_width = -1;
3657
3658 /*
3659 ** The following is the open SQLite database. We make a pointer
3660 ** to this database a static variable so that it can be accessed
3661 ** by the SIGINT handler to interrupt database processing.
3662 */
@@ -994,11 +3790,11 @@
3790 #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
3791
3792 /* Indicate out-of-memory and exit. */
3793 static void shell_out_of_memory(void){
3794 eputz("Error: out of memory\n");
3795 cli_exit(1);
3796 }
3797
3798 /* Check a pointer to see if it is NULL. If it is NULL, exit with an
3799 ** out-of-memory error.
3800 */
@@ -1025,306 +3821,24 @@
3821 char *z;
3822 if( iotrace==0 ) return;
3823 va_start(ap, zFormat);
3824 z = sqlite3_vmprintf(zFormat, ap);
3825 va_end(ap);
3826 cli_printf(iotrace, "%s", z);
3827 sqlite3_free(z);
3828 }
3829 #endif
3830
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3831 /*
3832 ** Compute a string length that is limited to what can be stored in
3833 ** lower 30 bits of a 32-bit signed integer.
3834 */
3835 static int strlen30(const char *z){
3836 size_t n;
3837 if( z==0 ) return 0;
3838 n = strlen(z);
3839 return n>0x3fffffff ? 0x3fffffff : (int)n;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3840 }
3841
3842 /*
3843 ** Return open FILE * if zFile exists, can be opened for read
3844 ** and is an ordinary file or a character stream source.
@@ -1770,11 +4284,11 @@
4284 ** work here in the middle of this regular program.
4285 */
4286 #define SQLITE_EXTENSION_INIT1
4287 #define SQLITE_EXTENSION_INIT2(X) (void)(X)
4288
4289 /************************* Begin ext/misc/windirent.h ******************/
4290 /*
4291 ** 2025-06-05
4292 **
4293 ** The author disclaims copyright to this source code. In place of
4294 ** a legal notice, here is a blessing:
@@ -1935,12 +4449,12 @@
4449 return &pDir->cur;
4450 }
4451
4452 #endif /* defined(_WIN32) && defined(_MSC_VER) */
4453
4454 /************************* End ext/misc/windirent.h ********************/
4455 /************************* Begin ext/misc/memtrace.c ******************/
4456 /*
4457 ** 2019-01-21
4458 **
4459 ** The author disclaims copyright to this source code. In place of
4460 ** a legal notice, here is a blessing:
@@ -2046,12 +4560,12 @@
4560 }
4561 memtraceOut = 0;
4562 return rc;
4563 }
4564
4565 /************************* End ext/misc/memtrace.c ********************/
4566 /************************* Begin ext/misc/pcachetrace.c ******************/
4567 /*
4568 ** 2023-06-21
4569 **
4570 ** The author disclaims copyright to this source code. In place of
4571 ** a legal notice, here is a blessing:
@@ -2228,12 +4742,12 @@
4742 }
4743 pcachetraceOut = 0;
4744 return rc;
4745 }
4746
4747 /************************* End ext/misc/pcachetrace.c ********************/
4748 /************************* Begin ext/misc/shathree.c ******************/
4749 /*
4750 ** 2017-03-08
4751 **
4752 ** The author disclaims copyright to this source code. In place of
4753 ** a legal notice, here is a blessing:
@@ -3085,12 +5599,12 @@
5599 0, sha3QueryFunc, 0, 0);
5600 }
5601 return rc;
5602 }
5603
5604 /************************* End ext/misc/shathree.c ********************/
5605 /************************* Begin ext/misc/sha1.c ******************/
5606 /*
5607 ** 2017-01-27
5608 **
5609 ** The author disclaims copyright to this source code. In place of
5610 ** a legal notice, here is a blessing:
@@ -3497,12 +6011,12 @@
6011 sha1QueryFunc, 0, 0);
6012 }
6013 return rc;
6014 }
6015
6016 /************************* End ext/misc/sha1.c ********************/
6017 /************************* Begin ext/misc/uint.c ******************/
6018 /*
6019 ** 2020-04-14
6020 **
6021 ** The author disclaims copyright to this source code. In place of
6022 ** a legal notice, here is a blessing:
@@ -3592,12 +6106,12 @@
6106 SQLITE_EXTENSION_INIT2(pApi);
6107 (void)pzErrMsg; /* Unused parameter */
6108 return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
6109 }
6110
6111 /************************* End ext/misc/uint.c ********************/
6112 /************************* Begin ext/misc/decimal.c ******************/
6113 /*
6114 ** 2020-06-22
6115 **
6116 ** The author disclaims copyright to this source code. In place of
6117 ** a legal notice, here is a blessing:
@@ -4497,14 +7011,14 @@
7011 0, decimalCollFunc);
7012 }
7013 return rc;
7014 }
7015
7016 /************************* End ext/misc/decimal.c ********************/
7017 #undef sqlite3_base_init
7018 #define sqlite3_base_init sqlite3_base64_init
7019 /************************* Begin ext/misc/base64.c ******************/
7020 /*
7021 ** 2022-11-18
7022 **
7023 ** The author disclaims copyright to this source code. In place of
7024 ** a legal notice, here is a blessing:
@@ -4799,15 +7313,15 @@
7313 ** allows shell.c, as distributed, to have this extension built in.
7314 */
7315 #define BASE64_INIT(db) sqlite3_base64_init(db, 0, 0)
7316 #define BASE64_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */
7317
7318 /************************* End ext/misc/base64.c ********************/
7319 #undef sqlite3_base_init
7320 #define sqlite3_base_init sqlite3_base85_init
7321 #define OMIT_BASE85_CHECKER
7322 /************************* Begin ext/misc/base85.c ******************/
7323 /*
7324 ** 2022-11-16
7325 **
7326 ** The author disclaims copyright to this source code. In place of
7327 ** a legal notice, here is a blessing:
@@ -5259,12 +7773,12 @@
7773 return rc;
7774 }
7775
7776 #endif
7777
7778 /************************* End ext/misc/base85.c ********************/
7779 /************************* Begin ext/misc/ieee754.c ******************/
7780 /*
7781 ** 2013-04-17
7782 **
7783 ** The author disclaims copyright to this source code. In place of
7784 ** a legal notice, here is a blessing:
@@ -5589,12 +8103,12 @@
8103 aFunc[i].xFunc, 0, 0);
8104 }
8105 return rc;
8106 }
8107
8108 /************************* End ext/misc/ieee754.c ********************/
8109 /************************* Begin ext/misc/series.c ******************/
8110 /*
8111 ** 2015-08-18, 2023-04-28
8112 **
8113 ** The author disclaims copyright to this source code. In place of
8114 ** a legal notice, here is a blessing:
@@ -6529,12 +9043,12 @@
9043 rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
9044 #endif
9045 return rc;
9046 }
9047
9048 /************************* End ext/misc/series.c ********************/
9049 /************************* Begin ext/misc/regexp.c ******************/
9050 /*
9051 ** 2012-11-13
9052 **
9053 ** The author disclaims copyright to this source code. In place of
9054 ** a legal notice, here is a blessing:
@@ -7446,13 +9960,13 @@
9960 #endif /* SQLITE_DEBUG */
9961 }
9962 return rc;
9963 }
9964
9965 /************************* End ext/misc/regexp.c ********************/
9966 #ifndef SQLITE_SHELL_FIDDLE
9967 /************************* Begin ext/misc/fileio.c ******************/
9968 /*
9969 ** 2014-06-13
9970 **
9971 ** The author disclaims copyright to this source code. In place of
9972 ** a legal notice, here is a blessing:
@@ -8574,20 +11088,12 @@
11088 rc = fsdirRegister(db);
11089 }
11090 return rc;
11091 }
11092
11093 /************************* End ext/misc/fileio.c ********************/
11094 /************************* Begin ext/misc/completion.c ******************/
 
 
 
 
 
 
 
 
11095 /*
11096 ** 2017-07-10
11097 **
11098 ** The author disclaims copyright to this source code. In place of
11099 ** a legal notice, here is a blessing:
@@ -9095,12 +11601,12 @@
11601 rc = sqlite3CompletionVtabInit(db);
11602 #endif
11603 return rc;
11604 }
11605
11606 /************************* End ext/misc/completion.c ********************/
11607 /************************* Begin ext/misc/appendvfs.c ******************/
11608 /*
11609 ** 2017-10-20
11610 **
11611 ** The author disclaims copyright to this source code. In place of
11612 ** a legal notice, here is a blessing:
@@ -9770,14 +12276,14 @@
12276 #endif
12277 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
12278 return rc;
12279 }
12280
12281 /************************* End ext/misc/appendvfs.c ********************/
12282 #endif
12283 #ifdef SQLITE_HAVE_ZLIB
12284 /************************* Begin ext/misc/zipfile.c ******************/
12285 /*
12286 ** 2017-12-26
12287 **
12288 ** The author disclaims copyright to this source code. In place of
12289 ** a legal notice, here is a blessing:
@@ -12062,12 +14568,12 @@
14568 SQLITE_EXTENSION_INIT2(pApi);
14569 (void)pzErrMsg; /* Unused parameter */
14570 return zipfileRegister(db);
14571 }
14572
14573 /************************* End ext/misc/zipfile.c ********************/
14574 /************************* Begin ext/misc/sqlar.c ******************/
14575 /*
14576 ** 2017-12-17
14577 **
14578 ** The author disclaims copyright to this source code. In place of
14579 ** a legal notice, here is a blessing:
@@ -12191,14 +14697,14 @@
14697 sqlarUncompressFunc, 0, 0);
14698 }
14699 return rc;
14700 }
14701
14702 /************************* End ext/misc/sqlar.c ********************/
14703 #endif
14704 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
14705 /************************* Begin ext/expert/sqlite3expert.h ******************/
14706 /*
14707 ** 2017 April 07
14708 **
14709 ** The author disclaims copyright to this source code. In place of
14710 ** a legal notice, here is a blessing:
@@ -12364,12 +14870,12 @@
14870 */
14871 void sqlite3_expert_destroy(sqlite3expert*);
14872
14873 #endif /* !defined(SQLITEEXPERT_H) */
14874
14875 /************************* End ext/expert/sqlite3expert.h ********************/
14876 /************************* Begin ext/expert/sqlite3expert.c ******************/
14877 /*
14878 ** 2017 April 09
14879 **
14880 ** The author disclaims copyright to this source code. In place of
14881 ** a legal notice, here is a blessing:
@@ -14603,13 +17109,13 @@
17109 }
17110 }
17111
17112 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
17113
17114 /************************* End ext/expert/sqlite3expert.c ********************/
17115 #endif
17116 /************************* Begin ext/intck/sqlite3intck.h ******************/
17117 /*
17118 ** 2024-02-08
17119 **
17120 ** The author disclaims copyright to this source code. In place of
17121 ** a legal notice, here is a blessing:
@@ -14778,12 +17284,12 @@
17284 } /* end of the 'extern "C"' block */
17285 #endif
17286
17287 #endif /* ifndef _SQLITE_INTCK_H */
17288
17289 /************************* End ext/intck/sqlite3intck.h ********************/
17290 /************************* Begin ext/intck/sqlite3intck.c ******************/
17291 /*
17292 ** 2024-02-08
17293 **
17294 ** The author disclaims copyright to this source code. In place of
17295 ** a legal notice, here is a blessing:
@@ -14942,10 +17448,11 @@
17448 }
17449 }else{
17450 sqlite3_free(zRet);
17451 zRet = 0;
17452 }
17453 va_end(ap);
17454 return zRet;
17455 }
17456
17457 /*
17458 ** This is used by sqlite3_intck_unlock() to save the vector key value
@@ -15721,12 +18228,12 @@
18228 }
18229 }
18230 return p->zTestSql;
18231 }
18232
18233 /************************* End ext/intck/sqlite3intck.c ********************/
18234 /************************* Begin ext/misc/stmtrand.c ******************/
18235 /*
18236 ** 2024-05-24
18237 **
18238 ** The author disclaims copyright to this source code. In place of
18239 ** a legal notice, here is a blessing:
@@ -15821,12 +18328,12 @@
18328 stmtrandFunc, 0, 0);
18329 }
18330 return rc;
18331 }
18332
18333 /************************* End ext/misc/stmtrand.c ********************/
18334 /************************* Begin ext/misc/vfstrace.c ******************/
18335 /*
18336 ** 2011 March 16
18337 **
18338 ** The author disclaims copyright to this source code. In place of
18339 ** a legal notice, here is a blessing:
@@ -17035,19 +19542,19 @@
19542 if( pVfs->xOpen!=vfstraceOpen ) return;
19543 sqlite3_vfs_unregister(pVfs);
19544 sqlite3_free(pVfs);
19545 }
19546
19547 /************************* End ext/misc/vfstrace.c ********************/
19548
19549 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
19550 #define SQLITE_SHELL_HAVE_RECOVER 1
19551 #else
19552 #define SQLITE_SHELL_HAVE_RECOVER 0
19553 #endif
19554 #if SQLITE_SHELL_HAVE_RECOVER
19555 /************************* Begin ext/recover/sqlite3recover.h ******************/
19556 /*
19557 ** 2022-08-27
19558 **
19559 ** The author disclaims copyright to this source code. In place of
19560 ** a legal notice, here is a blessing:
@@ -17294,13 +19801,13 @@
19801 } /* end of the 'extern "C"' block */
19802 #endif
19803
19804 #endif /* ifndef _SQLITE_RECOVER_H */
19805
19806 /************************* End ext/recover/sqlite3recover.h ********************/
19807 # ifndef SQLITE_HAVE_SQLITE3R
19808 /************************* Begin ext/recover/dbdata.c ******************/
19809 /*
19810 ** 2019-04-17
19811 **
19812 ** The author disclaims copyright to this source code. In place of
19813 ** a legal notice, here is a blessing:
@@ -18321,12 +20828,12 @@
20828 return sqlite3DbdataRegister(db);
20829 }
20830
20831 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
20832
20833 /************************* End ext/recover/dbdata.c ********************/
20834 /************************* Begin ext/recover/sqlite3recover.c ******************/
20835 /*
20836 ** 2022-08-27
20837 **
20838 ** The author disclaims copyright to this source code. In place of
20839 ** a legal notice, here is a blessing:
@@ -21225,11 +23732,11 @@
23732 return rc;
23733 }
23734
23735 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
23736
23737 /************************* End ext/recover/sqlite3recover.c ********************/
23738 # endif /* SQLITE_HAVE_SQLITE3R */
23739 #endif
23740 #ifdef SQLITE_SHELL_EXTSRC
23741 # include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
23742 #endif
@@ -21253,97 +23760,78 @@
23760 sqlite3expert *pExpert;
23761 int bVerbose;
23762 };
23763 #endif
23764
23765 /* All the parameters that determine how to render query results.
23766 */
23767 typedef struct Mode {
23768 u8 autoExplain; /* Automatically turn on .explain mode */
23769 u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */
23770 u8 autoEQPtrace; /* autoEQP is in trace mode */
23771 u8 scanstatsOn; /* True to display scan stats before each finalize */
23772 u8 bAutoScreenWidth; /* Using the TTY to determine screen width */
23773 u8 mFlags; /* MFLG_ECHO and/or MFLG_CRLF */
23774 u8 eMode; /* One of the MODE_ values */
23775 sqlite3_qrf_spec spec; /* Spec to be passed into QRF */
23776 } Mode;
23777
23778 /* Flags for Mode.mFlags */
23779 #define MFLG_ECHO 0x01 /* Echo inputs to output */
23780 #define MFLG_CRLF 0x02 /* Use CR/LF output line endings */
23781
 
 
 
 
 
 
 
 
23782
23783 /*
23784 ** State information about the database connection is contained in an
23785 ** instance of the following structure.
23786 */
23787 typedef struct ShellState ShellState;
23788 struct ShellState {
23789 sqlite3 *db; /* The database */
23790 int iCompat; /* Compatibility date YYYYMMDD */
 
 
 
 
23791 u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
23792 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
23793 u8 nEqpLevel; /* Depth of the EQP output graph */
23794 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
23795 u8 bSafeMode; /* True to prohibit unsafe operations */
23796 u8 bSafeModePersist; /* The long-term value of bSafeMode */
23797 u8 eRestoreState; /* See comments above doAutoDetectRestore() */
 
 
 
23798 unsigned statsOn; /* True to display memory stats before each finalize */
23799 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
23800 u8 nPopOutput; /* Revert .output settings when reaching zero */
23801 u8 nPopMode; /* Revert .mode settings when reaching zero */
23802 int inputNesting; /* Track nesting level of .read and other redirects */
 
 
23803 i64 lineno; /* Line number of last line read from in */
23804 const char *zInFile; /* Name of the input file */
23805 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
23806 FILE *in; /* Read commands from this stream */
23807 FILE *out; /* Write results here */
23808 FILE *traceOut; /* Output for sqlite3_trace() */
23809 int nErr; /* Number of errors seen */
 
 
 
 
23810 int writableSchema; /* True if PRAGMA writable_schema=ON */
 
23811 int nCheck; /* Number of ".check" commands run */
23812 unsigned nProgress; /* Number of progress callbacks encountered */
23813 unsigned mxProgress; /* Maximum progress callbacks before failing */
23814 unsigned flgProgress; /* Flags for the progress callback */
23815 unsigned shellFlgs; /* Various flags */
23816 unsigned nTestRun; /* Number of test cases run */
23817 unsigned nTestErr; /* Number of test cases that failed */
23818 sqlite3_int64 szMax; /* --maxsize argument to .open */
23819 char *zDestTable; /* Name of destination table when MODE_Insert */
23820 char *zTempFile; /* Temporary file that might need deleting */
23821 char *zErrPrefix; /* Alternative error message prefix */
23822 char zTestcase[30]; /* Name of current test case */
 
 
 
 
 
 
 
 
 
23823 char outfile[FILENAME_MAX]; /* Filename for *out */
23824 sqlite3_stmt *pStmt; /* Current statement if any. */
23825 FILE *pLog; /* Write log output here */
23826 Mode mode; /* Current display mode */
23827 Mode modePrior; /* Backup */
23828 struct SavedMode { /* Ability to define custom mode configurations */
23829 char *zTag; /* Name of this saved mode */
23830 Mode mode; /* The saved mode */
23831 } *aSavedModes; /* Array of saved .mode settings. system malloc() */
23832 int nSavedModes; /* Number of saved .mode settings */
23833 struct AuxDb { /* Storage space for auxiliary database connections */
23834 sqlite3 *db; /* Connection pointer */
23835 const char *zDbFilename; /* Filename used to open the connection */
23836 char *zFreeOnClose; /* Free this memory allocation on close */
23837 #if defined(SQLITE_ENABLE_SESSION)
@@ -21350,18 +23838,23 @@
23838 int nSession; /* Number of active sessions */
23839 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
23840 #endif
23841 } aAuxDb[5], /* Array of all database connections */
23842 *pAuxDb; /* Currently active database connection */
 
 
 
23843 char *zNonce; /* Nonce for temporary safe-mode escapes */
 
23844 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
23845 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
23846 #endif
23847 struct DotCmdLine { /* Info about arguments to a dot-command */
23848 const char *zOrig; /* Original text of the dot-command */
23849 char *zCopy; /* Copy of zOrig, from malloc() */
23850 int nAlloc; /* Size of allocates for arrays below */
23851 int nArg; /* Number of argument slots actually used */
23852 char **azArg; /* Pointer to each argument, dequoted */
23853 int *aiOfst; /* Offset into zOrig[] for start of each arg */
23854 char *abQuot; /* True if the argment was originally quoted */
23855 } dot;
23856 #ifdef SQLITE_SHELL_FIDDLE
23857 struct {
23858 const char * zInput; /* Input string from wasm/JS proxy */
23859 const char * zPos; /* Cursor pos into zInput */
23860 const char * zDefaultDbName; /* Default name for db file */
@@ -21372,11 +23865,11 @@
23865 #ifdef SQLITE_SHELL_FIDDLE
23866 static ShellState shellState;
23867 #endif
23868
23869
23870 /* Allowed values for ShellState.mode.autoEQP
23871 */
23872 #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
23873 #define AUTOEQP_on 1 /* Automatic EQP is on */
23874 #define AUTOEQP_trigger 2 /* On and also show plans for triggers */
23875 #define AUTOEQP_full 3 /* Show full EXPLAIN */
@@ -21401,30 +23894,25 @@
23894 #define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progress
23895 ** callback limit is reached, and for each
23896 ** top-level SQL statement */
23897 #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
23898
23899 /* Names of values for Mode.spec.eEsc and Mode.spec.eText
 
23900 */
23901 static const char *qrfEscNames[] = { "auto", "off", "ascii", "symbol" };
23902 static const char *qrfQuoteNames[] =
23903 { "off","off","sql","hex","csv","tcl","json"};
 
 
23904
23905 /*
23906 ** These are the allowed shellFlgs values
23907 */
23908 #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
23909 #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
23910 #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
23911 #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
23912 #define SHFLG_NoErrLineno 0x00000010 /* Omit line numbers from error msgs */
23913 #define SHFLG_CountChanges 0x00000020 /* .changes setting */
 
 
23914 #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
23915 #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
23916 #define SHFLG_TestingMode 0x00000400 /* allow unsafe testing features */
23917
23918 /*
@@ -21433,58 +23921,105 @@
23921 #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
23922 #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
23923 #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
23924
23925 /*
23926 ** These are the allowed values for Mode.eMode. There is a lot of overlap
23927 ** between these values and the Mode.spec.eStyle values, but they are not
23928 ** one-to-one, and thus need to be tracked separately.
23929 */
23930 #define MODE_Ascii 0 /* Use ASCII unit and record separators (0x1F/0x1E) */
23931 #define MODE_Box 1 /* Unicode box-drawing characters */
23932 #define MODE_C 2 /* Comma-separated list of C-strings */
23933 #define MODE_Column 3 /* One record per line in neat columns */
23934 #define MODE_Count 4 /* Output only a count of the rows of output */
23935 #define MODE_Csv 5 /* Quote strings, numbers are plain */
23936 #define MODE_Html 6 /* Generate an XHTML table */
23937 #define MODE_Insert 7 /* Generate SQL "insert" statements */
23938 #define MODE_JAtom 8 /* Comma-separated list of JSON atoms */
23939 #define MODE_JObject 9 /* One JSON object per row */
23940 #define MODE_Json 10 /* Output JSON */
23941 #define MODE_Line 11 /* One column per line. Blank line between records */
23942 #define MODE_List 12 /* One record per line with a separator */
23943 #define MODE_Markdown 13 /* Markdown formatting */
23944 #define MODE_Off 14 /* No query output shown */
23945 #define MODE_QBox 15 /* BOX with SQL-quoted content */
23946 #define MODE_Quote 16 /* Quote values as for SQL */
23947 #define MODE_Table 17 /* MySQL-style table formatting */
23948 #define MODE_Tabs 18 /* Tab-separated values */
23949 #define MODE_Tcl 19 /* Space-separated list of TCL strings */
23950 #define MODE_Www 20 /* Full web-page output */
23951
23952 #define MODE_BUILTIN 20 /* Maximum built-in mode */
23953 #define MODE_BATCH 50 /* Default mode for batch processing */
23954 #define MODE_TTY 51 /* Default mode for interactive processing */
23955 #define MODE_USER 75 /* First user-defined mode */
23956 #define MODE_N_USER 25 /* Maximum number of user-defined modes */
23957
23958 /*
23959 ** Information about built-in display modes
23960 */
23961 typedef struct ModeInfo ModeInfo;
23962 struct ModeInfo {
23963 char zName[9]; /* Symbolic name of the mode */
23964 unsigned char eCSep; /* Column separator */
23965 unsigned char eRSep; /* Row separator */
23966 unsigned char eNull; /* Null representation */
23967 unsigned char eText; /* Default text encoding */
23968 unsigned char eHdr; /* Default header encoding. */
23969 unsigned char eBlob; /* Default blob encoding. */
23970 unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
23971 unsigned char eStyle; /* Underlying QRF style */
23972 unsigned char eCx; /* 0: other, 1: line, 2: columnar */
 
23973 };
23974
23975 /* String constants used by built-in modes */
23976 static const char *aModeStr[] =
23977 /* 0 1 2 3 4 5 6 7 8 */
23978 { 0, "\n", "|", " ", ",", "\r\n", "\036", "\037", "\t",
23979 "", "NULL", "null", "\"\"" };
23980 /* 9 10 11 12 */
23981
23982 static const ModeInfo aModeInfo[] = {
23983 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
23984 { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 },
23985 { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 },
23986 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 },
23987 { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 },
23988 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 },
23989 { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 },
23990 { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 },
23991 { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 },
23992 { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 },
23993 { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 },
23994 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 },
23995 { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 },
23996 { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 },
23997 { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 },
23998 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 },
23999 { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 },
24000 { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 },
24001 { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 },
24002 { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 },
24003 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 },
24004 { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 }
24005 }; /* | / / | / / | | \
24006 ** | / / | / / | | \_ 2: columnar
24007 ** Index into aModeStr[] | / / | | 1: line
24008 ** | / / | | 0: other
24009 ** | / / | \
24010 ** text encoding |/ | show | \
24011 ** v-------------------' | hdrs? | The QRF style
24012 ** 0: n/a blob | v-----'
24013 ** 1: plain v_---------' 0: n/a
24014 ** 2: sql 0: n/a 1: no
24015 ** 3: csv 1: as-text 2: yes
24016 ** 4: html 2: sql
24017 ** 5: c 3: hex
24018 ** 6: json 4: c
24019 ** 5: json
24020 ******************************************************************/
24021 /*
24022 ** These are the column/row/line separators used by the various
24023 ** import/export modes.
24024 */
24025 #define SEP_Column "|"
@@ -21499,18 +24034,183 @@
24034 /*
24035 ** Limit input nesting via .read or any other input redirect.
24036 ** It's not too expensive, so a generous allowance can be made.
24037 */
24038 #define MAX_INPUT_NESTING 25
24039
24040
24041 /*
24042 ** Clear a display mode, freeing any allocated memory that it
24043 ** contains.
24044 */
24045 static void modeFree(Mode *p){
24046 free(p->spec.aWidth);
24047 free(p->spec.aAlign);
24048 free(p->spec.zColumnSep);
24049 free(p->spec.zRowSep);
24050 free(p->spec.zTableName);
24051 free(p->spec.zNull);
24052 memset(p, 0, sizeof(*p));
24053 p->spec.iVersion = 1;
24054 }
24055
24056 /*
24057 ** Duplicate Mode pSrc into pDest. pDest is assumed to be
24058 ** uninitialized prior to invoking this routine.
24059 */
24060 static void modeDup(Mode *pDest, Mode *pSrc){
24061 memcpy(pDest, pSrc, sizeof(*pDest));
24062 if( pDest->spec.aWidth ){
24063 size_t sz = sizeof(pSrc->spec.aWidth[0]) * pSrc->spec.nWidth;
24064 pDest->spec.aWidth = malloc( sz );
24065 if( pDest->spec.aWidth ){
24066 memcpy(pDest->spec.aWidth, pSrc->spec.aWidth, sz);
24067 }else{
24068 pDest->spec.nWidth = 0;
24069 }
24070 }
24071 if( pDest->spec.aAlign ){
24072 size_t sz = sizeof(pSrc->spec.aAlign[0]) * pSrc->spec.nAlign;
24073 pDest->spec.aAlign = malloc( sz );
24074 if( pDest->spec.aAlign ){
24075 memcpy(pDest->spec.aAlign, pSrc->spec.aAlign, sz);
24076 }else{
24077 pDest->spec.nAlign = 0;
24078 }
24079 }
24080 if( pDest->spec.zColumnSep ){
24081 pDest->spec.zColumnSep = strdup(pSrc->spec.zColumnSep);
24082 }
24083 if( pDest->spec.zRowSep ){
24084 pDest->spec.zRowSep = strdup(pSrc->spec.zRowSep);
24085 }
24086 if( pDest->spec.zTableName ){
24087 pDest->spec.zTableName = strdup(pSrc->spec.zTableName);
24088 }
24089 if( pDest->spec.zNull ){
24090 pDest->spec.zNull = strdup(pSrc->spec.zNull);
24091 }
24092 }
24093
24094 /*
24095 ** Set a string value to a copy of the zNew string in memory
24096 ** obtained from system malloc().
24097 */
24098 static void modeSetStr(char **az, const char *zNew){
24099 free(*az);
24100 if( zNew==0 ){
24101 *az = 0;
24102 }else{
24103 size_t n = strlen(zNew);
24104 *az = malloc( n+1 );
24105 if( *az ){
24106 memcpy(*az, zNew, n+1 );
24107 }
24108 }
24109 }
24110
24111 /*
24112 ** Change the mode to eMode
24113 */
24114 static void modeChange(ShellState *p, unsigned char eMode){
24115 const ModeInfo *pI;
24116 if( eMode<ArraySize(aModeInfo) ){
24117 pI = &aModeInfo[eMode];
24118 Mode *pM = &p->mode;
24119 pM->eMode = eMode;
24120 if( pI->eCSep ) modeSetStr(&pM->spec.zColumnSep, aModeStr[pI->eCSep]);
24121 if( pI->eRSep ) modeSetStr(&pM->spec.zRowSep, aModeStr[pI->eRSep]);
24122 if( pI->eNull ) modeSetStr(&pM->spec.zNull, aModeStr[pI->eNull]);
24123 pM->spec.eText = pI->eText;
24124 pM->spec.eBlob = pI->eBlob;
24125 pM->spec.bTitles = pI->bHdr;
24126 pM->spec.eTitle = pI->eHdr;
24127 }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
24128 modeFree(&p->mode);
24129 modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
24130 }else if( eMode==MODE_BATCH ){
24131 u8 mFlags = p->mode.mFlags;
24132 modeFree(&p->mode);
24133 modeChange(p, MODE_List);
24134 p->mode.mFlags = mFlags;
24135 }else if( eMode==MODE_TTY ){
24136 u8 mFlags = p->mode.mFlags;
24137 modeFree(&p->mode);
24138 modeChange(p, MODE_QBox);
24139 p->mode.bAutoScreenWidth = 1;
24140 p->mode.spec.nCharLimit = 300;
24141 p->mode.spec.nLineLimit = 5;
24142 p->mode.spec.bTextJsonb = QRF_Yes;
24143 p->mode.mFlags = mFlags;
24144 }
24145 }
24146
24147 /*
24148 ** Set the mode to the default according to p->iCompat. It assumed
24149 ** that the mode has already been freed and zeroed prior to calling
24150 ** this routine.
24151 */
24152 static void modeDefault(ShellState *p){
24153 p->mode.spec.iVersion = 1;
24154 p->mode.autoExplain = 1;
24155 if( p->iCompat>=20251115 && (stdin_is_interactive || stdout_is_console) ){
24156 modeChange(p, MODE_TTY);
24157 }else{
24158 modeChange(p, MODE_BATCH);
24159 }
24160 }
24161
24162 /*
24163 ** Find the number of a display mode given its name. Return -1 if
24164 ** the name does not match any mode.
24165 **
24166 ** Saved modes are also searched if p!=NULL. The number returned
24167 ** for a saved mode is the index into the p->aSavedModes[] array
24168 ** plus MODE_USER.
24169 **
24170 ** Two special mode names are also available: "batch" and "tty".
24171 ** evaluate to the default mode for batch operation and interactive
24172 ** operation on a TTY, respectively.
24173 */
24174 static int modeFind(ShellState *p, const char *zName){
24175 int i;
24176 for(i=0; i<ArraySize(aModeInfo); i++){
24177 if( cli_strcmp(aModeInfo[i].zName,zName)==0 ) return i;
24178 }
24179 for(i=0; i<p->nSavedModes; i++){
24180 if( cli_strcmp(p->aSavedModes[i].zTag,zName)==0 ) return i+MODE_USER;
24181 }
24182 if( strcmp(zName,"batch")==0 ) return MODE_BATCH;
24183 if( strcmp(zName,"tty")==0 ) return MODE_TTY;
24184 return -1;
24185 }
24186
24187 /*
24188 ** Save or restore the current output mode
24189 */
24190 static void modePush(ShellState *p){
24191 if( p->nPopMode==0 ){
24192 modeFree(&p->modePrior);
24193 modeDup(&p->modePrior,&p->mode);
24194 }
24195 }
24196 static void modePop(ShellState *p){
24197 if( p->modePrior.spec.iVersion>0 ){
24198 modeFree(&p->mode);
24199 p->mode = p->modePrior;
24200 memset(&p->modePrior, 0, sizeof(p->modePrior));
24201 }
24202 }
24203
24204
24205 /*
24206 ** A callback for the sqlite3_log() interface.
24207 */
24208 static void shellLog(void *pArg, int iErrCode, const char *zMsg){
24209 ShellState *p = (ShellState*)pArg;
24210 if( p->pLog==0 ) return;
24211 cli_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
24212 fflush(p->pLog);
24213 }
24214
24215 /*
24216 ** SQL function: shell_putsnl(X)
@@ -21523,13 +24223,29 @@
24223 int nVal,
24224 sqlite3_value **apVal
24225 ){
24226 ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
24227 (void)nVal;
24228 cli_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
24229 sqlite3_result_value(pCtx, apVal[0]);
24230 }
24231
24232 /*
24233 ** Compute the name of the location of an input error in memory
24234 ** obtained from sqlite3_malloc().
24235 */
24236 static char *shellErrorLocation(ShellState *p){
24237 char *zLoc;
24238 if( p->zErrPrefix ){
24239 zLoc = sqlite3_mprintf("%s", p->zErrPrefix);
24240 }else if( p->zInFile==0 || strcmp(p->zInFile,"<stdin>")==0){
24241 zLoc = sqlite3_mprintf("line %lld:", p->lineno);
24242 }else{
24243 zLoc = sqlite3_mprintf("%s:%lld:", p->zInFile, p->lineno);
24244 }
24245 return zLoc;
24246 }
24247
24248 /*
24249 ** If in safe mode, print an error message described by the arguments
24250 ** and exit immediately.
24251 */
@@ -21539,17 +24255,53 @@
24255 ...
24256 ){
24257 if( p->bSafeMode ){
24258 va_list ap;
24259 char *zMsg;
24260 char *zLoc = shellErrorLocation(p);
24261 va_start(ap, zErrMsg);
24262 zMsg = sqlite3_vmprintf(zErrMsg, ap);
24263 va_end(ap);
24264 cli_printf(stderr, "%s %s\n", zLoc, zMsg);
24265 cli_exit(1);
24266 }
24267 }
24268
24269 /*
24270 ** Issue an error message from a dot-command.
24271 */
24272 static void dotCmdError(
24273 ShellState *p, /* Shell state */
24274 int iArg, /* Index of argument on which error occurred */
24275 const char *zBrief, /* Brief (<20 character) error description */
24276 const char *zDetail, /* Error details */
24277 ...
24278 ){
24279 FILE *out = stderr;
24280 char *zLoc = shellErrorLocation(p);
24281 if( zBrief!=0 && iArg>=0 && iArg<p->dot.nArg ){
24282 int i = p->dot.aiOfst[iArg];
24283 int nPrompt = strlen30(zBrief) + 5;
24284 cli_printf(out, "%s %s\n", zLoc, p->dot.zOrig);
24285 if( i > nPrompt ){
24286 cli_printf(out, "%s %*s%s ---^\n", zLoc, 1+i-nPrompt, "", zBrief);
24287 }else{
24288 cli_printf(out, "%s %*s^--- %s\n", zLoc, i, "", zBrief);
24289 }
24290 }
24291 if( zDetail ){
24292 char *zMsg;
24293 va_list ap;
24294 va_start(ap, zDetail);
24295 zMsg = sqlite3_vmprintf(zDetail,ap);
24296 va_end(ap);
24297 cli_printf(out,"%s %s\n", zLoc, zMsg);
24298 sqlite3_free(zMsg);
24299 }
24300 sqlite3_free(zLoc);
24301 }
24302
24303
24304 /*
24305 ** SQL function: edit(VALUE)
24306 ** edit(VALUE,EDITOR)
24307 **
@@ -21691,161 +24443,25 @@
24443 sqlite3_free(zTempFile);
24444 sqlite3_free(p);
24445 }
24446 #endif /* SQLITE_NOHAVE_SYSTEM */
24447
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24448 /*
24449 ** Set output mode to text or binary for Windows.
24450 */
24451 static void setCrlfMode(ShellState *p){
24452 #ifdef _WIN32
24453 if( p->mode.mFlags & MFLG_CRLF ){
24454 sqlite3_fsetmode(p->out, _O_TEXT);
24455 }else{
24456 sqlite3_fsetmode(p->out, _O_BINARY);
24457 }
24458 #else
24459 UNUSED_PARAMETER(p);
24460 #endif
24461 }
24462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24463 /*
24464 ** Find earliest of chars within s specified in zAny.
24465 ** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated.
24466 */
24467 static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){
@@ -21905,17 +24521,63 @@
24521 static const char *zq = "\"";
24522 static long ctrlMask = ~0L;
24523 static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
24524 char ace[3] = "\\?";
24525 char cbsSay;
24526 cli_puts(zq, out);
24527 if( z==0 ) z = "";
24528 while( *z!=0 ){
24529 const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
24530 const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
24531 const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
24532 if( pcEnd > z ){
24533 cli_printf(out, "%.*s", (int)(pcEnd-z), z);
24534 }
24535 if( (c = *pcEnd)==0 ) break;
24536 ++pcEnd;
24537 switch( c ){
24538 case '\\': case '"':
24539 cbsSay = (char)c;
24540 break;
24541 case '\t': cbsSay = 't'; break;
24542 case '\n': cbsSay = 'n'; break;
24543 case '\r': cbsSay = 'r'; break;
24544 case '\f': cbsSay = 'f'; break;
24545 default: cbsSay = 0; break;
24546 }
24547 if( cbsSay ){
24548 ace[1] = cbsSay;
24549 cli_puts(ace, out);
24550 }else if( !isprint(c&0xff) ){
24551 cli_printf(out, "\\%03o", c&0xff);
24552 }else{
24553 ace[1] = (char)c;
24554 cli_puts(ace+1, out);
24555 }
24556 z = pcEnd;
24557 }
24558 cli_puts(zq, out);
24559 }
24560
24561 /* Encode input string z[] as a C-language string literal and
24562 ** append it to the sqlite3_str. If z is NULL render and empty string.
24563 */
24564 static void append_c_string(sqlite3_str *out, const char *z){
24565 char c;
24566 static const char *zq = "\"";
24567 static long ctrlMask = ~0L;
24568 static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
24569 char ace[3] = "\\?";
24570 char cbsSay;
24571 if( z==0 ) z = "";
24572 sqlite3_str_appendall(out,zq);
24573 while( *z!=0 ){
24574 const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
24575 const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
24576 const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
24577 if( pcEnd > z ){
24578 sqlite3_str_appendf(out, "%.*s", (int)(pcEnd-z), z);
24579 }
24580 if( (c = *pcEnd)==0 ) break;
24581 ++pcEnd;
24582 switch( c ){
24583 case '\\': case '"':
@@ -21927,255 +24589,63 @@
24589 case '\f': cbsSay = 'f'; break;
24590 default: cbsSay = 0; break;
24591 }
24592 if( cbsSay ){
24593 ace[1] = cbsSay;
24594 sqlite3_str_appendall(out,ace);
24595 }else if( !isprint(c&0xff) ){
24596 sqlite3_str_appendf(out, "\\%03o", c&0xff);
24597 }else{
24598 ace[1] = (char)c;
24599 sqlite3_str_appendall(out, ace+1);
24600 }
24601 z = pcEnd;
24602 }
24603 sqlite3_str_appendall(out, zq);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24604 }
24605
24606 /*
24607 ** This routine runs when the user presses Ctrl-C
24608 */
24609 static void interrupt_handler(int NotUsed){
24610 UNUSED_PARAMETER(NotUsed);
24611 if( ++seenInterrupt>1 ) cli_exit(1);
24612 if( globalDb ) sqlite3_interrupt(globalDb);
24613 }
24614
24615 /* Try to determine the screen width. Use the default if unable.
24616 */
24617 int shellScreenWidth(void){
24618 if( stdout_tty_width>0 ) return stdout_tty_width;
24619 #if defined(TIOCGSIZE)
24620 struct ttysize ts;
24621 if( ioctl(STDIN_FILENO, TIOCGSIZE, &ts)>=0
24622 || ioctl(STDOUT_FILENO, TIOCGSIZE, &ts)>=0
24623 || ioctl(STDERR_FILENO, TIOCGSIZE, &ts)>=0
24624 ){
24625 return ts.ts_cols;
24626 }
24627 #elif defined(TIOCGWINSZ)
24628 struct winsize ws;
24629 if( ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)>=0
24630 || ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)>=0
24631 || ioctl(STDERR_FILENO, TIOCGWINSZ, &ws)>=0
24632 ){
24633 return ws.ws_col;
24634 }
24635 #elif defined(_WIN32)
24636 CONSOLE_SCREEN_BUFFER_INFO csbi;
24637 if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)
24638 || GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi)
24639 || GetConsoleScreenBufferInfo(GetStdHandle(STD_INPUT_HANDLE), &csbi)
24640 ){
24641 return csbi.srWindow.Right - csbi.srWindow.Left + 1;
24642 }
24643 #endif
24644 #define DEFAULT_SCREEN_WIDTH 80
24645 return DEFAULT_SCREEN_WIDTH;
24646 }
24647
24648 #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
24649 /*
24650 ** This routine runs for console events (e.g. Ctrl-C) on Win32
24651 */
@@ -22268,27 +24738,27 @@
24738 const char *az[4];
24739 az[0] = zA1;
24740 az[1] = zA2;
24741 az[2] = zA3;
24742 az[3] = zA4;
24743 cli_printf(p->out, "authorizer: %s", azAction[op]);
24744 for(i=0; i<4; i++){
24745 cli_puts(" ", p->out);
24746 if( az[i] ){
24747 output_c_string(p->out, az[i]);
24748 }else{
24749 cli_puts("NULL", p->out);
24750 }
24751 }
24752 cli_puts("\n", p->out);
24753 if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
24754 return SQLITE_OK;
24755 }
24756 #endif
24757
24758 /*
24759 ** Print a schema statement. This is helper routine to dump_callbac().
24760 **
24761 ** This routine converts some CREATE TABLE statements for shadow tables
24762 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
24763 **
24764 ** If the schema statement in z[] contains a start-of-comment and if
@@ -22315,22 +24785,16 @@
24785 }
24786 sqlite3_free(zNew);
24787 }
24788 }
24789 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
24790 cli_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
24791 }else{
24792 cli_printf(out, "%s%s", z, zTail);
24793 }
24794 sqlite3_free(zToFree);
24795 }
 
 
 
 
 
 
24796
24797 /*
24798 ** Return true if string z[] has nothing but whitespace and comments to the
24799 ** end of the first line.
24800 */
@@ -22344,99 +24808,132 @@
24808 }
24809 return 1;
24810 }
24811
24812 /*
24813 ** SQL Function: shell_format_schema(SQL,FLAGS)
24814 **
24815 ** This function is internally by the CLI to assist with the
24816 ** ".schema", ".fullschema", and ".dump" commands. The first
24817 ** argument is the value from sqlite_schema.sql. The value returned
24818 ** is a modification of the input that can actually be run as SQL
24819 ** to recreate the schema object.
24820 **
24821 ** When FLAGS is zero, the only changes is to append ";". If the
24822 ** 0x01 bit of FLAGS is set, then transformations are made to implement
24823 ** ".schema --indent".
24824 */
24825 static void shellFormatSchema(
24826 sqlite3_context *pCtx,
24827 int nVal,
24828 sqlite3_value **apVal
24829 ){
24830 int flags; /* Value of 2nd parameter */
24831 const char *zSql; /* Value of 1st parameter */
24832 int nSql; /* Bytes of text in zSql[] */
24833 sqlite3_str *pOut; /* Output buffer */
24834 char *z; /* Writable copy of zSql */
24835 int i, j; /* Loop counters */
24836 int nParen = 0;
24837 char cEnd = 0;
24838 char c;
24839 int nLine = 0;
24840 int isIndex;
24841 int isWhere = 0;
24842
24843 assert( nVal==2 );
24844 pOut = sqlite3_str_new(sqlite3_context_db_handle(pCtx));
24845 nSql = sqlite3_value_bytes(apVal[0]);
24846 zSql = (const char*)sqlite3_value_text(apVal[0]);
24847 if( zSql==0 || zSql[0]==0 ) goto shellFormatSchema_finish;
24848 flags = sqlite3_value_int(apVal[1]);
24849 if( (flags & 0x01)==0 ){
24850 sqlite3_str_append(pOut, zSql, nSql);
24851 sqlite3_str_append(pOut, ";", 1);
24852 goto shellFormatSchema_finish;
24853 }
24854 if( sqlite3_strlike("CREATE VIEW%", zSql, 0)==0
24855 || sqlite3_strlike("CREATE TRIG%", zSql, 0)==0
24856 ){
24857 sqlite3_str_append(pOut, zSql, nSql);
24858 sqlite3_str_append(pOut, ";", 1);
24859 goto shellFormatSchema_finish;
24860 }
24861 isIndex = sqlite3_strlike("CREATE INDEX%", zSql, 0)==0
24862 || sqlite3_strlike("CREATE UNIQUE INDEX%", zSql, 0)==0;
24863 z = sqlite3_mprintf("%s", zSql);
24864 if( z==0 ){
24865 sqlite3_str_free(pOut);
24866 sqlite3_result_error_nomem(pCtx);
24867 return;
24868 }
24869 j = 0;
24870 for(i=0; IsSpace(z[i]); i++){}
24871 for(; (c = z[i])!=0; i++){
24872 if( IsSpace(c) ){
24873 if( z[j-1]=='\r' ) z[j-1] = '\n';
24874 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
24875 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
24876 j--;
24877 }
24878 z[j++] = c;
24879 }
24880 while( j>0 && IsSpace(z[j-1]) ){ j--; }
24881 z[j] = 0;
24882 if( strlen30(z)>=79 ){
24883 for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
24884 if( c==cEnd ){
24885 cEnd = 0;
24886 }else if( c=='"' || c=='\'' || c=='`' ){
24887 cEnd = c;
24888 }else if( c=='[' ){
24889 cEnd = ']';
24890 }else if( c=='-' && z[i+1]=='-' ){
24891 cEnd = '\n';
24892 }else if( c=='(' ){
24893 nParen++;
24894 }else if( c==')' ){
24895 nParen--;
24896 if( nLine>0 && nParen==0 && j>0 && !isWhere ){
24897 sqlite3_str_append(pOut, z, j);
24898 sqlite3_str_append(pOut, "\n", 1);
24899 j = 0;
24900 }
24901 }else if( (c=='w' || c=='W')
24902 && nParen==0 && isIndex
24903 && sqlite3_strnicmp("WHERE",&z[i],5)==0
24904 && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
24905 isWhere = 1;
24906 }else if( isWhere && (c=='A' || c=='a')
24907 && nParen==0
24908 && sqlite3_strnicmp("AND",&z[i],3)==0
24909 && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
24910 sqlite3_str_append(pOut, z, j);
24911 sqlite3_str_append(pOut, "\n ", 5);
24912 j = 0;
24913 }
24914 z[j++] = c;
24915 if( nParen==1 && cEnd==0
24916 && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
24917 && !isWhere
24918 ){
24919 if( c=='\n' ) j--;
24920 sqlite3_str_append(pOut, z, j);
24921 sqlite3_str_append(pOut, "\n ", 3);
24922 j = 0;
24923 nLine++;
24924 while( IsSpace(z[i+1]) ){ i++; }
24925 }
24926 }
24927 z[j] = 0;
24928 }
24929 sqlite3_str_appendall(pOut, z);
24930 sqlite3_str_append(pOut, ";", 1);
24931 sqlite3_free(z);
24932
24933 shellFormatSchema_finish:
24934 sqlite3_result_text(pCtx, sqlite3_str_finish(pOut), -1, sqlite3_free);
24935 }
24936
24937 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
24938 /*
24939 ** Progress handler callback.
@@ -22443,496 +24940,22 @@
24940 */
24941 static int progress_handler(void *pClientData) {
24942 ShellState *p = (ShellState*)pClientData;
24943 p->nProgress++;
24944 if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
24945 cli_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
24946 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
24947 if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
24948 return 1;
24949 }
24950 if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
24951 cli_printf(p->out, "Progress %u\n", p->nProgress);
24952 }
24953 return 0;
24954 }
24955 #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
24956
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24957 /*
24958 ** This is the callback routine from sqlite3_exec() that appends all
24959 ** output onto the end of a ShellText object.
24960 */
24961 static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
@@ -22988,11 +25011,11 @@
25011 "INSERT INTO selftest(tno,op,cmd,ans)"
25012 " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
25013 "DROP TABLE [_shell$self];"
25014 ,0,0,&zErrMsg);
25015 if( zErrMsg ){
25016 cli_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
25017 sqlite3_free(zErrMsg);
25018 }
25019 sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
25020 }
25021
@@ -23006,15 +25029,11 @@
25029 if( p->zDestTable ){
25030 sqlite3_free(p->zDestTable);
25031 p->zDestTable = 0;
25032 }
25033 if( zName==0 ) return;
25034 p->zDestTable = sqlite3_mprintf("%s", zName);
 
 
 
 
25035 shell_check_oom(p->zDestTable);
25036 }
25037
25038 /*
25039 ** Maybe construct two lines of text that point out the position of a
@@ -23080,36 +25099,36 @@
25099 int i;
25100 const char *z;
25101 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
25102 if( rc!=SQLITE_OK || !pSelect ){
25103 char *zContext = shell_error_context(zSelect, p->db);
25104 cli_printf(p->out, "/**** ERROR: (%d) %s *****/\n%s",
25105 rc, sqlite3_errmsg(p->db), zContext);
25106 sqlite3_free(zContext);
25107 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
25108 return rc;
25109 }
25110 rc = sqlite3_step(pSelect);
25111 nResult = sqlite3_column_count(pSelect);
25112 while( rc==SQLITE_ROW ){
25113 z = (const char*)sqlite3_column_text(pSelect, 0);
25114 cli_printf(p->out, "%s", z);
25115 for(i=1; i<nResult; i++){
25116 cli_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
25117 }
25118 if( z==0 ) z = "";
25119 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
25120 if( z[0] ){
25121 cli_puts("\n;\n", p->out);
25122 }else{
25123 cli_puts(";\n", p->out);
25124 }
25125 rc = sqlite3_step(pSelect);
25126 }
25127 rc = sqlite3_finalize(pSelect);
25128 if( rc!=SQLITE_OK ){
25129 cli_printf(p->out, "/**** ERROR: (%d) %s *****/\n",
25130 rc, sqlite3_errmsg(p->db));
25131 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
25132 }
25133 return rc;
25134 }
@@ -23165,11 +25184,11 @@
25184 };
25185 int i;
25186 for(i=0; i<ArraySize(aTrans); i++){
25187 int n = strlen30(aTrans[i].zPattern);
25188 if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){
25189 cli_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
25190 break;
25191 }
25192 }
25193 }
25194 fclose(in);
@@ -23197,11 +25216,11 @@
25216 if( nPercent>1 ){
25217 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
25218 }else{
25219 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
25220 }
25221 cli_printf(out, "%-36s %s\n", zLabel, zLine);
25222 }
25223
25224 /*
25225 ** Display memory stats.
25226 */
@@ -23219,34 +25238,34 @@
25238 if( pArg->pStmt && pArg->statsOn==2 ){
25239 int nCol, i, x;
25240 sqlite3_stmt *pStmt = pArg->pStmt;
25241 char z[100];
25242 nCol = sqlite3_column_count(pStmt);
25243 cli_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
25244 for(i=0; i<nCol; i++){
25245 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
25246 cli_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
25247 #ifndef SQLITE_OMIT_DECLTYPE
25248 sqlite3_snprintf(30, z+x, "declared type:");
25249 cli_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
25250 #endif
25251 #ifdef SQLITE_ENABLE_COLUMN_METADATA
25252 sqlite3_snprintf(30, z+x, "database name:");
25253 cli_printf(out, "%-36s %s\n", z,
25254 sqlite3_column_database_name(pStmt,i));
25255 sqlite3_snprintf(30, z+x, "table name:");
25256 cli_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
25257 sqlite3_snprintf(30, z+x, "origin name:");
25258 cli_printf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i));
25259 #endif
25260 }
25261 }
25262
25263 if( pArg->statsOn==3 ){
25264 if( pArg->pStmt ){
25265 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
25266 cli_printf(out, "VM-steps: %d\n", iCur);
25267 }
25268 return 0;
25269 }
25270
25271 displayStatLine(out, "Memory Used:",
@@ -23271,93 +25290,93 @@
25290 if( db ){
25291 if( pArg->shellFlgs & SHFLG_Lookaside ){
25292 iHiwtr = iCur = -1;
25293 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
25294 &iCur, &iHiwtr, bReset);
25295 cli_printf(out,
25296 "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
25297 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
25298 &iCur, &iHiwtr, bReset);
25299 cli_printf(out,
25300 "Successful lookaside attempts: %d\n", iHiwtr);
25301 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
25302 &iCur, &iHiwtr, bReset);
25303 cli_printf(out,
25304 "Lookaside failures due to size: %d\n", iHiwtr);
25305 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
25306 &iCur, &iHiwtr, bReset);
25307 cli_printf(out,
25308 "Lookaside failures due to OOM: %d\n", iHiwtr);
25309 }
25310 iHiwtr = iCur = -1;
25311 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
25312 cli_printf(out,
25313 "Pager Heap Usage: %d bytes\n", iCur);
25314 iHiwtr = iCur = -1;
25315 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
25316 cli_printf(out,
25317 "Page cache hits: %d\n", iCur);
25318 iHiwtr = iCur = -1;
25319 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
25320 cli_printf(out,
25321 "Page cache misses: %d\n", iCur);
25322 iHiwtr64 = iCur64 = -1;
25323 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
25324 0);
25325 iHiwtr = iCur = -1;
25326 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
25327 cli_printf(out,
25328 "Page cache writes: %d\n", iCur);
25329 iHiwtr = iCur = -1;
25330 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
25331 cli_printf(out,
25332 "Page cache spills: %d\n", iCur);
25333 cli_printf(out,
25334 "Temporary data spilled to disk: %lld\n", iCur64);
25335 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
25336 1);
25337 iHiwtr = iCur = -1;
25338 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
25339 cli_printf(out,
25340 "Schema Heap Usage: %d bytes\n", iCur);
25341 iHiwtr = iCur = -1;
25342 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
25343 cli_printf(out,
25344 "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
25345 }
25346
25347 if( pArg->pStmt ){
25348 int iHit, iMiss;
25349 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
25350 bReset);
25351 cli_printf(out,
25352 "Fullscan Steps: %d\n", iCur);
25353 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
25354 cli_printf(out,
25355 "Sort Operations: %d\n", iCur);
25356 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
25357 cli_printf(out,
25358 "Autoindex Inserts: %d\n", iCur);
25359 iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
25360 bReset);
25361 iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
25362 bReset);
25363 if( iHit || iMiss ){
25364 cli_printf(out,
25365 "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss);
25366 }
25367 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
25368 cli_printf(out,
25369 "Virtual Machine Steps: %d\n", iCur);
25370 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
25371 cli_printf(out,
25372 "Reprepare operations: %d\n", iCur);
25373 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
25374 cli_printf(out,
25375 "Number of times run: %d\n", iCur);
25376 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
25377 cli_printf(out,
25378 "Memory used by prepared stmt: %d\n", iCur);
25379 }
25380
25381 #ifdef __linux__
25382 displayLinuxIoStats(pArg->out);
@@ -23366,271 +25385,10 @@
25385 /* Do not remove this machine readable comment: extra-stats-output-here */
25386
25387 return 0;
25388 }
25389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25390 /*
25391 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
25392 */
25393 static unsigned int savedSelectTrace;
25394 static unsigned int savedWhereTrace;
@@ -23756,584 +25514,10 @@
25514 sqlite3_reset(pQ);
25515 }
25516 sqlite3_finalize(pQ);
25517 }
25518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25519 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
25520 /*
25521 ** This function is called to process SQL if the previous shell command
25522 ** was ".expert". It passes the SQL in the second argument directly to
25523 ** the sqlite3expert object.
@@ -24381,25 +25565,25 @@
25565 int nQuery = sqlite3_expert_count(p);
25566 int i;
25567
25568 if( bVerbose ){
25569 const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
25570 cli_puts("-- Candidates -----------------------------\n", out);
25571 cli_printf(out, "%s\n", zCand);
25572 }
25573 for(i=0; i<nQuery; i++){
25574 const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
25575 const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
25576 const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
25577 if( zIdx==0 ) zIdx = "(no new indexes)\n";
25578 if( bVerbose ){
25579 cli_printf(out,
25580 "-- Query %d --------------------------------\n"
25581 "%s\n\n"
25582 ,i+1, zSql);
25583 }
25584 cli_printf(out, "%s\n%s\n", zIdx, zEQP);
25585 }
25586 }
25587 }
25588 sqlite3_expert_destroy(p);
25589 pState->expert.pExpert = 0;
@@ -24430,30 +25614,30 @@
25614 if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){
25615 pState->expert.bVerbose = 1;
25616 }
25617 else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
25618 if( i==(nArg-1) ){
25619 cli_printf(stderr, "option requires an argument: %s\n", z);
25620 rc = SQLITE_ERROR;
25621 }else{
25622 iSample = (int)integerValue(azArg[++i]);
25623 if( iSample<0 || iSample>100 ){
25624 cli_printf(stderr,"value out of range: %s\n", azArg[i]);
25625 rc = SQLITE_ERROR;
25626 }
25627 }
25628 }
25629 else{
25630 cli_printf(stderr,"unknown option: %s\n", z);
25631 rc = SQLITE_ERROR;
25632 }
25633 }
25634
25635 if( rc==SQLITE_OK ){
25636 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
25637 if( pState->expert.pExpert==0 ){
25638 cli_printf(stderr,
25639 "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
25640 rc = SQLITE_ERROR;
25641 }else{
25642 sqlite3_expert_config(
25643 pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
@@ -24463,10 +25647,19 @@
25647 sqlite3_free(zErr);
25648
25649 return rc;
25650 }
25651 #endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */
25652
25653 /*
25654 ** QRF write callback
25655 */
25656 static int shellWriteQR(void *pX, const char *z, sqlite3_int64 n){
25657 ShellState *pArg = (ShellState*)pX;
25658 cli_printf(pArg->out, "%.*s", (int)n, z);
25659 return SQLITE_OK;
25660 }
25661
25662 /*
25663 ** Execute a statement or set of statements. Print
25664 ** any result rows/columns depending on the current mode
25665 ** set via the supplied callback.
@@ -24483,13 +25676,26 @@
25676 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
25677 int rc = SQLITE_OK; /* Return Code */
25678 int rc2;
25679 const char *zLeftover; /* Tail of unprocessed SQL */
25680 sqlite3 *db = pArg->db;
25681 unsigned char eStyle;
25682 sqlite3_qrf_spec spec;
25683
25684 if( pzErrMsg ){
25685 *pzErrMsg = NULL;
25686 }
25687 memcpy(&spec, &pArg->mode.spec, sizeof(spec));
25688 spec.xWrite = shellWriteQR;
25689 spec.pWriteArg = (void*)pArg;
25690 if( pArg->mode.eMode==MODE_Insert && ShellHasFlag(pArg, SHFLG_PreserveRowid) ){
25691 spec.bTitles = QRF_SW_On;
25692 }
25693 assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) );
25694 eStyle = aModeInfo[pArg->mode.eMode].eStyle;
25695 if( pArg->mode.bAutoScreenWidth ){
25696 spec.nScreenWidth = shellScreenWidth();
25697 }
25698
25699 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
25700 if( pArg->expert.pExpert ){
25701 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
@@ -24503,10 +25709,11 @@
25709 if( SQLITE_OK != rc ){
25710 if( pzErrMsg ){
25711 *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
25712 }
25713 }else{
25714 int isExplain;
25715 if( !pStmt ){
25716 /* this happens for a comment or white-space */
25717 zSql = zLeftover;
25718 while( IsSpace(zSql[0]) ) zSql++;
25719 continue;
@@ -24513,93 +25720,73 @@
25720 }
25721 zStmtSql = sqlite3_sql(pStmt);
25722 if( zStmtSql==0 ) zStmtSql = "";
25723 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
25724
25725 /* save off the prepared statement handle */
25726 if( pArg ){
25727 pArg->pStmt = pStmt;
 
25728 }
25729
25730 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
25731 isExplain = sqlite3_stmt_isexplain(pStmt);
25732 if( pArg && pArg->mode.autoEQP && isExplain==0 ){
25733 int triggerEQP = 0;
25734 disable_debug_trace_modes();
25735 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
25736 if( pArg->mode.autoEQP>=AUTOEQP_trigger ){
25737 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
25738 }
25739 sqlite3_reset(pStmt);
25740 spec.eStyle = QRF_STYLE_Auto;
25741 sqlite3_stmt_explain(pStmt, 2-(pArg->mode.autoEQP>=AUTOEQP_full));
25742 sqlite3_format_query_result(pStmt, &spec, 0);
25743 if( pArg->mode.autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25744 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
25745 }
25746 sqlite3_reset(pStmt);
25747 sqlite3_stmt_explain(pStmt, 0);
25748 restore_debug_trace_modes();
25749 }
25750
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25751 bind_prepared_stmt(pArg, pStmt);
25752 if( isExplain && pArg->mode.autoExplain ){
25753 spec.eStyle = isExplain==1 ? QRF_STYLE_Explain : QRF_STYLE_Eqp;
25754 sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25755 }else if( pArg->mode.eMode==MODE_Www ){
25756 cli_printf(pArg->out,
25757 "</PRE>\n"
25758 "<TABLE border='1' cellspacing='0' cellpadding='2'>\n");
25759 spec.eStyle = QRF_STYLE_Html;
25760 sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25761 cli_printf(pArg->out,
25762 "</TABLE>\n"
25763 "<PRE>");
25764 }else{
25765 spec.eStyle = eStyle;
25766 sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
25767 }
25768
25769 /* print usage stats if stats on */
25770 if( pArg && pArg->statsOn ){
25771 display_stats(db, pArg, 0);
25772 }
25773
25774 /* print loop-counters if required */
25775 if( pArg && pArg->mode.scanstatsOn ){
25776 char *zErr = 0;
25777 switch( pArg->mode.scanstatsOn ){
25778 case 1: spec.eStyle = QRF_STYLE_Stats; break;
25779 case 2: spec.eStyle = QRF_STYLE_StatsEst; break;
25780 default: spec.eStyle = QRF_STYLE_StatsVm; break;
25781 }
25782 sqlite3_reset(pStmt);
25783 rc = sqlite3_format_query_result(pStmt, &spec, &zErr);
25784 if( rc ){
25785 cli_printf(stderr, "Stats query failed: %s\n", zErr);
25786 sqlite3_free(zErr);
25787 }
25788 }
25789
25790 /* Finalize the statement just executed. If this fails, save a
25791 ** copy of the error message. Otherwise, set zSql to point to the
25792 ** next statement to execute. */
@@ -24791,34 +25978,34 @@
25978 ** have been recreated by prior repopulations. See forum posts:
25979 ** 2024-10-13T17:10:01z and 2025-10-29T19:38:43z
25980 */
25981 if( db_int(p->db, "SELECT count(*) FROM sqlite_sequence")>0 ){
25982 if( !p->writableSchema ){
25983 cli_puts("PRAGMA writable_schema=ON;\n", p->out);
25984 p->writableSchema = 1;
25985 }
25986 cli_puts("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n"
25987 "DELETE FROM sqlite_sequence;\n", p->out);
25988 }
25989 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
25990 if( !dataOnly ) cli_puts("ANALYZE sqlite_schema;\n", p->out);
25991 }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
25992 return 0;
25993 }else if( dataOnly ){
25994 /* no-op */
25995 }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
25996 char *zIns;
25997 if( !p->writableSchema ){
25998 cli_puts("PRAGMA writable_schema=ON;\n", p->out);
25999 p->writableSchema = 1;
26000 }
26001 zIns = sqlite3_mprintf(
26002 "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
26003 "VALUES('table','%q','%q',0,'%q');",
26004 zTable, zTable, zSql);
26005 shell_check_oom(zIns);
26006 cli_printf(p->out, "%s\n", zIns);
26007 sqlite3_free(zIns);
26008 return 0;
26009 }else{
26010 printSchemaLine(p->out, zSql, ";\n");
26011 }
@@ -24826,12 +26013,11 @@
26013 if( cli_strcmp(zType, "table")==0 ){
26014 ShellText sSelect;
26015 ShellText sTable;
26016 char **azCol;
26017 int i;
26018 Mode savedMode;
 
26019
26020 azCol = tableColumnList(p, zTable);
26021 if( azCol==0 ){
26022 p->nErr++;
26023 return 0;
@@ -24870,22 +26056,22 @@
26056 }
26057 freeColumnList(azCol);
26058 appendText(&sSelect, " FROM ", 0);
26059 appendText(&sSelect, zTable, quoteChar(zTable));
26060
26061
26062 savedMode = p->mode;
26063 p->mode.spec.zTableName = (char*)zTable;
26064 p->mode.eMode = MODE_Insert;
26065 p->mode.spec.bTitles = QRF_No;
26066 rc = shell_exec(p, sSelect.zTxt, 0);
26067 if( (rc&0xff)==SQLITE_CORRUPT ){
26068 cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
26069 toggleSelectOrder(p->db);
26070 shell_exec(p, sSelect.zTxt, 0);
26071 toggleSelectOrder(p->db);
26072 }
 
26073 p->mode = savedMode;
26074 freeText(&sTable);
26075 freeText(&sSelect);
26076 if( rc ) p->nErr++;
26077 }
@@ -24907,22 +26093,22 @@
26093 char *zErr = 0;
26094 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
26095 if( rc==SQLITE_CORRUPT ){
26096 char *zQ2;
26097 int len = strlen30(zQuery);
26098 cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
26099 if( zErr ){
26100 cli_printf(p->out, "/****** %s ******/\n", zErr);
26101 sqlite3_free(zErr);
26102 zErr = 0;
26103 }
26104 zQ2 = malloc( len+100 );
26105 if( zQ2==0 ) return rc;
26106 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
26107 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
26108 if( rc ){
26109 cli_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
26110 }else{
26111 rc = SQLITE_CORRUPT;
26112 }
26113 free(zQ2);
26114 }
@@ -25019,27 +26205,14 @@
26205 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
26206 ".filectrl CMD ... Run various sqlite3_file_control() operations",
26207 " --schema SCHEMA Use SCHEMA instead of \"main\"",
26208 " --help Show CMD details",
26209 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
26210 ",headers on|off Turn display of headers on or off",
26211 ".help ?-all? ?PATTERN? Show help text for PATTERN",
26212 #ifndef SQLITE_SHELL_FIDDLE
26213 ".import FILE TABLE Import data from FILE into TABLE",
 
 
 
 
 
 
 
 
 
 
 
 
 
26214 #endif
26215 #ifndef SQLITE_OMIT_TEST_CONTROL
26216 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
26217 #endif
26218 ".indexes ?TABLE? Show names of indexes",
@@ -25060,46 +26233,16 @@
26233 ".log FILE|on|off Turn logging on or off. FILE can be stderr/stdout",
26234 #else
26235 ".log on|off Turn logging on or off.",
26236 #endif
26237 ".mode ?MODE? ?OPTIONS? Set output mode",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26238 #ifndef SQLITE_SHELL_FIDDLE
26239 ".nonce STRING Suspend safe mode for one command if nonce matches",
26240 #endif
26241 ".nullvalue STRING Use STRING in place of NULL values",
26242 #ifndef SQLITE_SHELL_FIDDLE
26243 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
 
 
 
 
 
 
26244 /* Note that .open is (partially) available in WASM builds but is
26245 ** currently only intended to be used by the fiddle tool, not
26246 ** end users, so is "undocumented." */
26247 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
26248 " Options:",
@@ -25121,18 +26264,10 @@
26264 " --nofollow Do not follow symbolic links",
26265 " --readonly Open FILE readonly",
26266 " --zip FILE is a ZIP archive",
26267 #ifndef SQLITE_SHELL_FIDDLE
26268 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
 
 
 
 
 
 
 
 
26269 #endif
26270 ".parameter CMD ... Manage SQL parameter bindings",
26271 " clear Erase all bindings",
26272 " init Initialize the TEMP table that holds bindings",
26273 " list List the current parameter bindings",
@@ -25171,11 +26306,11 @@
26306 " --nosys Omit objects whose names start with \"sqlite_\"",
26307 ",selftest ?OPTIONS? Run tests defined in the SELFTEST table",
26308 " Options:",
26309 " --init Create a new SELFTEST table",
26310 " -v Verbose output",
26311 ",separator COL ?ROW? Change the column and row separators",
26312 #if defined(SQLITE_ENABLE_SESSION)
26313 ".session ?NAME? CMD ... Create or control sessions",
26314 " Subcommands:",
26315 " attach TABLE Attach TABLE",
26316 " changeset FILE Write a changeset into FILE",
@@ -25198,11 +26333,11 @@
26333 " --sha3-512 Use the sha3-512 algorithm",
26334 " Any other argument is a LIKE pattern for tables to hash",
26335 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE)
26336 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
26337 #endif
26338 ",show Show the current values for various settings",
26339 ".stats ?ARG? Show stats or turn stats on or off",
26340 " off Turn off automatic stat display",
26341 " on Turn on automatic stat display",
26342 " stmt Show statement stats",
26343 " vmstep Show the virtual machine step count only",
@@ -25239,17 +26374,167 @@
26374 #endif
26375 ".version Show source, library and compiler versions",
26376 ".vfsinfo ?AUX? Information about the top-level VFS",
26377 ".vfslist List all available VFSes",
26378 ".vfsname ?AUX? Print the name of the VFS stack",
26379 ",width NUM1 NUM2 ... Set minimum column widths for columnar output",
26380 " Negative values right-justify",
26381 #ifndef SQLITE_SHELL_FIDDLE
26382 ".www Display output of the next command in web browser",
26383 " --plain Show results as text/plain, not as HTML",
26384 #endif
26385 };
26386
26387 /**************************************************************
26388 ** "Usage" help text automatically generated from comments */
26389 static const struct {
26390 const char *zCmd; /* Name of the dot-command */
26391 const char *zUsage; /* Documentation */
26392 } aUsage[] = {
26393 { ".import",
26394 "USAGE: .import [OPTIONS] FILE TABLE\n"
26395 "\n"
26396 "Import CSV or similar text from FILE into TABLE. If TABLE does\n"
26397 "not exist, it is created using the first row of FILE as the column\n"
26398 "names. If FILE begins with \"|\" then it is a command that is run\n"
26399 "and the output from the command is used as the input data.\n"
26400 "\n"
26401 "FILE is assumed to be in a CSV format, unless the current mode\n"
26402 "is \"ascii\" or \"tabs\" or unless one of the options below specify\n"
26403 "an alternative.\n"
26404 "\n"
26405 "Options:\n"
26406 " --ascii Use \\037 and \\036 as column and row separators on input\n"
26407 " --csv Input is standard RFC-4180 CSV.\n"
26408 " --schema S When creating TABLE, put it in schema S\n"
26409 " --skip N Ignore the first N rows of input\n"
26410 " -v Verbose mode\n"
26411 },
26412 { ".mode",
26413 "USAGE: .mode [MODE] [OPTIONS]\n"
26414 "\n"
26415 "Change the output mode to MODE and/or apply OPTIONS to the\n"
26416 "output mode. If no arguments, show the current output mode\n"
26417 "and relevant options.\n"
26418 "\n"
26419 "Options:\n"
26420 " --align STRING Set the alignment of text in columnar modes\n"
26421 " String consists of characters 'L', 'C', 'R'\n"
26422 " meaning \"left\", \"centered\", and \"right\", with\n"
26423 " one letter per column starting from the left.\n"
26424 " Unspecified alignment defaults to 'L'.\n"
26425 " --charlimit N Set the maximum number of output characters to\n"
26426 " show for any single SQL value to N. Longer values\n"
26427 " truncated. Zero means \"no limit\".\n"
26428 " --colsep STRING Use STRING as the column separator\n"
26429 " --escape ESC Enable/disable escaping of control characters\n"
26430 " in output. ESC can be \"off\", \"ascii\", or\n"
26431 " \"symbol\".\n"
26432 " --linelimit N Set the maximum number of output lines to show for\n"
26433 " any single SQL value to N. Longer values are\n"
26434 " truncated. Zero means \"no limit\". Only works\n"
26435 " in \"line\" mode and in columnar modes.\n"
26436 " --list List available modes\n"
26437 " --null STRING Render SQL NULL values as the given string\n"
26438 " --once Setting changes to the right are reverted after\n"
26439 " the next SQL command.\n"
26440 " --quote ARG Enable/disable quoting of text. ARG can be\n"
26441 " \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n"
26442 " or \"json\". \"off\" means show the text as-is.\n"
26443 " \"on and \"sql\" are synonyms.\n"
26444 " --reset Changes all mode settings back to their default.\n"
26445 " --rowsep STRING Use STRING as the row separator\n"
26446 " --screenwidth N Declare the screen width of the output device\n"
26447 " to be N characters. An attempt may be made to\n"
26448 " wrap output text to fit within this limit. Zero\n"
26449 " means \"no limit\". Or N can be \"auto\" to set the\n"
26450 " width automatically.\n"
26451 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
26452 " --tag NAME Save mode to the left as NAME.\n"
26453 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
26454 " --title ARG Whether or not to show column headers, and if so\n"
26455 " how to encode them. ARG can be \"off\", \"on\",\n"
26456 " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
26457 " -v|--verbose Verbose output\n"
26458 " --widths LIST Set the columns widths for columnar modes. The\n"
26459 " argument is a list of integers, one for each\n"
26460 " column. A \"0\" width means use a dynamic width\n"
26461 " based on the actual width of data. If there are\n"
26462 " fewer entries in LIST than columns, \"0\" is used\n"
26463 " for the unspecified widths.\n"
26464 " --wordwrap BOOLEAN Enable/disable word wrapping\n"
26465 " --wrap N Wrap columns wider than N characters\n"
26466 " --ww Shorthand for \"--wordwrap on\"\n"
26467 },
26468 { ".output",
26469 "USAGE: .output [OPTIONS] [FILE]\n"
26470 "\n"
26471 "Begin redirecting output to FILE. Or if FILE is omitted, revert\n"
26472 "to sending output to the console. If FILE begins with \"|\" then\n"
26473 "the remainder of file is taken as a pipe and output is directed\n"
26474 "into that pipe. If FILE is \"memory\" then output is captured in an\n"
26475 "internal memory buffer. If FILE is \"off\" then output is redirected\n"
26476 "into /dev/null or the equivalent.\n"
26477 "\n"
26478 "Options:\n"
26479 " --bom Prepend a byte-order mark to the output\n"
26480 " -e Accumulate output in a temporary text file then\n"
26481 " launch a text editor when the redirection ends.\n"
26482 " --error-prefix X Use X as the left-margin prefix for error messages.\n"
26483 " Set to an empty string to restore the default.\n"
26484 " --glob GLOB Raise an error if the memory buffer does not match\n"
26485 " the GLOB pattern.\n"
26486 " --keep Continue using the same \"memory\" buffer. Do not\n"
26487 " reset it or delete it. Useful in combination with\n"
26488 " --glob, --not-glob, and/or --verify.\n"
26489 " ---notglob GLOB Raise an error if the memory buffer does not match\n"
26490 " the GLOB pattern.\n"
26491 " --plain Use plain text rather than HTML tables with -w\n"
26492 " --show Write the memory buffer to the screen, for debugging.\n"
26493 " --verify ENDMARK Read subsequent lines of text until the first line\n"
26494 " that matches ENDMARK. Discard the ENDMARK. Compare\n"
26495 " the text against the accumulated output in memory and\n"
26496 " raise an error if there are any differences.\n"
26497 " -w Show the output in a web browser. Output is\n"
26498 " written into a temporary HTML file until the\n"
26499 " redirect ends, then the web browser is launched.\n"
26500 " Query results are shown as HTML tables, unless\n"
26501 " the --plain is used too.\n"
26502 " -x Show the output in a spreadsheet. Output is\n"
26503 " written to a temp file as CSV then the spreadsheet\n"
26504 " is launched when\n"
26505 },
26506 { ".once",
26507 "USAGE: .once [OPTIONS] FILE ...\n"
26508 "\n"
26509 "Write the output for the next line of SQL or the next dot-command into\n"
26510 "FILE. If FILE begins with \"|\" then it is a program into which output\n"
26511 "is written. The FILE argument should be omitted if one of the -e, -w,\n"
26512 "or -x options is used.\n"
26513 "\n"
26514 "Options:\n"
26515 " -e Capture output into a temporary file then bring up\n"
26516 " a text editor on that temporary file.\n"
26517 " --plain Use plain text rather than HTML tables with -w\n"
26518 " -w Capture output into an HTML file then bring up that\n"
26519 " file in a web browser\n"
26520 " -x Show the output in a spreadsheet. Output is\n"
26521 " written to a temp file as CSV then the spreadsheet\n"
26522 " is launched when\n"
26523 },
26524 };
26525
26526 /*
26527 ** Return a pointer to usage text for zCmd, or NULL if none exists.
26528 */
26529 static const char *findUsage(const char *zCmd){
26530 int i;
26531 for(i=0; i<ArraySize(aUsage); i++){
26532 if( sqlite3_strglob(zCmd, aUsage[i].zCmd)==0 ) return aUsage[i].zUsage;
26533 }
26534 return 0;
26535 }
26536
26537 /*
26538 ** Output help text for commands that match zPattern.
26539 **
26540 ** * If zPattern is NULL, then show all documented commands, but
@@ -25276,10 +26561,11 @@
26561 static int showHelp(FILE *out, const char *zPattern){
26562 int i = 0;
26563 int j = 0;
26564 int n = 0;
26565 char *zPat;
26566 const char *zHit = 0;
26567 if( zPattern==0 ){
26568 /* Show just the first line for all help topics */
26569 zPattern = "[a-z]";
26570 }else if( cli_strcmp(zPattern,"-a")==0
26571 || cli_strcmp(zPattern,"-all")==0
@@ -25293,41 +26579,50 @@
26579 for(i=0; i<ArraySize(azHelp); i++){
26580 if( azHelp[i][0]=='.' ){
26581 show = 0;
26582 }else if( azHelp[i][0]==',' ){
26583 show = 1;
26584 cli_printf(out, ".%s\n", &azHelp[i][1]);
26585 n++;
26586 }else if( show ){
26587 cli_printf(out, "%s\n", azHelp[i]);
26588 }
26589 }
26590 return n;
26591 }
26592
26593 /* Seek documented commands for which zPattern is an exact prefix */
26594 zPat = sqlite3_mprintf(".%s*", zPattern[0]=='.' ? &zPattern[1] : zPattern);
26595 shell_check_oom(zPat);
26596 for(i=0; i<ArraySize(azHelp); i++){
26597 if( sqlite3_strglob(zPat, azHelp[i])==0 ){
26598 if( zHit ) cli_printf(out, "%s\n", zHit);
26599 zHit = azHelp[i];
26600 j = i+1;
26601 n++;
26602 }
26603 }
 
26604 if( n ){
26605 if( n==1 ){
26606 const char *zUsage = findUsage(zPat);
26607 if( zUsage ){
26608 cli_puts(zUsage, out);
26609 }else{
26610 /* when zPattern is a prefix of exactly one command, then include
26611 ** the details of that command, which should begin at offset j */
26612 cli_printf(out, "%s\n", zHit);
26613 while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
26614 cli_printf(out, "%s\n", azHelp[j]);
26615 j++;
26616 }
26617 }
26618 }else{
26619 cli_printf(out, "%s\n", zHit);
26620 }
26621 }
26622 sqlite3_free(zPat);
26623 if( n ) return n;
26624
26625 /* Look for documented commands that contain zPattern anywhere.
26626 ** Show complete text of all documented commands that match. */
26627 zPat = sqlite3_mprintf("%%%s%%", zPattern);
26628 shell_check_oom(zPat);
@@ -25336,14 +26631,14 @@
26631 while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
26632 continue;
26633 }
26634 if( azHelp[i][0]=='.' ) j = i;
26635 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
26636 cli_printf(out, "%s\n", azHelp[j]);
26637 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
26638 j++;
26639 cli_printf(out, "%s\n", azHelp[j]);
26640 }
26641 i = j;
26642 n++;
26643 }
26644 }
@@ -25376,27 +26671,27 @@
26671 char *pBuf;
26672 int rc;
26673 if( in==0 ) return 0;
26674 rc = fseek(in, 0, SEEK_END);
26675 if( rc!=0 ){
26676 cli_printf(stderr,"Error: '%s' not seekable\n", zName);
26677 fclose(in);
26678 return 0;
26679 }
26680 nIn = ftell(in);
26681 rewind(in);
26682 pBuf = sqlite3_malloc64( nIn+1 );
26683 if( pBuf==0 ){
26684 cli_puts("Error: out of memory\n", stderr);
26685 fclose(in);
26686 return 0;
26687 }
26688 nRead = fread(pBuf, nIn, 1, in);
26689 fclose(in);
26690 if( nRead!=1 ){
26691 sqlite3_free(pBuf);
26692 cli_printf(stderr,"Error: cannot read '%s'\n", zName);
26693 return 0;
26694 }
26695 pBuf[nIn] = 0;
26696 if( pnByte ) *pnByte = nIn;
26697 return pBuf;
@@ -25529,11 +26824,11 @@
26824 unsigned int x[16];
26825 char zLine[1000];
26826 if( zDbFilename ){
26827 in = sqlite3_fopen(zDbFilename, "r");
26828 if( in==0 ){
26829 cli_printf(stderr,"cannot open \"%s\" for reading\n", zDbFilename);
26830 return 0;
26831 }
26832 nLine = 0;
26833 }else{
26834 in = p->in;
@@ -25545,11 +26840,11 @@
26840 if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
26841 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
26842 if( rc!=2 ) goto readHexDb_error;
26843 if( n<0 ) goto readHexDb_error;
26844 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
26845 cli_puts("invalid pagesize\n", stderr);
26846 goto readHexDb_error;
26847 }
26848 sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
26849 a = sqlite3_malloc64( sz ? sz : 1 );
26850 shell_check_oom(a);
@@ -25556,11 +26851,11 @@
26851 memset(a, 0, sz);
26852 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
26853 int j = 0; /* Page number from "| page" line */
26854 int k = 0; /* Offset from "| page" line */
26855 if( nLine>=2000000000 ){
26856 cli_printf(stderr, "input too big\n");
26857 goto readHexDb_error;
26858 }
26859 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
26860 if( rc==2 ){
26861 iOffset = k;
@@ -25597,11 +26892,11 @@
26892 if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
26893 }
26894 p->lineno = nLine;
26895 }
26896 sqlite3_free(a);
26897 cli_printf(stderr,"Error on line %lld of --hexdb input\n", nLine);
26898 return 0;
26899 }
26900 #endif /* SQLITE_OMIT_DESERIALIZE */
26901
26902 /*
@@ -25702,23 +26997,23 @@
26997 sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0);
26998 break;
26999 }
27000 }
27001 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
27002 cli_printf(stderr,"Error: unable to open database \"%s\": %s\n",
27003 zDbFilename, sqlite3_errmsg(p->db));
27004 if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
27005 cli_exit(1);
27006 }
27007 sqlite3_close(p->db);
27008 sqlite3_open(":memory:", &p->db);
27009 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
27010 cli_puts("Also: unable to open substitute in-memory database.\n",
27011 stderr);
27012 cli_exit(1);
27013 }else{
27014 cli_printf(stderr,
27015 "Notice: using substitute in-memory database instead of \"%s\"\n",
27016 zDbFilename);
27017 }
27018 }
27019 globalDb = p->db;
@@ -25792,10 +27087,12 @@
27087 shellAddSchemaName, 0, 0);
27088 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, p,
27089 shellModuleSchema, 0, 0);
27090 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
27091 shellPutsFunc, 0, 0);
27092 sqlite3_create_function(p->db, "shell_format_schema", 2, SQLITE_UTF8, p,
27093 shellFormatSchema, 0, 0);
27094 sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
27095 shellUSleepFunc, 0, 0);
27096 #ifndef SQLITE_NOHAVE_SYSTEM
27097 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
27098 editFunc, 0, 0);
@@ -25826,11 +27123,11 @@
27123 }
27124 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
27125 SQLITE_DESERIALIZE_RESIZEABLE |
27126 SQLITE_DESERIALIZE_FREEONCLOSE);
27127 if( rc ){
27128 cli_printf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc);
27129 }
27130 if( p->szMax>0 ){
27131 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
27132 }
27133 }
@@ -25841,11 +27138,11 @@
27138 if( p->bSafeModePersist ){
27139 sqlite3_set_authorizer(p->db, safeModeAuth, p);
27140 }
27141 #endif
27142 sqlite3_db_config(
27143 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->mode.scanstatsOn, (int*)0
27144 );
27145 }
27146 }
27147
27148 /*
@@ -25852,11 +27149,11 @@
27149 ** Attempt to close the database connection. Report errors.
27150 */
27151 void close_db(sqlite3 *db){
27152 int rc = sqlite3_close(db);
27153 if( rc ){
27154 cli_printf(stderr,
27155 "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
27156 }
27157 }
27158
27159 #if (HAVE_READLINE || HAVE_EDITLINE) \
@@ -26025,11 +27322,11 @@
27322 return 1;
27323 }
27324 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
27325 return 0;
27326 }
27327 cli_printf(stderr,
27328 "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
27329 return 0;
27330 }
27331
27332 /*
@@ -26053,22 +27350,22 @@
27350 /*
27351 ** Try to open an output file. The names "stdout" and "stderr" are
27352 ** recognized and do the right thing. NULL is returned if the output
27353 ** filename is "off".
27354 */
27355 static FILE *output_file_open(ShellState *p, const char *zFile){
27356 FILE *f;
27357 if( cli_strcmp(zFile,"stdout")==0 ){
27358 f = stdout;
27359 }else if( cli_strcmp(zFile, "stderr")==0 ){
27360 f = stderr;
27361 }else if( cli_strcmp(zFile, "off")==0 || p->bSafeMode ){
27362 f = 0;
27363 }else{
27364 f = sqlite3_fopen(zFile, "w");
27365 if( f==0 ){
27366 cli_printf(stderr,"Error: cannot open \"%s\"\n", zFile);
27367 }
27368 }
27369 return f;
27370 }
27371
@@ -26117,16 +27414,16 @@
27414 if( nSql>1000000000 ) nSql = 1000000000;
27415 while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
27416 switch( mType ){
27417 case SQLITE_TRACE_ROW:
27418 case SQLITE_TRACE_STMT: {
27419 cli_printf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
27420 break;
27421 }
27422 case SQLITE_TRACE_PROFILE: {
27423 sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
27424 cli_printf(p->traceOut,
27425 "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
27426 break;
27427 }
27428 }
27429 return 0;
@@ -26230,15 +27527,15 @@
27527 do{ p->n--; }while( p->z[p->n]!=cQuote );
27528 p->cTerm = c;
27529 break;
27530 }
27531 if( pc==cQuote && c!='\r' ){
27532 cli_printf(stderr,"%s:%d: unescaped %c character\n",
27533 p->zFile, p->nLine, cQuote);
27534 }
27535 if( c==EOF ){
27536 cli_printf(stderr,"%s:%d: unterminated %c-quoted field\n",
27537 p->zFile, startLine, cQuote);
27538 p->cTerm = c;
27539 break;
27540 }
27541 import_append_char(p, c);
@@ -26333,11 +27630,11 @@
27630
27631 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
27632 shell_check_oom(zQuery);
27633 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
27634 if( rc ){
27635 cli_printf(stderr,"Error %d: %s on [%s]\n",
27636 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
27637 goto end_data_xfer;
27638 }
27639 n = sqlite3_column_count(pQuery);
27640 zInsert = sqlite3_malloc64(200 + nTable + n*3);
@@ -26350,11 +27647,11 @@
27647 i += 2;
27648 }
27649 memcpy(zInsert+i, ");", 3);
27650 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
27651 if( rc ){
27652 cli_printf(stderr,"Error %d: %s on [%s]\n",
27653 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert);
27654 goto end_data_xfer;
27655 }
27656 for(k=0; k<2; k++){
27657 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
@@ -26386,11 +27683,11 @@
27683 }
27684 }
27685 } /* End for */
27686 rc = sqlite3_step(pInsert);
27687 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
27688 cli_printf(stderr,"Error %d: %s\n",
27689 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb));
27690 }
27691 sqlite3_reset(pInsert);
27692 cnt++;
27693 if( (cnt%spinRate)==0 ){
@@ -26404,11 +27701,11 @@
27701 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
27702 zTable);
27703 shell_check_oom(zQuery);
27704 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
27705 if( rc ){
27706 cli_printf(stderr,"Warning: cannot step \"%s\" backwards", zTable);
27707 break;
27708 }
27709 } /* End for(k=0...) */
27710
27711 end_data_xfer:
@@ -26441,24 +27738,24 @@
27738 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
27739 " WHERE %s ORDER BY rowid ASC", zWhere);
27740 shell_check_oom(zQuery);
27741 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
27742 if( rc ){
27743 cli_printf(stderr,
27744 "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
27745 sqlite3_errmsg(p->db), zQuery);
27746 goto end_schema_xfer;
27747 }
27748 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
27749 zName = sqlite3_column_text(pQuery, 0);
27750 zSql = sqlite3_column_text(pQuery, 1);
27751 if( zName==0 || zSql==0 ) continue;
27752 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
27753 cli_printf(stdout, "%s... ", zName); fflush(stdout);
27754 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
27755 if( zErrMsg ){
27756 cli_printf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
27757 sqlite3_free(zErrMsg);
27758 zErrMsg = 0;
27759 }
27760 }
27761 if( xForEach ){
@@ -26472,23 +27769,23 @@
27769 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
27770 " WHERE %s ORDER BY rowid DESC", zWhere);
27771 shell_check_oom(zQuery);
27772 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
27773 if( rc ){
27774 cli_printf(stderr,"Error: (%d) %s on [%s]\n",
27775 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
27776 goto end_schema_xfer;
27777 }
27778 while( sqlite3_step(pQuery)==SQLITE_ROW ){
27779 zName = sqlite3_column_text(pQuery, 0);
27780 zSql = sqlite3_column_text(pQuery, 1);
27781 if( zName==0 || zSql==0 ) continue;
27782 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
27783 cli_printf(stdout, "%s... ", zName); fflush(stdout);
27784 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
27785 if( zErrMsg ){
27786 cli_printf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
27787 sqlite3_free(zErrMsg);
27788 zErrMsg = 0;
27789 }
27790 if( xForEach ){
27791 xForEach(p, newDb, (const char*)zName);
@@ -26508,16 +27805,16 @@
27805 */
27806 static void tryToClone(ShellState *p, const char *zNewDb){
27807 int rc;
27808 sqlite3 *newDb = 0;
27809 if( access(zNewDb,0)==0 ){
27810 cli_printf(stderr,"File \"%s\" already exists.\n", zNewDb);
27811 return;
27812 }
27813 rc = sqlite3_open(zNewDb, &newDb);
27814 if( rc ){
27815 cli_printf(stderr,
27816 "Cannot create output database: %s\n", sqlite3_errmsg(newDb));
27817 }else{
27818 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
27819 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
27820 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
@@ -26532,16 +27829,16 @@
27829 /*
27830 ** Change the output stream (file or pipe or console) to something else.
27831 */
27832 static void output_redir(ShellState *p, FILE *pfNew){
27833 if( p->out != stdout ){
27834 cli_puts("Output already redirected.\n", stderr);
27835 }else{
27836 p->out = pfNew;
27837 setCrlfMode(p);
27838 if( p->mode.eMode==MODE_Www ){
27839 cli_puts(
27840 "<!DOCTYPE html>\n"
27841 "<HTML><BODY><PRE>\n",
27842 p->out
27843 );
27844 }
@@ -26559,12 +27856,12 @@
27856 if( p->outfile[0]=='|' ){
27857 #ifndef SQLITE_OMIT_POPEN
27858 pclose(p->out);
27859 #endif
27860 }else{
27861 if( p->mode.eMode==MODE_Www ){
27862 cli_puts("</PRE></BODY></HTML>\n", p->out);
27863 }
27864 output_file_close(p->out);
27865 #ifndef SQLITE_NOHAVE_SYSTEM
27866 if( p->doXdgOpen ){
27867 const char *zXdgOpenCmd =
@@ -26576,26 +27873,30 @@
27873 "xdg-open";
27874 #endif
27875 char *zCmd;
27876 zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
27877 if( system(zCmd) ){
27878 cli_printf(stderr,"Failed: [%s]\n", zCmd);
27879 }else{
27880 /* Give the start/open/xdg-open command some time to get
27881 ** going before we continue, and potential delete the
27882 ** p->zTempFile data file out from under it */
27883 sqlite3_sleep(2000);
27884 }
27885 sqlite3_free(zCmd);
27886 modePop(p);
27887 p->doXdgOpen = 0;
27888 }
27889 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
27890 }
27891 p->outfile[0] = 0;
27892 p->out = stdout;
27893 setCrlfMode(p);
27894 if( cli_output_capture ){
27895 sqlite3_str_free(cli_output_capture);
27896 cli_output_capture = 0;
27897 }
27898 }
27899 #else
27900 # define output_redir(SS,pfO)
27901 # define output_reset(SS)
27902 #endif
@@ -26676,11 +27977,11 @@
27977 if( p->db==0 ) return 1;
27978 rc = sqlite3_prepare_v2(p->db,
27979 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
27980 -1, &pStmt, 0);
27981 if( rc ){
27982 cli_printf(stderr,"error: %s\n", sqlite3_errmsg(p->db));
27983 sqlite3_finalize(pStmt);
27984 return 1;
27985 }
27986 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
27987 if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -26689,32 +27990,32 @@
27990 const u8 *pb = sqlite3_column_blob(pStmt,0);
27991 shell_check_oom(pb);
27992 memcpy(aHdr, pb, 100);
27993 sqlite3_finalize(pStmt);
27994 }else{
27995 cli_puts("unable to read database header\n", stderr);
27996 sqlite3_finalize(pStmt);
27997 return 1;
27998 }
27999 i = get2byteInt(aHdr+16);
28000 if( i==1 ) i = 65536;
28001 cli_printf(p->out, "%-20s %d\n", "database page size:", i);
28002 cli_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
28003 cli_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
28004 cli_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
28005 for(i=0; i<ArraySize(aField); i++){
28006 int ofst = aField[i].ofst;
28007 unsigned int val = get4byteInt(aHdr + ofst);
28008 cli_printf(p->out, "%-20s %u", aField[i].zName, val);
28009 switch( ofst ){
28010 case 56: {
28011 if( val==1 ) cli_puts(" (utf8)", p->out);
28012 if( val==2 ) cli_puts(" (utf16le)", p->out);
28013 if( val==3 ) cli_puts(" (utf16be)", p->out);
28014 }
28015 }
28016 cli_puts("\n", p->out);
28017 }
28018 if( zDb==0 ){
28019 zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
28020 }else if( cli_strcmp(zDb,"temp")==0 ){
28021 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
@@ -26721,15 +28022,15 @@
28022 }else{
28023 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
28024 }
28025 for(i=0; i<ArraySize(aQuery); i++){
28026 int val = db_int(p->db, aQuery[i].zSql, zSchemaTab);
28027 cli_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
28028 }
28029 sqlite3_free(zSchemaTab);
28030 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
28031 cli_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
28032 return 0;
28033 }
28034 #endif /* SQLITE_SHELL_HAVE_RECOVER */
28035
28036 /*
@@ -26785,11 +28086,11 @@
28086 zTail++;
28087 }
28088 }
28089 zName = strdup(zTail);
28090 shell_check_oom(zName);
28091 cli_printf(p->out, "| size %lld pagesize %d filename %s\n",
28092 nPage*pgSz, pgSz, zName);
28093 sqlite3_finalize(pStmt);
28094 pStmt = 0;
28095 rc = sqlite3_prepare_v2(p->db,
28096 "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
@@ -26801,31 +28102,31 @@
28102 for(i=0; i<pgSz; i+=16){
28103 const u8 *aLine = aData+i;
28104 for(j=0; j<16 && aLine[j]==0; j++){}
28105 if( j==16 ) continue;
28106 if( !seenPageLabel ){
28107 cli_printf(p->out, "| page %lld offset %lld\n",pgno,(pgno-1)*pgSz);
28108 seenPageLabel = 1;
28109 }
28110 cli_printf(p->out, "| %5d:", i);
28111 for(j=0; j<16; j++) cli_printf(p->out, " %02x", aLine[j]);
28112 cli_printf(p->out, " ");
28113 for(j=0; j<16; j++){
28114 unsigned char c = (unsigned char)aLine[j];
28115 cli_printf(p->out, "%c", bShow[c]);
28116 }
28117 cli_printf(p->out, "\n");
28118 }
28119 }
28120 sqlite3_finalize(pStmt);
28121 cli_printf(p->out, "| end %s\n", zName);
28122 free(zName);
28123 return 0;
28124
28125 dbtotxt_error:
28126 if( rc ){
28127 cli_printf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
28128 }
28129 sqlite3_finalize(pStmt);
28130 free(zName);
28131 return 1;
28132 }
@@ -26832,11 +28133,11 @@
28133
28134 /*
28135 ** Print the given string as an error message.
28136 */
28137 static void shellEmitError(const char *zErr){
28138 cli_printf(stderr,"Error: %s\n", zErr);
28139 }
28140 /*
28141 ** Print the current sqlite3_errmsg() value to stderr and return 1.
28142 */
28143 static int shellDatabaseError(sqlite3 *db){
@@ -27015,42 +28316,45 @@
28316 if( shellDeleteFile(p->zTempFile) ) return;
28317 sqlite3_free(p->zTempFile);
28318 p->zTempFile = 0;
28319 }
28320
28321 /* Forward reference */
28322 static char *find_home_dir(int clearFlag);
28323
28324 /*
28325 ** Create a new temp file name with the given suffix.
28326 **
28327 ** Because the classic temp folders like /tmp are no longer
28328 ** accessible to web browsers, for security reasons, create the
28329 ** temp file in the user's home directory.
28330 */
28331 static void newTempFile(ShellState *p, const char *zSuffix){
28332 char *zHome; /* Home directory */
28333 int i; /* Loop counter */
28334 sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
28335 char zRand[32]; /* Text string with 160 bits of randomness */
28336 #ifdef _WIN32
28337 const char cDirSep = '\\';
28338 #else
28339 const char cDirSep = '/';
28340 #endif
28341
28342 for(i=0; i<31; i++){
28343 if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
28344 zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
28345 r /= 36;
28346 }
28347 zRand[i] = 0;
28348 clearTempFile(p);
28349 sqlite3_free(p->zTempFile);
28350 p->zTempFile = 0;
28351 zHome = find_home_dir(0);
28352 p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
28353 zHome,cDirSep,zRand,zSuffix);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28354 shell_check_oom(p->zTempFile);
28355 }
 
28356
28357 /*
28358 ** The implementation of SQL scalar function fkey_collate_clause(), used
28359 ** by the ".lint fkey-indexes" command. This scalar function is always
28360 ** called with four arguments - the parent table name, the parent column name,
@@ -27192,11 +28496,11 @@
28496 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
28497 bGroupByParent = 1;
28498 zIndent = " ";
28499 }
28500 else{
28501 cli_printf(stderr,
28502 "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]);
28503 return SQLITE_ERROR;
28504 }
28505 }
28506
@@ -27237,45 +28541,45 @@
28541 }
28542 rc = sqlite3_finalize(pExplain);
28543 if( rc!=SQLITE_OK ) break;
28544
28545 if( res<0 ){
28546 cli_puts("Error: internal error", stderr);
28547 break;
28548 }else{
28549 if( bGroupByParent
28550 && (bVerbose || res==0)
28551 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
28552 ){
28553 cli_printf(out, "-- Parent table %s\n", zParent);
28554 sqlite3_free(zPrev);
28555 zPrev = sqlite3_mprintf("%s", zParent);
28556 }
28557
28558 if( res==0 ){
28559 cli_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
28560 }else if( bVerbose ){
28561 cli_printf(out,
28562 "%s/* no extra indexes required for %s -> %s */\n",
28563 zIndent, zFrom, zTarget
28564 );
28565 }
28566 }
28567 }
28568 sqlite3_free(zPrev);
28569
28570 if( rc!=SQLITE_OK ){
28571 cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
28572 }
28573
28574 rc2 = sqlite3_finalize(pSql);
28575 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
28576 rc = rc2;
28577 cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
28578 }
28579 }else{
28580 cli_printf(stderr,"%s\n", sqlite3_errmsg(db));
28581 }
28582
28583 return rc;
28584 }
28585
@@ -27291,13 +28595,13 @@
28595 n = (nArg>=2 ? strlen30(azArg[1]) : 0);
28596 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
28597 return lintFkeyIndexes(pState, azArg, nArg);
28598
28599 usage:
28600 cli_printf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]);
28601 cli_printf(stderr, "Where sub-commands are:\n");
28602 cli_printf(stderr, " fkey-indexes\n");
28603 return SQLITE_ERROR;
28604 }
28605
28606 static void shellPrepare(
28607 sqlite3 *db,
@@ -27307,11 +28611,11 @@
28611 ){
28612 *ppStmt = 0;
28613 if( *pRc==SQLITE_OK ){
28614 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
28615 if( rc!=SQLITE_OK ){
28616 cli_printf(stderr,
28617 "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db));
28618 *pRc = rc;
28619 }
28620 }
28621 }
@@ -27352,11 +28656,11 @@
28656 if( pStmt ){
28657 sqlite3 *db = sqlite3_db_handle(pStmt);
28658 int rc = sqlite3_finalize(pStmt);
28659 if( *pRc==SQLITE_OK ){
28660 if( rc!=SQLITE_OK ){
28661 cli_printf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
28662 }
28663 *pRc = rc;
28664 }
28665 }
28666 }
@@ -27374,11 +28678,11 @@
28678 ){
28679 int rc = sqlite3_reset(pStmt);
28680 if( *pRc==SQLITE_OK ){
28681 if( rc!=SQLITE_OK ){
28682 sqlite3 *db = sqlite3_db_handle(pStmt);
28683 cli_printf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));
28684 }
28685 *pRc = rc;
28686 }
28687 }
28688 #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
@@ -27427,13 +28731,13 @@
28731 va_start(ap, zFmt);
28732 z = sqlite3_vmprintf(zFmt, ap);
28733 va_end(ap);
28734 shellEmitError(z);
28735 if( pAr->fromCmdLine ){
28736 cli_puts("Use \"-A\" for more help\n", stderr);
28737 }else{
28738 cli_puts("Use \".archive --help\" for more help\n", stderr);
28739 }
28740 sqlite3_free(z);
28741 return SQLITE_ERROR;
28742 }
28743
@@ -27529,11 +28833,11 @@
28833 };
28834 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
28835 struct ArSwitch *pEnd = &aSwitch[nSwitch];
28836
28837 if( nArg<=1 ){
28838 cli_printf(stderr, "Wrong number of arguments. Usage:\n");
28839 return arUsage(stderr);
28840 }else{
28841 char *z = azArg[1];
28842 if( z[0]!='-' ){
28843 /* Traditional style [tar] invocation */
@@ -27635,11 +28939,11 @@
28939 }
28940 }
28941 }
28942 }
28943 if( pAr->eCmd==0 ){
28944 cli_printf(stderr, "Required argument missing. Usage:\n");
28945 return arUsage(stderr);
28946 }
28947 return SQLITE_OK;
28948 }
28949
@@ -27678,11 +28982,11 @@
28982 if( SQLITE_ROW==sqlite3_step(pTest) ){
28983 bOk = 1;
28984 }
28985 shellReset(&rc, pTest);
28986 if( rc==SQLITE_OK && bOk==0 ){
28987 cli_printf(stderr,"not found in archive: %s\n", z);
28988 rc = SQLITE_ERROR;
28989 }
28990 }
28991 shellFinalize(&rc, pTest);
28992 }
@@ -27761,19 +29065,19 @@
29065 arWhereClause(&rc, pAr, &zWhere);
29066
29067 shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
29068 pAr->zSrcTable, zWhere);
29069 if( pAr->bDryRun ){
29070 cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
29071 }else{
29072 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
29073 if( pAr->bVerbose ){
29074 cli_printf(pAr->out, "%s % 10d %s %s\n",
29075 sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1),
29076 sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3));
29077 }else{
29078 cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
29079 }
29080 }
29081 }
29082 shellFinalize(&rc, pSql);
29083 sqlite3_free(zWhere);
@@ -27796,11 +29100,11 @@
29100 }
29101 if( rc==SQLITE_OK ){
29102 zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
29103 pAr->zSrcTable, zWhere);
29104 if( pAr->bDryRun ){
29105 cli_printf(pAr->out, "%s\n", zSql);
29106 }else{
29107 char *zErr = 0;
29108 rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
29109 if( rc==SQLITE_OK ){
29110 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
@@ -27809,11 +29113,11 @@
29113 }else{
29114 rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
29115 }
29116 }
29117 if( zErr ){
29118 cli_printf(stdout, "ERROR: %s\n", zErr); /* stdout? */
29119 sqlite3_free(zErr);
29120 }
29121 }
29122 }
29123 sqlite3_free(zWhere);
@@ -27873,15 +29177,15 @@
29177 ** populating them changes the timestamp). */
29178 for(i=0; i<2; i++){
29179 j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
29180 sqlite3_bind_int(pSql, j, i);
29181 if( pAr->bDryRun ){
29182 cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
29183 }else{
29184 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
29185 if( i==0 && pAr->bVerbose ){
29186 cli_printf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0));
29187 }
29188 }
29189 }
29190 shellReset(&rc, pSql);
29191 }
@@ -27897,17 +29201,17 @@
29201 ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
29202 */
29203 static int arExecSql(ArCommand *pAr, const char *zSql){
29204 int rc;
29205 if( pAr->bDryRun ){
29206 cli_printf(pAr->out, "%s\n", zSql);
29207 rc = SQLITE_OK;
29208 }else{
29209 char *zErr = 0;
29210 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
29211 if( zErr ){
29212 cli_printf(stdout, "ERROR: %s\n", zErr);
29213 sqlite3_free(zErr);
29214 }
29215 }
29216 return rc;
29217 }
@@ -28079,17 +29383,17 @@
29383 }else{
29384 flags = SQLITE_OPEN_READONLY;
29385 }
29386 cmd.db = 0;
29387 if( cmd.bDryRun ){
29388 cli_printf(cmd.out, "-- open database '%s'%s\n", cmd.zFile,
29389 eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
29390 }
29391 rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
29392 eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
29393 if( rc!=SQLITE_OK ){
29394 cli_printf(stderr, "cannot open file: %s (%s)\n",
29395 cmd.zFile, sqlite3_errmsg(cmd.db));
29396 goto end_ar_command;
29397 }
29398 sqlite3_fileio_init(cmd.db, 0, 0);
29399 sqlite3_sqlar_init(cmd.db, 0, 0);
@@ -28099,11 +29403,11 @@
29403 }
29404 if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
29405 if( cmd.eCmd!=AR_CMD_CREATE
29406 && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
29407 ){
29408 cli_printf(stderr, "database does not contain an 'sqlar' table\n");
29409 rc = SQLITE_ERROR;
29410 goto end_ar_command;
29411 }
29412 cmd.zSrcTable = sqlite3_mprintf("sqlar");
29413 }
@@ -28157,11 +29461,11 @@
29461 ** This function is used as a callback by the recover extension. Simply
29462 ** print the supplied SQL statement to stdout.
29463 */
29464 static int recoverSqlCb(void *pCtx, const char *zSql){
29465 ShellState *pState = (ShellState*)pCtx;
29466 cli_printf(pState->out, "%s;\n", zSql);
29467 return SQLITE_OK;
29468 }
29469
29470 /*
29471 ** This function is called to recover data from the database. A script
@@ -28200,11 +29504,11 @@
29504 }else
29505 if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
29506 bRowids = 0;
29507 }
29508 else{
29509 cli_printf(stderr,"unexpected option: %s\n", azArg[i]);
29510 showHelp(pState->out, azArg[0]);
29511 return 1;
29512 }
29513 }
29514
@@ -28215,16 +29519,16 @@
29519 sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */
29520 sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
29521 sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
29522 sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
29523
29524 cli_printf(pState->out, ".dbconfig defensive off\n");
29525 sqlite3_recover_run(p);
29526 if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
29527 const char *zErr = sqlite3_recover_errmsg(p);
29528 int errCode = sqlite3_recover_errcode(p);
29529 cli_printf(stderr,"sql error: %s (%d)\n", zErr, errCode);
29530 }
29531 rc = sqlite3_recover_finish(p);
29532 return rc;
29533 }
29534 #endif /* SQLITE_SHELL_HAVE_RECOVER */
@@ -28242,25 +29546,25 @@
29546 i64 nError = 0;
29547 const char *zErr = 0;
29548 while( SQLITE_OK==sqlite3_intck_step(p) ){
29549 const char *zMsg = sqlite3_intck_message(p);
29550 if( zMsg ){
29551 cli_printf(pState->out, "%s\n", zMsg);
29552 nError++;
29553 }
29554 nStep++;
29555 if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){
29556 sqlite3_intck_unlock(p);
29557 }
29558 }
29559 rc = sqlite3_intck_error(p, &zErr);
29560 if( zErr ){
29561 cli_printf(stderr,"%s\n", zErr);
29562 }
29563 sqlite3_intck_close(p);
29564
29565 cli_printf(pState->out, "%lld steps, %lld errors\n", nStep, nError);
29566 }
29567
29568 return rc;
29569 }
29570
@@ -28279,11 +29583,11 @@
29583 */
29584 #ifdef SHELL_DEBUG
29585 #define rc_err_oom_die(rc) \
29586 if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
29587 else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
29588 cli_printf(stderr,"E:%d\n",rc), assert(0)
29589 #else
29590 static void rc_err_oom_die(int rc){
29591 if( rc==SQLITE_NOMEM ) shell_check_oom(0);
29592 assert(rc==SQLITE_OK||rc==SQLITE_DONE);
29593 }
@@ -28496,11 +29800,11 @@
29800 shellPreparePrintf(p->db, &rc, &pStmt,
29801 "SELECT 1 FROM sqlite_schema o WHERE "
29802 "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true"
29803 );
29804 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
29805 cli_puts("/* WARNING: "
29806 "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n",
29807 p->out
29808 );
29809 }
29810 shellFinalize(&rc, pStmt);
@@ -28529,69 +29833,1323 @@
29833 return SQLITE_OK;
29834 }
29835 if( faultsim_state.iCnt ){
29836 if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--;
29837 if( faultsim_state.eVerbose>=2 ){
29838 cli_printf(stdout,
29839 "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt);
29840 }
29841 return SQLITE_OK;
29842 }
29843 if( faultsim_state.eVerbose>=1 ){
29844 cli_printf(stdout,
29845 "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr);
29846 }
29847 faultsim_state.iCnt = faultsim_state.iInterval;
29848 faultsim_state.nHit++;
29849 if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){
29850 faultsim_state.iCnt = -1;
29851 }
29852 return faultsim_state.iErr;
29853 }
29854
29855 /*
29856 ** pickStr(zArg, &zErr, zS1, zS2, ..., "");
29857 **
29858 ** Try to match zArg against zS1, zS2, and so forth until the first
29859 ** emptry string. Return the index of the match or -1 if none is found.
29860 ** If no match is found, and &zErr is not NULL, then write into
29861 ** zErr a message describing the valid choices.
29862 */
29863 static int pickStr(const char *zArg, char **pzErr, ...){
29864 int i, n;
29865 const char *z;
29866 sqlite3_str *pMsg;
29867 va_list ap;
29868 va_start(ap, pzErr);
29869 i = 0;
29870 while( (z = va_arg(ap,const char*))!=0 && z[0]!=0 ){
29871 if( cli_strcmp(zArg, z)==0 ) return i;
29872 i++;
29873 }
29874 va_end(ap);
29875 if( pzErr==0 ) return -1;
29876 n = i;
29877 pMsg = sqlite3_str_new(0);
29878 va_start(ap, pzErr);
29879 sqlite3_str_appendall(pMsg, "should be");
29880 i = 0;
29881 while( (z = va_arg(ap, const char*))!=0 && z[0]!=0 ){
29882 if( i==n-1 ){
29883 sqlite3_str_append(pMsg,", or",4);
29884 }else if( i>0 ){
29885 sqlite3_str_append(pMsg, ",", 1);
29886 }
29887 sqlite3_str_appendf(pMsg, " %s", z);
29888 i++;
29889 }
29890 va_end(ap);
29891 *pzErr = sqlite3_str_finish(pMsg);
29892 return -1;
29893 }
29894
29895 /*
29896 ** DOT-COMMAND: .import
29897 **
29898 ** USAGE: .import [OPTIONS] FILE TABLE
29899 **
29900 ** Import CSV or similar text from FILE into TABLE. If TABLE does
29901 ** not exist, it is created using the first row of FILE as the column
29902 ** names. If FILE begins with "|" then it is a command that is run
29903 ** and the output from the command is used as the input data.
29904 **
29905 ** FILE is assumed to be in a CSV format, unless the current mode
29906 ** is "ascii" or "tabs" or unless one of the options below specify
29907 ** an alternative.
29908 **
29909 ** Options:
29910 ** --ascii Use \037 and \036 as column and row separators on input
29911 ** --csv Input is standard RFC-4180 CSV.
29912 ** --schema S When creating TABLE, put it in schema S
29913 ** --skip N Ignore the first N rows of input
29914 ** -v Verbose mode
29915 */
29916 static int dotCmdImport(ShellState *p){
29917 int nArg = p->dot.nArg; /* Number of arguments */
29918 char **azArg = p->dot.azArg;/* Argument list */
29919 char *zTable = 0; /* Insert data into this table */
29920 char *zSchema = 0; /* Schema of zTable */
29921 char *zFile = 0; /* Name of file to extra content from */
29922 sqlite3_stmt *pStmt = NULL; /* A statement */
29923 int nCol; /* Number of columns in the table */
29924 i64 nByte; /* Number of bytes in an SQL string */
29925 int i, j; /* Loop counters */
29926 int needCommit; /* True to COMMIT or ROLLBACK at end */
29927 int nSep; /* Number of bytes in spec.zColumnSep */
29928 char *zSql = 0; /* An SQL statement */
29929 ImportCtx sCtx; /* Reader context */
29930 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29931 int eVerbose = 0; /* Larger for more console output */
29932 i64 nSkip = 0; /* Initial lines to skip */
29933 int useOutputMode = 1; /* Use output mode to determine separators */
29934 char *zCreate = 0; /* CREATE TABLE statement text */
29935 int rc; /* Result code */
29936
29937 failIfSafeMode(p, "cannot run .import in safe mode");
29938 memset(&sCtx, 0, sizeof(sCtx));
29939 if( p->mode.eMode==MODE_Ascii ){
29940 xRead = ascii_read_one_field;
29941 }else{
29942 xRead = csv_read_one_field;
29943 }
29944 for(i=1; i<nArg; i++){
29945 char *z = azArg[i];
29946 if( z[0]=='-' && z[1]=='-' ) z++;
29947 if( z[0]!='-' ){
29948 if( zFile==0 ){
29949 zFile = z;
29950 }else if( zTable==0 ){
29951 zTable = z;
29952 }else{
29953 dotCmdError(p, i, "unknown argument", 0);
29954 return 1;
29955 }
29956 }else if( cli_strcmp(z,"-v")==0 ){
29957 eVerbose++;
29958 }else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){
29959 zSchema = azArg[++i];
29960 }else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){
29961 nSkip = integerValue(azArg[++i]);
29962 }else if( cli_strcmp(z,"-ascii")==0 ){
29963 sCtx.cColSep = SEP_Unit[0];
29964 sCtx.cRowSep = SEP_Record[0];
29965 xRead = ascii_read_one_field;
29966 useOutputMode = 0;
29967 }else if( cli_strcmp(z,"-csv")==0 ){
29968 sCtx.cColSep = ',';
29969 sCtx.cRowSep = '\n';
29970 xRead = csv_read_one_field;
29971 useOutputMode = 0;
29972 }else{
29973 dotCmdError(p, i, "unknown option", 0);
29974 return 1;
29975 }
29976 }
29977 if( zTable==0 ){
29978 cli_printf(p->out, "ERROR: missing %s argument\n",
29979 zFile==0 ? "FILE" : "TABLE");
29980 return 1;
29981 }
29982 seenInterrupt = 0;
29983 open_db(p, 0);
29984 if( useOutputMode ){
29985 /* If neither the --csv or --ascii options are specified, then set
29986 ** the column and row separator characters from the output mode. */
29987 if( p->mode.spec.zColumnSep==0 ){
29988 modeSetStr(&p->mode.spec.zColumnSep, ",");
29989 nSep = 1;
29990 }else if( (nSep = strlen30(p->mode.spec.zColumnSep))==0 ){
29991 eputz("Error: non-null column separator required for import\n");
29992 return 1;
29993 }
29994 if( nSep>1 ){
29995 eputz("Error: multi-character column separators not allowed"
29996 " for import\n");
29997 return 1;
29998 }
29999 if( p->mode.spec.zRowSep==0 ){
30000 modeSetStr(&p->mode.spec.zRowSep, "\n");
30001 nSep = 1;
30002 }else if( (nSep = strlen30(p->mode.spec.zRowSep))==0 ){
30003 eputz("Error: non-null row separator required for import\n");
30004 return 1;
30005 }
30006 if( nSep==2 && p->mode.eMode==MODE_Csv
30007 && cli_strcmp(p->mode.spec.zRowSep,SEP_CrLf)==0
30008 ){
30009 /* When importing CSV (only), if the row separator is set to the
30010 ** default output row separator, change it to the default input
30011 ** row separator. This avoids having to maintain different input
30012 ** and output row separators. */
30013 modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
30014 nSep = strlen30(p->mode.spec.zRowSep);
30015 }
30016 if( nSep>1 ){
30017 eputz("Error: multi-character row separators not allowed"
30018 " for import\n");
30019 return 1;
30020 }
30021 sCtx.cColSep = (u8)p->mode.spec.zColumnSep[0];
30022 sCtx.cRowSep = (u8)p->mode.spec.zRowSep[0];
30023 }
30024 sCtx.zFile = zFile;
30025 sCtx.nLine = 1;
30026 if( sCtx.zFile[0]=='|' ){
30027 #ifdef SQLITE_OMIT_POPEN
30028 eputz("Error: pipes are not supported in this OS\n");
30029 return 1;
30030 #else
30031 sCtx.in = sqlite3_popen(sCtx.zFile+1, "r");
30032 sCtx.zFile = "<pipe>";
30033 sCtx.xCloser = pclose;
30034 #endif
30035 }else{
30036 sCtx.in = sqlite3_fopen(sCtx.zFile, "rb");
30037 sCtx.xCloser = fclose;
30038 }
30039 if( sCtx.in==0 ){
30040 cli_printf(stderr,"Error: cannot open \"%s\"\n", zFile);
30041 return 1;
30042 }
30043 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
30044 char zSep[2];
30045 zSep[1] = 0;
30046 zSep[0] = sCtx.cColSep;
30047 cli_puts("Column separator ", p->out);
30048 output_c_string(p->out, zSep);
30049 cli_puts(", row separator ", p->out);
30050 zSep[0] = sCtx.cRowSep;
30051 output_c_string(p->out, zSep);
30052 cli_puts("\n", p->out);
30053 }
30054 sCtx.z = sqlite3_malloc64(120);
30055 if( sCtx.z==0 ){
30056 import_cleanup(&sCtx);
30057 shell_out_of_memory();
30058 }
30059 /* Below, resources must be freed before exit. */
30060 while( nSkip>0 ){
30061 nSkip--;
30062 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
30063 }
30064 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
30065 if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
30066 && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
30067 " WHERE name=%Q AND type='view'",
30068 zSchema ? zSchema : "main", zTable)
30069 ){
30070 /* Table does not exist. Create it. */
30071 sqlite3 *dbCols = 0;
30072 char *zRenames = 0;
30073 char *zColDefs;
30074 zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
30075 zSchema ? zSchema : "main", zTable);
30076 while( xRead(&sCtx) ){
30077 zAutoColumn(sCtx.z, &dbCols, 0);
30078 if( sCtx.cTerm!=sCtx.cColSep ) break;
30079 }
30080 zColDefs = zAutoColumn(0, &dbCols, &zRenames);
30081 if( zRenames!=0 ){
30082 cli_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
30083 "Columns renamed during .import %s due to duplicates:\n"
30084 "%s\n", sCtx.zFile, zRenames);
30085 sqlite3_free(zRenames);
30086 }
30087 assert(dbCols==0);
30088 if( zColDefs==0 ){
30089 cli_printf(stderr,"%s: empty file\n", sCtx.zFile);
30090 import_cleanup(&sCtx);
30091 sqlite3_free(zCreate);
30092 return 1;
30093 }
30094 zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
30095 if( zCreate==0 ){
30096 import_cleanup(&sCtx);
30097 shell_out_of_memory();
30098 }
30099 if( eVerbose>=1 ){
30100 cli_printf(p->out, "%s\n", zCreate);
30101 }
30102 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
30103 if( rc ){
30104 cli_printf(stderr,
30105 "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
30106 }
30107 sqlite3_free(zCreate);
30108 zCreate = 0;
30109 if( rc ){
30110 import_cleanup(&sCtx);
30111 return 1;
30112 }
30113 }
30114 zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
30115 zTable, zSchema);
30116 if( zSql==0 ){
30117 import_cleanup(&sCtx);
30118 shell_out_of_memory();
30119 }
30120 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
30121 sqlite3_free(zSql);
30122 zSql = 0;
30123 if( rc ){
30124 if (pStmt) sqlite3_finalize(pStmt);
30125 shellDatabaseError(p->db);
30126 import_cleanup(&sCtx);
30127 return 1;
30128 }
30129 if( sqlite3_step(pStmt)==SQLITE_ROW ){
30130 nCol = sqlite3_column_int(pStmt, 0);
30131 }else{
30132 nCol = 0;
30133 }
30134 sqlite3_finalize(pStmt);
30135 pStmt = 0;
30136 if( nCol==0 ) return 0; /* no columns, no error */
30137
30138 nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */
30139 + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */
30140 + strlen(zTable)*2 + 2 /* Quoted table name */
30141 + nCol*2; /* Space for ",?" for each column */
30142 zSql = sqlite3_malloc64( nByte );
30143 if( zSql==0 ){
30144 import_cleanup(&sCtx);
30145 shell_out_of_memory();
30146 }
30147 if( zSchema ){
30148 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
30149 zSchema, zTable);
30150 }else{
30151 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
30152 }
30153 j = strlen30(zSql);
30154 for(i=1; i<nCol; i++){
30155 zSql[j++] = ',';
30156 zSql[j++] = '?';
30157 }
30158 zSql[j++] = ')';
30159 zSql[j] = 0;
30160 assert( j<nByte );
30161 if( eVerbose>=2 ){
30162 cli_printf(p->out, "Insert using: %s\n", zSql);
30163 }
30164 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
30165 sqlite3_free(zSql);
30166 zSql = 0;
30167 if( rc ){
30168 shellDatabaseError(p->db);
30169 if (pStmt) sqlite3_finalize(pStmt);
30170 import_cleanup(&sCtx);
30171 return 1;
30172 }
30173 needCommit = sqlite3_get_autocommit(p->db);
30174 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
30175 do{
30176 int startLine = sCtx.nLine;
30177 for(i=0; i<nCol; i++){
30178 char *z = xRead(&sCtx);
30179 /*
30180 ** Did we reach end-of-file before finding any columns?
30181 ** If so, stop instead of NULL filling the remaining columns.
30182 */
30183 if( z==0 && i==0 ) break;
30184 /*
30185 ** Did we reach end-of-file OR end-of-line before finding any
30186 ** columns in ASCII mode? If so, stop instead of NULL filling
30187 ** the remaining columns.
30188 */
30189 if( p->mode.eMode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
30190 /*
30191 ** For CSV mode, per RFC 4180, accept EOF in lieu of final
30192 ** record terminator but only for last field of multi-field row.
30193 ** (If there are too few fields, it's not valid CSV anyway.)
30194 */
30195 if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
30196 z = "";
30197 }
30198 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
30199 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
30200 cli_printf(stderr,"%s:%d: expected %d columns but found %d"
30201 " - filling the rest with NULL\n",
30202 sCtx.zFile, startLine, nCol, i+1);
30203 i += 2;
30204 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
30205 }
30206 }
30207 if( sCtx.cTerm==sCtx.cColSep ){
30208 do{
30209 xRead(&sCtx);
30210 i++;
30211 }while( sCtx.cTerm==sCtx.cColSep );
30212 cli_printf(stderr,
30213 "%s:%d: expected %d columns but found %d - extras ignored\n",
30214 sCtx.zFile, startLine, nCol, i);
30215 }
30216 if( i>=nCol ){
30217 sqlite3_step(pStmt);
30218 rc = sqlite3_reset(pStmt);
30219 if( rc!=SQLITE_OK ){
30220 cli_printf(stderr,"%s:%d: INSERT failed: %s\n",
30221 sCtx.zFile, startLine, sqlite3_errmsg(p->db));
30222 sCtx.nErr++;
30223 }else{
30224 sCtx.nRow++;
30225 }
30226 }
30227 }while( sCtx.cTerm!=EOF );
30228
30229 import_cleanup(&sCtx);
30230 sqlite3_finalize(pStmt);
30231 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
30232 if( eVerbose>0 ){
30233 cli_printf(p->out,
30234 "Added %d rows with %d errors using %d lines of input\n",
30235 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
30236 }
30237 return 0;
30238 }
30239
30240
30241 /*
30242 ** This function computes what to show the user about the configured
30243 ** titles (or column-names). Output is an integer between 0 and 3:
30244 **
30245 ** 0: The titles do not matter. Never show anything.
30246 ** 1: Show "--titles off"
30247 ** 2: Show "--titles on"
30248 ** 3: Show "--title VALUE" where VALUE is an encoding method
30249 ** to use, one of: plain sql csv html tcl json
30250 **
30251 ** Inputs are:
30252 **
30253 ** spec.bTitles (bT) Whether or not to show the titles
30254 ** spec.eTitle (eT) The actual encoding to be used for titles
30255 ** ModeInfo.bHdr (bH) Default value for spec.bTitles
30256 ** ModeInfo.eHdr (eH) Default value for spec.eTitle
30257 ** bAll Whether the -v option is used
30258 */
30259 static int modeTitleDsply(ShellState *p, int bAll){
30260 int eMode = p->mode.eMode;
30261 const ModeInfo *pI = &aModeInfo[eMode];
30262 int bT = p->mode.spec.bTitles;
30263 int eT = p->mode.spec.eTitle;
30264 int bH = pI->bHdr;
30265 int eH = pI->eHdr;
30266
30267 /* Variable "v" is the truth table that will determine the answer
30268 **
30269 ** Actual encoding is different from default
30270 ** vvvvvvvv */
30271 sqlite3_uint64 v = 0x0133013311220102;
30272 /* ^^^^ ^^^^
30273 ** Upper 2-byte groups for when ON/OFF disagrees with
30274 ** the default. */
30275
30276 if( bH==0 ) return 0; /* Header not appliable. Ex: off, count */
30277
30278 if( eT==0 ) eT = eH; /* Fill in missing spec.eTitle */
30279 if( bT==0 ) bT = bH; /* Fill in missing spec.bTitles */
30280
30281 if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
30282 if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
30283 if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
30284 if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
30285
30286 return v & 3; /* Return the selected truth-table entry */
30287 }
30288
30289 /*
30290 ** DOT-COMMAND: .mode
30291 **
30292 ** USAGE: .mode [MODE] [OPTIONS]
30293 **
30294 ** Change the output mode to MODE and/or apply OPTIONS to the
30295 ** output mode. If no arguments, show the current output mode
30296 ** and relevant options.
30297 **
30298 ** Options:
30299 ** --align STRING Set the alignment of text in columnar modes
30300 ** String consists of characters 'L', 'C', 'R'
30301 ** meaning "left", "centered", and "right", with
30302 ** one letter per column starting from the left.
30303 ** Unspecified alignment defaults to 'L'.
30304 ** --charlimit N Set the maximum number of output characters to
30305 ** show for any single SQL value to N. Longer values
30306 ** truncated. Zero means "no limit".
30307 ** --colsep STRING Use STRING as the column separator
30308 ** --escape ESC Enable/disable escaping of control characters
30309 ** in output. ESC can be "off", "ascii", or
30310 ** "symbol".
30311 ** --linelimit N Set the maximum number of output lines to show for
30312 ** any single SQL value to N. Longer values are
30313 ** truncated. Zero means "no limit". Only works
30314 ** in "line" mode and in columnar modes.
30315 ** --list List available modes
30316 ** --null STRING Render SQL NULL values as the given string
30317 ** --once Setting changes to the right are reverted after
30318 ** the next SQL command.
30319 ** --quote ARG Enable/disable quoting of text. ARG can be
30320 ** "off", "on", "sql", "csv", "html", "tcl",
30321 ** or "json". "off" means show the text as-is.
30322 ** "on and "sql" are synonyms.
30323 ** --reset Changes all mode settings back to their default.
30324 ** --rowsep STRING Use STRING as the row separator
30325 ** --screenwidth N Declare the screen width of the output device
30326 ** to be N characters. An attempt may be made to
30327 ** wrap output text to fit within this limit. Zero
30328 ** means "no limit". Or N can be "auto" to set the
30329 ** width automatically.
30330 ** --tablename NAME Set the name of the table for "insert" mode.
30331 ** --tag NAME Save mode to the left as NAME.
30332 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
30333 ** --title ARG Whether or not to show column headers, and if so
30334 ** how to encode them. ARG can be "off", "on",
30335 ** "sql", "csv", "html", "tcl", or "json".
30336 ** -v|--verbose Verbose output
30337 ** --widths LIST Set the columns widths for columnar modes. The
30338 ** argument is a list of integers, one for each
30339 ** column. A "0" width means use a dynamic width
30340 ** based on the actual width of data. If there are
30341 ** fewer entries in LIST than columns, "0" is used
30342 ** for the unspecified widths.
30343 ** --wordwrap BOOLEAN Enable/disable word wrapping
30344 ** --wrap N Wrap columns wider than N characters
30345 ** --ww Shorthand for "--wordwrap on"
30346 */
30347 static int dotCmdMode(ShellState *p){
30348 int nArg = p->dot.nArg; /* Number of arguments */
30349 char **azArg = p->dot.azArg;/* Argument list */
30350 int eMode = -1; /* New mode value, or -1 for none */
30351 int iMode = -1; /* Index of the argument that is the mode name */
30352 int i; /* Loop counter */
30353 int k; /* Misc index variable */
30354 int chng = 0; /* True if anything has changed */
30355 int bAll = 0; /* Show all details of the mode */
30356
30357 for(i=1; i<nArg; i++){
30358 const char *z = azArg[i];
30359 if( z[0]=='-' && z[1]=='-' ) z++;
30360 if( z[0]!='-'
30361 && iMode<0
30362 && (eMode = modeFind(p, azArg[i]))>=0
30363 && eMode!=MODE_Www
30364 ){
30365 iMode = i;
30366 modeChange(p, eMode);
30367 /* (Legacy) If the mode is MODE_Insert and the next argument
30368 ** is not an option, then the next argument must be the table
30369 ** name.
30370 */
30371 if( i+1<nArg && azArg[i+1][0]!='-' ){
30372 i++;
30373 modeSetStr(&p->mode.spec.zTableName, azArg[i]);
30374 }
30375 chng = 1;
30376 }else if( optionMatch(z,"align") ){
30377 char *zAlign;
30378 int nAlign;
30379 int nErr = 0;
30380 if( i+1>=nArg ){
30381 dotCmdError(p, i, "missing argument", 0);
30382 return 1;
30383 }
30384 i++;
30385 zAlign = azArg[i];
30386 nAlign = 0x3fff & strlen(zAlign);
30387 free(p->mode.spec.aAlign);
30388 p->mode.spec.aAlign = malloc(nAlign);
30389 shell_check_oom(p->mode.spec.aAlign);
30390 for(k=0; k<nAlign; k++){
30391 unsigned char c = 0;
30392 switch( zAlign[k] ){
30393 case 'l': case 'L': c = QRF_ALIGN_Left; break;
30394 case 'c': case 'C': c = QRF_ALIGN_Center; break;
30395 case 'r': case 'R': c = QRF_ALIGN_Right; break;
30396 default: nErr++; break;
30397 }
30398 p->mode.spec.aAlign[k] = c;
30399 }
30400 p->mode.spec.nAlign = nAlign;
30401 chng = 1;
30402 if( nErr ){
30403 dotCmdError(p, i, "bad alignment string",
30404 "Should contain only characters L, C, and R.");
30405 return 1;
30406 }
30407 }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
30408 int w; /* 0 1 */
30409 if( i+1>=nArg ){
30410 dotCmdError(p, i, "missing argument", 0);
30411 return 1;
30412 }
30413 w = integerValue(azArg[++i]);
30414 if( k==0 ){
30415 p->mode.spec.nCharLimit = w;
30416 }else{
30417 p->mode.spec.nLineLimit = w;
30418 }
30419 chng = 1;
30420 }else if( 0<=(k=pickStr(z,0,"-tablename","-rowsep","-colsep","-null","")) ){
30421 /* 0 1 2 3 */
30422 if( i+1>=nArg ){
30423 dotCmdError(p, i, "missing argument", 0);
30424 return 1;
30425 }
30426 i++;
30427 switch( k ){
30428 case 0: modeSetStr(&p->mode.spec.zTableName, azArg[i]); break;
30429 case 1: modeSetStr(&p->mode.spec.zRowSep, azArg[i]); break;
30430 case 2: modeSetStr(&p->mode.spec.zColumnSep, azArg[i]); break;
30431 case 3: modeSetStr(&p->mode.spec.zNull, azArg[i]); break;
30432 }
30433 chng = 1;
30434 }else if( optionMatch(z,"escape") ){
30435 /* See similar code at tag-20250224-1 */
30436 char *zErr = 0;
30437 if( i+1>=nArg ){
30438 dotCmdError(p, i, "missing argument", 0);
30439 return 1;
30440 }
30441 i++; /* 0 1 2 <-- One less than QRF_ESC_ */
30442 k = pickStr(azArg[i],&zErr,"off","ascii","symbol","");
30443 if( k<0 ){
30444 dotCmdError(p, i, "unknown escape type", "%s", zErr);
30445 sqlite3_free(zErr);
30446 return 1;
30447 }
30448 p->mode.spec.eEsc = k+1;
30449 chng = 1;
30450 }else if( optionMatch(z,"list") ){
30451 int ii;
30452 cli_puts("available modes:", p->out);
30453 for(ii=0; ii<ArraySize(aModeInfo); ii++){
30454 if( ii==MODE_Www ) continue;
30455 cli_printf(p->out, " %s", aModeInfo[ii].zName);
30456 }
30457 for(ii=0; ii<p->nSavedModes; ii++){
30458 cli_printf(p->out, " %s", p->aSavedModes[ii].zTag);
30459 }
30460 cli_puts(" batch tty\n", p->out);
30461 }else if( optionMatch(z,"quote") ){
30462 if( i+1<nArg
30463 && azArg[i+1][0]!='-'
30464 && (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0)
30465 ){
30466 /* --quote is followed by an argument other that is not an option
30467 ** or a mode name. See it must be a boolean or a keyword to describe
30468 ** how to set quoting. */
30469 i++;
30470 if( (k = pickStr(azArg[i],0,"no","yes","0","1",""))>=0 ){
30471 k &= 1; /* 0 for "off". 1 for "on". */
30472 }else{
30473 char *zErr = 0; /* 0 1 2 3 4 5 6 */
30474 k = pickStr(azArg[i],&zErr,"off","on","sql","csv","html","tcl","json",
30475 "");
30476 if( k<0 ){
30477 dotCmdError(p, i, "unknown", "%z", zErr);
30478 return 1;
30479 }
30480 }
30481 }else{
30482 /* (Legacy) no following boolean argument. Turn quoting on */
30483 k = 1;
30484 }
30485 switch( k ){
30486 case 1: /* on */
30487 case 2: /* sql */
30488 p->mode.spec.eText = QRF_TEXT_Sql;
30489 p->mode.spec.eBlob = QRF_BLOB_Sql;
30490 break;
30491 case 3: /* csv */
30492 p->mode.spec.eText = QRF_TEXT_Csv;
30493 p->mode.spec.eBlob = QRF_BLOB_Text;
30494 break;
30495 case 4: /* html */
30496 p->mode.spec.eText = QRF_TEXT_Html;
30497 p->mode.spec.eBlob = QRF_BLOB_Text;
30498 break;
30499 case 5: /* tcl */
30500 p->mode.spec.eText = QRF_TEXT_Tcl;
30501 p->mode.spec.eBlob = QRF_BLOB_Text;
30502 break;
30503 case 6: /* json */
30504 p->mode.spec.eText = QRF_TEXT_Json;
30505 p->mode.spec.eBlob = QRF_BLOB_Json;
30506 break;
30507 default: /* off */
30508 p->mode.spec.eText = QRF_TEXT_Plain;
30509 p->mode.spec.eBlob = QRF_BLOB_Text;
30510 break;
30511 }
30512 chng = 1;
30513 }else if( optionMatch(z,"once") ){
30514 p->nPopMode = 0;
30515 modePush(p);
30516 p->nPopMode = 1;
30517 }else if( optionMatch(z,"noquote") ){
30518 /* (undocumented legacy) --noquote always turns quoting off */
30519 p->mode.spec.eText = QRF_TEXT_Plain;
30520 p->mode.spec.eBlob = QRF_BLOB_Text;
30521 chng = 1;
30522 }else if( optionMatch(z,"reset") ){
30523 int saved_eMode = p->mode.eMode;
30524 modeFree(&p->mode);
30525 modeChange(p, saved_eMode);
30526 }else if( optionMatch(z,"screenwidth") ){
30527 if( i+1>=nArg ){
30528 dotCmdError(p, i, "missing argument", 0);
30529 return 1;
30530 }
30531 k = pickStr(azArg[i+1],0,"off","auto","");
30532 if( k==0 ){
30533 p->mode.bAutoScreenWidth = 0;
30534 p->mode.spec.nScreenWidth = 0;
30535 }else if( k==1 ){
30536 p->mode.bAutoScreenWidth = 1;
30537 }else{
30538 i64 w = integerValue(azArg[i+1]);
30539 p->mode.bAutoScreenWidth = 0;
30540 if( w<0 ) w = 0;
30541 if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30542 p->mode.spec.nScreenWidth = w;
30543 }
30544 i++;
30545 chng = 1;
30546 }else if( optionMatch(z,"tag") ){
30547 size_t nByte;
30548 int n;
30549 const char *zTag;
30550 if( i+1>=nArg ){
30551 dotCmdError(p, i, "missing argument", 0);
30552 return 1;
30553 }
30554 zTag = azArg[++i];
30555 if( modeFind(p, zTag)>=0 ){
30556 dotCmdError(p, i, "mode already exists", 0);
30557 return 1;
30558 }
30559 if( p->nSavedModes > MODE_N_USER ){
30560 dotCmdError(p, i-1, "cannot add more modes", 0);
30561 return 1;
30562 }
30563 n = p->nSavedModes++;
30564 nByte = sizeof(p->aSavedModes[0]);
30565 nByte *= n+1;
30566 p->aSavedModes = realloc( p->aSavedModes, nByte );
30567 shell_check_oom(p->aSavedModes);
30568 p->aSavedModes[n].zTag = strdup(zTag);
30569 shell_check_oom(p->aSavedModes[n].zTag);
30570 modeDup(&p->aSavedModes[n].mode, &p->mode);
30571 chng = 1;
30572 }else if( optionMatch(z,"textjsonb") ){
30573 if( i+1>=nArg ){
30574 dotCmdError(p, i, "missing argument", 0);
30575 return 1;
30576 }
30577 p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
30578 chng = 1;
30579 }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
30580 char *zErr = 0;
30581 if( i+1>=nArg ){
30582 dotCmdError(p, i, "missing argument", 0);
30583 return 1;
30584 }
30585 k = pickStr(azArg[++i],&zErr,
30586 "off","on","plain","sql","csv","html","tcl","json","");
30587 /* 0 1 2 3 4 5 6 7 */
30588 if( k<0 ){
30589 dotCmdError(p, i, "bad --titles value","%z", zErr);
30590 return 1;
30591 }
30592 p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
30593 p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
30594 chng = 1;
30595 }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
30596 int nWidth = 0;
30597 short int *aWidth;
30598 const char *zW;
30599 if( i+1>=nArg ){
30600 dotCmdError(p, i, "missing argument", 0);
30601 return 1;
30602 }
30603 zW = azArg[++i];
30604 /* Every width value takes at least 2 bytes in the input string to
30605 ** specify, so strlen(zW) bytes should be plenty of space to hold the
30606 ** result. */
30607 aWidth = malloc( strlen(zW) );
30608 while( isspace(zW[0]) ) zW++;
30609 while( zW[0] ){
30610 int w = 0;
30611 int nDigit = 0;
30612 k = zW[0]=='-' && isdigit(zW[1]);
30613 while( isdigit(zW[k]) ){
30614 w = w*10 + zW[k] - '0';
30615 if( w>QRF_MAX_WIDTH ){
30616 dotCmdError(p,i+1,"width too big",
30617 "Maximum column width is %d", QRF_MAX_WIDTH);
30618 free(aWidth);
30619 return 1;
30620 }
30621 nDigit++;
30622 k++;
30623 }
30624 if( nDigit==0 ){
30625 dotCmdError(p,i+1,"syntax error",
30626 "should be a comma-separated list if integers");
30627 free(aWidth);
30628 return 1;
30629 }
30630 if( zW[0]=='-' ) w = -w;
30631 aWidth[nWidth++] = w;
30632 zW += k;
30633 if( zW[0]==',' ) zW++;
30634 while( isspace(zW[0]) ) zW++;
30635 }
30636 free(p->mode.spec.aWidth);
30637 p->mode.spec.aWidth = aWidth;
30638 p->mode.spec.nWidth = nWidth;
30639 chng = 1;
30640 }else if( optionMatch(z,"wrap") ){
30641 int w;
30642 if( i+1>=nArg ){
30643 dotCmdError(p, i, "missing argument", 0);
30644 return 1;
30645 }
30646 w = integerValue(azArg[++i]);
30647 if( w<(-QRF_MAX_WIDTH) ) w = -QRF_MAX_WIDTH;
30648 if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30649 p->mode.spec.nWrap = w;
30650 chng = 1;
30651 }else if( optionMatch(z,"ww") ){
30652 p->mode.spec.bWordWrap = QRF_Yes;
30653 chng = 1;
30654 }else if( optionMatch(z,"wordwrap") ){
30655 if( i+1>=nArg ){
30656 dotCmdError(p, i, "missing argument", 0);
30657 return 1;
30658 }
30659 p->mode.spec.bWordWrap = (u8)booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
30660 chng = 1;
30661 }else if( optionMatch(z,"v") || optionMatch(z,"verbose") ){
30662 bAll = 1;
30663 }else if( z[0]=='-' ){
30664 dotCmdError(p, i, "bad option", "Use \".help .mode\" for more info");
30665 return 1;
30666 }else{
30667 dotCmdError(p, i, iMode>0?"bad argument":"unknown mode",
30668 "Use \".help .mode\" for more info");
30669 return 1;
30670 }
30671 }
30672 if( !chng || bAll ){
30673 const ModeInfo *pI = aModeInfo + p->mode.eMode;
30674 sqlite3_str *pDesc = sqlite3_str_new(p->db);
30675 char *zDesc;
30676 const char *zSetting;
30677
30678 if( p->nPopMode ) sqlite3_str_appendall(pDesc, "--once ");
30679 sqlite3_str_appendall(pDesc,pI->zName);
30680 if( bAll || (p->mode.spec.nAlign && pI->eCx==2) ){
30681 int ii;
30682 sqlite3_str_appendall(pDesc, " --align \"");
30683 for(ii=0; ii<p->mode.spec.nAlign; ii++){
30684 unsigned char a = p->mode.spec.aAlign[ii];
30685 sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]);
30686 }
30687 sqlite3_str_append(pDesc, "\"", 1);
30688 }
30689 if( bAll || p->mode.spec.nCharLimit>0 ){
30690 sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit);
30691 }
30692 zSetting = aModeStr[pI->eCSep];
30693 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){
30694 sqlite3_str_appendf(pDesc, " --colsep ");
30695 append_c_string(pDesc, p->mode.spec.zColumnSep);
30696 }
30697 if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
30698 sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
30699 }
30700 if( bAll || (p->mode.spec.nLineLimit>0 && pI->eCx>0) ){
30701 sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit);
30702 }
30703 zSetting = aModeStr[pI->eNull];
30704 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){
30705 sqlite3_str_appendf(pDesc, " --null ");
30706 append_c_string(pDesc, p->mode.spec.zNull);
30707 }
30708 if( bAll
30709 || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
30710 ){
30711 sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
30712 }
30713 zSetting = aModeStr[pI->eRSep];
30714 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
30715 sqlite3_str_appendf(pDesc, " --rowsep ");
30716 append_c_string(pDesc, p->mode.spec.zRowSep);
30717 }
30718 if( bAll
30719 || (pI->eCx && (p->mode.spec.nScreenWidth>0 || p->mode.bAutoScreenWidth))
30720 ){
30721 if( p->mode.bAutoScreenWidth ){
30722 sqlite3_str_appendall(pDesc, " --screenwidth auto");
30723 }else{
30724 sqlite3_str_appendf(pDesc," --screenwidth %d",
30725 p->mode.spec.nScreenWidth);
30726 }
30727 }
30728 if( bAll || p->mode.eMode==MODE_Insert ){
30729 sqlite3_str_appendf(pDesc," --tablename ");
30730 append_c_string(pDesc, p->mode.spec.zTableName);
30731 }
30732 if( bAll || p->mode.spec.bTextJsonb ){
30733 sqlite3_str_appendf(pDesc," --textjsonb %s",
30734 p->mode.spec.bTextJsonb==QRF_Yes ? "on" : "off");
30735 }
30736 k = modeTitleDsply(p, bAll);
30737 if( k==1 ){
30738 sqlite3_str_appendall(pDesc, " --titles off");
30739 }else if( k==2 ){
30740 sqlite3_str_appendall(pDesc, " --titles on");
30741 }else if( k==3 ){
30742 static const char *azTitle[] =
30743 { "plain", "sql", "csv", "html", "tcl", "json"};
30744 sqlite3_str_appendf(pDesc, " --titles %s",
30745 azTitle[p->mode.spec.eTitle-1]);
30746 }
30747 if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
30748 int ii;
30749 const char *zSep = " --widths ";
30750 for(ii=0; ii<p->mode.spec.nWidth; ii++){
30751 sqlite3_str_appendf(pDesc, "%s%d", zSep, (int)p->mode.spec.aWidth[ii]);
30752 zSep = ",";
30753 }
30754 }else if( bAll ){
30755 sqlite3_str_appendall(pDesc, " --widths \"\"");
30756 }
30757 if( bAll || (pI->eCx>0 && p->mode.spec.bWordWrap) ){
30758 if( bAll ){
30759 sqlite3_str_appendf(pDesc, " --wordwrap %s",
30760 p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off");
30761 }
30762 if( p->mode.spec.nWrap ){
30763 sqlite3_str_appendf(pDesc, " --wrap %d", p->mode.spec.nWrap);
30764 }
30765 if( !bAll ) sqlite3_str_append(pDesc, " --ww", 5);
30766 }
30767 zDesc = sqlite3_str_finish(pDesc);
30768 cli_printf(p->out, "current output mode: %s\n", zDesc);
30769 fflush(p->out);
30770 sqlite3_free(zDesc);
30771 }
30772 return 0;
30773 }
30774
30775 /*
30776 ** DOT-COMMAND: .output
30777 ** USAGE: .output [OPTIONS] [FILE]
30778 **
30779 ** Begin redirecting output to FILE. Or if FILE is omitted, revert
30780 ** to sending output to the console. If FILE begins with "|" then
30781 ** the remainder of file is taken as a pipe and output is directed
30782 ** into that pipe. If FILE is "memory" then output is captured in an
30783 ** internal memory buffer. If FILE is "off" then output is redirected
30784 ** into /dev/null or the equivalent.
30785 **
30786 ** Options:
30787 ** --bom Prepend a byte-order mark to the output
30788 ** -e Accumulate output in a temporary text file then
30789 ** launch a text editor when the redirection ends.
30790 ** --error-prefix X Use X as the left-margin prefix for error messages.
30791 ** Set to an empty string to restore the default.
30792 ** --glob GLOB Raise an error if the memory buffer does not match
30793 ** the GLOB pattern.
30794 ** --keep Continue using the same "memory" buffer. Do not
30795 ** reset it or delete it. Useful in combination with
30796 ** --glob, --not-glob, and/or --verify.
30797 ** ---notglob GLOB Raise an error if the memory buffer does not match
30798 ** the GLOB pattern.
30799 ** --plain Use plain text rather than HTML tables with -w
30800 ** --show Write the memory buffer to the screen, for debugging.
30801 ** --verify ENDMARK Read subsequent lines of text until the first line
30802 ** that matches ENDMARK. Discard the ENDMARK. Compare
30803 ** the text against the accumulated output in memory and
30804 ** raise an error if there are any differences.
30805 ** -w Show the output in a web browser. Output is
30806 ** written into a temporary HTML file until the
30807 ** redirect ends, then the web browser is launched.
30808 ** Query results are shown as HTML tables, unless
30809 ** the --plain is used too.
30810 ** -x Show the output in a spreadsheet. Output is
30811 ** written to a temp file as CSV then the spreadsheet
30812 ** is launched when
30813 **
30814 ** DOT-COMMAND: .once
30815 ** USAGE: .once [OPTIONS] FILE ...
30816 **
30817 ** Write the output for the next line of SQL or the next dot-command into
30818 ** FILE. If FILE begins with "|" then it is a program into which output
30819 ** is written. The FILE argument should be omitted if one of the -e, -w,
30820 ** or -x options is used.
30821 **
30822 ** Options:
30823 ** -e Capture output into a temporary file then bring up
30824 ** a text editor on that temporary file.
30825 ** --plain Use plain text rather than HTML tables with -w
30826 ** -w Capture output into an HTML file then bring up that
30827 ** file in a web browser
30828 ** -x Show the output in a spreadsheet. Output is
30829 ** written to a temp file as CSV then the spreadsheet
30830 ** is launched when
30831 **
30832 ** DOT-COMMAND: .excel
30833 ** Shorthand for ".once -x"
30834 **
30835 ** DOT-COMMAND: .www [--plain]
30836 ** Shorthand for ".once -w" or ".once --plain -w"
30837 */
30838 static int dotCmdOutput(ShellState *p){
30839 int nArg = p->dot.nArg; /* Number of arguments */
30840 char **azArg = p->dot.azArg; /* Text of the arguments */
30841 char *zFile = 0; /* The FILE argument */
30842 int i; /* Loop counter */
30843 int eMode = 0; /* 0: .outout/.once, 'x'=.excel, 'w'=.www */
30844 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */
30845 int bPlain = 0; /* --plain option */
30846 int bKeep = 0; /* --keep option */
30847 char *zCheck = 0; /* Argument to --glob, --notglob, --verify */
30848 int eCheck = 0; /* 1: --glob, 2: --notglob, 3: --verify */
30849 static const char *zBomUtf8 = "\357\273\277";
30850 const char *zBom = 0;
30851 char c = azArg[0][0];
30852 int n = strlen30(azArg[0]);
30853
30854 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
30855 if( c=='e' ){
30856 eMode = 'x';
30857 bOnce = 2;
30858 }else if( c=='w' ){
30859 eMode = 'w';
30860 bOnce = 2;
30861 }else if( n>=2 && cli_strncmp(azArg[0],"once",n)==0 ){
30862 bOnce = 1;
30863 }
30864 for(i=1; i<nArg; i++){
30865 char *z = azArg[i];
30866 if( z[0]=='-' ){
30867 if( z[1]=='-' ) z++;
30868 if( cli_strcmp(z,"-bom")==0 ){
30869 zBom = zBomUtf8;
30870 }else if( cli_strcmp(z,"-plain")==0 ){
30871 bPlain = 1;
30872 }else if( c=='o' && z[0]=='1' && z[1]!=0 && z[2]==0
30873 && (z[1]=='x' || z[1]=='e' || z[1]=='w') ){
30874 if( bKeep || eMode || eCheck ){
30875 dotCmdError(p, i, "incompatible with prior options",0);
30876 goto dotCmdOutput_error;
30877 }
30878 eMode = z[1];
30879 }else if( cli_strcmp(z,"-keep")==0 ){
30880 bKeep = 1;
30881 }else if( cli_strcmp(z,"-show")==0 ){
30882 if( cli_output_capture ){
30883 sqlite3_fprintf(stdout, "%s", sqlite3_str_value(cli_output_capture));
30884 }
30885 bKeep = 1;
30886 }else if( cli_strcmp(z,"-glob")==0
30887 || cli_strcmp(z,"-notglob")==0
30888 || cli_strcmp(z,"-verify")==0
30889 ){
30890 if( eCheck || eMode ){
30891 dotCmdError(p, i, "incompatible with prior options",0);
30892 goto dotCmdOutput_error;
30893 }
30894 if( i+1>=nArg ){
30895 dotCmdError(p, i, "missing argument", 0);
30896 goto dotCmdOutput_error;
30897 }
30898 zCheck = azArg[++i];
30899 eCheck = z[1]=='g' ? 1 : z[1]=='n' ? 2 : 3;
30900 }else if( optionMatch(z,"error-prefix") ){
30901 if( i+1>=nArg ){
30902 dotCmdError(p, i, "missing argument", 0);
30903 return 1;
30904 }
30905 free(p->zErrPrefix);
30906 i++;
30907 p->zErrPrefix = azArg[i][0]==0 ? 0 : strdup(azArg[i]);
30908 }else{
30909 dotCmdError(p, i, "unknown option", 0);
30910 sqlite3_free(zFile);
30911 return 1;
30912 }
30913 }else if( zFile==0 && eMode==0 ){
30914 if( bKeep || eCheck ){
30915 dotCmdError(p, i, "incompatible with prior options",0);
30916 goto dotCmdOutput_error;
30917 }
30918 if( cli_strcmp(z, "memory")==0 && bOnce ){
30919 dotCmdError(p, 0, "cannot redirect to \"memory\"", 0);
30920 goto dotCmdOutput_error;
30921 }
30922 if( cli_strcmp(z, "off")==0 ){
30923 #ifdef _WIN32
30924 zFile = sqlite3_mprintf("nul");
30925 #else
30926 zFile = sqlite3_mprintf("/dev/null");
30927 #endif
30928 }else{
30929 zFile = sqlite3_mprintf("%s", z);
30930 }
30931 if( zFile && zFile[0]=='|' ){
30932 while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
30933 break;
30934 }
30935 }else{
30936 dotCmdError(p, i, "surplus argument", 0);
30937 sqlite3_free(zFile);
30938 return 1;
30939 }
30940 }
30941 if( zFile==0 && !bKeep ){
30942 zFile = sqlite3_mprintf("stdout");
30943 shell_check_oom(zFile);
30944 }
30945 if( bOnce ){
30946 p->nPopOutput = 2;
30947 }else{
30948 p->nPopOutput = 0;
30949 }
30950 if( eCheck ){
30951 char *zTest;
30952 if( cli_output_capture ){
30953 zTest = sqlite3_str_value(cli_output_capture);
30954 }else{
30955 zTest = "";
30956 }
30957 p->nTestRun++;
30958 if( eCheck==3 ){
30959 int nCheck = strlen30(zCheck);
30960 sqlite3_str *pPattern = sqlite3_str_new(p->db);
30961 char *zPattern;
30962 sqlite3_int64 iStart = p->lineno;
30963 char zLine[2000];
30964 while( sqlite3_fgets(zLine,sizeof(zLine),p->in) ){
30965 if( strchr(zLine,'\n') ) p->lineno++;
30966 if( cli_strncmp(zCheck,zLine,nCheck)==0 ) break;
30967 sqlite3_str_appendall(pPattern, zLine);
30968 }
30969 zPattern = sqlite3_str_finish(pPattern);
30970 if( cli_strcmp(zPattern,zTest)!=0 ){
30971 sqlite3_fprintf(stderr,
30972 "%s:%lld: --verify does matches prior output\n",
30973 p->zInFile, iStart);
30974 p->nTestErr++;
30975 }
30976 sqlite3_free(zPattern);
30977 }else{
30978 char *zGlob = sqlite3_mprintf("*%s*", zCheck);
30979 if( eCheck==1 && sqlite3_strglob(zGlob, zTest)!=0 ){
30980 sqlite3_fprintf(stderr,
30981 "%s:%lld: --glob \"%s\" does not match prior output\n",
30982 p->zInFile, p->lineno, zCheck);
30983 p->nTestErr++;
30984 }else if( eCheck==2 && sqlite3_strglob(zGlob, zTest)==0 ){
30985 sqlite3_fprintf(stderr,
30986 "%s:%lld: --notglob \"%s\" matches prior output\n",
30987 p->zInFile, p->lineno, zCheck);
30988 p->nTestErr++;
30989 }
30990 sqlite3_free(zGlob);
30991 }
30992 }
30993 if( !bKeep ) output_reset(p);
30994 #ifndef SQLITE_NOHAVE_SYSTEM
30995 if( eMode=='e' || eMode=='x' || eMode=='w' ){
30996 p->doXdgOpen = 1;
30997 modePush(p);
30998 if( eMode=='x' ){
30999 /* spreadsheet mode. Output as CSV. */
31000 newTempFile(p, "csv");
31001 p->mode.mFlags &= ~MFLG_ECHO;
31002 p->mode.eMode = MODE_Csv;
31003 modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
31004 modeSetStr(&p->mode.spec.zRowSep, SEP_CrLf);
31005 #ifdef _WIN32
31006 zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does
31007 ** not work without it. */
31008 #endif
31009 }else if( eMode=='w' ){
31010 /* web-browser mode. */
31011 newTempFile(p, "html");
31012 if( !bPlain ) p->mode.eMode = MODE_Www;
31013 }else{
31014 /* text editor mode */
31015 newTempFile(p, "txt");
31016 }
31017 sqlite3_free(zFile);
31018 zFile = sqlite3_mprintf("%s", p->zTempFile);
31019 }
31020 #endif /* SQLITE_NOHAVE_SYSTEM */
31021 if( !bKeep ) shell_check_oom(zFile);
31022 if( bKeep ){
31023 /* no-op */
31024 }else if( cli_strcmp(zFile,"memory")==0 ){
31025 if( cli_output_capture ){
31026 sqlite3_str_free(cli_output_capture);
31027 }
31028 cli_output_capture = sqlite3_str_new(0);
31029 }else if( zFile[0]=='|' ){
31030 #ifdef SQLITE_OMIT_POPEN
31031 eputz("Error: pipes are not supported in this OS\n");
31032 output_redir(p, stdout);
31033 goto dotCmdOutput_error;
31034 #else
31035 FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
31036 if( pfPipe==0 ){
31037 assert( stderr!=NULL );
31038 cli_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
31039 goto dotCmdOutput_error;
31040 }else{
31041 output_redir(p, pfPipe);
31042 if( zBom ) cli_puts(zBom, pfPipe);
31043 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
31044 }
31045 #endif
31046 }else{
31047 FILE *pfFile = output_file_open(p, zFile);
31048 if( pfFile==0 ){
31049 if( cli_strcmp(zFile,"off")!=0 ){
31050 assert( stderr!=NULL );
31051 cli_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
31052 }
31053 goto dotCmdOutput_error;
31054 } else {
31055 output_redir(p, pfFile);
31056 if( zBom ) cli_puts(zBom, pfFile);
31057 if( bPlain && eMode=='w' ){
31058 cli_puts(
31059 "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n",
31060 pfFile
31061 );
31062 }
31063 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
31064 }
31065 }
31066 sqlite3_free(zFile);
31067 return 0;
31068
31069 dotCmdOutput_error:
31070 sqlite3_free(zFile);
31071 return 1;
31072 }
31073 /*
31074 ** Parse input line zLine up into individual arguments. Retain the
31075 ** parse in the p->dot substructure.
31076 */
31077 static void parseDotRealloc(ShellState *p, int nArg){
31078 p->dot.nAlloc = nArg+22;
31079 p->dot.azArg = realloc(p->dot.azArg,p->dot.nAlloc*sizeof(char*));
31080 shell_check_oom(p->dot.azArg);
31081 p->dot.aiOfst = realloc(p->dot.aiOfst,p->dot.nAlloc*sizeof(int));
31082 shell_check_oom(p->dot.aiOfst);
31083 p->dot.abQuot = realloc(p->dot.abQuot,p->dot.nAlloc);
31084 shell_check_oom(p->dot.abQuot);
31085 }
31086 static void parseDotCmdArgs(const char *zLine, ShellState *p){
31087 char *z;
31088 int h = 1;
31089 int nArg = 0;
31090
31091 p->dot.zOrig = zLine;
31092 free(p->dot.zCopy);
31093 z = p->dot.zCopy = strdup(zLine);
31094 shell_check_oom(z);
31095 parseDotRealloc(p, 2);
31096 while( z[h] ){
31097 while( IsSpace(z[h]) ){ h++; }
31098 if( z[h]==0 ) break;
31099 if( nArg+2>p->dot.nAlloc ){
31100 parseDotRealloc(p, nArg);
31101 }
31102 if( z[h]=='\'' || z[h]=='"' ){
31103 int delim = z[h++];
31104 p->dot.abQuot[nArg] = 1;
31105 p->dot.azArg[nArg] = &z[h];
31106 p->dot.aiOfst[nArg] = h;
31107 while( z[h] && z[h]!=delim ){
31108 if( z[h]=='\\' && delim=='"' && z[h+1]!=0 ) h++;
31109 h++;
31110 }
31111 if( z[h]==delim ){
31112 z[h++] = 0;
31113 }
31114 if( delim=='"' ) resolve_backslashes(p->dot.azArg[nArg]);
31115 }else{
31116 p->dot.abQuot[nArg] = 0;
31117 p->dot.azArg[nArg] = &z[h];
31118 p->dot.aiOfst[nArg] = h;
31119 while( z[h] && !IsSpace(z[h]) ){ h++; }
31120 if( z[h] ) z[h++] = 0;
31121 }
31122 nArg++;
31123 }
31124 p->dot.nArg = nArg;
31125 p->dot.azArg[nArg] = 0;
31126 }
31127
31128 /*
31129 ** If an input line begins with "." then invoke this routine to
31130 ** process that line.
31131 **
31132 ** Return 1 on error, 2 to exit, and 0 otherwise.
31133 */
31134 static int do_meta_command(const char *zLine, ShellState *p){
31135 int nArg;
 
31136 int n, c;
31137 int rc = 0;
31138 char **azArg;
31139
31140 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
31141 if( p->expert.pExpert ){
31142 expertFinish(p, 1, 0);
31143 }
31144 #endif
31145
31146 /* Parse the input line into tokens stored in p->dot.
31147 */
31148 parseDotCmdArgs(zLine, p);
31149 nArg = p->dot.nArg;
31150 azArg = p->dot.azArg;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31151
31152 /* Process the input line.
31153 */
31154 if( nArg==0 ) return 0; /* no tokens, no error */
31155 n = strlen30(azArg[0]);
@@ -28599,11 +31157,11 @@
31157 clearTempFile(p);
31158
31159 #ifndef SQLITE_OMIT_AUTHORIZATION
31160 if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
31161 if( nArg!=2 ){
31162 cli_printf(stderr, "Usage: .auth ON|OFF\n");
31163 rc = 1;
31164 goto meta_command_exit;
31165 }
31166 open_db(p, 0);
31167 if( booleanValue(azArg[1]) ){
@@ -28646,32 +31204,32 @@
31204 }else
31205 if( cli_strcmp(z, "-async")==0 ){
31206 bAsync = 1;
31207 }else
31208 {
31209 dotCmdError(p, j, "unknown option", "should be -append or -async");
31210 return 1;
31211 }
31212 }else if( zDestFile==0 ){
31213 zDestFile = azArg[j];
31214 }else if( zDb==0 ){
31215 zDb = zDestFile;
31216 zDestFile = azArg[j];
31217 }else{
31218 cli_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
31219 return 1;
31220 }
31221 }
31222 if( zDestFile==0 ){
31223 cli_printf(stderr, "missing FILENAME argument on .backup\n");
31224 return 1;
31225 }
31226 if( zDb==0 ) zDb = "main";
31227 rc = sqlite3_open_v2(zDestFile, &pDest,
31228 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
31229 if( rc!=SQLITE_OK ){
31230 cli_printf(stderr,"Error: cannot open \"%s\"\n", zDestFile);
31231 close_db(pDest);
31232 return 1;
31233 }
31234 if( bAsync ){
31235 sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
@@ -28728,11 +31286,11 @@
31286 sqlite3_free(z);
31287 #else
31288 rc = chdir(azArg[1]);
31289 #endif
31290 if( rc ){
31291 cli_printf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]);
31292 rc = 1;
31293 }
31294 }else{
31295 eputz("Usage: .cd DIRECTORY\n");
31296 rc = 1;
@@ -28761,16 +31319,16 @@
31319 eputz("Usage: .check GLOB-PATTERN\n");
31320 rc = 2;
31321 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
31322 rc = 2;
31323 }else if( testcase_glob(azArg[1],zRes)==0 ){
31324 cli_printf(stderr,
31325 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
31326 p->zTestcase, azArg[1], zRes);
31327 rc = 1;
31328 }else{
31329 cli_printf(p->out, "testcase-%s ok\n", p->zTestcase);
31330 p->nCheck++;
31331 }
31332 sqlite3_free(zRes);
31333 }else
31334 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28799,13 +31357,13 @@
31357 zFile = "(memory)";
31358 }else if( zFile[0]==0 ){
31359 zFile = "(temporary-file)";
31360 }
31361 if( p->pAuxDb == &p->aAuxDb[i] ){
31362 cli_printf(stdout, "ACTIVE %d: %s\n", i, zFile);
31363 }else if( p->aAuxDb[i].db!=0 ){
31364 cli_printf(stdout, " %d: %s\n", i, zFile);
31365 }
31366 }
31367 }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){
31368 int i = azArg[1][0] - '0';
31369 if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){
@@ -28837,16 +31395,21 @@
31395 && (cli_strncmp(azArg[0], "crlf", n)==0
31396 || cli_strncmp(azArg[0], "crnl",n)==0)
31397 ){
31398 if( nArg==2 ){
31399 #ifdef _WIN32
31400 if( booleanValue(azArg[1]) ){
31401 p->mode.mFlags |= MFLG_CRLF;
31402 }else{
31403 p->mode.mFlags &= ~MFLG_CRLF;
31404 }
31405 #else
31406 p->mode.mFlags &= ~MFLG_CRLF;
31407 #endif
31408 }
31409 cli_printf(stderr, "crlf is %s\n",
31410 (p->mode.mFlags & MFLG_CRLF)!=0 ? "ON" : "OFF");
31411 }else
31412
31413 if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
31414 char **azName = 0;
31415 int nName = 0;
@@ -28872,11 +31435,11 @@
31435 sqlite3_finalize(pStmt);
31436 for(i=0; i<nName; i++){
31437 int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
31438 int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
31439 const char *z = azName[i*2+1];
31440 cli_printf(p->out, "%s: %s %s%s\n",
31441 azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w",
31442 eTxn==SQLITE_TXN_NONE ? "" :
31443 eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
31444 free(azName[i*2]);
31445 free(azName[i*2+1]);
@@ -28917,17 +31480,17 @@
31480 if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
31481 if( nArg>=3 ){
31482 sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
31483 }
31484 sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
31485 cli_printf(p->out, "%19s %s\n",
31486 aDbConfig[ii].zName, v ? "on" : "off");
31487 if( nArg>1 ) break;
31488 }
31489 if( nArg>1 && ii==ArraySize(aDbConfig) ){
31490 dotCmdError(p, 1, "unknown dbconfig",
31491 "Enter \".dbconfig\" with no arguments for a list");
31492 }
31493 }else
31494
31495 #if SQLITE_SHELL_HAVE_RECOVER
31496 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
@@ -28942,42 +31505,41 @@
31505
31506 if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){
31507 char *zLike = 0;
31508 char *zSql;
31509 int i;
 
31510 int savedShellFlags = p->shellFlgs;
31511 Mode saved_mode;
31512 ShellClearFlag(p,
31513 SHFLG_PreserveRowid|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
 
31514 for(i=1; i<nArg; i++){
31515 if( azArg[i][0]=='-' ){
31516 const char *z = azArg[i]+1;
31517 if( z[0]=='-' ) z++;
31518 if( cli_strcmp(z,"preserve-rowids")==0 ){
31519 #ifdef SQLITE_OMIT_VIRTUALTABLE
31520 dotCmdError(p, i, "unable",
31521 "The --preserve-rowids option is not compatible"
31522 " with SQLITE_OMIT_VIRTUALTABLE");
31523 rc = 1;
31524 sqlite3_free(zLike);
31525 goto meta_command_exit;
31526 #else
31527 ShellSetFlag(p, SHFLG_PreserveRowid);
31528 #endif
31529 }else
31530 if( cli_strcmp(z,"newlines")==0 ){
31531 /*ShellSetFlag(p, SHFLG_Newlines);*/
31532 }else
31533 if( cli_strcmp(z,"data-only")==0 ){
31534 ShellSetFlag(p, SHFLG_DumpDataOnly);
31535 }else
31536 if( cli_strcmp(z,"nosys")==0 ){
31537 ShellSetFlag(p, SHFLG_DumpNoSys);
31538 }else
31539 {
31540 dotCmdError(p, i, "unknown option", 0);
 
31541 rc = 1;
31542 sqlite3_free(zLike);
31543 goto meta_command_exit;
31544 }
31545 }else{
@@ -29003,20 +31565,21 @@
31565 }
31566 }
31567
31568 open_db(p, 0);
31569
31570 modeDup(&saved_mode, &p->mode);
31571 outputDumpWarning(p, zLike);
31572 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
31573 /* When playing back a "dump", the content might appear in an order
31574 ** which causes immediate foreign key constraints to be violated.
31575 ** So disable foreign-key constraint enforcement to prevent problems. */
31576 cli_puts("PRAGMA foreign_keys=OFF;\n", p->out);
31577 cli_puts("BEGIN TRANSACTION;\n", p->out);
31578 }
31579 p->writableSchema = 0;
31580 p->mode.spec.bTitles = QRF_No;
31581 /* Set writable_schema=ON since doing so forces SQLite to initialize
31582 ** as much of the schema as it can even if the sqlite_schema table is
31583 ** corrupt. */
31584 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
31585 p->nErr = 0;
@@ -29041,25 +31604,31 @@
31604 run_table_dump_query(p, zSql);
31605 sqlite3_free(zSql);
31606 }
31607 sqlite3_free(zLike);
31608 if( p->writableSchema ){
31609 cli_puts("PRAGMA writable_schema=OFF;\n", p->out);
31610 p->writableSchema = 0;
31611 }
31612 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
31613 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
31614 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
31615 cli_puts(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out);
31616 }
 
31617 p->shellFlgs = savedShellFlags;
31618 modeFree(&p->mode);
31619 p->mode = saved_mode;
31620 rc = p->nErr>0;
31621 }else
31622
31623 if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
31624 if( nArg==2 ){
31625 if( booleanValue(azArg[1]) ){
31626 p->mode.mFlags |= MFLG_ECHO;
31627 }else{
31628 p->mode.mFlags &= ~MFLG_ECHO;
31629 }
31630 }else{
31631 eputz("Usage: .echo on|off\n");
31632 rc = 1;
31633 }
31634 }else
@@ -29069,74 +31638,58 @@
31638 rc = shell_dbtotxt_command(p, nArg, azArg);
31639 }else
31640
31641 if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
31642 if( nArg==2 ){
31643 if( p->mode.autoEQPtrace ){
 
31644 if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
31645 p->mode.autoEQPtrace = 0;
31646 }
31647 if( cli_strcmp(azArg[1],"full")==0 ){
31648 p->mode.autoEQP = AUTOEQP_full;
31649 }else if( cli_strcmp(azArg[1],"trigger")==0 ){
31650 p->mode.autoEQP = AUTOEQP_trigger;
31651 #ifdef SQLITE_DEBUG
 
 
 
31652 }else if( cli_strcmp(azArg[1],"trace")==0 ){
31653 p->mode.autoEQP = AUTOEQP_full;
31654 p->mode.autoEQPtrace = 1;
31655 open_db(p, 0);
31656 sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
31657 sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
31658 #endif
31659 }else{
31660 p->mode.autoEQP = (u8)booleanValue(azArg[1]);
31661 }
31662 }else{
31663 eputz("Usage: .eqp off|on|trace|trigger|full\n");
31664 rc = 1;
31665 }
31666 }else
31667
31668 #ifndef SQLITE_SHELL_FIDDLE
31669 if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
31670 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) cli_exit(rc);
31671 rc = 2;
31672 }else
31673 #endif
31674
31675 /* The ".explain" command is automatic now. It is largely pointless. It
31676 ** retained purely for backwards compatibility */
31677 if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){
 
31678 if( nArg>=2 ){
31679 if( cli_strcmp(azArg[1],"auto")==0 ){
31680 p->mode.autoExplain = 1;
31681 }else{
31682 p->mode.autoExplain = booleanValue(azArg[1]);
31683 }
 
 
 
 
 
 
 
 
 
 
 
31684 }
31685 }else
31686
31687 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
31688 if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
31689 if( p->bSafeMode ){
31690 cli_printf(stderr,
31691 "Cannot run experimental commands such as \"%s\" in safe mode\n",
31692 azArg[0]);
31693 rc = 1;
31694 }else{
31695 open_db(p, 0);
@@ -29190,13 +31743,13 @@
31743 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
31744 }
31745
31746 /* --help lists all file-controls */
31747 if( cli_strcmp(zCmd,"help")==0 ){
31748 cli_puts("Available file-controls:\n", p->out);
31749 for(i=0; i<ArraySize(aCtrl); i++){
31750 cli_printf(p->out,
31751 " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage);
31752 }
31753 rc = 1;
31754 goto meta_command_exit;
31755 }
@@ -29208,19 +31761,19 @@
31761 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
31762 if( filectrl<0 ){
31763 filectrl = aCtrl[i].ctrlCode;
31764 iCtrl = i;
31765 }else{
31766 cli_printf(stderr,"Error: ambiguous file-control: \"%s\"\n"
31767 "Use \".filectrl --help\" for help\n", zCmd);
31768 rc = 1;
31769 goto meta_command_exit;
31770 }
31771 }
31772 }
31773 if( filectrl<0 ){
31774 cli_printf(stderr,"Error: unknown file-control: %s\n"
31775 "Use \".filectrl --help\" for help\n", zCmd);
31776 }else{
31777 switch(filectrl){
31778 case SQLITE_FCNTL_SIZE_LIMIT: {
31779 if( nArg!=2 && nArg!=3 ) break;
@@ -29260,11 +31813,11 @@
31813 case SQLITE_FCNTL_TEMPFILENAME: {
31814 char *z = 0;
31815 if( nArg!=2 ) break;
31816 sqlite3_file_control(p->db, zSchema, filectrl, &z);
31817 if( z ){
31818 cli_printf(p->out, "%s\n", z);
31819 sqlite3_free(z);
31820 }
31821 isOk = 2;
31822 break;
31823 }
@@ -29274,81 +31827,96 @@
31827 x = atoi(azArg[2]);
31828 sqlite3_file_control(p->db, zSchema, filectrl, &x);
31829 }
31830 x = -1;
31831 sqlite3_file_control(p->db, zSchema, filectrl, &x);
31832 cli_printf(p->out, "%d\n", x);
31833 isOk = 2;
31834 break;
31835 }
31836 }
31837 }
31838 if( isOk==0 && iCtrl>=0 ){
31839 cli_printf(p->out, "Usage: .filectrl %s %s\n",
31840 zCmd, aCtrl[iCtrl].zUsage);
31841 rc = 1;
31842 }else if( isOk==1 ){
31843 char zBuf[100];
31844 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
31845 cli_printf(p->out, "%s\n", zBuf);
31846 }
31847 }else
31848
31849 if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){
31850 ShellState data;
31851 int doStats = 0;
31852 int hasStat[5];
31853 int flgs = 0;
31854 char *zSql;
31855 if( nArg==2 && optionMatch(azArg[1], "indent") ){
 
31856 nArg = 1;
31857 }
31858 if( nArg!=1 ){
31859 eputz("Usage: .fullschema ?--indent?\n");
31860 rc = 1;
31861 goto meta_command_exit;
31862 }
31863 open_db(p, 0);
31864 zSql = sqlite3_mprintf(
31865 "SELECT shell_format_schema(sql,%d) FROM"
31866 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
31867 " FROM sqlite_schema UNION ALL"
31868 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
31869 "WHERE type!='meta' AND sql NOTNULL"
31870 " AND name NOT LIKE 'sqlite__%%' ESCAPE '_' "
31871 "ORDER BY x", flgs);
31872 memcpy(&data, p, sizeof(data));
31873 data.mode.spec.bTitles = QRF_No;
31874 data.mode.eMode = MODE_List;
31875 data.mode.spec.eText = QRF_TEXT_Plain;
31876 data.mode.spec.nCharLimit = 0;
31877 data.mode.spec.zRowSep = "\n";
31878 rc = shell_exec(&data,zSql,0);
31879 sqlite3_free(zSql);
31880 if( rc==SQLITE_OK ){
31881 memset(hasStat, 0, sizeof(hasStat));
31882 sqlite3_stmt *pStmt;
31883 rc = sqlite3_prepare_v2(p->db,
31884 "SELECT substr(name,12,1) FROM sqlite_schema"
31885 " WHERE name GLOB 'sqlite_stat[134]'",
31886 -1, &pStmt, 0);
31887 if( rc==SQLITE_OK ){
31888 while( sqlite3_step(pStmt)==SQLITE_ROW ){
31889 int k = sqlite3_column_int(pStmt,0);
31890 assert( k==1 || k==3 || k==4 );
31891 hasStat[k] = 1;
31892 doStats = 1;
31893 }
31894 }
31895 sqlite3_finalize(pStmt);
31896 }
31897 if( doStats==0 ){
31898 cli_puts("/* No STAT tables available */\n", p->out);
31899 }else{
31900 cli_puts("ANALYZE sqlite_schema;\n", p->out);
31901 data.mode.eMode = MODE_Insert;
31902 if( hasStat[1] ){
31903 data.mode.spec.zTableName = "sqlite_stat1";
31904 shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
31905 }
31906 if( hasStat[4] ){
31907 data.mode.spec.zTableName = "sqlite_stat4";
31908 shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
31909 }
31910 cli_puts("ANALYZE sqlite_schema;\n", p->out);
31911 }
31912 }else
31913
31914 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
31915 if( nArg==2 ){
31916 p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
31917 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
31918 }else{
31919 eputz("Usage: .headers on|off\n");
31920 rc = 1;
31921 }
31922 }else
@@ -29355,340 +31923,20 @@
31923
31924 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
31925 if( nArg>=2 ){
31926 n = showHelp(p->out, azArg[1]);
31927 if( n==0 ){
31928 cli_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
31929 }
31930 }else{
31931 showHelp(p->out, 0);
31932 }
31933 }else
31934
31935 #ifndef SQLITE_SHELL_FIDDLE
31936 if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
31937 rc = dotCmdImport(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31938 }else
31939 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
31940
31941 #ifndef SQLITE_UNTESTABLE
31942 if( c=='i' && cli_strncmp(azArg[0], "imposter", n)==0 ){
@@ -29758,11 +32006,11 @@
32006 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
32007 }
32008 }
32009 sqlite3_finalize(pStmt);
32010 if( i==0 || tnum==0 ){
32011 cli_printf(stderr,"no such index: \"%s\"\n", azArg[1]);
32012 rc = 1;
32013 sqlite3_free(zCollist);
32014 goto meta_command_exit;
32015 }
32016 if( lenPK==0 ) lenPK = 100000;
@@ -29773,17 +32021,17 @@
32021 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum);
32022 if( rc==SQLITE_OK ){
32023 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
32024 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
32025 if( rc ){
32026 cli_printf(stderr,
32027 "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
32028 }else{
32029 cli_printf(stdout, "%s;\n", zSql);
32030 }
32031 }else{
32032 cli_printf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
32033 rc = 1;
32034 }
32035 sqlite3_free(zSql);
32036 }else
32037 #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
@@ -29793,11 +32041,11 @@
32041 if( nArg==2 ){
32042 iArg = integerValue(azArg[1]);
32043 if( iArg==0 ) iArg = -1;
32044 }
32045 if( (nArg!=1 && nArg!=2) || iArg<0 ){
32046 cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
32047 rc = 1;
32048 goto meta_command_exit;
32049 }
32050 open_db(p, 0);
32051 rc = intckDatabaseCmd(p, iArg);
@@ -29814,11 +32062,11 @@
32062 sqlite3IoTrace = iotracePrintf;
32063 iotrace = stdout;
32064 }else{
32065 iotrace = sqlite3_fopen(azArg[1], "w");
32066 if( iotrace==0 ){
32067 cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32068 sqlite3IoTrace = 0;
32069 rc = 1;
32070 }else{
32071 sqlite3IoTrace = iotracePrintf;
32072 }
@@ -29833,10 +32081,11 @@
32081 } aLimit[] = {
32082 { "length", SQLITE_LIMIT_LENGTH },
32083 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
32084 { "column", SQLITE_LIMIT_COLUMN },
32085 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
32086 { "parser_depth", SQLITE_LIMIT_PARSER_DEPTH },
32087 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
32088 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
32089 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
32090 { "attached", SQLITE_LIMIT_ATTACHED },
32091 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
@@ -29846,11 +32095,11 @@
32095 };
32096 int i, n2;
32097 open_db(p, 0);
32098 if( nArg==1 ){
32099 for(i=0; i<ArraySize(aLimit); i++){
32100 cli_printf(stdout, "%20s %d\n", aLimit[i].zLimitName,
32101 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
32102 }
32103 }else if( nArg>3 ){
32104 eputz("Usage: .limit NAME ?NEW-VALUE?\n");
32105 rc = 1;
@@ -29861,28 +32110,28 @@
32110 for(i=0; i<ArraySize(aLimit); i++){
32111 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
32112 if( iLimit<0 ){
32113 iLimit = i;
32114 }else{
32115 cli_printf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]);
32116 rc = 1;
32117 goto meta_command_exit;
32118 }
32119 }
32120 }
32121 if( iLimit<0 ){
32122 cli_printf(stderr,"unknown limit: \"%s\"\n"
32123 "enter \".limits\" with no arguments for a list.\n",
32124 azArg[1]);
32125 rc = 1;
32126 goto meta_command_exit;
32127 }
32128 if( nArg==3 ){
32129 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
32130 (int)integerValue(azArg[2]));
32131 }
32132 cli_printf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName,
32133 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
32134 }
32135 }else
32136
32137 if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){
@@ -29927,189 +32176,27 @@
32176 " than \"on\" or \"off\"\n");
32177 zFile = "off";
32178 }
32179 output_file_close(p->pLog);
32180 if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
32181 p->pLog = output_file_open(p, zFile);
32182 }
32183 }else
32184
32185 if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){
32186 rc = dotCmdMode(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32187 }else
32188
32189 #ifndef SQLITE_SHELL_FIDDLE
32190 if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
32191 if( nArg!=2 ){
32192 eputz("Usage: .nonce NONCE\n");
32193 rc = 1;
32194 }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
32195 cli_printf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
32196 p->lineno, azArg[1]);
32197 cli_exit(1);
32198 }else{
32199 p->bSafeMode = 0;
32200 return 0; /* Return immediately to bypass the safe mode reset
32201 ** at the end of this procedure */
32202 }
@@ -30116,12 +32203,11 @@
32203 }else
32204 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
32205
32206 if( c=='n' && cli_strncmp(azArg[0], "nullvalue", n)==0 ){
32207 if( nArg==2 ){
32208 modeSetStr(&p->mode.spec.zNull, azArg[1]);
 
32209 }else{
32210 eputz("Usage: .nullvalue STRING\n");
32211 rc = 1;
32212 }
32213 }else
@@ -30166,15 +32252,15 @@
32252 p->szMax = integerValue(azArg[++iName]);
32253 #endif /* SQLITE_OMIT_DESERIALIZE */
32254 }else
32255 #endif /* !SQLITE_SHELL_FIDDLE */
32256 if( z[0]=='-' ){
32257 cli_printf(stderr,"unknown option: %s\n", z);
32258 rc = 1;
32259 goto meta_command_exit;
32260 }else if( zFN ){
32261 cli_printf(stderr,"extra argument: \"%s\"\n", z);
32262 rc = 1;
32263 goto meta_command_exit;
32264 }else{
32265 zFN = z;
32266 }
@@ -30221,11 +32307,11 @@
32307 zNewFilename = 0;
32308 }
32309 p->pAuxDb->zDbFilename = zNewFilename;
32310 open_db(p, OPEN_DB_KEEPALIVE);
32311 if( p->db==0 ){
32312 cli_printf(stderr,"Error: cannot open '%s'\n", zNewFilename);
32313 sqlite3_free(zNewFilename);
32314 }else{
32315 p->pAuxDb->zFreeOnClose = zNewFilename;
32316 }
32317 }
@@ -30241,149 +32327,11 @@
32327 && (cli_strncmp(azArg[0], "output", n)==0
32328 || cli_strncmp(azArg[0], "once", n)==0))
32329 || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0)
32330 || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0)
32331 ){
32332 rc = dotCmdOutput(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32333 }else
32334 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
32335
32336 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "parameter", n)==0 ){
32337 open_db(p,0);
@@ -30416,11 +32364,11 @@
32364 if( len ){
32365 rx = sqlite3_prepare_v2(p->db,
32366 "SELECT key, quote(value) "
32367 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
32368 while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
32369 cli_printf(p->out,
32370 "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
32371 sqlite3_column_text(pStmt,1));
32372 }
32373 sqlite3_finalize(pStmt);
32374 }
@@ -30462,11 +32410,11 @@
32410 "VALUES(%Q,%Q);", zKey, zValue);
32411 shell_check_oom(zSql);
32412 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
32413 sqlite3_free(zSql);
32414 if( rx!=SQLITE_OK ){
32415 cli_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
32416 sqlite3_finalize(pStmt);
32417 pStmt = 0;
32418 rc = 1;
32419 }
32420 }
@@ -30492,14 +32440,14 @@
32440 }else
32441
32442 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
32443 int i;
32444 for(i=1; i<nArg; i++){
32445 if( i>1 ) cli_puts(" ", p->out);
32446 cli_puts(azArg[i], p->out);
32447 }
32448 cli_puts("\n", p->out);
32449 }else
32450
32451 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
32452 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){
32453 int i;
@@ -30532,11 +32480,11 @@
32480 }else{
32481 p->mxProgress = (int)integerValue(azArg[++i]);
32482 }
32483 continue;
32484 }
32485 cli_printf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]);
32486 rc = 1;
32487 goto meta_command_exit;
32488 }else{
32489 nn = (int)integerValue(z);
32490 }
@@ -30576,22 +32524,24 @@
32524 eputz("Error: pipes are not supported in this OS\n");
32525 rc = 1;
32526 #else
32527 p->in = sqlite3_popen(azArg[1]+1, "r");
32528 if( p->in==0 ){
32529 cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32530 rc = 1;
32531 }else{
32532 rc = process_input(p, "<pipe>");
32533 pclose(p->in);
32534 }
32535 #endif
32536 }else if( (p->in = openChrSource(azArg[1]))==0 ){
32537 cli_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
32538 rc = 1;
32539 }else{
32540 char *zFilename = strdup(azArg[1]);
32541 rc = process_input(p, zFilename);
32542 free(zFilename);
32543 fclose(p->in);
32544 }
32545 p->in = inSaved;
32546 p->lineno = savedLineno;
32547 }else
@@ -30617,11 +32567,11 @@
32567 rc = 1;
32568 goto meta_command_exit;
32569 }
32570 rc = sqlite3_open(zSrcFile, &pSrc);
32571 if( rc!=SQLITE_OK ){
32572 cli_printf(stderr,"Error: cannot open \"%s\"\n", zSrcFile);
32573 close_db(pSrc);
32574 return 1;
32575 }
32576 open_db(p, 0);
32577 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
@@ -30655,25 +32605,25 @@
32605 (cli_strncmp(azArg[0], "scanstats", n)==0 ||
32606 cli_strncmp(azArg[0], "scanstatus", n)==0)
32607 ){
32608 if( nArg==2 ){
32609 if( cli_strcmp(azArg[1], "vm")==0 ){
32610 p->mode.scanstatsOn = 3;
32611 }else
32612 if( cli_strcmp(azArg[1], "est")==0 ){
32613 p->mode.scanstatsOn = 2;
32614 }else{
32615 p->mode.scanstatsOn = (u8)booleanValue(azArg[1]);
32616 }
32617 open_db(p, 0);
32618 sqlite3_db_config(
32619 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->mode.scanstatsOn, (int*)0
32620 );
32621 #if !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
32622 eputz("Warning: .scanstats not available in this build.\n");
32623 #elif !defined(SQLITE_ENABLE_BYTECODE_VTAB)
32624 if( p->mode.scanstatsOn==3 ){
32625 eputz("Warning: \".scanstats vm\" not available in this build.\n");
32626 }
32627 #endif
32628 }else{
32629 eputz("Usage: .scanstats on|off|est\n");
@@ -30680,34 +32630,38 @@
32630 rc = 1;
32631 }
32632 }else
32633
32634 if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){
 
32635 ShellState data;
32636 char *zErrMsg = 0;
32637 const char *zDiv = "(";
32638 const char *zName = 0;
32639 int iSchema = 0;
32640 int bDebug = 0;
32641 int bNoSystemTabs = 0;
32642 int bIndent = 0;
32643 int ii;
32644 sqlite3_str *pSql;
32645 sqlite3_stmt *pStmt = 0;
32646
32647 open_db(p, 0);
32648 memcpy(&data, p, sizeof(data));
32649 data.mode.spec.bTitles = QRF_No;
32650 data.mode.eMode = MODE_List;
32651 data.mode.spec.eText = QRF_TEXT_Plain;
32652 data.mode.spec.nCharLimit = 0;
32653 data.mode.spec.zRowSep = "\n";
32654 for(ii=1; ii<nArg; ii++){
32655 if( optionMatch(azArg[ii],"indent") ){
32656 bIndent = 1;
32657 }else if( optionMatch(azArg[ii],"debug") ){
32658 bDebug = 1;
32659 }else if( optionMatch(azArg[ii],"nosys") ){
32660 bNoSystemTabs = 1;
32661 }else if( azArg[ii][0]=='-' ){
32662 cli_printf(stderr,"Unknown option: \"%s\"\n", azArg[ii]);
32663 rc = 1;
32664 goto meta_command_exit;
32665 }else if( zName==0 ){
32666 zName = azArg[ii];
32667 }else{
@@ -30720,100 +32674,87 @@
32674 int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
32675 || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
32676 || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
32677 || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
32678 if( isSchema ){
32679 cli_printf(p->out,
 
32680 "CREATE TABLE %s (\n"
32681 " type text,\n"
32682 " name text,\n"
32683 " tbl_name text,\n"
32684 " rootpage integer,\n"
32685 " sql text\n"
32686 ");\n", zName);
32687 }
32688 }
32689 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
32690 -1, &pStmt, 0);
32691 if( rc ){
32692 shellDatabaseError(p->db);
32693 sqlite3_finalize(pStmt);
32694
32695 rc = 1;
32696 goto meta_command_exit;
32697 }
32698 pSql = sqlite3_str_new(p->db);
32699 sqlite3_str_appendf(pSql, "SELECT sql FROM", 0);
32700 iSchema = 0;
32701 while( sqlite3_step(pStmt)==SQLITE_ROW ){
32702 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
32703 char zScNum[30];
32704 sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
32705 sqlite3_str_appendall(pSql, zDiv);
32706 zDiv = " UNION ALL ";
32707 if( sqlite3_stricmp(zDb, "main")==0 ){
32708 sqlite3_str_appendf(pSql,
32709 "SELECT shell_format_schema(shell_add_schema(sql,NULL,name),%d)",
32710 bIndent);
32711 }else{
32712 sqlite3_str_appendf(pSql,
32713 "SELECT shell_format_schema(shell_add_schema(sql,%Q,name),%d))",
32714 zDb, bIndent);
32715 }
32716 sqlite3_str_appendf(pSql,
32717 " AS sql, type, tbl_name, name, rowid, %d AS snum, %Q as sname",
32718 ++iSchema, zDb);
32719 sqlite3_str_appendf(pSql," FROM \"%w\".sqlite_schema", zDb);
32720 }
32721 sqlite3_finalize(pStmt);
 
 
 
 
 
 
32722 #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
32723 if( zName ){
32724 sqlite3_str_appendall(pSql,
32725 " UNION ALL SELECT shell_module_schema(name),"
32726 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list");
32727 }
32728 #endif
32729 sqlite3_str_appendf(pSql, ") WHERE ", 0);
32730 if( zName ){
32731 int bGlob;
32732 bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
32733 strchr(zName, '[') != 0;
32734 if( strchr(zName, '.') ){
32735 sqlite3_str_appendall(pSql, "lower(format('%%s.%%s',sname,tbl_name))");
32736 }else{
32737 sqlite3_str_appendall(pSql, "lower(tbl_name)");
32738 }
32739 if( bGlob ){
32740 sqlite3_str_appendf(pSql, " GLOB %Q AND ", zName);
32741 }else{
32742 sqlite3_str_appendf(pSql, " LIKE %Q ESCAPE '\\' AND ", zName);
32743 }
32744 }
32745 if( bNoSystemTabs ){
32746 sqlite3_str_appendf(pSql, " name NOT LIKE 'sqlite__%%' ESCALE '_' AND ");
32747 }
32748 sqlite3_str_appendf(pSql, "sql IS NOT NULL ORDER BY snum, rowid");
32749 if( bDebug ){
32750 cli_printf(p->out, "SQL: %s;\n", sqlite3_str_value(pSql));
32751 }else{
32752 rc = shell_exec(&data, sqlite3_str_value(pSql), &zErrMsg);
32753 }
32754 sqlite3_str_free(pSql);
32755
 
 
 
 
 
 
32756 if( zErrMsg ){
32757 shellEmitError(zErrMsg);
32758 sqlite3_free(zErrMsg);
32759 rc = 1;
32760 }else if( rc != SQLITE_OK ){
@@ -30865,11 +32806,11 @@
32806 session_not_open:
32807 eputz("ERROR: No sessions are open\n");
32808 }else{
32809 rc = sqlite3session_attach(pSession->p, azCmd[1]);
32810 if( rc ){
32811 cli_printf(stderr,
32812 "ERROR: sqlite3session_attach() returns %d\n",rc);
32813 rc = 0;
32814 }
32815 }
32816 }else
@@ -30885,11 +32826,11 @@
32826 failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
32827 if( nCmd!=2 ) goto session_syntax_error;
32828 if( pSession->p==0 ) goto session_not_open;
32829 out = sqlite3_fopen(azCmd[1], "wb");
32830 if( out==0 ){
32831 cli_printf(stderr,"ERROR: cannot open \"%s\" for writing\n",
32832 azCmd[1]);
32833 }else{
32834 int szChng;
32835 void *pChng;
32836 if( azCmd[0][0]=='c' ){
@@ -30896,16 +32837,16 @@
32837 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
32838 }else{
32839 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
32840 }
32841 if( rc ){
32842 cli_printf(stdout, "Error: error code %d\n", rc);
32843 rc = 0;
32844 }
32845 if( pChng
32846 && fwrite(pChng, szChng, 1, out)!=1 ){
32847 cli_printf(stderr,
32848 "ERROR: Failed to write entire %d-byte output\n", szChng);
32849 }
32850 sqlite3_free(pChng);
32851 fclose(out);
32852 }
@@ -30929,11 +32870,11 @@
32870 int ii;
32871 if( nCmd>2 ) goto session_syntax_error;
32872 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
32873 if( pAuxDb->nSession ){
32874 ii = sqlite3session_enable(pSession->p, ii);
32875 cli_printf(p->out,
32876 "session %s enable flag = %d\n", pSession->zName, ii);
32877 }
32878 }else
32879
32880 /* .session filter GLOB ....
@@ -30966,11 +32907,11 @@
32907 int ii;
32908 if( nCmd>2 ) goto session_syntax_error;
32909 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
32910 if( pAuxDb->nSession ){
32911 ii = sqlite3session_indirect(pSession->p, ii);
32912 cli_printf(p->out,
32913 "session %s indirect flag = %d\n", pSession->zName, ii);
32914 }
32915 }else
32916
32917 /* .session isempty
@@ -30979,21 +32920,21 @@
32920 if( cli_strcmp(azCmd[0], "isempty")==0 ){
32921 int ii;
32922 if( nCmd!=1 ) goto session_syntax_error;
32923 if( pAuxDb->nSession ){
32924 ii = sqlite3session_isempty(pSession->p);
32925 cli_printf(p->out,
32926 "session %s isempty flag = %d\n", pSession->zName, ii);
32927 }
32928 }else
32929
32930 /* .session list
32931 ** List all currently open sessions
32932 */
32933 if( cli_strcmp(azCmd[0],"list")==0 ){
32934 for(i=0; i<pAuxDb->nSession; i++){
32935 cli_printf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName);
32936 }
32937 }else
32938
32939 /* .session open DB NAME
32940 ** Open a new session called NAME on the attached database DB.
@@ -31004,23 +32945,23 @@
32945 if( nCmd!=3 ) goto session_syntax_error;
32946 zName = azCmd[2];
32947 if( zName[0]==0 ) goto session_syntax_error;
32948 for(i=0; i<pAuxDb->nSession; i++){
32949 if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){
32950 cli_printf(stderr,"Session \"%s\" already exists\n", zName);
32951 goto meta_command_exit;
32952 }
32953 }
32954 if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
32955 cli_printf(stderr,
32956 "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
32957 goto meta_command_exit;
32958 }
32959 pSession = &pAuxDb->aSession[pAuxDb->nSession];
32960 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
32961 if( rc ){
32962 cli_printf(stderr,"Cannot open session: error code=%d\n", rc);
32963 rc = 0;
32964 goto meta_command_exit;
32965 }
32966 pSession->nFilter = 0;
32967 sqlite3session_table_filter(pSession->p, session_filter, pSession);
@@ -31040,20 +32981,20 @@
32981 if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){
32982 if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){
32983 int i, v;
32984 for(i=1; i<nArg; i++){
32985 v = booleanValue(azArg[i]);
32986 cli_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
32987 }
32988 }
32989 if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){
32990 int i; sqlite3_int64 v;
32991 for(i=1; i<nArg; i++){
32992 char zBuf[200];
32993 v = integerValue(azArg[i]);
32994 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
32995 cli_puts(zBuf, p->out);
32996 }
32997 }
32998 }else
32999 #endif
33000
@@ -31076,13 +33017,13 @@
33017 }else
33018 if( cli_strcmp(z,"-v")==0 ){
33019 bVerbose++;
33020 }else
33021 {
33022 cli_printf(stderr,
33023 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
33024 cli_puts("Should be one of: --init -v\n", stderr);
33025 rc = 1;
33026 goto meta_command_exit;
33027 }
33028 }
33029 if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
@@ -31123,61 +33064,59 @@
33064 if( zOp==0 ) continue;
33065 if( zSql==0 ) continue;
33066 if( zAns==0 ) continue;
33067 k = 0;
33068 if( bVerbose>0 ){
33069 cli_printf(stdout, "%d: %s %s\n", tno, zOp, zSql);
33070 }
33071 if( cli_strcmp(zOp,"memo")==0 ){
33072 cli_printf(p->out, "%s\n", zSql);
33073 }else
33074 if( cli_strcmp(zOp,"run")==0 ){
33075 char *zErrMsg = 0;
33076 str.n = 0;
33077 str.zTxt[0] = 0;
33078 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
33079 nTest++;
33080 if( bVerbose ){
33081 cli_printf(p->out, "Result: %s\n", str.zTxt);
33082 }
33083 if( rc || zErrMsg ){
33084 nErr++;
33085 rc = 1;
33086 cli_printf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
33087 sqlite3_free(zErrMsg);
33088 }else if( cli_strcmp(zAns,str.zTxt)!=0 ){
33089 nErr++;
33090 rc = 1;
33091 cli_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
33092 cli_printf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
33093 }
33094 }
33095 else{
33096 cli_printf(stderr,
33097 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
33098 rc = 1;
33099 break;
33100 }
33101 } /* End loop over rows of content from SELFTEST */
33102 sqlite3_finalize(pStmt);
33103 } /* End loop over k */
33104 freeText(&str);
33105 cli_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
33106 }else
33107
33108 if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){
33109 if( nArg<2 || nArg>3 ){
33110 eputz("Usage: .separator COL ?ROW?\n");
33111 rc = 1;
33112 }
33113 if( nArg>=2 ){
33114 modeSetStr(&p->mode.spec.zColumnSep, azArg[1]);
 
33115 }
33116 if( nArg>=3 ){
33117 modeSetStr(&p->mode.spec.zRowSep,azArg[2]);
 
33118 }
33119 }else
33120
33121 if( c=='s' && n>=4 && cli_strncmp(azArg[0],"sha3sum",n)==0 ){
33122 const char *zLike = 0; /* Which table to checksum. 0 means everything */
@@ -31207,11 +33146,11 @@
33146 }else
33147 if( cli_strcmp(z,"debug")==0 ){
33148 bDebug = 1;
33149 }else
33150 {
33151 cli_printf(stderr,
33152 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
33153 showHelp(p->out, azArg[0]);
33154 rc = 1;
33155 goto meta_command_exit;
33156 }
@@ -31286,11 +33225,11 @@
33225 }
33226 shell_check_oom(zSql);
33227 freeText(&sQuery);
33228 freeText(&sSql);
33229 if( bDebug ){
33230 cli_printf(p->out, "%s\n", zSql);
33231 }else{
33232 shell_exec(p, zSql, 0);
33233 }
33234 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
33235 {
@@ -31316,11 +33255,11 @@
33255 "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
33256 "|| ' AND typeof('||cname||')=''text'' ',\n"
33257 "' OR ') as query, tname from tabcols group by tname)"
33258 , zRevText);
33259 shell_check_oom(zRevText);
33260 if( bDebug ) cli_printf(p->out, "%s\n", zRevText);
33261 lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
33262 if( lrc!=SQLITE_OK ){
33263 /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the
33264 ** user does cruel and unnatural things like ".limit expr_depth 0". */
33265 rc = 1;
@@ -31329,19 +33268,19 @@
33268 lrc = SQLITE_ROW==sqlite3_step(pStmt);
33269 if( lrc ){
33270 const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
33271 sqlite3_stmt *pCheckStmt;
33272 lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
33273 if( bDebug ) cli_printf(p->out, "%s\n", zGenQuery);
33274 if( lrc!=SQLITE_OK ){
33275 rc = 1;
33276 }else{
33277 if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
33278 double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
33279 if( countIrreversible>0 ){
33280 int sz = (int)(countIrreversible + 0.5);
33281 cli_printf(stderr,
33282 "Digest includes %d invalidly encoded text field%s.\n",
33283 sz, (sz>1)? "s": "");
33284 }
33285 }
33286 sqlite3_finalize(pCheckStmt);
@@ -31376,11 +33315,11 @@
33315 }
33316 /*consoleRestore();*/
33317 x = zCmd!=0 ? system(zCmd) : 1;
33318 /*consoleRenewSetup();*/
33319 sqlite3_free(zCmd);
33320 if( x ) cli_printf(stderr,"System command returns %d\n", x);
33321 }else
33322 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */
33323
33324 if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){
33325 static const char *azBool[] = { "off", "on", "trigger", "full"};
@@ -31389,52 +33328,55 @@
33328 if( nArg!=1 ){
33329 eputz("Usage: .show\n");
33330 rc = 1;
33331 goto meta_command_exit;
33332 }
33333 cli_printf(p->out, "%12.12s: %s\n","echo",
33334 azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
33335 cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
33336 cli_printf(p->out, "%12.12s: %s\n","explain",
33337 p->mode.autoExplain ? "auto" : "off");
33338 cli_printf(p->out, "%12.12s: %s\n","headers",
33339 azBool[p->mode.spec.bTitles==QRF_Yes]);
33340 if( p->mode.spec.eStyle==QRF_STYLE_Column
33341 || p->mode.spec.eStyle==QRF_STYLE_Box
33342 || p->mode.spec.eStyle==QRF_STYLE_Table
33343 || p->mode.spec.eStyle==QRF_STYLE_Markdown
33344 ){
33345 cli_printf(p->out,
33346 "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
33347 aModeInfo[p->mode.eMode].zName, p->mode.spec.nWrap,
33348 p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off",
33349 p->mode.spec.eText==QRF_TEXT_Sql ? "" : "no");
33350 }else{
33351 cli_printf(p->out, "%12.12s: %s\n","mode",
33352 aModeInfo[p->mode.eMode].zName);
33353 }
33354 cli_printf(p->out, "%12.12s: ", "nullvalue");
33355 output_c_string(p->out, p->mode.spec.zNull);
33356 cli_puts("\n", p->out);
33357 cli_printf(p->out, "%12.12s: %s\n","output",
33358 strlen30(p->outfile) ? p->outfile : "stdout");
33359 cli_printf(p->out, "%12.12s: ", "colseparator");
33360 output_c_string(p->out, p->mode.spec.zColumnSep);
33361 cli_puts("\n", p->out);
33362 cli_printf(p->out, "%12.12s: ", "rowseparator");
33363 output_c_string(p->out, p->mode.spec.zRowSep);
33364 cli_puts("\n", p->out);
33365 switch( p->statsOn ){
33366 case 0: zOut = "off"; break;
33367 default: zOut = "on"; break;
33368 case 2: zOut = "stmt"; break;
33369 case 3: zOut = "vmstep"; break;
33370 }
33371 cli_printf(p->out, "%12.12s: %s\n","stats", zOut);
33372 cli_printf(p->out, "%12.12s: ", "width");
33373 for(i=0; i<p->mode.spec.nWidth; i++){
33374 cli_printf(p->out, "%d ", (int)p->mode.spec.aWidth[i]);
33375 }
33376 cli_puts("\n", p->out);
33377 cli_printf(p->out, "%12.12s: %s\n", "filename",
33378 p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
33379 }else
33380
33381 if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){
33382 if( nArg==2 ){
@@ -31542,20 +33484,20 @@
33484 int nPrintCol, nPrintRow;
33485 for(i=0; i<nRow; i++){
33486 len = strlen30(azResult[i]);
33487 if( len>maxlen ) maxlen = len;
33488 }
33489 nPrintCol = shellScreenWidth()/(maxlen+2);
33490 if( nPrintCol<1 ) nPrintCol = 1;
33491 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
33492 for(i=0; i<nPrintRow; i++){
33493 for(j=i; j<nRow; j+=nPrintRow){
33494 char *zSp = j<nPrintRow ? "" : " ";
33495 cli_printf(p->out,
33496 "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
33497 }
33498 cli_puts("\n", p->out);
33499 }
33500 }
33501
33502 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
33503 sqlite3_free(azResult);
@@ -31563,11 +33505,11 @@
33505
33506 #ifndef SQLITE_SHELL_FIDDLE
33507 /* Begin redirecting output to the file "testcase-out.txt" */
33508 if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){
33509 output_reset(p);
33510 p->out = output_file_open(p, "testcase-out.txt");
33511 if( p->out==0 ){
33512 eputz("Error: cannot open 'testcase-out.txt'\n");
33513 }
33514 if( nArg>=2 ){
33515 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
@@ -31626,14 +33568,14 @@
33568 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
33569 }
33570
33571 /* --help lists all test-controls */
33572 if( cli_strcmp(zCmd,"help")==0 ){
33573 cli_puts("Available test-controls:\n", p->out);
33574 for(i=0; i<ArraySize(aCtrl); i++){
33575 if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue;
33576 cli_printf(p->out, " .testctrl %s %s\n",
33577 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
33578 }
33579 rc = 1;
33580 goto meta_command_exit;
33581 }
@@ -31646,19 +33588,19 @@
33588 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
33589 if( testctrl<0 ){
33590 testctrl = aCtrl[i].ctrlCode;
33591 iCtrl = i;
33592 }else{
33593 cli_printf(stderr,"Error: ambiguous test-control: \"%s\"\n"
33594 "Use \".testctrl --help\" for help\n", zCmd);
33595 rc = 1;
33596 goto meta_command_exit;
33597 }
33598 }
33599 }
33600 if( testctrl<0 ){
33601 cli_printf(stderr,"Error: unknown test-control: %s\n"
33602 "Use \".testctrl --help\" for help\n", zCmd);
33603 }else{
33604 switch(testctrl){
33605
33606 /* Special processing for .testctrl opt MASK ...
@@ -31734,17 +33676,17 @@
33676 int jj;
33677 for(jj=0; jj<ArraySize(aLabel); jj++){
33678 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
33679 }
33680 if( jj>=ArraySize(aLabel) ){
33681 cli_printf(stderr,
33682 "Error: no such optimization: \"%s\"\n", zLabel);
33683 cli_puts("Should be one of:", stderr);
33684 for(jj=0; jj<ArraySize(aLabel); jj++){
33685 cli_printf(stderr," %s", aLabel[jj].zLabel);
33686 }
33687 cli_puts("\n", stderr);
33688 rc = 1;
33689 goto meta_command_exit;
33690 }
33691 if( useLabel=='+' ){
33692 newOpt &= ~aLabel[jj].mask;
@@ -31758,27 +33700,27 @@
33700 }
33701 for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){
33702 if( m & newOpt ) nOff++;
33703 }
33704 if( nOff<12 ){
33705 cli_puts("+All", p->out);
33706 for(ii=0; ii<ArraySize(aLabel); ii++){
33707 if( !aLabel[ii].bDsply ) continue;
33708 if( (newOpt & aLabel[ii].mask)!=0 ){
33709 cli_printf(p->out, " -%s", aLabel[ii].zLabel);
33710 }
33711 }
33712 }else{
33713 cli_puts("-All", p->out);
33714 for(ii=0; ii<ArraySize(aLabel); ii++){
33715 if( !aLabel[ii].bDsply ) continue;
33716 if( (newOpt & aLabel[ii].mask)==0 ){
33717 cli_printf(p->out, " +%s", aLabel[ii].zLabel);
33718 }
33719 }
33720 }
33721 cli_puts("\n", p->out);
33722 rc2 = isOk = 3;
33723 break;
33724 }
33725
33726 /* sqlite3_test_control(int, db, int) */
@@ -31814,11 +33756,11 @@
33756 if( nArg==3 || nArg==4 ){
33757 int ii = (int)integerValue(azArg[2]);
33758 sqlite3 *db;
33759 if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){
33760 sqlite3_randomness(sizeof(ii),&ii);
33761 cli_printf(stdout, "-- random seed: %d\n", ii);
33762 }
33763 if( nArg==3 ){
33764 db = 0;
33765 }else{
33766 db = p->db;
@@ -31867,11 +33809,11 @@
33809 break;
33810
33811 case SQLITE_TESTCTRL_SEEK_COUNT: {
33812 u64 x = 0;
33813 rc2 = sqlite3_test_control(testctrl, p->db, &x);
33814 cli_printf(p->out, "%llu\n", x);
33815 isOk = 3;
33816 break;
33817 }
33818
33819 #ifdef YYCOVERAGE
@@ -31898,15 +33840,15 @@
33840 int id = 1;
33841 while(1){
33842 int val = 0;
33843 rc2 = sqlite3_test_control(testctrl, -id, &val);
33844 if( rc2!=SQLITE_OK ) break;
33845 if( id>1 ) cli_puts(" ", p->out);
33846 cli_printf(p->out, "%d: %d", id, val);
33847 id++;
33848 }
33849 if( id>1 ) cli_puts("\n", p->out);
33850 isOk = 3;
33851 }
33852 break;
33853 }
33854 #endif
@@ -31941,11 +33883,11 @@
33883 const char *zTestArg;
33884 int nOp;
33885 int ii, jj, x;
33886 int *aOp;
33887 if( nArg!=4 ){
33888 cli_printf(stderr,
33889 "ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n"
33890 );
33891 rc = 1;
33892 goto meta_command_exit;
33893 }
@@ -31964,11 +33906,11 @@
33906 x = 0;
33907 }
33908 }
33909 aOp[jj] = x;
33910 x = sqlite3_test_control(testctrl, iSize, aOp);
33911 cli_printf(p->out, "result: %d\n", x);
33912 free(aOp);
33913 break;
33914 }
33915 case SQLITE_TESTCTRL_FAULT_INSTALL: {
33916 int kk;
@@ -31987,25 +33929,25 @@
33929 }else if( cli_strcmp(z,"reset")==0 ){
33930 faultsim_state.iCnt = faultsim_state.nSkip;
33931 faultsim_state.nHit = 0;
33932 sqlite3_test_control(testctrl, faultsim_callback);
33933 }else if( cli_strcmp(z,"status")==0 ){
33934 cli_printf(p->out, "faultsim.iId: %d\n",
33935 faultsim_state.iId);
33936 cli_printf(p->out, "faultsim.iErr: %d\n",
33937 faultsim_state.iErr);
33938 cli_printf(p->out, "faultsim.iCnt: %d\n",
33939 faultsim_state.iCnt);
33940 cli_printf(p->out, "faultsim.nHit: %d\n",
33941 faultsim_state.nHit);
33942 cli_printf(p->out, "faultsim.iInterval: %d\n",
33943 faultsim_state.iInterval);
33944 cli_printf(p->out, "faultsim.eVerbose: %d\n",
33945 faultsim_state.eVerbose);
33946 cli_printf(p->out, "faultsim.nRepeat: %d\n",
33947 faultsim_state.nRepeat);
33948 cli_printf(p->out, "faultsim.nSkip: %d\n",
33949 faultsim_state.nSkip);
33950 }else if( cli_strcmp(z,"-v")==0 ){
33951 if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++;
33952 }else if( cli_strcmp(z,"-q")==0 ){
33953 if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--;
@@ -32020,20 +33962,20 @@
33962 }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){
33963 faultsim_state.nSkip = atoi(azArg[++kk]);
33964 }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){
33965 bShowHelp = 1;
33966 }else{
33967 cli_printf(stderr,
33968 "Unrecognized fault_install argument: \"%s\"\n",
33969 azArg[kk]);
33970 rc = 1;
33971 bShowHelp = 1;
33972 break;
33973 }
33974 }
33975 if( bShowHelp ){
33976 cli_puts(
33977 "Usage: .testctrl fault_install ARGS\n"
33978 "Possible arguments:\n"
33979 " off Disable faultsim\n"
33980 " on Activate faultsim\n"
33981 " reset Reset the trigger counter\n"
@@ -32051,17 +33993,17 @@
33993 break;
33994 }
33995 }
33996 }
33997 if( isOk==0 && iCtrl>=0 ){
33998 cli_printf(p->out,
33999 "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
34000 rc = 1;
34001 }else if( isOk==1 ){
34002 cli_printf(p->out, "%d\n", rc2);
34003 }else if( isOk==2 ){
34004 cli_printf(p->out, "0x%08x\n", rc2);
34005 }
34006 }else
34007 #endif /* !defined(SQLITE_UNTESTABLE) */
34008
34009 if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){
@@ -32112,17 +34054,17 @@
34054 }
34055 else if( optionMatch(z, "close") ){
34056 mType |= SQLITE_TRACE_CLOSE;
34057 }
34058 else {
34059 cli_printf(stderr,"Unknown option \"%s\" on \".trace\"\n", z);
34060 rc = 1;
34061 goto meta_command_exit;
34062 }
34063 }else{
34064 output_file_close(p->traceOut);
34065 p->traceOut = output_file_open(p, z);
34066 }
34067 }
34068 if( p->traceOut==0 ){
34069 sqlite3_trace_v2(p->db, 0, 0, 0);
34070 }else{
@@ -32157,38 +34099,38 @@
34099 }else
34100 #endif
34101
34102 if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
34103 char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
34104 cli_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
34105 sqlite3_libversion(), sqlite3_sourceid());
34106 #if SQLITE_HAVE_ZLIB
34107 cli_printf(p->out, "zlib version %s\n", zlibVersion());
34108 #endif
34109 #define CTIMEOPT_VAL_(opt) #opt
34110 #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
34111 #if defined(__clang__) && defined(__clang_major__)
34112 cli_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
34113 CTIMEOPT_VAL(__clang_minor__) "."
34114 CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz);
34115 #elif defined(_MSC_VER)
34116 cli_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
34117 #elif defined(__GNUC__) && defined(__VERSION__)
34118 cli_printf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz);
34119 #endif
34120 }else
34121
34122 if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){
34123 const char *zDbName = nArg==2 ? azArg[1] : "main";
34124 sqlite3_vfs *pVfs = 0;
34125 if( p->db ){
34126 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
34127 if( pVfs ){
34128 cli_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
34129 cli_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
34130 cli_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
34131 cli_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
34132 }
34133 }
34134 }else
34135
34136 if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){
@@ -32196,17 +34138,17 @@
34138 sqlite3_vfs *pCurrent = 0;
34139 if( p->db ){
34140 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
34141 }
34142 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
34143 cli_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
34144 pVfs==pCurrent ? " <--- CURRENT" : "");
34145 cli_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
34146 cli_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
34147 cli_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
34148 if( pVfs->pNext ){
34149 cli_puts("-----------------------------------\n", p->out);
34150 }
34151 }
34152 }else
34153
34154 if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){
@@ -32213,11 +34155,11 @@
34155 const char *zDbName = nArg==2 ? azArg[1] : "main";
34156 char *zVfsName = 0;
34157 if( p->db ){
34158 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
34159 if( zVfsName ){
34160 cli_printf(p->out, "%s\n", zVfsName);
34161 sqlite3_free(zVfsName);
34162 }
34163 }
34164 }else
34165
@@ -32226,33 +34168,32 @@
34168 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
34169 }else
34170
34171 if( c=='w' && cli_strncmp(azArg[0], "width", n)==0 ){
34172 int j;
34173 p->mode.spec.nWidth = nArg-1;
34174 p->mode.spec.aWidth = realloc(p->mode.spec.aWidth,
34175 (p->mode.spec.nWidth+1)*sizeof(short int));
34176 shell_check_oom(p->mode.spec.aWidth);
 
34177 for(j=1; j<nArg; j++){
34178 i64 w = integerValue(azArg[j]);
34179 if( w < -QRF_MAX_WIDTH ) w = -QRF_MAX_WIDTH;
34180 if( w > QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
34181 p->mode.spec.aWidth[j-1] = (short int)w;
34182 }
34183 }else
34184
34185 {
34186 cli_printf(stderr,"Error: unknown command or invalid arguments: "
34187 " \"%s\". Enter \".help\" for help\n", azArg[0]);
34188 rc = 1;
34189 }
34190
34191 meta_command_exit:
34192 if( p->nPopOutput ){
34193 p->nPopOutput--;
34194 if( p->nPopOutput==0 ) output_reset(p);
34195 }
34196 p->bSafeMode = p->bSafeModePersist;
34197 return rc;
34198 }
34199
@@ -32513,29 +34454,29 @@
34454 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
34455 "%s near line %d:", zErrorType, startline);
34456 }else{
34457 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
34458 }
34459 cli_printf(stderr,"%s %s\n", zPrefix, zErrorTail);
34460 sqlite3_free(zErrMsg);
34461 zErrMsg = 0;
34462 return 1;
34463 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
34464 char zLineBuf[2000];
34465 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
34466 "changes: %lld total_changes: %lld",
34467 sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
34468 cli_printf(p->out, "%s\n", zLineBuf);
34469 }
34470
34471 if( doAutoDetectRestore(p, zSql) ) return 1;
34472 return 0;
34473 }
34474
34475 static void echo_group_input(ShellState *p, const char *zDo){
34476 if( p->mode.mFlags & MFLG_ECHO ){
34477 cli_printf(p->out, "%s\n", zDo);
34478 fflush(p->out);
34479 }
34480 }
34481
34482 #ifdef SQLITE_SHELL_FIDDLE
@@ -32588,26 +34529,31 @@
34529 i64 nAlloc = 0; /* Allocated zSql[] space */
34530 int rc; /* Error code */
34531 int errCnt = 0; /* Number of errors seen */
34532 i64 startline = 0; /* Line number for start of current input */
34533 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
34534 const char *saved_zInFile; /* Prior value of p->zInFile */
34535 i64 saved_lineno; /* Prior value of p->lineno */
34536
34537 if( p->inputNesting==MAX_INPUT_NESTING ){
34538 /* This will be more informative in a later version. */
34539 cli_printf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
34540 " Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
34541 return 1;
34542 }
34543 ++p->inputNesting;
34544 saved_zInFile = p->zInFile;
34545 p->zInFile = zSrc;
34546 saved_lineno = p->lineno;
34547 p->lineno = 0;
34548 CONTINUE_PROMPT_RESET;
34549 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
34550 fflush(p->out);
34551 zLine = one_input_line(p->in, zLine, nSql>0);
34552 if( zLine==0 ){
34553 /* End of input */
34554 if( p->in==0 && stdin_is_interactive ) cli_puts("\n", p->out);
34555 break;
34556 }
34557 if( seenInterrupt ){
34558 if( p->in!=0 ) break;
34559 seenInterrupt = 0;
@@ -32660,25 +34606,29 @@
34606 nSql += nLine;
34607 }
34608 if( nSql>0x7fff0000 ){
34609 char zSize[100];
34610 sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
34611 cli_printf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
34612 zSrc, startline, zSize);
34613 nSql = 0;
34614 errCnt++;
34615 break;
34616 }else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
34617 echo_group_input(p, zSql);
34618 errCnt += runOneSqlLine(p, zSql, p->in, startline);
34619 CONTINUE_PROMPT_RESET;
34620 nSql = 0;
34621 if( p->nPopOutput ){
34622 output_reset(p);
34623 p->nPopOutput = 0;
34624 }else{
34625 clearTempFile(p);
34626 }
34627 if( p->nPopMode ){
34628 modePop(p);
34629 p->nPopMode = 0;
34630 }
34631 p->bSafeMode = p->bSafeModePersist;
34632 qss = QSS_Start;
34633 }else if( nSql && QSS_PLAINWHITE(qss) ){
34634 echo_group_input(p, zSql);
@@ -32693,10 +34643,12 @@
34643 CONTINUE_PROMPT_RESET;
34644 }
34645 free(zSql);
34646 free(zLine);
34647 --p->inputNesting;
34648 p->zInFile = saved_zInFile;
34649 p->lineno = saved_lineno;
34650 return errCnt>0;
34651 }
34652
34653 /*
34654 ** Return a pathname which is the user's home directory. A
@@ -32853,17 +34805,17 @@
34805 shell_check_oom(sqliterc);
34806 }
34807 p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
34808 if( p->in ){
34809 if( stdin_is_interactive ){
34810 cli_printf(stderr,"-- Loading resources from %s\n", sqliterc);
34811 }
34812 if( process_input(p, sqliterc) && bail_on_error ) cli_exit(1);
34813 fclose(p->in);
34814 }else if( sqliterc_override!=0 ){
34815 cli_printf(stderr,"cannot open: \"%s\"\n", sqliterc);
34816 if( bail_on_error ) cli_exit(1);
34817 }
34818 p->in = inSaved;
34819 p->lineno = savedLineno;
34820 if( sqliterc != sqliterc_override ){
34821 sqlite3_free(sqliterc);
@@ -32881,12 +34833,13 @@
34833 " -append append the database to the end of the file\n"
34834 " -ascii set output mode to 'ascii'\n"
34835 " -bail stop after hitting an error\n"
34836 " -batch force batch I/O\n"
34837 " -box set output mode to 'box'\n"
 
34838 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
34839 " -column set output mode to 'column'\n"
34840 " -compat YYYYMMDD set default options for date YYYYMMDD\n"
34841 " -csv set output mode to 'csv'\n"
34842 #if !defined(SQLITE_OMIT_DESERIALIZE)
34843 " -deserialize open the database using sqlite3_deserialize()\n"
34844 #endif
34845 " -echo print inputs before execution\n"
@@ -32913,18 +34866,20 @@
34866 #ifdef SQLITE_ENABLE_MULTIPLEX
34867 " -multiplex enable the multiplexor VFS\n"
34868 #endif
34869 " -newline SEP set output row separator. Default: '\\n'\n"
34870 " -nofollow refuse to open symbolic links to database files\n"
34871 " -noinit Do not read the ~/.sqliterc file at startup\n"
34872 " -nonce STRING set the safe-mode escape nonce\n"
34873 " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
34874 " -nullvalue TEXT set text string for NULL values. Default ''\n"
34875 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
34876 " -pcachetrace trace all page cache operations\n"
34877 " -quote set output mode to 'quote'\n"
34878 " -readonly open the database read-only\n"
34879 " -safe enable safe-mode\n"
34880 " -screenwidth N use N as the default screenwidth \n"
34881 " -separator SEP set output column separator. Default: '|'\n"
34882 #ifdef SQLITE_ENABLE_SORTER_REFERENCES
34883 " -sorterref SIZE sorter references threshold size\n"
34884 #endif
34885 " -stats print memory stats before each finalize\n"
@@ -32937,15 +34892,15 @@
34892 #ifdef SQLITE_HAVE_ZLIB
34893 " -zip open the file as a ZIP Archive\n"
34894 #endif
34895 ;
34896 static void usage(int showDetail){
34897 cli_printf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL...]]\n"
34898 "FILENAME is the name of an SQLite database. A new database is created\n"
34899 "if the file does not previously exist. Defaults to :memory:.\n", Argv0);
34900 if( showDetail ){
34901 cli_printf(stderr,"OPTIONS include:\n%s", zOptions);
34902 }else{
34903 eputz("Use the -help option for additional information\n");
34904 }
34905 exit(0);
34906 }
@@ -32962,23 +34917,20 @@
34917 }
34918
34919 /*
34920 ** Initialize the state information in data
34921 */
34922 static void main_init(ShellState *p) {
34923 memset(p, 0, sizeof(*p));
34924 #if defined(COMPATIBILITY_DATE)
34925 p->iCompat = COMPATIBILITY_DATE;
34926 #else
34927 p->iCompat = 20251116;
34928 #endif
34929 p->pAuxDb = &p->aAuxDb[0];
34930 p->shellFlgs = SHFLG_Lookaside;
34931 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, p);
 
 
 
34932 #if !defined(SQLITE_SHELL_FIDDLE)
34933 verify_uninitialized();
34934 #endif
34935 sqlite3_config(SQLITE_CONFIG_URI, 1);
34936 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
@@ -33004,23 +34956,23 @@
34956 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
34957 #endif
34958 }
34959 #else
34960 static void printBold(const char *zText){
34961 cli_printf(stdout, "\033[1m%s\033[0m", zText);
34962 }
34963 #endif
34964
34965 /*
34966 ** Get the argument to an --option. Throw an error and die if no argument
34967 ** is available.
34968 */
34969 static char *cmdline_option_value(int argc, char **argv, int i){
34970 if( i==argc ){
34971 cli_printf(stderr,
34972 "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
34973 cli_exit(1);
34974 }
34975 return argv[i];
34976 }
34977
34978 static void sayAbnormalExit(void){
@@ -33029,11 +34981,11 @@
34981
34982 /* Routine to output from vfstrace
34983 */
34984 static int vfstraceOut(const char *z, void *pArg){
34985 ShellState *p = (ShellState*)pArg;
34986 cli_puts(z, p->out);
34987 fflush(p->out);
34988 return 1;
34989 }
34990
34991 #ifndef SQLITE_SHELL_IS_UTF8
@@ -33067,14 +35019,16 @@
35019 const char *zInitFile = 0;
35020 int i;
35021 int rc = 0;
35022 int warnInmemoryDb = 0;
35023 int readStdin = 1;
35024 int noInit = 0; /* Do not read ~/.sqliterc if true */
35025 int nCmd = 0;
35026 int nOptsEnd = argc;
35027 int bEnableVfstrace = 0;
35028 char **azCmd = 0;
35029 int *aiCmd = 0;
35030 const char *zVfs = 0; /* Value of -vfs command-line option */
35031 #if !SQLITE_SHELL_IS_UTF8
35032 char **argvToFree = 0;
35033 int argcToFree = 0;
35034 #endif
@@ -33094,11 +35048,11 @@
35048 #endif
35049 #if !defined(_WIN32_WCE)
35050 if( getenv("SQLITE_DEBUG_BREAK") ){
35051 if( isatty(0) && isatty(2) ){
35052 char zLine[100];
35053 cli_printf(stderr,
35054 "attach debugger to process %d and press ENTER to continue...",
35055 GETPID());
35056 if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0
35057 && cli_strcmp(zLine,"stop")==0
35058 ){
@@ -33126,11 +35080,11 @@
35080 }
35081 #endif
35082
35083 #if USE_SYSTEM_SQLITE+0!=1
35084 if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
35085 cli_printf(stderr,
35086 "SQLite header and source version mismatch\n%s\n%s\n",
35087 sqlite3_sourceid(), SQLITE_SOURCE_ID);
35088 exit(1);
35089 }
35090 #endif
@@ -33193,14 +35147,18 @@
35147 data.aAuxDb->zDbFilename = z;
35148 }else{
35149 /* Excess arguments are interpreted as SQL (or dot-commands) and
35150 ** mean that nothing is read from stdin */
35151 readStdin = 0;
35152 stdin_is_interactive = 0;
35153 nCmd++;
35154 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
35155 shell_check_oom(azCmd);
35156 aiCmd = realloc(aiCmd, sizeof(aiCmd[0])*nCmd);
35157 shell_check_oom(azCmd);
35158 azCmd[nCmd-1] = z;
35159 aiCmd[nCmd-1] = i;
35160 }
35161 continue;
35162 }
35163 if( z[1]=='-' ) z++;
35164 if( cli_strcmp(z, "-")==0 ){
@@ -33219,10 +35177,24 @@
35177 /* Need to check for batch mode here to so we can avoid printing
35178 ** informational messages (like from process_sqliterc) before
35179 ** we do the actual processing of arguments later in a second pass.
35180 */
35181 stdin_is_interactive = 0;
35182 stdout_is_console = 0;
35183 modeChange(&data, MODE_BATCH);
35184 }else if( cli_strcmp(z,"-screenwidth")==0 ){
35185 int n = atoi(cmdline_option_value(argc, argv, ++i));
35186 if( n<2 ){
35187 sqlite3_fprintf(stderr,"minimum --screenwidth is 2\n");
35188 exit(1);
35189 }
35190 stdout_tty_width = n;
35191 }else if( cli_strcmp(z,"-compat")==0 ){
35192 data.iCompat = atoi(cmdline_option_value(argc, argv, ++i));
35193 modeFree(&data.mode);
35194 memset(&data.mode, 0, sizeof(data.mode));
35195 modeDefault(&data);
35196 }else if( cli_strcmp(z,"-utf8")==0 ){
35197 }else if( cli_strcmp(z,"-no-utf8")==0 ){
35198 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
35199 int val = 0;
35200 sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val);
@@ -33252,11 +35224,11 @@
35224 if( sz>0 && (sz & (sz-1))==0 ){
35225 /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */
35226 int szHdr = 0;
35227 sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr);
35228 sz += szHdr;
35229 cli_printf(stdout, "Page cache size increased to %d to accommodate"
35230 " the %d-byte headers\n", (int)sz, szHdr);
35231 }
35232 verify_uninitialized();
35233 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
35234 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
@@ -33313,10 +35285,12 @@
35285 }else if( cli_strcmp(z,"-readonly")==0 ){
35286 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
35287 data.openFlags |= SQLITE_OPEN_READONLY;
35288 }else if( cli_strcmp(z,"-nofollow")==0 ){
35289 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
35290 }else if( cli_strcmp(z,"-noinit")==0 ){
35291 noInit = 1;
35292 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
35293 data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
35294 }else if( cli_strcmp(z,"-ifexists")==0 ){
35295 data.openFlags &= ~(SQLITE_OPEN_CREATE);
35296 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
@@ -33367,21 +35341,21 @@
35341 if( zVfs ){
35342 sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
35343 if( pVfs ){
35344 sqlite3_vfs_register(pVfs, 1);
35345 }else{
35346 cli_printf(stderr,"no such VFS: \"%s\"\n", zVfs);
35347 exit(1);
35348 }
35349 }
35350
35351 if( data.pAuxDb->zDbFilename==0 ){
35352 #ifndef SQLITE_OMIT_MEMORYDB
35353 data.pAuxDb->zDbFilename = ":memory:";
35354 warnInmemoryDb = argc==1;
35355 #else
35356 cli_printf(stderr,
35357 "%s: Error: no database filename specified\n", Argv0);
35358 return 1;
35359 #endif
35360 }
35361 data.out = stdout;
@@ -33389,10 +35363,11 @@
35363 vfstrace_register("trace",0,vfstraceOut, &data, 1);
35364 }
35365 #ifndef SQLITE_SHELL_FIDDLE
35366 sqlite3_appendvfs_init(0,0,0);
35367 #endif
35368 modeDefault(&data);
35369
35370 /* Go ahead and open the database file if it already exists. If the
35371 ** file does not exist, delay opening it. This prevents empty database
35372 ** files from being created if a user mistypes the database name argument
35373 ** to the sqlite command-line tool.
@@ -33403,11 +35378,11 @@
35378
35379 /* Process the initialization file if there is one. If no -init option
35380 ** is given on the command line, look for a file named ~/.sqliterc and
35381 ** try to process it.
35382 */
35383 if( !noInit ) process_sqliterc(&data,zInitFile);
35384
35385 /* Make a second pass through the command-line argument and set
35386 ** options. This second pass is delayed until after the initialization
35387 ** file is processed so that the command-line arguments will override
35388 ** settings in the initialization file.
@@ -33417,49 +35392,46 @@
35392 if( z[0]!='-' || i>=nOptsEnd ) continue;
35393 if( z[1]=='-' ){ z++; }
35394 if( cli_strcmp(z,"-init")==0 ){
35395 i++;
35396 }else if( cli_strcmp(z,"-html")==0 ){
35397 modeChange(&data, MODE_Html);
35398 }else if( cli_strcmp(z,"-list")==0 ){
35399 modeChange(&data, MODE_List);
35400 }else if( cli_strcmp(z,"-quote")==0 ){
35401 modeChange(&data, MODE_Quote);
 
 
35402 }else if( cli_strcmp(z,"-line")==0 ){
35403 modeChange(&data, MODE_Line);
35404 }else if( cli_strcmp(z,"-column")==0 ){
35405 modeChange(&data, MODE_Column);
35406 }else if( cli_strcmp(z,"-json")==0 ){
35407 modeChange(&data, MODE_Json);
35408 }else if( cli_strcmp(z,"-markdown")==0 ){
35409 modeChange(&data, MODE_Markdown);
35410 }else if( cli_strcmp(z,"-table")==0 ){
35411 modeChange(&data, MODE_Table);
35412 }else if( cli_strcmp(z,"-box")==0 ){
35413 modeChange(&data, MODE_Box);
35414 }else if( cli_strcmp(z,"-csv")==0 ){
35415 modeChange(&data, MODE_Csv);
 
35416 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){
35417 /* See similar code at tag-20250224-1 */
35418 const char *zEsc = argv[++i];
35419 int k;
35420 for(k=0; k<ArraySize(qrfEscNames); k++){
35421 if( sqlite3_stricmp(zEsc,qrfEscNames[k])==0 ){
35422 data.mode.spec.eEsc = k;
35423 break;
35424 }
35425 }
35426 if( k>=ArraySize(qrfEscNames) ){
35427 cli_printf(stderr, "unknown control character escape mode \"%s\""
35428 " - choices:", zEsc);
35429 for(k=0; k<ArraySize(qrfEscNames); k++){
35430 cli_printf(stderr, " %s", qrfEscNames[k]);
35431 }
35432 cli_printf(stderr, "\n");
35433 exit(1);
35434 }
35435 #ifdef SQLITE_HAVE_ZLIB
35436 }else if( cli_strcmp(z,"-zip")==0 ){
35437 data.openMode = SHELL_OPEN_ZIPFILE;
@@ -33475,48 +35447,44 @@
35447 }else if( cli_strcmp(z,"-readonly")==0 ){
35448 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
35449 data.openFlags |= SQLITE_OPEN_READONLY;
35450 }else if( cli_strcmp(z,"-nofollow")==0 ){
35451 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
35452 }else if( cli_strcmp(z,"-noinit")==0 ){
35453 /* No-op */
35454 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */
35455 data.openFlags |= SQLITE_OPEN_EXCLUSIVE;
35456 }else if( cli_strcmp(z,"-ifexists")==0 ){
35457 data.openFlags &= ~(SQLITE_OPEN_CREATE);
35458 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE;
35459 }else if( cli_strcmp(z,"-ascii")==0 ){
35460 modeChange(&data, MODE_Ascii);
 
 
35461 }else if( cli_strcmp(z,"-tabs")==0 ){
35462 modeChange(&data, MODE_Tabs);
 
 
35463 }else if( cli_strcmp(z,"-separator")==0 ){
35464 modeSetStr(&data.mode.spec.zColumnSep,
35465 cmdline_option_value(argc,argv,++i));
35466 }else if( cli_strcmp(z,"-newline")==0 ){
35467 modeSetStr(&data.mode.spec.zRowSep,
35468 cmdline_option_value(argc,argv,++i));
35469 }else if( cli_strcmp(z,"-nullvalue")==0 ){
35470 modeSetStr(&data.mode.spec.zNull,
35471 cmdline_option_value(argc,argv,++i));
35472 }else if( cli_strcmp(z,"-header")==0 ){
35473 data.mode.spec.bTitles = QRF_Yes;
 
35474 }else if( cli_strcmp(z,"-noheader")==0 ){
35475 data.mode.spec.bTitles = QRF_No;
 
35476 }else if( cli_strcmp(z,"-echo")==0 ){
35477 data.mode.mFlags |= MFLG_ECHO;
35478 }else if( cli_strcmp(z,"-eqp")==0 ){
35479 data.mode.autoEQP = AUTOEQP_on;
35480 }else if( cli_strcmp(z,"-eqpfull")==0 ){
35481 data.mode.autoEQP = AUTOEQP_full;
35482 }else if( cli_strcmp(z,"-stats")==0 ){
35483 data.statsOn = 1;
35484 }else if( cli_strcmp(z,"-scanstats")==0 ){
35485 data.mode.scanstatsOn = 1;
35486 }else if( cli_strcmp(z,"-backslash")==0 ){
35487 /* Undocumented command-line option: -backslash
35488 ** Causes C-style backslash escapes to be evaluated in SQL statements
35489 ** prior to sending the SQL into SQLite. Useful for injecting
35490 ** crazy bytes in the middle of SQL statements for testing and debugging.
@@ -33523,20 +35491,24 @@
35491 */
35492 ShellSetFlag(&data, SHFLG_Backslash);
35493 }else if( cli_strcmp(z,"-bail")==0 ){
35494 /* No-op. The bail_on_error flag should already be set. */
35495 }else if( cli_strcmp(z,"-version")==0 ){
35496 cli_printf(stdout, "%s %s (%d-bit)\n",
35497 sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
35498 return 0;
35499 }else if( cli_strcmp(z,"-interactive")==0 ){
35500 /* Need to check for interactive override here to so that it can
35501 ** affect console setup (for Windows only) and testing thereof.
35502 */
35503 stdin_is_interactive = 1;
35504 }else if( cli_strcmp(z,"-batch")==0 ){
35505 /* already handled */
35506 }else if( cli_strcmp(z,"-screenwidth")==0 ){
35507 i++;
35508 }else if( cli_strcmp(z,"-compat")==0 ){
35509 i++;
35510 }else if( cli_strcmp(z,"-utf8")==0 ){
35511 /* already handled */
35512 }else if( cli_strcmp(z,"-no-utf8")==0 ){
35513 /* already handled */
35514 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
@@ -33584,20 +35556,21 @@
35556 }else{
35557 open_db(&data, 0);
35558 rc = shell_exec(&data, z, &zErrMsg);
35559 if( zErrMsg!=0 ){
35560 shellEmitError(zErrMsg);
35561 sqlite3_free(zErrMsg);
35562 if( bail_on_error ) return rc!=0 ? rc : 1;
35563 }else if( rc!=0 ){
35564 cli_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
35565 if( bail_on_error ) return rc;
35566 }
35567 }
35568 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
35569 }else if( cli_strncmp(z, "-A", 2)==0 ){
35570 if( nCmd>0 ){
35571 cli_printf(stderr,"Error: cannot mix regular SQL or dot-commands"
35572 " with \"%s\"\n", z);
35573 return 1;
35574 }
35575 open_db(&data, OPEN_DB_ZIPFILE);
35576 if( z[2] ){
@@ -33605,22 +35578,22 @@
35578 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
35579 }else{
35580 arDotCommand(&data, 1, argv+i, argc-i);
35581 }
35582 readStdin = 0;
35583 stdin_is_interactive = 0;
35584 break;
35585 #endif
35586 }else if( cli_strcmp(z,"-safe")==0 ){
35587 data.bSafeMode = data.bSafeModePersist = 1;
35588 }else if( cli_strcmp(z,"-unsafe-testing")==0 ){
35589 /* Acted upon in first pass. */
35590 }else{
35591 cli_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
35592 eputz("Use -help for a list of options.\n");
35593 return 1;
35594 }
 
35595 }
35596
35597 if( !readStdin ){
35598 /* Run all arguments that do not begin with '-' as if they were separate
35599 ** command-line inputs, except for the argToSkip argument which contains
@@ -33627,11 +35600,18 @@
35600 ** the database filename.
35601 */
35602 for(i=0; i<nCmd; i++){
35603 echo_group_input(&data, azCmd[i]);
35604 if( azCmd[i][0]=='.' ){
35605 char *zErrCtx = malloc( 64 );
35606 shell_check_oom(zErrCtx);
35607 sqlite3_snprintf(64,zErrCtx,"argv[%i]:",aiCmd[i]);
35608 data.zInFile = "<cmdline>";
35609 data.zErrPrefix = zErrCtx;
35610 rc = do_meta_command(azCmd[i], &data);
35611 free(data.zErrPrefix);
35612 data.zErrPrefix = 0;
35613 if( rc ){
35614 if( rc==2 ) rc = 0;
35615 goto shell_main_exit;
35616 }
35617 }else{
@@ -33639,11 +35619,11 @@
35619 rc = shell_exec(&data, azCmd[i], &zErrMsg);
35620 if( zErrMsg || rc ){
35621 if( zErrMsg!=0 ){
35622 shellEmitError(zErrMsg);
35623 }else{
35624 cli_printf(stderr,
35625 "Error: unable to process SQL: %s\n", azCmd[i]);
35626 }
35627 sqlite3_free(zErrMsg);
35628 if( rc==0 ) rc = 1;
35629 goto shell_main_exit;
@@ -33654,11 +35634,11 @@
35634 /* Run commands received from standard input
35635 */
35636 if( stdin_is_interactive ){
35637 char *zHome;
35638 char *zHistory;
35639 cli_printf(stdout,
35640 "SQLite version %s %.19s\n" /*extra-version-info*/
35641 "Enter \".help\" for usage hints.\n",
35642 sqlite3_libversion(), sqlite3_sourceid());
35643 if( warnInmemoryDb ){
35644 sputz(stdout, "Connected to a ");
@@ -33707,10 +35687,11 @@
35687 expertFinish(&data, 1, 0);
35688 }
35689 #endif
35690 shell_main_exit:
35691 free(azCmd);
35692 free(aiCmd);
35693 set_table_name(&data, 0);
35694 if( data.db ){
35695 session_close_all(&data, -1);
35696 close_db(data.db);
35697 }
@@ -33727,21 +35708,41 @@
35708 clearTempFile(&data);
35709 #if !SQLITE_SHELL_IS_UTF8
35710 for(i=0; i<argcToFree; i++) free(argvToFree[i]);
35711 free(argvToFree);
35712 #endif
35713 modeFree(&data.mode);
35714 if( data.nSavedModes ){
35715 int ii;
35716 for(ii=0; ii<data.nSavedModes; ii++){
35717 modeFree(&data.aSavedModes[ii].mode);
35718 free(data.aSavedModes[ii].zTag);
35719 }
35720 free(data.aSavedModes);
35721 }
35722 free(data.zErrPrefix);
35723 free(data.zNonce);
35724 free(data.dot.zCopy);
35725 free(data.dot.azArg);
35726 free(data.dot.aiOfst);
35727 free(data.dot.abQuot);
35728 if( data.nTestRun ){
35729 sqlite3_fprintf(stdout, "%d test%s run with %d error%s\n",
35730 data.nTestRun, data.nTestRun==1 ? "" : "s",
35731 data.nTestErr, data.nTestErr==1 ? "" : "s");
35732 fflush(stdout);
35733 rc = data.nTestErr>0;
35734 }
35735 /* Clear the global data structure so that valgrind will detect memory
35736 ** leaks */
35737 memset(&data, 0, sizeof(data));
35738 if( bEnableVfstrace ){
35739 vfstrace_unregister("trace");
35740 }
35741 #ifdef SQLITE_DEBUG
35742 if( sqlite3_memory_used()>mem_main_enter ){
35743 cli_printf(stderr,"Memory leaked: %u bytes\n",
35744 (unsigned int)(sqlite3_memory_used()-mem_main_enter));
35745 }
35746 #endif
35747 #else /* SQLITE_SHELL_FIDDLE... */
35748 shell_main_exit:
@@ -33777,11 +35778,11 @@
35778 return pVfs;
35779 }
35780
35781 /* Only for emcc experimentation purposes. */
35782 sqlite3 * fiddle_db_arg(sqlite3 *arg){
35783 cli_printf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg);
35784 return arg;
35785 }
35786
35787 /*
35788 ** Intended to be called via a SharedWorker() while a separate
@@ -33814,11 +35815,11 @@
35815 while( sqlite3_txn_state(globalDb,0)>0 ){
35816 /*
35817 ** Resolve problem reported in
35818 ** https://sqlite.org/forum/forumpost/0b41a25d65
35819 */
35820 cli_puts("Rolling back in-progress transaction.\n", stdout);
35821 sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0);
35822 }
35823 rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
35824 if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0);
35825 sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
@@ -33881,5 +35882,6 @@
35882 process_input(&shellState, "<stdin>");
35883 shellState.wasm.zInput = shellState.wasm.zPos = 0;
35884 }
35885 }
35886 #endif /* SQLITE_SHELL_FIDDLE */
35887 /************************* End src/shell.c.in ******************/
35888
+244 -67
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.51.0. By combining all the individual C code files into this
3
+** version 3.52.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -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
-** 38c993c8b7137d6d5623d387292639634297 with changes in files:
21
+** 7e460ffa5aae884807db9e7c8214d6d822d5 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -465,16 +465,16 @@
465465
**
466466
** See also: [sqlite3_libversion()],
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470
-#define SQLITE_VERSION "3.51.0"
471
-#define SQLITE_VERSION_NUMBER 3051000
472
-#define SQLITE_SOURCE_ID "2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8"
470
+#define SQLITE_VERSION "3.52.0"
471
+#define SQLITE_VERSION_NUMBER 3052000
472
+#define SQLITE_SOURCE_ID "2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2025-10-31T16:07:31.438Z"
475
+#define SQLITE_SCM_DATETIME "2025-11-18T17:49:48.189Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -2886,16 +2886,19 @@
28862886
** </dd>
28872887
**
28882888
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
28892889
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
28902890
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2891
-** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
2892
-** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
2893
-** statistics. For statistics to be collected, the flag must be set on
2894
-** the database handle both when the SQL statement is prepared and when it
2895
-** is stepped. The flag is set (collection of statistics is enabled)
2896
-** by default. <p>This option takes two arguments: an integer and a pointer to
2891
+** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
2892
+** a flag that enables collection of run-time performance statistics
2893
+** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
2894
+** columns of the [bytecode virtual table].
2895
+** For statistics to be collected, the flag must be set on
2896
+** the database handle both when the SQL statement is
2897
+** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
2898
+** The flag is set (collection of statistics is enabled) by default.
2899
+** <p>This option takes two arguments: an integer and a pointer to
28972900
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
28982901
** leave unchanged the statement scanstatus option. If the second argument
28992902
** is not NULL, then the value of the statement scanstatus setting after
29002903
** processing the first argument is written into the integer that the second
29012904
** argument points to.
@@ -4536,11 +4539,11 @@
45364539
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
45374540
SQLITE_API const char *sqlite3_errstr(int);
45384541
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
45394542
45404543
/*
4541
-** CAPI3REF: Set Error Codes And Message
4544
+** CAPI3REF: Set Error Code And Message
45424545
** METHOD: sqlite3
45434546
**
45444547
** Set the error code of the database handle passed as the first argument
45454548
** to errcode, and the error message to a copy of nul-terminated string
45464549
** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4654,10 +4657,14 @@
46544657
** result set of a [SELECT] or the maximum number of columns in an index
46554658
** or in an ORDER BY or GROUP BY clause.</dd>)^
46564659
**
46574660
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
46584661
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
4662
+**
4663
+** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
4664
+** <dd>The maximum depth of the LALR(1) parser stack used to analyze
4665
+** input SQL statements.</dd>)^
46594666
**
46604667
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
46614668
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
46624669
**
46634670
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4699,10 +4706,11 @@
46994706
#define SQLITE_LIMIT_ATTACHED 7
47004707
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
47014708
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
47024709
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
47034710
#define SQLITE_LIMIT_WORKER_THREADS 11
4711
+#define SQLITE_LIMIT_PARSER_DEPTH 12
47044712
47054713
/*
47064714
** CAPI3REF: Prepare Flags
47074715
**
47084716
** These constants define various flags that can be passed into the
@@ -9043,19 +9051,24 @@
90439051
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
90449052
** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
90459053
** errors were encountered during construction of the string. ^The
90469054
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
90479055
** string in [sqlite3_str] object X is zero bytes long.
9056
+**
9057
+** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
9058
+** X and the string content it contains. Calling sqlite3_str_free(X) is
9059
+** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
90489060
*/
90499061
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
9062
+SQLITE_API void sqlite3_str_free(sqlite3_str*);
90509063
90519064
/*
90529065
** CAPI3REF: Add Content To A Dynamic String
90539066
** METHOD: sqlite3_str
90549067
**
9055
-** These interfaces add content to an sqlite3_str object previously obtained
9056
-** from [sqlite3_str_new()].
9068
+** These interfaces add or remove content to an sqlite3_str object
9069
+** previously obtained from [sqlite3_str_new()].
90579070
**
90589071
** ^The [sqlite3_str_appendf(X,F,...)] and
90599072
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
90609073
** functionality of SQLite to append formatted text onto the end of
90619074
** [sqlite3_str] object X.
@@ -9073,10 +9086,14 @@
90739086
** single-byte character C onto the end of [sqlite3_str] object X.
90749087
** ^This method can be used, for example, to add whitespace indentation.
90759088
**
90769089
** ^The [sqlite3_str_reset(X)] method resets the string under construction
90779090
** inside [sqlite3_str] object X back to zero bytes in length.
9091
+**
9092
+** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
9093
+** under construction to be N bytes are less. This routine is a no-op if
9094
+** N is negative or if the string is already N bytes or smaller in size.
90789095
**
90799096
** These methods do not return a result code. ^If an error occurs, that fact
90809097
** is recorded in the [sqlite3_str] object and can be recovered by a
90819098
** subsequent call to [sqlite3_str_errcode(X)].
90829099
*/
@@ -9084,10 +9101,11 @@
90849101
SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
90859102
SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
90869103
SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
90879104
SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
90889105
SQLITE_API void sqlite3_str_reset(sqlite3_str*);
9106
+SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
90899107
90909108
/*
90919109
** CAPI3REF: Status Of A Dynamic String
90929110
** METHOD: sqlite3_str
90939111
**
@@ -10745,11 +10763,11 @@
1074510763
** &nbsp; rc==SQLITE_OK && pVal;
1074610764
** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
1074710765
** &nbsp; ){
1074810766
** &nbsp; // do something with pVal
1074910767
** &nbsp; }
10750
-** &nbsp; if( rc!=SQLITE_OK ){
10768
+** &nbsp; if( rc!=SQLITE_DONE ){
1075110769
** &nbsp; // an error has occurred
1075210770
** &nbsp; }
1075310771
** </pre></blockquote>)^
1075410772
**
1075510773
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10917,13 +10935,13 @@
1091710935
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
1091810936
** of this interface is undefined. ^The requested measurement is written into
1091910937
** a variable pointed to by the "pOut" parameter.
1092010938
**
1092110939
** The "flags" parameter must be passed a mask of flags. At present only
10922
-** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
10940
+** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
1092310941
** is specified, then status information is available for all elements
10924
-** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
10942
+** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
1092510943
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
1092610944
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
1092710945
** the EXPLAIN QUERY PLAN output) are available. Invoking API
1092810946
** sqlite3_stmt_scanstatus() is equivalent to calling
1092910947
** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10933,11 +10951,12 @@
1093310951
** retrieve statistics for the entire query. ^If idx is out of range
1093410952
** - less than -1 or greater than or equal to the total number of query
1093510953
** elements used to implement the statement - a non-zero value is returned and
1093610954
** the variable that pOut points to is unchanged.
1093710955
**
10938
-** See also: [sqlite3_stmt_scanstatus_reset()]
10956
+** See also: [sqlite3_stmt_scanstatus_reset()] and the
10957
+** [nexec and ncycle] columnes of the [bytecode virtual table].
1093910958
*/
1094010959
SQLITE_API int sqlite3_stmt_scanstatus(
1094110960
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
1094210961
int idx, /* Index of loop to report on */
1094310962
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -14373,19 +14392,37 @@
1437314392
#ifndef SQLITE_MAX_SQL_LENGTH
1437414393
# define SQLITE_MAX_SQL_LENGTH 1000000000
1437514394
#endif
1437614395
1437714396
/*
14378
-** The maximum depth of an expression tree. This is limited to
14379
-** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
14380
-** want to place more severe limits on the complexity of an
14381
-** expression. A value of 0 means that there is no limit.
14397
+** The maximum depth of an expression tree. The expression tree depth
14398
+** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by
14399
+** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of
14400
+** expressions can help prevent excess memory usage by hostile SQL.
14401
+**
14402
+** A value of 0 for this compile-time option causes all expression
14403
+** depth limiting code to be omitted.
1438214404
*/
1438314405
#ifndef SQLITE_MAX_EXPR_DEPTH
1438414406
# define SQLITE_MAX_EXPR_DEPTH 1000
1438514407
#endif
1438614408
14409
+/*
14410
+** The maximum depth of the LALR(1) stack used in the parser that
14411
+** interprets SQL inputs. The parser stack depth can also be limited
14412
+** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack
14413
+** depth can help prevent excess memory usage and excess CPU stack
14414
+** usage when processing hostile SQL.
14415
+**
14416
+** Prior to version 3.45.0 (2024-01-15), the parser stack was
14417
+** hard-coded to 100 entries, and that worked fine for almost all
14418
+** applications. So the upper bound on this limit need not be large.
14419
+*/
14420
+#ifndef SQLITE_MAX_PARSER_DEPTH
14421
+# define SQLITE_MAX_PARSER_DEPTH 2500
14422
+#endif
14423
+
1438714424
/*
1438814425
** The maximum number of terms in a compound SELECT statement.
1438914426
** The code generator for compound SELECT statements does one
1439014427
** level of recursion for each term. A stack overflow can result
1439114428
** if the number of terms is too large. In practice, most SQL
@@ -18113,11 +18150,11 @@
1811318150
1811418151
/*
1811518152
** The number of different kinds of things that can be limited
1811618153
** using the sqlite3_limit() interface.
1811718154
*/
18118
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
18155
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1)
1811918156
1812018157
/*
1812118158
** Lookaside malloc is a set of fixed-size buffers that can be used
1812218159
** to satisfy small transient memory allocation requests for objects
1812318160
** associated with a particular database connection. The use of
@@ -33169,10 +33206,18 @@
3316933206
3317033207
/* Return the current length of p in bytes */
3317133208
SQLITE_API int sqlite3_str_length(sqlite3_str *p){
3317233209
return p ? p->nChar : 0;
3317333210
}
33211
+
33212
+/* Truncate the text of the string to be no more than N bytes. */
33213
+SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){
33214
+ if( p!=0 && N>=0 && (u32)N<p->nChar ){
33215
+ p->nChar = N;
33216
+ p->zText[p->nChar] = 0;
33217
+ }
33218
+}
3317433219
3317533220
/* Return the current value for p */
3317633221
SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
3317733222
if( p==0 || p->nChar==0 ) return 0;
3317833223
p->zText[p->nChar] = 0;
@@ -33189,10 +33234,21 @@
3318933234
}
3319033235
p->nAlloc = 0;
3319133236
p->nChar = 0;
3319233237
p->zText = 0;
3319333238
}
33239
+
33240
+/*
33241
+** Destroy a dynamically allocate sqlite3_str object and all
33242
+** of its content, all in one call.
33243
+*/
33244
+SQLITE_API void sqlite3_str_free(sqlite3_str *p){
33245
+ if( p ){
33246
+ sqlite3_str_reset(p);
33247
+ sqlite3_free(p);
33248
+ }
33249
+}
3319433250
3319533251
/*
3319633252
** Initialize a string accumulator.
3319733253
**
3319833254
** p: The accumulator to be initialized.
@@ -38001,10 +38057,11 @@
3800138057
rehash(pH, pH->count*3);
3800238058
}
3800338059
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
3800438060
return 0;
3800538061
}
38062
+
3800638063
3800738064
/************** End of hash.c ************************************************/
3800838065
/************** Begin file opcodes.c *****************************************/
3800938066
/* Automatically generated. Do not edit */
3801038067
/* See the tool/mkopcodec.tcl script for details. */
@@ -59732,10 +59789,12 @@
5973259789
if( pPager->pWal ){
5973359790
u32 iRead = 0;
5973459791
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
5973559792
if( iRead ) return 0; /* Case (4) */
5973659793
}
59794
+#else
59795
+ UNUSED_PARAMETER(pgno);
5973759796
#endif
5973859797
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
5973959798
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
5974059799
& SQLITE_IOCAP_SUBPAGE_READ)==0 ){
5974159800
return 0; /* Case (2) */
@@ -63111,10 +63170,12 @@
6311163170
a = pTmp;
6311263171
}
6311363172
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
6311463173
pPager->pWal = 0;
6311563174
}
63175
+#else
63176
+ UNUSED_PARAMETER(db);
6311663177
#endif
6311763178
pager_reset(pPager);
6311863179
if( MEMDB ){
6311963180
pager_unlock(pPager);
6312063181
}else{
@@ -76104,10 +76165,34 @@
7610476165
assert( pBt->inTransaction==TRANS_NONE );
7610576166
rc = sqlite3PagerWalWriteLock(pPager, 1);
7610676167
if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
7610776168
}
7610876169
#endif
76170
+
76171
+#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114
76172
+ /* If both a read and write transaction will be opened by this call,
76173
+ ** then issue a file-control as if the following pragma command had
76174
+ ** been evaluated:
76175
+ **
76176
+ ** PRAGMA experimental_pragma_20251114 = 1|2
76177
+ **
76178
+ ** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag
76179
+ ** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS.
76180
+ **
76181
+ ** WARNING: This code will likely remain part of SQLite only temporarily -
76182
+ ** it exists to allow users to experiment with certain types of blocking
76183
+ ** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */
76184
+ if( pBt->pPage1==0 && wrflag ){
76185
+ sqlite3_file *fd = sqlite3PagerFile(pPager);
76186
+ char *aFcntl[3] = {0,0,0};
76187
+ aFcntl[1] = "experimental_pragma_20251114";
76188
+ assert( wrflag==1 || wrflag==2 );
76189
+ aFcntl[2] = (wrflag==1 ? "1" : "2");
76190
+ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
76191
+ sqlite3_free(aFcntl[0]);
76192
+ }
76193
+#endif
7610976194
7611076195
/* Call lockBtree() until either pBt->pPage1 is populated or
7611176196
** lockBtree() returns something other than SQLITE_OK. lockBtree()
7611276197
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
7611376198
** reading page 1 it discovers that the page-size of the database
@@ -82190,11 +82275,11 @@
8219082275
}
8219182276
}
8219282277
}while( rc==SQLITE_OK && nOut>0 );
8219382278
8219482279
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
82195
- Pgno pgnoNew;
82280
+ Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
8219682281
MemPage *pNew = 0;
8219782282
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
8219882283
put4byte(pPgnoOut, pgnoNew);
8219982284
if( ISAUTOVACUUM(pBt) && pPageOut ){
8220082285
ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
@@ -93132,10 +93217,12 @@
9313293217
if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
9313393218
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
9313493219
}
9313593220
}
9313693221
}
93222
+#else
93223
+ UNUSED_PARAMETER(db);
9313793224
#endif
9313893225
return rc;
9313993226
}
9314093227
9314193228
@@ -95243,45 +95330,43 @@
9524395330
** counters for x86 and x86_64 class CPUs.
9524495331
*/
9524595332
#ifndef SQLITE_HWTIME_H
9524695333
#define SQLITE_HWTIME_H
9524795334
95248
-/*
95249
-** The following routine only works on Pentium-class (or newer) processors.
95250
-** It uses the RDTSC opcode to read the cycle count value out of the
95251
-** processor and returns that value. This can be used for high-res
95252
-** profiling.
95253
-*/
95254
-#if !defined(__STRICT_ANSI__) && \
95255
- (defined(__GNUC__) || defined(_MSC_VER)) && \
95335
+#if defined(_MSC_VER) && defined(_WIN32)
95336
+
95337
+ #include <profileapi.h>
95338
+
95339
+ __inline sqlite3_uint64 sqlite3Hwtime(void){
95340
+ LARGE_INTEGER tm;
95341
+ QueryPerformanceCounter(&tm);
95342
+ return (sqlite3_uint64)tm.QuadPart;
95343
+ }
95344
+
95345
+#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
9525695346
(defined(i386) || defined(__i386__) || defined(_M_IX86))
9525795347
95258
- #if defined(__GNUC__)
95348
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
95349
+ unsigned int lo, hi;
95350
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95351
+ return (sqlite_uint64)hi << 32 | lo;
95352
+ }
95353
+
95354
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
9525995355
9526095356
__inline__ sqlite_uint64 sqlite3Hwtime(void){
9526195357
unsigned int lo, hi;
9526295358
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
9526395359
return (sqlite_uint64)hi << 32 | lo;
9526495360
}
9526595361
95266
- #elif defined(_MSC_VER)
95267
-
95268
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
95269
- __asm {
95270
- rdtsc
95271
- ret ; return value at EDX:EAX
95272
- }
95273
- }
95274
-
95275
- #endif
95276
-
95277
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
95362
+#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
9527895363
9527995364
__inline__ sqlite_uint64 sqlite3Hwtime(void){
95280
- unsigned int lo, hi;
95281
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95282
- return (sqlite_uint64)hi << 32 | lo;
95365
+ sqlite3_uint64 cnt;
95366
+ __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
95367
+ return cnt;
9528395368
}
9528495369
9528595370
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
9528695371
9528795372
__inline__ sqlite_uint64 sqlite3Hwtime(void){
@@ -130653,10 +130738,11 @@
130653130738
sqlite3HashInit(&pSchema->trigHash);
130654130739
sqlite3HashClear(&pSchema->idxHash);
130655130740
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
130656130741
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
130657130742
}
130743
+
130658130744
sqlite3HashClear(&temp2);
130659130745
sqlite3HashInit(&pSchema->tblHash);
130660130746
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
130661130747
Table *pTab = sqliteHashData(pElem);
130662130748
sqlite3DeleteTable(&xdb, pTab);
@@ -140610,11 +140696,13 @@
140610140696
/* Version 3.50.0 and later */
140611140697
int (*setlk_timeout)(sqlite3*,int,int);
140612140698
/* Version 3.51.0 and later */
140613140699
int (*set_errmsg)(sqlite3*,int,const char*);
140614140700
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
140615
-
140701
+ /* Version 3.52.0 and later */
140702
+ void (*str_truncate)(sqlite3_str*,int);
140703
+ void (*str_free)(sqlite3_str*);
140616140704
};
140617140705
140618140706
/*
140619140707
** This is the function signature used for all extension entry points. It
140620140708
** is also defined in the file "loadext.c".
@@ -140949,10 +141037,13 @@
140949141037
/* Version 3.50.0 and later */
140950141038
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
140951141039
/* Version 3.51.0 and later */
140952141040
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
140953141041
#define sqlite3_db_status64 sqlite3_api->db_status64
141042
+/* Version 3.52.0 and later */
141043
+#define sqlite3_str_truncate sqlite3_api->str_truncate
141044
+#define sqlite3_str_free sqlite3_api->str_free
140954141045
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
140955141046
140956141047
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
140957141048
/* This case when the file really is being compiled as a loadable
140958141049
** extension */
@@ -141475,11 +141566,14 @@
141475141566
sqlite3_set_clientdata,
141476141567
/* Version 3.50.0 and later */
141477141568
sqlite3_setlk_timeout,
141478141569
/* Version 3.51.0 and later */
141479141570
sqlite3_set_errmsg,
141480
- sqlite3_db_status64
141571
+ sqlite3_db_status64,
141572
+ /* Version 3.52.0 and later */
141573
+ sqlite3_str_truncate,
141574
+ sqlite3_str_free
141481141575
};
141482141576
141483141577
/* True if x is the directory separator character
141484141578
*/
141485141579
#if SQLITE_OS_WIN
@@ -160974,13 +161068,16 @@
160974161068
pTab->iPKey = -1;
160975161069
pTab->tabFlags |= TF_Eponymous;
160976161070
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
160977161071
addModuleArgument(pParse, pTab, 0);
160978161072
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
161073
+ db->nSchemaLock++;
160979161074
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
161075
+ db->nSchemaLock--;
160980161076
if( rc ){
160981161077
sqlite3ErrorMsg(pParse, "%s", zErr);
161078
+ pParse->rc = rc;
160982161079
sqlite3DbFree(db, zErr);
160983161080
sqlite3VtabEponymousTableClear(db, pMod);
160984161081
}
160985161082
return 1;
160986161083
}
@@ -174038,12 +174135,26 @@
174038174135
VdbeCoverageIf(v, op==OP_SeekLT);
174039174136
VdbeCoverageIf(v, op==OP_SeekGT);
174040174137
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
174041174138
}
174042174139
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
174043
- if( pTabList->a[pLevel->iFrom].fg.fromExists ){
174044
- sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
174140
+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174141
+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174142
+ ** loop(s) will be the inner-most loops of the join. There might be
174143
+ ** multiple EXISTS loops, but they will all be nested, and the join
174144
+ ** order will not have been changed by the query planner. If the
174145
+ ** inner-most EXISTS loop sees a single successful row, it should
174146
+ ** break out of *all* EXISTS loops. But only the inner-most of the
174147
+ ** nested EXISTS loops should do this breakout. */
174148
+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174149
+ while( nOuter<i ){
174150
+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174151
+ nOuter++;
174152
+ }
174153
+ testcase( nOuter>0 );
174154
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174155
+ VdbeComment((v, "EXISTS break"));
174045174156
}
174046174157
/* The common case: Advance to the next row */
174047174158
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174048174159
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
174049174160
sqlite3VdbeChangeP5(v, pLevel->p5);
@@ -177626,12 +177737,27 @@
177626177737
177627177738
/* Memory allocator for parser stack resizing. This is a thin wrapper around
177628177739
** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
177629177740
** testing.
177630177741
*/
177631
- static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
177632
- return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
177742
+ static void *parserStackRealloc(
177743
+ void *pOld, /* Prior allocation */
177744
+ sqlite3_uint64 newSize, /* Requested new alloation size */
177745
+ Parse *pParse /* Parsing context */
177746
+ ){
177747
+ void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
177748
+ if( p==0 ) sqlite3OomFault(pParse->db);
177749
+ return p;
177750
+ }
177751
+ static void parserStackFree(void *pOld, Parse *pParse){
177752
+ (void)pParse;
177753
+ sqlite3_free(pOld);
177754
+ }
177755
+
177756
+ /* Return an integer that is the maximum allowed stack size */
177757
+ static int parserStackSizeLimit(Parse *pParse){
177758
+ return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH];
177633177759
}
177634177760
177635177761
177636177762
/* Construct a new Expr object from a single token */
177637177763
static Expr *tokenExpr(Parse *pParse, int op, Token t){
@@ -177984,25 +178110,34 @@
177984178110
SrcList* yy563;
177985178111
Expr* yy590;
177986178112
Select* yy637;
177987178113
} YYMINORTYPE;
177988178114
#ifndef YYSTACKDEPTH
177989
-#define YYSTACKDEPTH 100
178115
+#define YYSTACKDEPTH 50
177990178116
#endif
177991178117
#define sqlite3ParserARG_SDECL
177992178118
#define sqlite3ParserARG_PDECL
177993178119
#define sqlite3ParserARG_PARAM
177994178120
#define sqlite3ParserARG_FETCH
177995178121
#define sqlite3ParserARG_STORE
178122
+#undef YYREALLOC
177996178123
#define YYREALLOC parserStackRealloc
177997
-#define YYFREE sqlite3_free
178124
+#undef YYFREE
178125
+#define YYFREE parserStackFree
178126
+#undef YYDYNSTACK
177998178127
#define YYDYNSTACK 1
178128
+#undef YYSIZELIMIT
178129
+#define YYSIZELIMIT parserStackSizeLimit
178130
+#define sqlite3ParserCTX(P) ((P)->pParse)
177999178131
#define sqlite3ParserCTX_SDECL Parse *pParse;
178000178132
#define sqlite3ParserCTX_PDECL ,Parse *pParse
178001178133
#define sqlite3ParserCTX_PARAM ,pParse
178002178134
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
178003178135
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
178136
+#undef YYERRORSYMBOL
178137
+#undef YYERRSYMDT
178138
+#undef YYFALLBACK
178004178139
#define YYFALLBACK 1
178005178140
#define YYNSTATE 583
178006178141
#define YYNRULE 409
178007178142
#define YYNRULE_WITH_ACTION 344
178008178143
#define YYNTOKEN 187
@@ -179775,19 +179910,28 @@
179775179910
static int yyGrowStack(yyParser *p){
179776179911
int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
179777179912
int newSize;
179778179913
int idx;
179779179914
yyStackEntry *pNew;
179915
+#ifdef YYSIZELIMIT
179916
+ int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p));
179917
+#endif
179780179918
179781179919
newSize = oldSize*2 + 100;
179920
+#ifdef YYSIZELIMIT
179921
+ if( newSize>nLimit ){
179922
+ newSize = nLimit;
179923
+ if( newSize<=oldSize ) return 1;
179924
+ }
179925
+#endif
179782179926
idx = (int)(p->yytos - p->yystack);
179783179927
if( p->yystack==p->yystk0 ){
179784
- pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
179928
+ pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
179785179929
if( pNew==0 ) return 1;
179786179930
memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
179787179931
}else{
179788
- pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
179932
+ pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
179789179933
if( pNew==0 ) return 1;
179790179934
}
179791179935
p->yystack = pNew;
179792179936
p->yytos = &p->yystack[idx];
179793179937
#ifndef NDEBUG
@@ -180028,11 +180172,13 @@
180028180172
}
180029180173
yytos--;
180030180174
}
180031180175
180032180176
#if YYGROWABLESTACK
180033
- if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack);
180177
+ if( pParser->yystack!=pParser->yystk0 ){
180178
+ YYFREE(pParser->yystack, sqlite3ParserCTX(pParser));
180179
+ }
180034180180
#endif
180035180181
}
180036180182
180037180183
#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
180038180184
/*
@@ -180211,11 +180357,11 @@
180211180357
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
180212180358
/* Here code is inserted which will execute if the parser
180213180359
** stack every overflows */
180214180360
/******** Begin %stack_overflow code ******************************************/
180215180361
180216
- sqlite3OomFault(pParse->db);
180362
+ if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit");
180217180363
/******** End %stack_overflow code ********************************************/
180218180364
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
180219180365
sqlite3ParserCTX_STORE
180220180366
}
180221180367
@@ -186223,10 +186369,11 @@
186223186369
}
186224186370
}
186225186371
/* Clear the TEMP schema separately and last */
186226186372
if( db->aDb[1].pSchema ){
186227186373
sqlite3SchemaClear(db->aDb[1].pSchema);
186374
+ assert( db->aDb[1].pSchema->trigHash.count==0 );
186228186375
}
186229186376
sqlite3VtabUnlockList(db);
186230186377
186231186378
/* Free up the array of auxiliary databases */
186232186379
sqlite3CollapseDatabaseArray(db);
@@ -187354,10 +187501,13 @@
187354187501
db->xWalCallback = xCallback;
187355187502
db->pWalArg = pArg;
187356187503
sqlite3_mutex_leave(db->mutex);
187357187504
return pRet;
187358187505
#else
187506
+ UNUSED_PARAMETER(db);
187507
+ UNUSED_PARAMETER(xCallback);
187508
+ UNUSED_PARAMETER(pArg);
187359187509
return 0;
187360187510
#endif
187361187511
}
187362187512
187363187513
/*
@@ -187369,10 +187519,15 @@
187369187519
int eMode, /* SQLITE_CHECKPOINT_* value */
187370187520
int *pnLog, /* OUT: Size of WAL log in frames */
187371187521
int *pnCkpt /* OUT: Total number of frames checkpointed */
187372187522
){
187373187523
#ifdef SQLITE_OMIT_WAL
187524
+ UNUSED_PARAMETER(db);
187525
+ UNUSED_PARAMETER(zDb);
187526
+ UNUSED_PARAMETER(eMode);
187527
+ UNUSED_PARAMETER(pnLog);
187528
+ UNUSED_PARAMETER(pnCkpt);
187374187529
return SQLITE_OK;
187375187530
#else
187376187531
int rc; /* Return code */
187377187532
int iDb; /* Schema to checkpoint */
187378187533
@@ -187551,11 +187706,11 @@
187551187706
** Session extension). Internal logic should invoke sqlite3Error() or
187552187707
** sqlite3ErrorWithMsg() directly.
187553187708
*/
187554187709
SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
187555187710
int rc = SQLITE_OK;
187556
- if( !sqlite3SafetyCheckSickOrOk(db) ){
187711
+ if( !sqlite3SafetyCheckOk(db) ){
187557187712
return SQLITE_MISUSE_BKPT;
187558187713
}
187559187714
sqlite3_mutex_enter(db->mutex);
187560187715
if( zMsg ){
187561187716
sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
@@ -187750,10 +187905,11 @@
187750187905
SQLITE_MAX_ATTACHED,
187751187906
SQLITE_MAX_LIKE_PATTERN_LENGTH,
187752187907
SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
187753187908
SQLITE_MAX_TRIGGER_DEPTH,
187754187909
SQLITE_MAX_WORKER_THREADS,
187910
+ SQLITE_MAX_PARSER_DEPTH,
187755187911
};
187756187912
187757187913
/*
187758187914
** Make sure the hard limits are set to reasonable values
187759187915
*/
@@ -187819,20 +187975,21 @@
187819187975
*/
187820187976
assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
187821187977
assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
187822187978
assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
187823187979
assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
187980
+ assert( aHardLimit[SQLITE_LIMIT_PARSER_DEPTH]==SQLITE_MAX_PARSER_DEPTH );
187824187981
assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
187825187982
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
187826187983
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
187827187984
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
187828187985
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
187829187986
SQLITE_MAX_LIKE_PATTERN_LENGTH );
187830187987
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
187831187988
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
187832187989
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
187833
- assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
187990
+ assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) );
187834187991
187835187992
187836187993
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
187837187994
return -1;
187838187995
}
@@ -189731,10 +189888,11 @@
189731189888
}
189732189889
return zFilename + 1;
189733189890
}
189734189891
SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
189735189892
#ifdef SQLITE_OMIT_WAL
189893
+ UNUSED_PARAMETER(zFilename);
189736189894
return 0;
189737189895
#else
189738189896
zFilename = sqlite3_filename_journal(zFilename);
189739189897
if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
189740189898
return zFilename;
@@ -239557,18 +239715,26 @@
239557239715
#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
239558239716
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
239559239717
#define sqlite3Fts5ParserARG_PARAM ,pParse
239560239718
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
239561239719
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
239720
+#undef fts5YYREALLOC
239562239721
#define fts5YYREALLOC realloc
239722
+#undef fts5YYFREE
239563239723
#define fts5YYFREE free
239724
+#undef fts5YYDYNSTACK
239564239725
#define fts5YYDYNSTACK 0
239726
+#undef fts5YYSIZELIMIT
239727
+#define sqlite3Fts5ParserCTX(P) 0
239565239728
#define sqlite3Fts5ParserCTX_SDECL
239566239729
#define sqlite3Fts5ParserCTX_PDECL
239567239730
#define sqlite3Fts5ParserCTX_PARAM
239568239731
#define sqlite3Fts5ParserCTX_FETCH
239569239732
#define sqlite3Fts5ParserCTX_STORE
239733
+#undef fts5YYERRORSYMBOL
239734
+#undef fts5YYERRSYMDT
239735
+#undef fts5YYFALLBACK
239570239736
#define fts5YYNSTATE 35
239571239737
#define fts5YYNRULE 28
239572239738
#define fts5YYNRULE_WITH_ACTION 28
239573239739
#define fts5YYNFTS5TOKEN 16
239574239740
#define fts5YY_MAX_SHIFT 34
@@ -239889,19 +240055,28 @@
239889240055
static int fts5yyGrowStack(fts5yyParser *p){
239890240056
int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
239891240057
int newSize;
239892240058
int idx;
239893240059
fts5yyStackEntry *pNew;
240060
+#ifdef fts5YYSIZELIMIT
240061
+ int nLimit = fts5YYSIZELIMIT(sqlite3Fts5ParserCTX(p));
240062
+#endif
239894240063
239895240064
newSize = oldSize*2 + 100;
240065
+#ifdef fts5YYSIZELIMIT
240066
+ if( newSize>nLimit ){
240067
+ newSize = nLimit;
240068
+ if( newSize<=oldSize ) return 1;
240069
+ }
240070
+#endif
239896240071
idx = (int)(p->fts5yytos - p->fts5yystack);
239897240072
if( p->fts5yystack==p->fts5yystk0 ){
239898
- pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]));
240073
+ pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
239899240074
if( pNew==0 ) return 1;
239900240075
memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0]));
239901240076
}else{
239902
- pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]));
240077
+ pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
239903240078
if( pNew==0 ) return 1;
239904240079
}
239905240080
p->fts5yystack = pNew;
239906240081
p->fts5yytos = &p->fts5yystack[idx];
239907240082
#ifndef NDEBUG
@@ -240077,11 +240252,13 @@
240077240252
}
240078240253
fts5yytos--;
240079240254
}
240080240255
240081240256
#if fts5YYGROWABLESTACK
240082
- if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack);
240257
+ if( pParser->fts5yystack!=pParser->fts5yystk0 ){
240258
+ fts5YYFREE(pParser->fts5yystack, sqlite3Fts5ParserCTX(pParser));
240259
+ }
240083240260
#endif
240084240261
}
240085240262
240086240263
#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
240087240264
/*
@@ -260281,11 +260458,11 @@
260281260458
int nArg, /* Number of args */
260282260459
sqlite3_value **apUnused /* Function arguments */
260283260460
){
260284260461
assert( nArg==0 );
260285260462
UNUSED_PARAM2(nArg, apUnused);
260286
- sqlite3_result_text(pCtx, "fts5: 2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8", -1, SQLITE_TRANSIENT);
260463
+ sqlite3_result_text(pCtx, "fts5: 2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa", -1, SQLITE_TRANSIENT);
260287260464
}
260288260465
260289260466
/*
260290260467
** Implementation of fts5_locale(LOCALE, TEXT) function.
260291260468
**
260292260469
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.51.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 38c993c8b7137d6d5623d387292639634297 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -465,16 +465,16 @@
465 **
466 ** See also: [sqlite3_libversion()],
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-10-31T16:07:31.438Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -2886,16 +2886,19 @@
2886 ** </dd>
2887 **
2888 ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
2889 ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
2890 ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2891 ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
2892 ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
2893 ** statistics. For statistics to be collected, the flag must be set on
2894 ** the database handle both when the SQL statement is prepared and when it
2895 ** is stepped. The flag is set (collection of statistics is enabled)
2896 ** by default. <p>This option takes two arguments: an integer and a pointer to
 
 
 
2897 ** an integer. The first argument is 1, 0, or -1 to enable, disable, or
2898 ** leave unchanged the statement scanstatus option. If the second argument
2899 ** is not NULL, then the value of the statement scanstatus setting after
2900 ** processing the first argument is written into the integer that the second
2901 ** argument points to.
@@ -4536,11 +4539,11 @@
4536 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4537 SQLITE_API const char *sqlite3_errstr(int);
4538 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4539
4540 /*
4541 ** CAPI3REF: Set Error Codes And Message
4542 ** METHOD: sqlite3
4543 **
4544 ** Set the error code of the database handle passed as the first argument
4545 ** to errcode, and the error message to a copy of nul-terminated string
4546 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4654,10 +4657,14 @@
4654 ** result set of a [SELECT] or the maximum number of columns in an index
4655 ** or in an ORDER BY or GROUP BY clause.</dd>)^
4656 **
4657 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
4658 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
 
 
 
 
4659 **
4660 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
4661 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
4662 **
4663 ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4699,10 +4706,11 @@
4699 #define SQLITE_LIMIT_ATTACHED 7
4700 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
4701 #define SQLITE_LIMIT_VARIABLE_NUMBER 9
4702 #define SQLITE_LIMIT_TRIGGER_DEPTH 10
4703 #define SQLITE_LIMIT_WORKER_THREADS 11
 
4704
4705 /*
4706 ** CAPI3REF: Prepare Flags
4707 **
4708 ** These constants define various flags that can be passed into the
@@ -9043,19 +9051,24 @@
9043 ** pass the returned value to [sqlite3_free()] to avoid a memory leak.
9044 ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
9045 ** errors were encountered during construction of the string. ^The
9046 ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
9047 ** string in [sqlite3_str] object X is zero bytes long.
 
 
 
 
9048 */
9049 SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
 
9050
9051 /*
9052 ** CAPI3REF: Add Content To A Dynamic String
9053 ** METHOD: sqlite3_str
9054 **
9055 ** These interfaces add content to an sqlite3_str object previously obtained
9056 ** from [sqlite3_str_new()].
9057 **
9058 ** ^The [sqlite3_str_appendf(X,F,...)] and
9059 ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
9060 ** functionality of SQLite to append formatted text onto the end of
9061 ** [sqlite3_str] object X.
@@ -9073,10 +9086,14 @@
9073 ** single-byte character C onto the end of [sqlite3_str] object X.
9074 ** ^This method can be used, for example, to add whitespace indentation.
9075 **
9076 ** ^The [sqlite3_str_reset(X)] method resets the string under construction
9077 ** inside [sqlite3_str] object X back to zero bytes in length.
 
 
 
 
9078 **
9079 ** These methods do not return a result code. ^If an error occurs, that fact
9080 ** is recorded in the [sqlite3_str] object and can be recovered by a
9081 ** subsequent call to [sqlite3_str_errcode(X)].
9082 */
@@ -9084,10 +9101,11 @@
9084 SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
9085 SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
9086 SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
9087 SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
9088 SQLITE_API void sqlite3_str_reset(sqlite3_str*);
 
9089
9090 /*
9091 ** CAPI3REF: Status Of A Dynamic String
9092 ** METHOD: sqlite3_str
9093 **
@@ -10745,11 +10763,11 @@
10745 ** &nbsp; rc==SQLITE_OK && pVal;
10746 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10747 ** &nbsp; ){
10748 ** &nbsp; // do something with pVal
10749 ** &nbsp; }
10750 ** &nbsp; if( rc!=SQLITE_OK ){
10751 ** &nbsp; // an error has occurred
10752 ** &nbsp; }
10753 ** </pre></blockquote>)^
10754 **
10755 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10917,13 +10935,13 @@
10917 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
10918 ** of this interface is undefined. ^The requested measurement is written into
10919 ** a variable pointed to by the "pOut" parameter.
10920 **
10921 ** The "flags" parameter must be passed a mask of flags. At present only
10922 ** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
10923 ** is specified, then status information is available for all elements
10924 ** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
10925 ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
10926 ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
10927 ** the EXPLAIN QUERY PLAN output) are available. Invoking API
10928 ** sqlite3_stmt_scanstatus() is equivalent to calling
10929 ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10933,11 +10951,12 @@
10933 ** retrieve statistics for the entire query. ^If idx is out of range
10934 ** - less than -1 or greater than or equal to the total number of query
10935 ** elements used to implement the statement - a non-zero value is returned and
10936 ** the variable that pOut points to is unchanged.
10937 **
10938 ** See also: [sqlite3_stmt_scanstatus_reset()]
 
10939 */
10940 SQLITE_API int sqlite3_stmt_scanstatus(
10941 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
10942 int idx, /* Index of loop to report on */
10943 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -14373,19 +14392,37 @@
14373 #ifndef SQLITE_MAX_SQL_LENGTH
14374 # define SQLITE_MAX_SQL_LENGTH 1000000000
14375 #endif
14376
14377 /*
14378 ** The maximum depth of an expression tree. This is limited to
14379 ** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
14380 ** want to place more severe limits on the complexity of an
14381 ** expression. A value of 0 means that there is no limit.
 
 
 
14382 */
14383 #ifndef SQLITE_MAX_EXPR_DEPTH
14384 # define SQLITE_MAX_EXPR_DEPTH 1000
14385 #endif
14386
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14387 /*
14388 ** The maximum number of terms in a compound SELECT statement.
14389 ** The code generator for compound SELECT statements does one
14390 ** level of recursion for each term. A stack overflow can result
14391 ** if the number of terms is too large. In practice, most SQL
@@ -18113,11 +18150,11 @@
18113
18114 /*
18115 ** The number of different kinds of things that can be limited
18116 ** using the sqlite3_limit() interface.
18117 */
18118 #define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
18119
18120 /*
18121 ** Lookaside malloc is a set of fixed-size buffers that can be used
18122 ** to satisfy small transient memory allocation requests for objects
18123 ** associated with a particular database connection. The use of
@@ -33169,10 +33206,18 @@
33169
33170 /* Return the current length of p in bytes */
33171 SQLITE_API int sqlite3_str_length(sqlite3_str *p){
33172 return p ? p->nChar : 0;
33173 }
 
 
 
 
 
 
 
 
33174
33175 /* Return the current value for p */
33176 SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
33177 if( p==0 || p->nChar==0 ) return 0;
33178 p->zText[p->nChar] = 0;
@@ -33189,10 +33234,21 @@
33189 }
33190 p->nAlloc = 0;
33191 p->nChar = 0;
33192 p->zText = 0;
33193 }
 
 
 
 
 
 
 
 
 
 
 
33194
33195 /*
33196 ** Initialize a string accumulator.
33197 **
33198 ** p: The accumulator to be initialized.
@@ -38001,10 +38057,11 @@
38001 rehash(pH, pH->count*3);
38002 }
38003 insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
38004 return 0;
38005 }
 
38006
38007 /************** End of hash.c ************************************************/
38008 /************** Begin file opcodes.c *****************************************/
38009 /* Automatically generated. Do not edit */
38010 /* See the tool/mkopcodec.tcl script for details. */
@@ -59732,10 +59789,12 @@
59732 if( pPager->pWal ){
59733 u32 iRead = 0;
59734 (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
59735 if( iRead ) return 0; /* Case (4) */
59736 }
 
 
59737 #endif
59738 assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
59739 if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
59740 & SQLITE_IOCAP_SUBPAGE_READ)==0 ){
59741 return 0; /* Case (2) */
@@ -63111,10 +63170,12 @@
63111 a = pTmp;
63112 }
63113 sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
63114 pPager->pWal = 0;
63115 }
 
 
63116 #endif
63117 pager_reset(pPager);
63118 if( MEMDB ){
63119 pager_unlock(pPager);
63120 }else{
@@ -76104,10 +76165,34 @@
76104 assert( pBt->inTransaction==TRANS_NONE );
76105 rc = sqlite3PagerWalWriteLock(pPager, 1);
76106 if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
76107 }
76108 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76109
76110 /* Call lockBtree() until either pBt->pPage1 is populated or
76111 ** lockBtree() returns something other than SQLITE_OK. lockBtree()
76112 ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
76113 ** reading page 1 it discovers that the page-size of the database
@@ -82190,11 +82275,11 @@
82190 }
82191 }
82192 }while( rc==SQLITE_OK && nOut>0 );
82193
82194 if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
82195 Pgno pgnoNew;
82196 MemPage *pNew = 0;
82197 rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
82198 put4byte(pPgnoOut, pgnoNew);
82199 if( ISAUTOVACUUM(pBt) && pPageOut ){
82200 ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
@@ -93132,10 +93217,12 @@
93132 if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
93133 rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
93134 }
93135 }
93136 }
 
 
93137 #endif
93138 return rc;
93139 }
93140
93141
@@ -95243,45 +95330,43 @@
95243 ** counters for x86 and x86_64 class CPUs.
95244 */
95245 #ifndef SQLITE_HWTIME_H
95246 #define SQLITE_HWTIME_H
95247
95248 /*
95249 ** The following routine only works on Pentium-class (or newer) processors.
95250 ** It uses the RDTSC opcode to read the cycle count value out of the
95251 ** processor and returns that value. This can be used for high-res
95252 ** profiling.
95253 */
95254 #if !defined(__STRICT_ANSI__) && \
95255 (defined(__GNUC__) || defined(_MSC_VER)) && \
 
 
 
95256 (defined(i386) || defined(__i386__) || defined(_M_IX86))
95257
95258 #if defined(__GNUC__)
 
 
 
 
 
 
95259
95260 __inline__ sqlite_uint64 sqlite3Hwtime(void){
95261 unsigned int lo, hi;
95262 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95263 return (sqlite_uint64)hi << 32 | lo;
95264 }
95265
95266 #elif defined(_MSC_VER)
95267
95268 __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
95269 __asm {
95270 rdtsc
95271 ret ; return value at EDX:EAX
95272 }
95273 }
95274
95275 #endif
95276
95277 #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
95278
95279 __inline__ sqlite_uint64 sqlite3Hwtime(void){
95280 unsigned int lo, hi;
95281 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95282 return (sqlite_uint64)hi << 32 | lo;
95283 }
95284
95285 #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
95286
95287 __inline__ sqlite_uint64 sqlite3Hwtime(void){
@@ -130653,10 +130738,11 @@
130653 sqlite3HashInit(&pSchema->trigHash);
130654 sqlite3HashClear(&pSchema->idxHash);
130655 for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
130656 sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
130657 }
 
130658 sqlite3HashClear(&temp2);
130659 sqlite3HashInit(&pSchema->tblHash);
130660 for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
130661 Table *pTab = sqliteHashData(pElem);
130662 sqlite3DeleteTable(&xdb, pTab);
@@ -140610,11 +140696,13 @@
140610 /* Version 3.50.0 and later */
140611 int (*setlk_timeout)(sqlite3*,int,int);
140612 /* Version 3.51.0 and later */
140613 int (*set_errmsg)(sqlite3*,int,const char*);
140614 int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
140615
 
 
140616 };
140617
140618 /*
140619 ** This is the function signature used for all extension entry points. It
140620 ** is also defined in the file "loadext.c".
@@ -140949,10 +141037,13 @@
140949 /* Version 3.50.0 and later */
140950 #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
140951 /* Version 3.51.0 and later */
140952 #define sqlite3_set_errmsg sqlite3_api->set_errmsg
140953 #define sqlite3_db_status64 sqlite3_api->db_status64
 
 
 
140954 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
140955
140956 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
140957 /* This case when the file really is being compiled as a loadable
140958 ** extension */
@@ -141475,11 +141566,14 @@
141475 sqlite3_set_clientdata,
141476 /* Version 3.50.0 and later */
141477 sqlite3_setlk_timeout,
141478 /* Version 3.51.0 and later */
141479 sqlite3_set_errmsg,
141480 sqlite3_db_status64
 
 
 
141481 };
141482
141483 /* True if x is the directory separator character
141484 */
141485 #if SQLITE_OS_WIN
@@ -160974,13 +161068,16 @@
160974 pTab->iPKey = -1;
160975 pTab->tabFlags |= TF_Eponymous;
160976 addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
160977 addModuleArgument(pParse, pTab, 0);
160978 addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
 
160979 rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
 
160980 if( rc ){
160981 sqlite3ErrorMsg(pParse, "%s", zErr);
 
160982 sqlite3DbFree(db, zErr);
160983 sqlite3VtabEponymousTableClear(db, pMod);
160984 }
160985 return 1;
160986 }
@@ -174038,12 +174135,26 @@
174038 VdbeCoverageIf(v, op==OP_SeekLT);
174039 VdbeCoverageIf(v, op==OP_SeekGT);
174040 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
174041 }
174042 #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
174043 if( pTabList->a[pLevel->iFrom].fg.fromExists ){
174044 sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174045 }
174046 /* The common case: Advance to the next row */
174047 if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174048 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
174049 sqlite3VdbeChangeP5(v, pLevel->p5);
@@ -177626,12 +177737,27 @@
177626
177627 /* Memory allocator for parser stack resizing. This is a thin wrapper around
177628 ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
177629 ** testing.
177630 */
177631 static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
177632 return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177633 }
177634
177635
177636 /* Construct a new Expr object from a single token */
177637 static Expr *tokenExpr(Parse *pParse, int op, Token t){
@@ -177984,25 +178110,34 @@
177984 SrcList* yy563;
177985 Expr* yy590;
177986 Select* yy637;
177987 } YYMINORTYPE;
177988 #ifndef YYSTACKDEPTH
177989 #define YYSTACKDEPTH 100
177990 #endif
177991 #define sqlite3ParserARG_SDECL
177992 #define sqlite3ParserARG_PDECL
177993 #define sqlite3ParserARG_PARAM
177994 #define sqlite3ParserARG_FETCH
177995 #define sqlite3ParserARG_STORE
 
177996 #define YYREALLOC parserStackRealloc
177997 #define YYFREE sqlite3_free
 
 
177998 #define YYDYNSTACK 1
 
 
 
177999 #define sqlite3ParserCTX_SDECL Parse *pParse;
178000 #define sqlite3ParserCTX_PDECL ,Parse *pParse
178001 #define sqlite3ParserCTX_PARAM ,pParse
178002 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
178003 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
 
 
 
178004 #define YYFALLBACK 1
178005 #define YYNSTATE 583
178006 #define YYNRULE 409
178007 #define YYNRULE_WITH_ACTION 344
178008 #define YYNTOKEN 187
@@ -179775,19 +179910,28 @@
179775 static int yyGrowStack(yyParser *p){
179776 int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
179777 int newSize;
179778 int idx;
179779 yyStackEntry *pNew;
 
 
 
179780
179781 newSize = oldSize*2 + 100;
 
 
 
 
 
 
179782 idx = (int)(p->yytos - p->yystack);
179783 if( p->yystack==p->yystk0 ){
179784 pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
179785 if( pNew==0 ) return 1;
179786 memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
179787 }else{
179788 pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
179789 if( pNew==0 ) return 1;
179790 }
179791 p->yystack = pNew;
179792 p->yytos = &p->yystack[idx];
179793 #ifndef NDEBUG
@@ -180028,11 +180172,13 @@
180028 }
180029 yytos--;
180030 }
180031
180032 #if YYGROWABLESTACK
180033 if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack);
 
 
180034 #endif
180035 }
180036
180037 #ifndef sqlite3Parser_ENGINEALWAYSONSTACK
180038 /*
@@ -180211,11 +180357,11 @@
180211 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
180212 /* Here code is inserted which will execute if the parser
180213 ** stack every overflows */
180214 /******** Begin %stack_overflow code ******************************************/
180215
180216 sqlite3OomFault(pParse->db);
180217 /******** End %stack_overflow code ********************************************/
180218 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
180219 sqlite3ParserCTX_STORE
180220 }
180221
@@ -186223,10 +186369,11 @@
186223 }
186224 }
186225 /* Clear the TEMP schema separately and last */
186226 if( db->aDb[1].pSchema ){
186227 sqlite3SchemaClear(db->aDb[1].pSchema);
 
186228 }
186229 sqlite3VtabUnlockList(db);
186230
186231 /* Free up the array of auxiliary databases */
186232 sqlite3CollapseDatabaseArray(db);
@@ -187354,10 +187501,13 @@
187354 db->xWalCallback = xCallback;
187355 db->pWalArg = pArg;
187356 sqlite3_mutex_leave(db->mutex);
187357 return pRet;
187358 #else
 
 
 
187359 return 0;
187360 #endif
187361 }
187362
187363 /*
@@ -187369,10 +187519,15 @@
187369 int eMode, /* SQLITE_CHECKPOINT_* value */
187370 int *pnLog, /* OUT: Size of WAL log in frames */
187371 int *pnCkpt /* OUT: Total number of frames checkpointed */
187372 ){
187373 #ifdef SQLITE_OMIT_WAL
 
 
 
 
 
187374 return SQLITE_OK;
187375 #else
187376 int rc; /* Return code */
187377 int iDb; /* Schema to checkpoint */
187378
@@ -187551,11 +187706,11 @@
187551 ** Session extension). Internal logic should invoke sqlite3Error() or
187552 ** sqlite3ErrorWithMsg() directly.
187553 */
187554 SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
187555 int rc = SQLITE_OK;
187556 if( !sqlite3SafetyCheckSickOrOk(db) ){
187557 return SQLITE_MISUSE_BKPT;
187558 }
187559 sqlite3_mutex_enter(db->mutex);
187560 if( zMsg ){
187561 sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
@@ -187750,10 +187905,11 @@
187750 SQLITE_MAX_ATTACHED,
187751 SQLITE_MAX_LIKE_PATTERN_LENGTH,
187752 SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
187753 SQLITE_MAX_TRIGGER_DEPTH,
187754 SQLITE_MAX_WORKER_THREADS,
 
187755 };
187756
187757 /*
187758 ** Make sure the hard limits are set to reasonable values
187759 */
@@ -187819,20 +187975,21 @@
187819 */
187820 assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
187821 assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
187822 assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
187823 assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
 
187824 assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
187825 assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
187826 assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
187827 assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
187828 assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
187829 SQLITE_MAX_LIKE_PATTERN_LENGTH );
187830 assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
187831 assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
187832 assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
187833 assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
187834
187835
187836 if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
187837 return -1;
187838 }
@@ -189731,10 +189888,11 @@
189731 }
189732 return zFilename + 1;
189733 }
189734 SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
189735 #ifdef SQLITE_OMIT_WAL
 
189736 return 0;
189737 #else
189738 zFilename = sqlite3_filename_journal(zFilename);
189739 if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
189740 return zFilename;
@@ -239557,18 +239715,26 @@
239557 #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
239558 #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
239559 #define sqlite3Fts5ParserARG_PARAM ,pParse
239560 #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
239561 #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
 
239562 #define fts5YYREALLOC realloc
 
239563 #define fts5YYFREE free
 
239564 #define fts5YYDYNSTACK 0
 
 
239565 #define sqlite3Fts5ParserCTX_SDECL
239566 #define sqlite3Fts5ParserCTX_PDECL
239567 #define sqlite3Fts5ParserCTX_PARAM
239568 #define sqlite3Fts5ParserCTX_FETCH
239569 #define sqlite3Fts5ParserCTX_STORE
 
 
 
239570 #define fts5YYNSTATE 35
239571 #define fts5YYNRULE 28
239572 #define fts5YYNRULE_WITH_ACTION 28
239573 #define fts5YYNFTS5TOKEN 16
239574 #define fts5YY_MAX_SHIFT 34
@@ -239889,19 +240055,28 @@
239889 static int fts5yyGrowStack(fts5yyParser *p){
239890 int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
239891 int newSize;
239892 int idx;
239893 fts5yyStackEntry *pNew;
 
 
 
239894
239895 newSize = oldSize*2 + 100;
 
 
 
 
 
 
239896 idx = (int)(p->fts5yytos - p->fts5yystack);
239897 if( p->fts5yystack==p->fts5yystk0 ){
239898 pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]));
239899 if( pNew==0 ) return 1;
239900 memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0]));
239901 }else{
239902 pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]));
239903 if( pNew==0 ) return 1;
239904 }
239905 p->fts5yystack = pNew;
239906 p->fts5yytos = &p->fts5yystack[idx];
239907 #ifndef NDEBUG
@@ -240077,11 +240252,13 @@
240077 }
240078 fts5yytos--;
240079 }
240080
240081 #if fts5YYGROWABLESTACK
240082 if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack);
 
 
240083 #endif
240084 }
240085
240086 #ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
240087 /*
@@ -260281,11 +260458,11 @@
260281 int nArg, /* Number of args */
260282 sqlite3_value **apUnused /* Function arguments */
260283 ){
260284 assert( nArg==0 );
260285 UNUSED_PARAM2(nArg, apUnused);
260286 sqlite3_result_text(pCtx, "fts5: 2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8", -1, SQLITE_TRANSIENT);
260287 }
260288
260289 /*
260290 ** Implementation of fts5_locale(LOCALE, TEXT) function.
260291 **
260292
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.52.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 7e460ffa5aae884807db9e7c8214d6d822d5 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -465,16 +465,16 @@
465 **
466 ** See also: [sqlite3_libversion()],
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.52.0"
471 #define SQLITE_VERSION_NUMBER 3052000
472 #define SQLITE_SOURCE_ID "2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-11-18T17:49:48.189Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -2886,16 +2886,19 @@
2886 ** </dd>
2887 **
2888 ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
2889 ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
2890 ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2891 ** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
2892 ** a flag that enables collection of run-time performance statistics
2893 ** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
2894 ** columns of the [bytecode virtual table].
2895 ** For statistics to be collected, the flag must be set on
2896 ** the database handle both when the SQL statement is
2897 ** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
2898 ** The flag is set (collection of statistics is enabled) by default.
2899 ** <p>This option takes two arguments: an integer and a pointer to
2900 ** an integer. The first argument is 1, 0, or -1 to enable, disable, or
2901 ** leave unchanged the statement scanstatus option. If the second argument
2902 ** is not NULL, then the value of the statement scanstatus setting after
2903 ** processing the first argument is written into the integer that the second
2904 ** argument points to.
@@ -4536,11 +4539,11 @@
4539 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4540 SQLITE_API const char *sqlite3_errstr(int);
4541 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4542
4543 /*
4544 ** CAPI3REF: Set Error Code And Message
4545 ** METHOD: sqlite3
4546 **
4547 ** Set the error code of the database handle passed as the first argument
4548 ** to errcode, and the error message to a copy of nul-terminated string
4549 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4654,10 +4657,14 @@
4657 ** result set of a [SELECT] or the maximum number of columns in an index
4658 ** or in an ORDER BY or GROUP BY clause.</dd>)^
4659 **
4660 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
4661 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
4662 **
4663 ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
4664 ** <dd>The maximum depth of the LALR(1) parser stack used to analyze
4665 ** input SQL statements.</dd>)^
4666 **
4667 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
4668 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
4669 **
4670 ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4699,10 +4706,11 @@
4706 #define SQLITE_LIMIT_ATTACHED 7
4707 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
4708 #define SQLITE_LIMIT_VARIABLE_NUMBER 9
4709 #define SQLITE_LIMIT_TRIGGER_DEPTH 10
4710 #define SQLITE_LIMIT_WORKER_THREADS 11
4711 #define SQLITE_LIMIT_PARSER_DEPTH 12
4712
4713 /*
4714 ** CAPI3REF: Prepare Flags
4715 **
4716 ** These constants define various flags that can be passed into the
@@ -9043,19 +9051,24 @@
9051 ** pass the returned value to [sqlite3_free()] to avoid a memory leak.
9052 ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
9053 ** errors were encountered during construction of the string. ^The
9054 ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
9055 ** string in [sqlite3_str] object X is zero bytes long.
9056 **
9057 ** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
9058 ** X and the string content it contains. Calling sqlite3_str_free(X) is
9059 ** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
9060 */
9061 SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
9062 SQLITE_API void sqlite3_str_free(sqlite3_str*);
9063
9064 /*
9065 ** CAPI3REF: Add Content To A Dynamic String
9066 ** METHOD: sqlite3_str
9067 **
9068 ** These interfaces add or remove content to an sqlite3_str object
9069 ** previously obtained from [sqlite3_str_new()].
9070 **
9071 ** ^The [sqlite3_str_appendf(X,F,...)] and
9072 ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
9073 ** functionality of SQLite to append formatted text onto the end of
9074 ** [sqlite3_str] object X.
@@ -9073,10 +9086,14 @@
9086 ** single-byte character C onto the end of [sqlite3_str] object X.
9087 ** ^This method can be used, for example, to add whitespace indentation.
9088 **
9089 ** ^The [sqlite3_str_reset(X)] method resets the string under construction
9090 ** inside [sqlite3_str] object X back to zero bytes in length.
9091 **
9092 ** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
9093 ** under construction to be N bytes are less. This routine is a no-op if
9094 ** N is negative or if the string is already N bytes or smaller in size.
9095 **
9096 ** These methods do not return a result code. ^If an error occurs, that fact
9097 ** is recorded in the [sqlite3_str] object and can be recovered by a
9098 ** subsequent call to [sqlite3_str_errcode(X)].
9099 */
@@ -9084,10 +9101,11 @@
9101 SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
9102 SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
9103 SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
9104 SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
9105 SQLITE_API void sqlite3_str_reset(sqlite3_str*);
9106 SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
9107
9108 /*
9109 ** CAPI3REF: Status Of A Dynamic String
9110 ** METHOD: sqlite3_str
9111 **
@@ -10745,11 +10763,11 @@
10763 ** &nbsp; rc==SQLITE_OK && pVal;
10764 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10765 ** &nbsp; ){
10766 ** &nbsp; // do something with pVal
10767 ** &nbsp; }
10768 ** &nbsp; if( rc!=SQLITE_DONE ){
10769 ** &nbsp; // an error has occurred
10770 ** &nbsp; }
10771 ** </pre></blockquote>)^
10772 **
10773 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10917,13 +10935,13 @@
10935 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
10936 ** of this interface is undefined. ^The requested measurement is written into
10937 ** a variable pointed to by the "pOut" parameter.
10938 **
10939 ** The "flags" parameter must be passed a mask of flags. At present only
10940 ** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
10941 ** is specified, then status information is available for all elements
10942 ** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
10943 ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
10944 ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
10945 ** the EXPLAIN QUERY PLAN output) are available. Invoking API
10946 ** sqlite3_stmt_scanstatus() is equivalent to calling
10947 ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10933,11 +10951,12 @@
10951 ** retrieve statistics for the entire query. ^If idx is out of range
10952 ** - less than -1 or greater than or equal to the total number of query
10953 ** elements used to implement the statement - a non-zero value is returned and
10954 ** the variable that pOut points to is unchanged.
10955 **
10956 ** See also: [sqlite3_stmt_scanstatus_reset()] and the
10957 ** [nexec and ncycle] columnes of the [bytecode virtual table].
10958 */
10959 SQLITE_API int sqlite3_stmt_scanstatus(
10960 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
10961 int idx, /* Index of loop to report on */
10962 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -14373,19 +14392,37 @@
14392 #ifndef SQLITE_MAX_SQL_LENGTH
14393 # define SQLITE_MAX_SQL_LENGTH 1000000000
14394 #endif
14395
14396 /*
14397 ** The maximum depth of an expression tree. The expression tree depth
14398 ** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by
14399 ** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of
14400 ** expressions can help prevent excess memory usage by hostile SQL.
14401 **
14402 ** A value of 0 for this compile-time option causes all expression
14403 ** depth limiting code to be omitted.
14404 */
14405 #ifndef SQLITE_MAX_EXPR_DEPTH
14406 # define SQLITE_MAX_EXPR_DEPTH 1000
14407 #endif
14408
14409 /*
14410 ** The maximum depth of the LALR(1) stack used in the parser that
14411 ** interprets SQL inputs. The parser stack depth can also be limited
14412 ** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack
14413 ** depth can help prevent excess memory usage and excess CPU stack
14414 ** usage when processing hostile SQL.
14415 **
14416 ** Prior to version 3.45.0 (2024-01-15), the parser stack was
14417 ** hard-coded to 100 entries, and that worked fine for almost all
14418 ** applications. So the upper bound on this limit need not be large.
14419 */
14420 #ifndef SQLITE_MAX_PARSER_DEPTH
14421 # define SQLITE_MAX_PARSER_DEPTH 2500
14422 #endif
14423
14424 /*
14425 ** The maximum number of terms in a compound SELECT statement.
14426 ** The code generator for compound SELECT statements does one
14427 ** level of recursion for each term. A stack overflow can result
14428 ** if the number of terms is too large. In practice, most SQL
@@ -18113,11 +18150,11 @@
18150
18151 /*
18152 ** The number of different kinds of things that can be limited
18153 ** using the sqlite3_limit() interface.
18154 */
18155 #define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1)
18156
18157 /*
18158 ** Lookaside malloc is a set of fixed-size buffers that can be used
18159 ** to satisfy small transient memory allocation requests for objects
18160 ** associated with a particular database connection. The use of
@@ -33169,10 +33206,18 @@
33206
33207 /* Return the current length of p in bytes */
33208 SQLITE_API int sqlite3_str_length(sqlite3_str *p){
33209 return p ? p->nChar : 0;
33210 }
33211
33212 /* Truncate the text of the string to be no more than N bytes. */
33213 SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){
33214 if( p!=0 && N>=0 && (u32)N<p->nChar ){
33215 p->nChar = N;
33216 p->zText[p->nChar] = 0;
33217 }
33218 }
33219
33220 /* Return the current value for p */
33221 SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
33222 if( p==0 || p->nChar==0 ) return 0;
33223 p->zText[p->nChar] = 0;
@@ -33189,10 +33234,21 @@
33234 }
33235 p->nAlloc = 0;
33236 p->nChar = 0;
33237 p->zText = 0;
33238 }
33239
33240 /*
33241 ** Destroy a dynamically allocate sqlite3_str object and all
33242 ** of its content, all in one call.
33243 */
33244 SQLITE_API void sqlite3_str_free(sqlite3_str *p){
33245 if( p ){
33246 sqlite3_str_reset(p);
33247 sqlite3_free(p);
33248 }
33249 }
33250
33251 /*
33252 ** Initialize a string accumulator.
33253 **
33254 ** p: The accumulator to be initialized.
@@ -38001,10 +38057,11 @@
38057 rehash(pH, pH->count*3);
38058 }
38059 insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
38060 return 0;
38061 }
38062
38063
38064 /************** End of hash.c ************************************************/
38065 /************** Begin file opcodes.c *****************************************/
38066 /* Automatically generated. Do not edit */
38067 /* See the tool/mkopcodec.tcl script for details. */
@@ -59732,10 +59789,12 @@
59789 if( pPager->pWal ){
59790 u32 iRead = 0;
59791 (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
59792 if( iRead ) return 0; /* Case (4) */
59793 }
59794 #else
59795 UNUSED_PARAMETER(pgno);
59796 #endif
59797 assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
59798 if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
59799 & SQLITE_IOCAP_SUBPAGE_READ)==0 ){
59800 return 0; /* Case (2) */
@@ -63111,10 +63170,12 @@
63170 a = pTmp;
63171 }
63172 sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
63173 pPager->pWal = 0;
63174 }
63175 #else
63176 UNUSED_PARAMETER(db);
63177 #endif
63178 pager_reset(pPager);
63179 if( MEMDB ){
63180 pager_unlock(pPager);
63181 }else{
@@ -76104,10 +76165,34 @@
76165 assert( pBt->inTransaction==TRANS_NONE );
76166 rc = sqlite3PagerWalWriteLock(pPager, 1);
76167 if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
76168 }
76169 #endif
76170
76171 #ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114
76172 /* If both a read and write transaction will be opened by this call,
76173 ** then issue a file-control as if the following pragma command had
76174 ** been evaluated:
76175 **
76176 ** PRAGMA experimental_pragma_20251114 = 1|2
76177 **
76178 ** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag
76179 ** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS.
76180 **
76181 ** WARNING: This code will likely remain part of SQLite only temporarily -
76182 ** it exists to allow users to experiment with certain types of blocking
76183 ** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */
76184 if( pBt->pPage1==0 && wrflag ){
76185 sqlite3_file *fd = sqlite3PagerFile(pPager);
76186 char *aFcntl[3] = {0,0,0};
76187 aFcntl[1] = "experimental_pragma_20251114";
76188 assert( wrflag==1 || wrflag==2 );
76189 aFcntl[2] = (wrflag==1 ? "1" : "2");
76190 sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
76191 sqlite3_free(aFcntl[0]);
76192 }
76193 #endif
76194
76195 /* Call lockBtree() until either pBt->pPage1 is populated or
76196 ** lockBtree() returns something other than SQLITE_OK. lockBtree()
76197 ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
76198 ** reading page 1 it discovers that the page-size of the database
@@ -82190,11 +82275,11 @@
82275 }
82276 }
82277 }while( rc==SQLITE_OK && nOut>0 );
82278
82279 if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
82280 Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
82281 MemPage *pNew = 0;
82282 rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
82283 put4byte(pPgnoOut, pgnoNew);
82284 if( ISAUTOVACUUM(pBt) && pPageOut ){
82285 ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
@@ -93132,10 +93217,12 @@
93217 if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
93218 rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
93219 }
93220 }
93221 }
93222 #else
93223 UNUSED_PARAMETER(db);
93224 #endif
93225 return rc;
93226 }
93227
93228
@@ -95243,45 +95330,43 @@
95330 ** counters for x86 and x86_64 class CPUs.
95331 */
95332 #ifndef SQLITE_HWTIME_H
95333 #define SQLITE_HWTIME_H
95334
95335 #if defined(_MSC_VER) && defined(_WIN32)
95336
95337 #include <profileapi.h>
95338
95339 __inline sqlite3_uint64 sqlite3Hwtime(void){
95340 LARGE_INTEGER tm;
95341 QueryPerformanceCounter(&tm);
95342 return (sqlite3_uint64)tm.QuadPart;
95343 }
95344
95345 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
95346 (defined(i386) || defined(__i386__) || defined(_M_IX86))
95347
95348 __inline__ sqlite_uint64 sqlite3Hwtime(void){
95349 unsigned int lo, hi;
95350 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95351 return (sqlite_uint64)hi << 32 | lo;
95352 }
95353
95354 #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
95355
95356 __inline__ sqlite_uint64 sqlite3Hwtime(void){
95357 unsigned int lo, hi;
95358 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
95359 return (sqlite_uint64)hi << 32 | lo;
95360 }
95361
95362 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
 
 
 
 
 
 
 
 
 
 
 
95363
95364 __inline__ sqlite_uint64 sqlite3Hwtime(void){
95365 sqlite3_uint64 cnt;
95366 __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
95367 return cnt;
95368 }
95369
95370 #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
95371
95372 __inline__ sqlite_uint64 sqlite3Hwtime(void){
@@ -130653,10 +130738,11 @@
130738 sqlite3HashInit(&pSchema->trigHash);
130739 sqlite3HashClear(&pSchema->idxHash);
130740 for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
130741 sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
130742 }
130743
130744 sqlite3HashClear(&temp2);
130745 sqlite3HashInit(&pSchema->tblHash);
130746 for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
130747 Table *pTab = sqliteHashData(pElem);
130748 sqlite3DeleteTable(&xdb, pTab);
@@ -140610,11 +140696,13 @@
140696 /* Version 3.50.0 and later */
140697 int (*setlk_timeout)(sqlite3*,int,int);
140698 /* Version 3.51.0 and later */
140699 int (*set_errmsg)(sqlite3*,int,const char*);
140700 int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
140701 /* Version 3.52.0 and later */
140702 void (*str_truncate)(sqlite3_str*,int);
140703 void (*str_free)(sqlite3_str*);
140704 };
140705
140706 /*
140707 ** This is the function signature used for all extension entry points. It
140708 ** is also defined in the file "loadext.c".
@@ -140949,10 +141037,13 @@
141037 /* Version 3.50.0 and later */
141038 #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
141039 /* Version 3.51.0 and later */
141040 #define sqlite3_set_errmsg sqlite3_api->set_errmsg
141041 #define sqlite3_db_status64 sqlite3_api->db_status64
141042 /* Version 3.52.0 and later */
141043 #define sqlite3_str_truncate sqlite3_api->str_truncate
141044 #define sqlite3_str_free sqlite3_api->str_free
141045 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
141046
141047 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
141048 /* This case when the file really is being compiled as a loadable
141049 ** extension */
@@ -141475,11 +141566,14 @@
141566 sqlite3_set_clientdata,
141567 /* Version 3.50.0 and later */
141568 sqlite3_setlk_timeout,
141569 /* Version 3.51.0 and later */
141570 sqlite3_set_errmsg,
141571 sqlite3_db_status64,
141572 /* Version 3.52.0 and later */
141573 sqlite3_str_truncate,
141574 sqlite3_str_free
141575 };
141576
141577 /* True if x is the directory separator character
141578 */
141579 #if SQLITE_OS_WIN
@@ -160974,13 +161068,16 @@
161068 pTab->iPKey = -1;
161069 pTab->tabFlags |= TF_Eponymous;
161070 addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
161071 addModuleArgument(pParse, pTab, 0);
161072 addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
161073 db->nSchemaLock++;
161074 rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
161075 db->nSchemaLock--;
161076 if( rc ){
161077 sqlite3ErrorMsg(pParse, "%s", zErr);
161078 pParse->rc = rc;
161079 sqlite3DbFree(db, zErr);
161080 sqlite3VtabEponymousTableClear(db, pMod);
161081 }
161082 return 1;
161083 }
@@ -174038,12 +174135,26 @@
174135 VdbeCoverageIf(v, op==OP_SeekLT);
174136 VdbeCoverageIf(v, op==OP_SeekGT);
174137 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
174138 }
174139 #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
174140 if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174141 /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174142 ** loop(s) will be the inner-most loops of the join. There might be
174143 ** multiple EXISTS loops, but they will all be nested, and the join
174144 ** order will not have been changed by the query planner. If the
174145 ** inner-most EXISTS loop sees a single successful row, it should
174146 ** break out of *all* EXISTS loops. But only the inner-most of the
174147 ** nested EXISTS loops should do this breakout. */
174148 int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174149 while( nOuter<i ){
174150 if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174151 nOuter++;
174152 }
174153 testcase( nOuter>0 );
174154 sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174155 VdbeComment((v, "EXISTS break"));
174156 }
174157 /* The common case: Advance to the next row */
174158 if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174159 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
174160 sqlite3VdbeChangeP5(v, pLevel->p5);
@@ -177626,12 +177737,27 @@
177737
177738 /* Memory allocator for parser stack resizing. This is a thin wrapper around
177739 ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
177740 ** testing.
177741 */
177742 static void *parserStackRealloc(
177743 void *pOld, /* Prior allocation */
177744 sqlite3_uint64 newSize, /* Requested new alloation size */
177745 Parse *pParse /* Parsing context */
177746 ){
177747 void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
177748 if( p==0 ) sqlite3OomFault(pParse->db);
177749 return p;
177750 }
177751 static void parserStackFree(void *pOld, Parse *pParse){
177752 (void)pParse;
177753 sqlite3_free(pOld);
177754 }
177755
177756 /* Return an integer that is the maximum allowed stack size */
177757 static int parserStackSizeLimit(Parse *pParse){
177758 return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH];
177759 }
177760
177761
177762 /* Construct a new Expr object from a single token */
177763 static Expr *tokenExpr(Parse *pParse, int op, Token t){
@@ -177984,25 +178110,34 @@
178110 SrcList* yy563;
178111 Expr* yy590;
178112 Select* yy637;
178113 } YYMINORTYPE;
178114 #ifndef YYSTACKDEPTH
178115 #define YYSTACKDEPTH 50
178116 #endif
178117 #define sqlite3ParserARG_SDECL
178118 #define sqlite3ParserARG_PDECL
178119 #define sqlite3ParserARG_PARAM
178120 #define sqlite3ParserARG_FETCH
178121 #define sqlite3ParserARG_STORE
178122 #undef YYREALLOC
178123 #define YYREALLOC parserStackRealloc
178124 #undef YYFREE
178125 #define YYFREE parserStackFree
178126 #undef YYDYNSTACK
178127 #define YYDYNSTACK 1
178128 #undef YYSIZELIMIT
178129 #define YYSIZELIMIT parserStackSizeLimit
178130 #define sqlite3ParserCTX(P) ((P)->pParse)
178131 #define sqlite3ParserCTX_SDECL Parse *pParse;
178132 #define sqlite3ParserCTX_PDECL ,Parse *pParse
178133 #define sqlite3ParserCTX_PARAM ,pParse
178134 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
178135 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
178136 #undef YYERRORSYMBOL
178137 #undef YYERRSYMDT
178138 #undef YYFALLBACK
178139 #define YYFALLBACK 1
178140 #define YYNSTATE 583
178141 #define YYNRULE 409
178142 #define YYNRULE_WITH_ACTION 344
178143 #define YYNTOKEN 187
@@ -179775,19 +179910,28 @@
179910 static int yyGrowStack(yyParser *p){
179911 int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
179912 int newSize;
179913 int idx;
179914 yyStackEntry *pNew;
179915 #ifdef YYSIZELIMIT
179916 int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p));
179917 #endif
179918
179919 newSize = oldSize*2 + 100;
179920 #ifdef YYSIZELIMIT
179921 if( newSize>nLimit ){
179922 newSize = nLimit;
179923 if( newSize<=oldSize ) return 1;
179924 }
179925 #endif
179926 idx = (int)(p->yytos - p->yystack);
179927 if( p->yystack==p->yystk0 ){
179928 pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
179929 if( pNew==0 ) return 1;
179930 memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
179931 }else{
179932 pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
179933 if( pNew==0 ) return 1;
179934 }
179935 p->yystack = pNew;
179936 p->yytos = &p->yystack[idx];
179937 #ifndef NDEBUG
@@ -180028,11 +180172,13 @@
180172 }
180173 yytos--;
180174 }
180175
180176 #if YYGROWABLESTACK
180177 if( pParser->yystack!=pParser->yystk0 ){
180178 YYFREE(pParser->yystack, sqlite3ParserCTX(pParser));
180179 }
180180 #endif
180181 }
180182
180183 #ifndef sqlite3Parser_ENGINEALWAYSONSTACK
180184 /*
@@ -180211,11 +180357,11 @@
180357 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
180358 /* Here code is inserted which will execute if the parser
180359 ** stack every overflows */
180360 /******** Begin %stack_overflow code ******************************************/
180361
180362 if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit");
180363 /******** End %stack_overflow code ********************************************/
180364 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
180365 sqlite3ParserCTX_STORE
180366 }
180367
@@ -186223,10 +186369,11 @@
186369 }
186370 }
186371 /* Clear the TEMP schema separately and last */
186372 if( db->aDb[1].pSchema ){
186373 sqlite3SchemaClear(db->aDb[1].pSchema);
186374 assert( db->aDb[1].pSchema->trigHash.count==0 );
186375 }
186376 sqlite3VtabUnlockList(db);
186377
186378 /* Free up the array of auxiliary databases */
186379 sqlite3CollapseDatabaseArray(db);
@@ -187354,10 +187501,13 @@
187501 db->xWalCallback = xCallback;
187502 db->pWalArg = pArg;
187503 sqlite3_mutex_leave(db->mutex);
187504 return pRet;
187505 #else
187506 UNUSED_PARAMETER(db);
187507 UNUSED_PARAMETER(xCallback);
187508 UNUSED_PARAMETER(pArg);
187509 return 0;
187510 #endif
187511 }
187512
187513 /*
@@ -187369,10 +187519,15 @@
187519 int eMode, /* SQLITE_CHECKPOINT_* value */
187520 int *pnLog, /* OUT: Size of WAL log in frames */
187521 int *pnCkpt /* OUT: Total number of frames checkpointed */
187522 ){
187523 #ifdef SQLITE_OMIT_WAL
187524 UNUSED_PARAMETER(db);
187525 UNUSED_PARAMETER(zDb);
187526 UNUSED_PARAMETER(eMode);
187527 UNUSED_PARAMETER(pnLog);
187528 UNUSED_PARAMETER(pnCkpt);
187529 return SQLITE_OK;
187530 #else
187531 int rc; /* Return code */
187532 int iDb; /* Schema to checkpoint */
187533
@@ -187551,11 +187706,11 @@
187706 ** Session extension). Internal logic should invoke sqlite3Error() or
187707 ** sqlite3ErrorWithMsg() directly.
187708 */
187709 SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
187710 int rc = SQLITE_OK;
187711 if( !sqlite3SafetyCheckOk(db) ){
187712 return SQLITE_MISUSE_BKPT;
187713 }
187714 sqlite3_mutex_enter(db->mutex);
187715 if( zMsg ){
187716 sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
@@ -187750,10 +187905,11 @@
187905 SQLITE_MAX_ATTACHED,
187906 SQLITE_MAX_LIKE_PATTERN_LENGTH,
187907 SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
187908 SQLITE_MAX_TRIGGER_DEPTH,
187909 SQLITE_MAX_WORKER_THREADS,
187910 SQLITE_MAX_PARSER_DEPTH,
187911 };
187912
187913 /*
187914 ** Make sure the hard limits are set to reasonable values
187915 */
@@ -187819,20 +187975,21 @@
187975 */
187976 assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
187977 assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
187978 assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
187979 assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
187980 assert( aHardLimit[SQLITE_LIMIT_PARSER_DEPTH]==SQLITE_MAX_PARSER_DEPTH );
187981 assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
187982 assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
187983 assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
187984 assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
187985 assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
187986 SQLITE_MAX_LIKE_PATTERN_LENGTH );
187987 assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
187988 assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
187989 assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
187990 assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) );
187991
187992
187993 if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
187994 return -1;
187995 }
@@ -189731,10 +189888,11 @@
189888 }
189889 return zFilename + 1;
189890 }
189891 SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
189892 #ifdef SQLITE_OMIT_WAL
189893 UNUSED_PARAMETER(zFilename);
189894 return 0;
189895 #else
189896 zFilename = sqlite3_filename_journal(zFilename);
189897 if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
189898 return zFilename;
@@ -239557,18 +239715,26 @@
239715 #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
239716 #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
239717 #define sqlite3Fts5ParserARG_PARAM ,pParse
239718 #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
239719 #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
239720 #undef fts5YYREALLOC
239721 #define fts5YYREALLOC realloc
239722 #undef fts5YYFREE
239723 #define fts5YYFREE free
239724 #undef fts5YYDYNSTACK
239725 #define fts5YYDYNSTACK 0
239726 #undef fts5YYSIZELIMIT
239727 #define sqlite3Fts5ParserCTX(P) 0
239728 #define sqlite3Fts5ParserCTX_SDECL
239729 #define sqlite3Fts5ParserCTX_PDECL
239730 #define sqlite3Fts5ParserCTX_PARAM
239731 #define sqlite3Fts5ParserCTX_FETCH
239732 #define sqlite3Fts5ParserCTX_STORE
239733 #undef fts5YYERRORSYMBOL
239734 #undef fts5YYERRSYMDT
239735 #undef fts5YYFALLBACK
239736 #define fts5YYNSTATE 35
239737 #define fts5YYNRULE 28
239738 #define fts5YYNRULE_WITH_ACTION 28
239739 #define fts5YYNFTS5TOKEN 16
239740 #define fts5YY_MAX_SHIFT 34
@@ -239889,19 +240055,28 @@
240055 static int fts5yyGrowStack(fts5yyParser *p){
240056 int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
240057 int newSize;
240058 int idx;
240059 fts5yyStackEntry *pNew;
240060 #ifdef fts5YYSIZELIMIT
240061 int nLimit = fts5YYSIZELIMIT(sqlite3Fts5ParserCTX(p));
240062 #endif
240063
240064 newSize = oldSize*2 + 100;
240065 #ifdef fts5YYSIZELIMIT
240066 if( newSize>nLimit ){
240067 newSize = nLimit;
240068 if( newSize<=oldSize ) return 1;
240069 }
240070 #endif
240071 idx = (int)(p->fts5yytos - p->fts5yystack);
240072 if( p->fts5yystack==p->fts5yystk0 ){
240073 pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
240074 if( pNew==0 ) return 1;
240075 memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0]));
240076 }else{
240077 pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
240078 if( pNew==0 ) return 1;
240079 }
240080 p->fts5yystack = pNew;
240081 p->fts5yytos = &p->fts5yystack[idx];
240082 #ifndef NDEBUG
@@ -240077,11 +240252,13 @@
240252 }
240253 fts5yytos--;
240254 }
240255
240256 #if fts5YYGROWABLESTACK
240257 if( pParser->fts5yystack!=pParser->fts5yystk0 ){
240258 fts5YYFREE(pParser->fts5yystack, sqlite3Fts5ParserCTX(pParser));
240259 }
240260 #endif
240261 }
240262
240263 #ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
240264 /*
@@ -260281,11 +260458,11 @@
260458 int nArg, /* Number of args */
260459 sqlite3_value **apUnused /* Function arguments */
260460 ){
260461 assert( nArg==0 );
260462 UNUSED_PARAM2(nArg, apUnused);
260463 sqlite3_result_text(pCtx, "fts5: 2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa", -1, SQLITE_TRANSIENT);
260464 }
260465
260466 /*
260467 ** Implementation of fts5_locale(LOCALE, TEXT) function.
260468 **
260469
+36 -17
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,16 +144,16 @@
144144
**
145145
** See also: [sqlite3_libversion()],
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149
-#define SQLITE_VERSION "3.51.0"
150
-#define SQLITE_VERSION_NUMBER 3051000
151
-#define SQLITE_SOURCE_ID "2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8"
149
+#define SQLITE_VERSION "3.52.0"
150
+#define SQLITE_VERSION_NUMBER 3052000
151
+#define SQLITE_SOURCE_ID "2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2025-10-31T16:07:31.438Z"
154
+#define SQLITE_SCM_DATETIME "2025-11-18T17:49:48.189Z"
155155
156156
/*
157157
** CAPI3REF: Run-Time Library Version Numbers
158158
** KEYWORDS: sqlite3_version sqlite3_sourceid
159159
**
@@ -2565,16 +2565,19 @@
25652565
** </dd>
25662566
**
25672567
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
25682568
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
25692569
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2570
-** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
2571
-** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
2572
-** statistics. For statistics to be collected, the flag must be set on
2573
-** the database handle both when the SQL statement is prepared and when it
2574
-** is stepped. The flag is set (collection of statistics is enabled)
2575
-** by default. <p>This option takes two arguments: an integer and a pointer to
2570
+** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
2571
+** a flag that enables collection of run-time performance statistics
2572
+** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
2573
+** columns of the [bytecode virtual table].
2574
+** For statistics to be collected, the flag must be set on
2575
+** the database handle both when the SQL statement is
2576
+** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
2577
+** The flag is set (collection of statistics is enabled) by default.
2578
+** <p>This option takes two arguments: an integer and a pointer to
25762579
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
25772580
** leave unchanged the statement scanstatus option. If the second argument
25782581
** is not NULL, then the value of the statement scanstatus setting after
25792582
** processing the first argument is written into the integer that the second
25802583
** argument points to.
@@ -4215,11 +4218,11 @@
42154218
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
42164219
SQLITE_API const char *sqlite3_errstr(int);
42174220
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
42184221
42194222
/*
4220
-** CAPI3REF: Set Error Codes And Message
4223
+** CAPI3REF: Set Error Code And Message
42214224
** METHOD: sqlite3
42224225
**
42234226
** Set the error code of the database handle passed as the first argument
42244227
** to errcode, and the error message to a copy of nul-terminated string
42254228
** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4333,10 +4336,14 @@
43334336
** result set of a [SELECT] or the maximum number of columns in an index
43344337
** or in an ORDER BY or GROUP BY clause.</dd>)^
43354338
**
43364339
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
43374340
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
4341
+**
4342
+** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
4343
+** <dd>The maximum depth of the LALR(1) parser stack used to analyze
4344
+** input SQL statements.</dd>)^
43384345
**
43394346
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
43404347
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
43414348
**
43424349
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4378,10 +4385,11 @@
43784385
#define SQLITE_LIMIT_ATTACHED 7
43794386
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
43804387
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
43814388
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
43824389
#define SQLITE_LIMIT_WORKER_THREADS 11
4390
+#define SQLITE_LIMIT_PARSER_DEPTH 12
43834391
43844392
/*
43854393
** CAPI3REF: Prepare Flags
43864394
**
43874395
** These constants define various flags that can be passed into the
@@ -8722,19 +8730,24 @@
87228730
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
87238731
** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
87248732
** errors were encountered during construction of the string. ^The
87258733
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
87268734
** string in [sqlite3_str] object X is zero bytes long.
8735
+**
8736
+** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
8737
+** X and the string content it contains. Calling sqlite3_str_free(X) is
8738
+** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
87278739
*/
87288740
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
8741
+SQLITE_API void sqlite3_str_free(sqlite3_str*);
87298742
87308743
/*
87318744
** CAPI3REF: Add Content To A Dynamic String
87328745
** METHOD: sqlite3_str
87338746
**
8734
-** These interfaces add content to an sqlite3_str object previously obtained
8735
-** from [sqlite3_str_new()].
8747
+** These interfaces add or remove content to an sqlite3_str object
8748
+** previously obtained from [sqlite3_str_new()].
87368749
**
87378750
** ^The [sqlite3_str_appendf(X,F,...)] and
87388751
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
87398752
** functionality of SQLite to append formatted text onto the end of
87408753
** [sqlite3_str] object X.
@@ -8752,10 +8765,14 @@
87528765
** single-byte character C onto the end of [sqlite3_str] object X.
87538766
** ^This method can be used, for example, to add whitespace indentation.
87548767
**
87558768
** ^The [sqlite3_str_reset(X)] method resets the string under construction
87568769
** inside [sqlite3_str] object X back to zero bytes in length.
8770
+**
8771
+** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
8772
+** under construction to be N bytes are less. This routine is a no-op if
8773
+** N is negative or if the string is already N bytes or smaller in size.
87578774
**
87588775
** These methods do not return a result code. ^If an error occurs, that fact
87598776
** is recorded in the [sqlite3_str] object and can be recovered by a
87608777
** subsequent call to [sqlite3_str_errcode(X)].
87618778
*/
@@ -8763,10 +8780,11 @@
87638780
SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
87648781
SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
87658782
SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
87668783
SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
87678784
SQLITE_API void sqlite3_str_reset(sqlite3_str*);
8785
+SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
87688786
87698787
/*
87708788
** CAPI3REF: Status Of A Dynamic String
87718789
** METHOD: sqlite3_str
87728790
**
@@ -10424,11 +10442,11 @@
1042410442
** &nbsp; rc==SQLITE_OK && pVal;
1042510443
** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
1042610444
** &nbsp; ){
1042710445
** &nbsp; // do something with pVal
1042810446
** &nbsp; }
10429
-** &nbsp; if( rc!=SQLITE_OK ){
10447
+** &nbsp; if( rc!=SQLITE_DONE ){
1043010448
** &nbsp; // an error has occurred
1043110449
** &nbsp; }
1043210450
** </pre></blockquote>)^
1043310451
**
1043410452
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10596,13 +10614,13 @@
1059610614
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
1059710615
** of this interface is undefined. ^The requested measurement is written into
1059810616
** a variable pointed to by the "pOut" parameter.
1059910617
**
1060010618
** The "flags" parameter must be passed a mask of flags. At present only
10601
-** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
10619
+** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
1060210620
** is specified, then status information is available for all elements
10603
-** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
10621
+** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
1060410622
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
1060510623
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
1060610624
** the EXPLAIN QUERY PLAN output) are available. Invoking API
1060710625
** sqlite3_stmt_scanstatus() is equivalent to calling
1060810626
** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10612,11 +10630,12 @@
1061210630
** retrieve statistics for the entire query. ^If idx is out of range
1061310631
** - less than -1 or greater than or equal to the total number of query
1061410632
** elements used to implement the statement - a non-zero value is returned and
1061510633
** the variable that pOut points to is unchanged.
1061610634
**
10617
-** See also: [sqlite3_stmt_scanstatus_reset()]
10635
+** See also: [sqlite3_stmt_scanstatus_reset()] and the
10636
+** [nexec and ncycle] columnes of the [bytecode virtual table].
1061810637
*/
1061910638
SQLITE_API int sqlite3_stmt_scanstatus(
1062010639
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
1062110640
int idx, /* Index of loop to report on */
1062210641
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
1062310642
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,16 +144,16 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-10-31 16:07:31 38c993c8b7137d6d5623d387292639634297c17da11befec9029f12a16a472f8"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-10-31T16:07:31.438Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
@@ -2565,16 +2565,19 @@
2565 ** </dd>
2566 **
2567 ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
2568 ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
2569 ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2570 ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
2571 ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
2572 ** statistics. For statistics to be collected, the flag must be set on
2573 ** the database handle both when the SQL statement is prepared and when it
2574 ** is stepped. The flag is set (collection of statistics is enabled)
2575 ** by default. <p>This option takes two arguments: an integer and a pointer to
 
 
 
2576 ** an integer. The first argument is 1, 0, or -1 to enable, disable, or
2577 ** leave unchanged the statement scanstatus option. If the second argument
2578 ** is not NULL, then the value of the statement scanstatus setting after
2579 ** processing the first argument is written into the integer that the second
2580 ** argument points to.
@@ -4215,11 +4218,11 @@
4215 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4216 SQLITE_API const char *sqlite3_errstr(int);
4217 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4218
4219 /*
4220 ** CAPI3REF: Set Error Codes And Message
4221 ** METHOD: sqlite3
4222 **
4223 ** Set the error code of the database handle passed as the first argument
4224 ** to errcode, and the error message to a copy of nul-terminated string
4225 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4333,10 +4336,14 @@
4333 ** result set of a [SELECT] or the maximum number of columns in an index
4334 ** or in an ORDER BY or GROUP BY clause.</dd>)^
4335 **
4336 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
4337 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
 
 
 
 
4338 **
4339 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
4340 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
4341 **
4342 ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4378,10 +4385,11 @@
4378 #define SQLITE_LIMIT_ATTACHED 7
4379 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
4380 #define SQLITE_LIMIT_VARIABLE_NUMBER 9
4381 #define SQLITE_LIMIT_TRIGGER_DEPTH 10
4382 #define SQLITE_LIMIT_WORKER_THREADS 11
 
4383
4384 /*
4385 ** CAPI3REF: Prepare Flags
4386 **
4387 ** These constants define various flags that can be passed into the
@@ -8722,19 +8730,24 @@
8722 ** pass the returned value to [sqlite3_free()] to avoid a memory leak.
8723 ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
8724 ** errors were encountered during construction of the string. ^The
8725 ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
8726 ** string in [sqlite3_str] object X is zero bytes long.
 
 
 
 
8727 */
8728 SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
 
8729
8730 /*
8731 ** CAPI3REF: Add Content To A Dynamic String
8732 ** METHOD: sqlite3_str
8733 **
8734 ** These interfaces add content to an sqlite3_str object previously obtained
8735 ** from [sqlite3_str_new()].
8736 **
8737 ** ^The [sqlite3_str_appendf(X,F,...)] and
8738 ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
8739 ** functionality of SQLite to append formatted text onto the end of
8740 ** [sqlite3_str] object X.
@@ -8752,10 +8765,14 @@
8752 ** single-byte character C onto the end of [sqlite3_str] object X.
8753 ** ^This method can be used, for example, to add whitespace indentation.
8754 **
8755 ** ^The [sqlite3_str_reset(X)] method resets the string under construction
8756 ** inside [sqlite3_str] object X back to zero bytes in length.
 
 
 
 
8757 **
8758 ** These methods do not return a result code. ^If an error occurs, that fact
8759 ** is recorded in the [sqlite3_str] object and can be recovered by a
8760 ** subsequent call to [sqlite3_str_errcode(X)].
8761 */
@@ -8763,10 +8780,11 @@
8763 SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
8764 SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
8765 SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
8766 SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
8767 SQLITE_API void sqlite3_str_reset(sqlite3_str*);
 
8768
8769 /*
8770 ** CAPI3REF: Status Of A Dynamic String
8771 ** METHOD: sqlite3_str
8772 **
@@ -10424,11 +10442,11 @@
10424 ** &nbsp; rc==SQLITE_OK && pVal;
10425 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10426 ** &nbsp; ){
10427 ** &nbsp; // do something with pVal
10428 ** &nbsp; }
10429 ** &nbsp; if( rc!=SQLITE_OK ){
10430 ** &nbsp; // an error has occurred
10431 ** &nbsp; }
10432 ** </pre></blockquote>)^
10433 **
10434 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10596,13 +10614,13 @@
10596 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
10597 ** of this interface is undefined. ^The requested measurement is written into
10598 ** a variable pointed to by the "pOut" parameter.
10599 **
10600 ** The "flags" parameter must be passed a mask of flags. At present only
10601 ** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
10602 ** is specified, then status information is available for all elements
10603 ** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
10604 ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
10605 ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
10606 ** the EXPLAIN QUERY PLAN output) are available. Invoking API
10607 ** sqlite3_stmt_scanstatus() is equivalent to calling
10608 ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10612,11 +10630,12 @@
10612 ** retrieve statistics for the entire query. ^If idx is out of range
10613 ** - less than -1 or greater than or equal to the total number of query
10614 ** elements used to implement the statement - a non-zero value is returned and
10615 ** the variable that pOut points to is unchanged.
10616 **
10617 ** See also: [sqlite3_stmt_scanstatus_reset()]
 
10618 */
10619 SQLITE_API int sqlite3_stmt_scanstatus(
10620 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
10621 int idx, /* Index of loop to report on */
10622 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
10623
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,16 +144,16 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.52.0"
150 #define SQLITE_VERSION_NUMBER 3052000
151 #define SQLITE_SOURCE_ID "2025-11-18 17:49:48 7e460ffa5aae884807db9e7c8214d6d822d5d38ea406fe3b3eac04ac16f158fa"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-11-18T17:49:48.189Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
@@ -2565,16 +2565,19 @@
2565 ** </dd>
2566 **
2567 ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
2568 ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
2569 ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
2570 ** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
2571 ** a flag that enables collection of run-time performance statistics
2572 ** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
2573 ** columns of the [bytecode virtual table].
2574 ** For statistics to be collected, the flag must be set on
2575 ** the database handle both when the SQL statement is
2576 ** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
2577 ** The flag is set (collection of statistics is enabled) by default.
2578 ** <p>This option takes two arguments: an integer and a pointer to
2579 ** an integer. The first argument is 1, 0, or -1 to enable, disable, or
2580 ** leave unchanged the statement scanstatus option. If the second argument
2581 ** is not NULL, then the value of the statement scanstatus setting after
2582 ** processing the first argument is written into the integer that the second
2583 ** argument points to.
@@ -4215,11 +4218,11 @@
4218 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4219 SQLITE_API const char *sqlite3_errstr(int);
4220 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4221
4222 /*
4223 ** CAPI3REF: Set Error Code And Message
4224 ** METHOD: sqlite3
4225 **
4226 ** Set the error code of the database handle passed as the first argument
4227 ** to errcode, and the error message to a copy of nul-terminated string
4228 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
@@ -4333,10 +4336,14 @@
4336 ** result set of a [SELECT] or the maximum number of columns in an index
4337 ** or in an ORDER BY or GROUP BY clause.</dd>)^
4338 **
4339 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
4340 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
4341 **
4342 ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
4343 ** <dd>The maximum depth of the LALR(1) parser stack used to analyze
4344 ** input SQL statements.</dd>)^
4345 **
4346 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
4347 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
4348 **
4349 ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
@@ -4378,10 +4385,11 @@
4385 #define SQLITE_LIMIT_ATTACHED 7
4386 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
4387 #define SQLITE_LIMIT_VARIABLE_NUMBER 9
4388 #define SQLITE_LIMIT_TRIGGER_DEPTH 10
4389 #define SQLITE_LIMIT_WORKER_THREADS 11
4390 #define SQLITE_LIMIT_PARSER_DEPTH 12
4391
4392 /*
4393 ** CAPI3REF: Prepare Flags
4394 **
4395 ** These constants define various flags that can be passed into the
@@ -8722,19 +8730,24 @@
8730 ** pass the returned value to [sqlite3_free()] to avoid a memory leak.
8731 ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
8732 ** errors were encountered during construction of the string. ^The
8733 ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
8734 ** string in [sqlite3_str] object X is zero bytes long.
8735 **
8736 ** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
8737 ** X and the string content it contains. Calling sqlite3_str_free(X) is
8738 ** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
8739 */
8740 SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
8741 SQLITE_API void sqlite3_str_free(sqlite3_str*);
8742
8743 /*
8744 ** CAPI3REF: Add Content To A Dynamic String
8745 ** METHOD: sqlite3_str
8746 **
8747 ** These interfaces add or remove content to an sqlite3_str object
8748 ** previously obtained from [sqlite3_str_new()].
8749 **
8750 ** ^The [sqlite3_str_appendf(X,F,...)] and
8751 ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
8752 ** functionality of SQLite to append formatted text onto the end of
8753 ** [sqlite3_str] object X.
@@ -8752,10 +8765,14 @@
8765 ** single-byte character C onto the end of [sqlite3_str] object X.
8766 ** ^This method can be used, for example, to add whitespace indentation.
8767 **
8768 ** ^The [sqlite3_str_reset(X)] method resets the string under construction
8769 ** inside [sqlite3_str] object X back to zero bytes in length.
8770 **
8771 ** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
8772 ** under construction to be N bytes are less. This routine is a no-op if
8773 ** N is negative or if the string is already N bytes or smaller in size.
8774 **
8775 ** These methods do not return a result code. ^If an error occurs, that fact
8776 ** is recorded in the [sqlite3_str] object and can be recovered by a
8777 ** subsequent call to [sqlite3_str_errcode(X)].
8778 */
@@ -8763,10 +8780,11 @@
8780 SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
8781 SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
8782 SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
8783 SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
8784 SQLITE_API void sqlite3_str_reset(sqlite3_str*);
8785 SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
8786
8787 /*
8788 ** CAPI3REF: Status Of A Dynamic String
8789 ** METHOD: sqlite3_str
8790 **
@@ -10424,11 +10442,11 @@
10442 ** &nbsp; rc==SQLITE_OK && pVal;
10443 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10444 ** &nbsp; ){
10445 ** &nbsp; // do something with pVal
10446 ** &nbsp; }
10447 ** &nbsp; if( rc!=SQLITE_DONE ){
10448 ** &nbsp; // an error has occurred
10449 ** &nbsp; }
10450 ** </pre></blockquote>)^
10451 **
10452 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
@@ -10596,13 +10614,13 @@
10614 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
10615 ** of this interface is undefined. ^The requested measurement is written into
10616 ** a variable pointed to by the "pOut" parameter.
10617 **
10618 ** The "flags" parameter must be passed a mask of flags. At present only
10619 ** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
10620 ** is specified, then status information is available for all elements
10621 ** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
10622 ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
10623 ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
10624 ** the EXPLAIN QUERY PLAN output) are available. Invoking API
10625 ** sqlite3_stmt_scanstatus() is equivalent to calling
10626 ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
@@ -10612,11 +10630,12 @@
10630 ** retrieve statistics for the entire query. ^If idx is out of range
10631 ** - less than -1 or greater than or equal to the total number of query
10632 ** elements used to implement the statement - a non-zero value is returned and
10633 ** the variable that pOut points to is unchanged.
10634 **
10635 ** See also: [sqlite3_stmt_scanstatus_reset()] and the
10636 ** [nexec and ncycle] columnes of the [bytecode virtual table].
10637 */
10638 SQLITE_API int sqlite3_stmt_scanstatus(
10639 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
10640 int idx, /* Index of loop to report on */
10641 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
10642
+1 -1
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -421,10 +421,10 @@
421421
#ifndef _WIN32
422422
linenoiseSetMultiLine(1);
423423
#endif
424424
atexit(sqlcmd_atexit);
425425
g.zConfigDbName = zConfigDb;
426
- g.argv[1] = "-quote";
426
+ g.argv[1] = "--noinit";
427427
sqlite3_shell(g.argc, g.argv);
428428
sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
429429
fossil_close(0, noRepository);
430430
}
431431
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -421,10 +421,10 @@
421 #ifndef _WIN32
422 linenoiseSetMultiLine(1);
423 #endif
424 atexit(sqlcmd_atexit);
425 g.zConfigDbName = zConfigDb;
426 g.argv[1] = "-quote";
427 sqlite3_shell(g.argc, g.argv);
428 sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
429 fossil_close(0, noRepository);
430 }
431
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -421,10 +421,10 @@
421 #ifndef _WIN32
422 linenoiseSetMultiLine(1);
423 #endif
424 atexit(sqlcmd_atexit);
425 g.zConfigDbName = zConfigDb;
426 g.argv[1] = "--noinit";
427 sqlite3_shell(g.argc, g.argv);
428 sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
429 fossil_close(0, noRepository);
430 }
431

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button