Fossil SCM

Update to the latest SQLite for testing. Reimplement "fossil sys ls" using the new split-column mode of QRF.

drh 2025-11-25 14:03 trunk
Commit 45de97fa3ecb1558270b965455a37dbe53e16389431035a85092324b9069b631
+142
--- a/extsrc/qrf.h
+++ b/extsrc/qrf.h
@@ -0,0 +1,142 @@
1
+/*
2
+** 2025-10-20
3
+**
4
+** The author disclaims copyright to this source code. In place of
5
+** a legal notice, here is a blessing:
6
+**
7
+** May you do good and not evil.
8
+** May you find forgiveness for yourself and forgive others.
9
+** May you share freely, never taking more than you give.
10
+**
11
+*************************************************************************
12
+** Header file for the Result-Format or "resfmt" utility library for SQLite.
13
+** See the resfmt.md documentation for additional information.
14
+*/
15
+#ifndef SQLITE_QRF_H
16
+#define SQLITE_QRF_H
17
+#ifdef __cplusplus
18
+extern "C" {
19
+#endif
20
+#include <stdlib.h>
21
+#include "sqlite3.h"
22
+
23
+/*
24
+** Specification used by clients to define the output format they want
25
+*/
26
+typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
27
+struct sqlite3_qrf_spec {
28
+ unsigned char iVersion; /* Version number of this structure */
29
+ unsigned char eStyle; /* Formatting style. "box", "csv", etc... */
30
+ unsigned char eEsc; /* How to escape control characters in text */
31
+ unsigned char eText; /* Quoting style for text */
32
+ unsigned char eTitle; /* Quating style for the text of column names */
33
+ unsigned char eBlob; wrap on word boundaries */
34
+ unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
35
+ unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
36
+ unsigned char eTitleAlign; /* Alignment for column headers */
37
+ unsigned char bSplitColumn; /* Wrap single-column output into many columns */
38
+ unsigned char bBorder; /* Show outer border in Box and Table styles */
39
+ short int nWrap; /* Wrap columns wider than erall table width */
40
+ short int nLineLimit; /* Maximum number of lines for any row */
41
+ short int nTitleLimit; /* Maximum number of characters in a title */
42
+ int nCharLimit; /*[] */
43
+ int nAlign; /* Number of entries in aAlignment[] */
44
+ short int *aWidth; /* Column widths */
45
+ unsigned char *aAlign; /* Column alignments */
46
+ char *zColumnSep; /* Alternative column separator */
47
+ char *zRowSep; /* Alternative row separator */
48
+ char *zTableName; /* Output table name */
49
+ char *zNull; /* Rendering of NULL */
50
+ char *(*xRender)(void*,sqlite3_value*); /* Render a value */
51
+ int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
52
+ void *pRenderArg; /* First argument to the xRender callback */
53
+ void *pWriteArg; /* First argument to the xWrite callback */
54
+ char **pzOutput; /* Storage location for output string */
55
+ /* Fields below are oner of characters in a title */
56
+ unsigned int nMultiInsert; /* Add rows to one INSERT until size exceeds */
57
+ int nCharLimit; /* Maximum number of characters in a cell */
58
+ int nWidth; /* Number of entries in aWidth[] */
59
+ int nAlign; /* Number of entries in aAlignment[] */
60
+ short int *aWidth; /* Column widths */
61
+ unsigned char *aAlign; /* Column alignments */
62
+ char *zColumnSep; /* Alternative column separator */
63
+ char *zRowSep; /* Alternative row separator */
64
+ char *zTableName; /* Output table name */
65
+ char *zNull; /* Rendering of NULL */
66
+ char *(*xRender)(void*,sqlite3_value*); /* Render a value */
67
+ int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
68
+ void *pRenderArg; /* First argument to the xRender callback */
69
+ void *pWriteArg; /* First argument to the xWrite callback */
70
+ char **pzOutput; /* Storage location for output string */
71
+ /* Additional fields may be added in the future */
72
+};
73
+
74
+/*
75
+** Interfaces
76
+*/
77
+int sqlite3_format_query_result(
78
+ sqlite3_stmt *pStmt, /* SQL statement to run */
79
+ const sqlite3_qrf_spec *pSpec, /* Result format specification */
80
+ char **pzErr /* OUT: Write error message here */
81
+);
82
+
83
+/*
84
+** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
85
+** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
86
+*/
87
+#define QRF_MAX_WIDTH 10000
88
+#define QRF_MIN_WIDTH 0
89
+
90
+/*
91
+** Output styles:
92
+*/
93
+#define QRF_STYLE_Auto 0 /* Choose a style automatically */
94
+#define QRF_STYLE_Box 1 /* Unicode box-drawing characters */
95
+#define QRF_STYLE_Column 2 /* One record per line in neat columns */
96
+#define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
97
+#define QRF_STYLE_Csv 4 /* Comma-separated-value */
98
+#define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
99
+#define QRF_STYLE_Explain 6 /* EXPLAIN output */
100
+#define QRF_STYLE_Html 7 /* Generate an XHTML table */
101
+#define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
102
+#define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
103
+#define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
104
+#define QRF_STYLE_Line 11 /* One column per line. */
105
+#define QRF_STYLE_List 12 /* One record per line with a separator */
106
+#define QRF_STYLE_Markdown 13 /* Mare QRF_STYLE_Off 14 /* No query output shown */
107
+#define QRF_STYLE_Quote 15 /* SQL-quoted, comma-separated */
108
+#define QRF_STYLE_Stats 16 /* EQP-like output but with performance stats */
109
+#define QRF_STYLE_StatsEst 17 /* EQP-like output with planner estimates */
110
+#define QRF_STYLE_StatsVm 18 /* EXPLAIN-like output with performance stats */
111
+#define QRF_STYLE_Table 19 /* MySQL-style table formatting */
112
+
113
+/*
114
+** Quoting styles for text.
115
+** Allowed values for sqlite3_qrf_spec.eText
116
+*/
117
+#define QRF_TEXT_Auto 0 /* Choose text encoding automatically */
118
+#define QRF_TEXT_Plain 1 /* Literal text */
119
+#define QRF_TEXT_Sql 2 /* Quote as an SQL literal */
120
+#define QRF_TEXT_Csv 3 /* CSV-style quoting */
121
+#define QRF_TEXT_Html 4 /* HTML-style quoting */
122
+#define QRF_TEXT_Tcl 5 /* C/Tcl quoting */
123
+#define QRF_TEXT_Json 6 /* JSON quoting */
124
+#define QRF_TEXT_Relaxed 7 /* Relaxed SQL quoting */
125
+
126
+/*
127
+** Quoting styles for BLOBs
128
+** Allowed values for sqlite3_qrf_spec.eBlob
129
+*/
130
+#define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eText */
131
+#define QRF_BLOB_Text 1 /* Display content exactly as it is */
132
+#define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
133
+#define QRF_BLOB_Hex 3 /* Hexadecimal representation isplayn */
134
+#define QRF_BLOB_Tcl 4 /* "\000" notation */
135
+#define QRF_BLOB_Json 5 /* A JSON string */
136
+#define QRF_BLOB_Size 6 /* Display the blob size only */
137
+
138
+/*
139
+** Control-character escape modes.
140
+** Allowed values for sqlite3_qrf_spec.eEsc
141
+*/
142
+#define QRF_ESC_Auto
--- a/extsrc/qrf.h
+++ b/extsrc/qrf.h
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/extsrc/qrf.h
+++ b/extsrc/qrf.h
@@ -0,0 +1,142 @@
1 /*
2 ** 2025-10-20
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 ** Header file for the Result-Format or "resfmt" utility library for SQLite.
13 ** See the resfmt.md documentation for additional information.
14 */
15 #ifndef SQLITE_QRF_H
16 #define SQLITE_QRF_H
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 #include <stdlib.h>
21 #include "sqlite3.h"
22
23 /*
24 ** Specification used by clients to define the output format they want
25 */
26 typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
27 struct sqlite3_qrf_spec {
28 unsigned char iVersion; /* Version number of this structure */
29 unsigned char eStyle; /* Formatting style. "box", "csv", etc... */
30 unsigned char eEsc; /* How to escape control characters in text */
31 unsigned char eText; /* Quoting style for text */
32 unsigned char eTitle; /* Quating style for the text of column names */
33 unsigned char eBlob; wrap on word boundaries */
34 unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
35 unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
36 unsigned char eTitleAlign; /* Alignment for column headers */
37 unsigned char bSplitColumn; /* Wrap single-column output into many columns */
38 unsigned char bBorder; /* Show outer border in Box and Table styles */
39 short int nWrap; /* Wrap columns wider than erall table width */
40 short int nLineLimit; /* Maximum number of lines for any row */
41 short int nTitleLimit; /* Maximum number of characters in a title */
42 int nCharLimit; /*[] */
43 int nAlign; /* Number of entries in aAlignment[] */
44 short int *aWidth; /* Column widths */
45 unsigned char *aAlign; /* Column alignments */
46 char *zColumnSep; /* Alternative column separator */
47 char *zRowSep; /* Alternative row separator */
48 char *zTableName; /* Output table name */
49 char *zNull; /* Rendering of NULL */
50 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
51 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
52 void *pRenderArg; /* First argument to the xRender callback */
53 void *pWriteArg; /* First argument to the xWrite callback */
54 char **pzOutput; /* Storage location for output string */
55 /* Fields below are oner of characters in a title */
56 unsigned int nMultiInsert; /* Add rows to one INSERT until size exceeds */
57 int nCharLimit; /* Maximum number of characters in a cell */
58 int nWidth; /* Number of entries in aWidth[] */
59 int nAlign; /* Number of entries in aAlignment[] */
60 short int *aWidth; /* Column widths */
61 unsigned char *aAlign; /* Column alignments */
62 char *zColumnSep; /* Alternative column separator */
63 char *zRowSep; /* Alternative row separator */
64 char *zTableName; /* Output table name */
65 char *zNull; /* Rendering of NULL */
66 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
67 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
68 void *pRenderArg; /* First argument to the xRender callback */
69 void *pWriteArg; /* First argument to the xWrite callback */
70 char **pzOutput; /* Storage location for output string */
71 /* Additional fields may be added in the future */
72 };
73
74 /*
75 ** Interfaces
76 */
77 int sqlite3_format_query_result(
78 sqlite3_stmt *pStmt, /* SQL statement to run */
79 const sqlite3_qrf_spec *pSpec, /* Result format specification */
80 char **pzErr /* OUT: Write error message here */
81 );
82
83 /*
84 ** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
85 ** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
86 */
87 #define QRF_MAX_WIDTH 10000
88 #define QRF_MIN_WIDTH 0
89
90 /*
91 ** Output styles:
92 */
93 #define QRF_STYLE_Auto 0 /* Choose a style automatically */
94 #define QRF_STYLE_Box 1 /* Unicode box-drawing characters */
95 #define QRF_STYLE_Column 2 /* One record per line in neat columns */
96 #define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
97 #define QRF_STYLE_Csv 4 /* Comma-separated-value */
98 #define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
99 #define QRF_STYLE_Explain 6 /* EXPLAIN output */
100 #define QRF_STYLE_Html 7 /* Generate an XHTML table */
101 #define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
102 #define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
103 #define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
104 #define QRF_STYLE_Line 11 /* One column per line. */
105 #define QRF_STYLE_List 12 /* One record per line with a separator */
106 #define QRF_STYLE_Markdown 13 /* Mare QRF_STYLE_Off 14 /* No query output shown */
107 #define QRF_STYLE_Quote 15 /* SQL-quoted, comma-separated */
108 #define QRF_STYLE_Stats 16 /* EQP-like output but with performance stats */
109 #define QRF_STYLE_StatsEst 17 /* EQP-like output with planner estimates */
110 #define QRF_STYLE_StatsVm 18 /* EXPLAIN-like output with performance stats */
111 #define QRF_STYLE_Table 19 /* MySQL-style table formatting */
112
113 /*
114 ** Quoting styles for text.
115 ** Allowed values for sqlite3_qrf_spec.eText
116 */
117 #define QRF_TEXT_Auto 0 /* Choose text encoding automatically */
118 #define QRF_TEXT_Plain 1 /* Literal text */
119 #define QRF_TEXT_Sql 2 /* Quote as an SQL literal */
120 #define QRF_TEXT_Csv 3 /* CSV-style quoting */
121 #define QRF_TEXT_Html 4 /* HTML-style quoting */
122 #define QRF_TEXT_Tcl 5 /* C/Tcl quoting */
123 #define QRF_TEXT_Json 6 /* JSON quoting */
124 #define QRF_TEXT_Relaxed 7 /* Relaxed SQL quoting */
125
126 /*
127 ** Quoting styles for BLOBs
128 ** Allowed values for sqlite3_qrf_spec.eBlob
129 */
130 #define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eText */
131 #define QRF_BLOB_Text 1 /* Display content exactly as it is */
132 #define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
133 #define QRF_BLOB_Hex 3 /* Hexadecimal representation isplayn */
134 #define QRF_BLOB_Tcl 4 /* "\000" notation */
135 #define QRF_BLOB_Json 5 /* A JSON string */
136 #define QRF_BLOB_Size 6 /* Display the blob size only */
137
138 /*
139 ** Control-character escape modes.
140 ** Allowed values for sqlite3_qrf_spec.eEsc
141 */
142 #define QRF_ESC_Auto
+137 -76
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -701,11 +701,10 @@
701701
unsigned char eTitle; /* Quating style for the text of column names */
702702
unsigned char eBlob; /* Quoting style for BLOBs */
703703
unsigned char bTitles; /* True to show column names */
704704
unsigned char bWordWrap; /* Try to wrap on word boundaries */
705705
unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
706
- unsigned char bTextNull; /* Apply eText encoding to zNull[] */
707706
unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
708707
unsigned char eTitleAlign; /* Alignment for column headers */
709708
unsigned char bSplitColumn; /* Wrap single-column output into many columns */
710709
short int nWrap; /* Wrap columns wider than this */
711710
short int nScreenWidth; /* Maximum overall table width */
@@ -787,10 +786,11 @@
787786
#define QRF_BLOB_Text 1 /* Display content exactly as it is */
788787
#define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
789788
#define QRF_BLOB_Hex 3 /* Hexadecimal representation */
790789
#define QRF_BLOB_Tcl 4 /* "\000" notation */
791790
#define QRF_BLOB_Json 5 /* A JSON string */
791
+#define QRF_BLOB_Size 6 /* Display the blob size only */
792792
793793
/*
794794
** Control-character escape modes.
795795
** Allowed values for sqlite3_qrf_spec.eEsc
796796
*/
@@ -1841,24 +1841,25 @@
18411841
zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf];
18421842
zVal[j+5] = "0123456789abcdef"[(c)&0xf];
18431843
}
18441844
}
18451845
break;
1846
+ }
1847
+ case QRF_BLOB_Size: {
1848
+ int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1849
+ sqlite3_str_appendf(pOut, "(%d-byte blob)", nBlob);
1850
+ break;
18461851
}
18471852
default: {
18481853
const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
18491854
qrfEncodeText(p, pOut, zTxt);
18501855
}
18511856
}
18521857
break;
18531858
}
18541859
case SQLITE_NULL: {
1855
- if( p->spec.bTextNull==QRF_Yes ){
1856
- qrfEncodeText(p, pOut, p->spec.zNull);
1857
- }else{
1858
- sqlite3_str_appendall(pOut, p->spec.zNull);
1859
- }
1860
+ sqlite3_str_appendall(pOut, p->spec.zNull);
18601861
break;
18611862
}
18621863
case SQLITE_TEXT: {
18631864
const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
18641865
qrfEncodeText(p, pOut, zTxt);
@@ -2690,21 +2691,23 @@
26902691
colSep = "|";
26912692
rowSep = "|\n";
26922693
}
26932694
qrfRowSeparator(p->pOut, &data, '+');
26942695
break;
2695
- case QRF_STYLE_Column:
2696
+ case QRF_STYLE_Column: {
2697
+ static const char zSpace[] = " ";
26962698
rowStart = "";
26972699
if( data.nMargin<2 ){
26982700
colSep = " ";
26992701
}else if( data.nMargin<=5 ){
2700
- colSep = " " + (5-data.nMargin);
2702
+ colSep = &zSpace[5-data.nMargin];
27012703
}else{
2702
- colSep = " ";
2704
+ colSep = zSpace;
27032705
}
27042706
rowSep = "\n";
27052707
break;
2708
+ }
27062709
default: /*case QRF_STYLE_Markdown:*/
27072710
if( data.nMargin ){
27082711
rowStart = "| ";
27092712
colSep = " | ";
27102713
rowSep = " |\n";
@@ -3277,10 +3280,15 @@
32773280
if( p->spec.zNull==0 ) p->spec.zNull = "";
32783281
p->mxWidth = p->spec.nScreenWidth;
32793282
if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
32803283
p->mxHeight = p->spec.nLineLimit;
32813284
if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3285
+ if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3286
+ if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3287
+ if( p->spec.eText>QRF_TEXT_Json ) p->spec.eText = QRF_Auto;
3288
+ if( p->spec.eTitle>QRF_TEXT_Json ) p->spec.eTitle = QRF_Auto;
3289
+ if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto;
32823290
qrf_reinit:
32833291
switch( p->spec.eStyle ){
32843292
case QRF_Auto: {
32853293
switch( sqlite3_stmt_isexplain(pStmt) ){
32863294
case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3295,11 +3303,10 @@
32953303
break;
32963304
}
32973305
case QRF_STYLE_JObject:
32983306
case QRF_STYLE_Json: {
32993307
p->spec.eText = QRF_TEXT_Json;
3300
- p->spec.eBlob = QRF_BLOB_Json;
33013308
p->spec.zNull = "null";
33023309
break;
33033310
}
33043311
case QRF_STYLE_Html: {
33053312
p->spec.eText = QRF_TEXT_Html;
@@ -3306,29 +3313,26 @@
33063313
p->spec.zNull = "null";
33073314
break;
33083315
}
33093316
case QRF_STYLE_Insert: {
33103317
p->spec.eText = QRF_TEXT_Sql;
3311
- p->spec.eBlob = QRF_BLOB_Sql;
33123318
p->spec.zNull = "NULL";
33133319
if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){
33143320
p->spec.zTableName = "tab";
33153321
}
33163322
break;
33173323
}
33183324
case QRF_STYLE_Csv: {
33193325
p->spec.eStyle = QRF_STYLE_List;
33203326
p->spec.eText = QRF_TEXT_Csv;
3321
- p->spec.eBlob = QRF_BLOB_Text;
33223327
p->spec.zColumnSep = ",";
33233328
p->spec.zRowSep = "\r\n";
33243329
p->spec.zNull = "";
33253330
break;
33263331
}
33273332
case QRF_STYLE_Quote: {
33283333
p->spec.eText = QRF_TEXT_Sql;
3329
- p->spec.eBlob = QRF_BLOB_Sql;
33303334
p->spec.zNull = "NULL";
33313335
p->spec.zColumnSep = ",";
33323336
p->spec.zRowSep = "\n";
33333337
break;
33343338
}
@@ -24153,47 +24157,48 @@
2415324157
"", "NULL", "null", "\"\"" };
2415424158
/* 9 10 11 12 */
2415524159
2415624160
static const ModeInfo aModeInfo[] = {
2415724161
/* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
24158
- { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 },
24159
- { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 },
24162
+ { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0 },
24163
+ { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2 },
2416024164
{ "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 },
24161
- { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 },
24165
+ { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2 },
2416224166
{ "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 },
24163
- { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 },
24164
- { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 },
24165
- { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 },
24166
- { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 },
24167
- { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 },
24167
+ { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0 },
24168
+ { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0 },
24169
+ { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0 },
24170
+ { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0 },
24171
+ { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0 },
2416824172
{ "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 },
2416924173
{ "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 },
24170
- { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 },
24171
- { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 },
24174
+ { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0 },
24175
+ { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2 },
2417224176
{ "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 },
24173
- { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 },
24174
- { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 },
24175
- { "split", 0, 0, 9, 1, 1, 1, 1, 2, 2 },
24176
- { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 },
24177
- { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 },
24177
+ { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2 },
24178
+ { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0 },
24179
+ { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2 },
24180
+ { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2 },
24181
+ { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0 },
2417824182
{ "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 },
24179
- { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 }
24183
+ { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0 }
2418024184
}; /* | / / | / / | | \
2418124185
** | / / | / / | | \_ 2: columnar
2418224186
** Index into aModeStr[] | / / | | 1: line
2418324187
** | / / | | 0: other
2418424188
** | / / | \
2418524189
** text encoding |/ | show | \
2418624190
** v-------------------' | hdrs? | The QRF style
2418724191
** 0: n/a blob | v-----'
2418824192
** 1: plain v_---------' 0: n/a
24189
- ** 2: sql 0: n/a 1: no
24193
+ ** 2: sql 0: auto 1: no
2419024194
** 3: csv 1: as-text 2: yes
2419124195
** 4: html 2: sql
2419224196
** 5: c 3: hex
2419324197
** 6: json 4: c
2419424198
** 5: json
24199
+ ** 6: size
2419524200
******************************************************************/
2419624201
/*
2419724202
** These are the column/row/line separators used by the various
2419824203
** import/export modes.
2419924204
*/
@@ -25879,10 +25884,17 @@
2587925884
assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) );
2588025885
eStyle = aModeInfo[pArg->mode.eMode].eStyle;
2588125886
if( pArg->mode.bAutoScreenWidth ){
2588225887
spec.nScreenWidth = shellScreenWidth();
2588325888
}
25889
+ if( spec.eBlob==QRF_BLOB_Auto ){
25890
+ switch( spec.eText ){
25891
+ case QRF_TEXT_Sql: spec.eBlob = QRF_BLOB_Sql; break;
25892
+ case QRF_TEXT_Json: spec.eBlob = QRF_BLOB_Json; break;
25893
+ default: spec.eBlob = QRF_BLOB_Text; break;
25894
+ }
25895
+ }
2588425896
2588525897
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
2588625898
if( pArg->expert.pExpert ){
2588725899
rc = expertHandleSQL(pArg, zSql, pzErrMsg);
2588825900
return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
@@ -26246,10 +26258,12 @@
2624626258
2624726259
2624826260
savedMode = p->mode;
2624926261
p->mode.spec.zTableName = (char*)zTable;
2625026262
p->mode.eMode = MODE_Insert;
26263
+ p->mode.spec.eText = QRF_TEXT_Sql;
26264
+ p->mode.spec.eBlob = QRF_BLOB_Sql;
2625126265
p->mode.spec.bTitles = QRF_No;
2625226266
rc = shell_exec(p, sSelect.zTxt, 0);
2625326267
if( (rc&0xff)==SQLITE_CORRUPT ){
2625426268
cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
2625526269
toggleSelectOrder(p->db);
@@ -26596,52 +26610,54 @@
2659626610
" -v Verbose mode\n"
2659726611
},
2659826612
{ ".mode",
2659926613
"USAGE: .mode [MODE] [OPTIONS]\n"
2660026614
"\n"
26601
-"Change the output mode to MODE and/or apply OPTIONS to the\n"
26602
-"output mode. If no arguments, show the current output mode\n"
26603
-"and relevant options.\n"
26615
+"Change the output mode to MODE and/or apply OPTIONS to the output mode.\n"
26616
+"Arguments are processed from left to right. If no arguments, show the\n"
26617
+"current output mode and relevant options.\n"
2660426618
"\n"
2660526619
"Options:\n"
2660626620
" --align STRING Set the alignment of text in columnar modes\n"
2660726621
" String consists of characters 'L', 'C', 'R'\n"
2660826622
" meaning \"left\", \"centered\", and \"right\", with\n"
2660926623
" one letter per column starting from the left.\n"
2661026624
" Unspecified alignment defaults to 'L'.\n"
26625
+" --blob-quote ARG ARG can be \"auto\", \"text\", \"sql\", \"hex\", \"tcl\",\n"
26626
+" \"json\", or \"size\". Default is \"auto\".\n"
2661126627
" --charlimit N Set the maximum number of output characters to\n"
2661226628
" show for any single SQL value to N. Longer values\n"
2661326629
" truncated. Zero means \"no limit\".\n"
2661426630
" --colsep STRING Use STRING as the column separator\n"
2661526631
" --escape ESC Enable/disable escaping of control characters\n"
26616
-" in output. ESC can be \"off\", \"ascii\", or\n"
26617
-" \"symbol\".\n"
26632
+" found in the output. ESC can be \"off\", \"ascii\",\n"
26633
+" or \"symbol\".\n"
2661826634
" --linelimit N Set the maximum number of output lines to show for\n"
2661926635
" any single SQL value to N. Longer values are\n"
2662026636
" truncated. Zero means \"no limit\". Only works\n"
2662126637
" in \"line\" mode and in columnar modes.\n"
26638
+" --limits L,C Shorthand for \"--linelimit L --charlimit C\".\n"
26639
+" Or \"off\" to mean \"0,0\". Or \"on\" for \"5,300\".\n"
2662226640
" --list List available modes\n"
26623
-" --no-limits Shorthand to turn off --linelimit, --charlimit,\n"
26624
-" and --screenwidth.\n"
2662526641
" --null STRING Render SQL NULL values as the given string\n"
2662626642
" --once Setting changes to the right are reverted after\n"
2662726643
" the next SQL command.\n"
2662826644
" --quote ARG Enable/disable quoting of text. ARG can be\n"
2662926645
" \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n"
2663026646
" or \"json\". \"off\" means show the text as-is.\n"
26631
-" \"on and \"sql\" are synonyms.\n"
26647
+" \"on\" is an alias for \"sql\".\n"
2663226648
" --reset Changes all mode settings back to their default.\n"
2663326649
" --rowsep STRING Use STRING as the row separator\n"
26634
-" --screenwidth N Declare the screen width of the output device\n"
26650
+" --sw|--screenwidth N Declare the screen width of the output device\n"
2663526651
" to be N characters. An attempt may be made to\n"
2663626652
" wrap output text to fit within this limit. Zero\n"
2663726653
" means \"no limit\". Or N can be \"auto\" to set the\n"
2663826654
" width automatically.\n"
2663926655
" --tablename NAME Set the name of the table for \"insert\" mode.\n"
2664026656
" --tag NAME Save mode to the left as NAME.\n"
2664126657
" --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
26642
-" --title ARG Whether or not to show column headers, and if so\n"
26658
+" --title ARG Whether or not to show column headers, and if so\n"
2664326659
" how to encode them. ARG can be \"off\", \"on\",\n"
2664426660
" \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
2664526661
" -v|--verbose Verbose output\n"
2664626662
" --widths LIST Set the columns widths for columnar modes. The\n"
2664726663
" argument is a list of integers, one for each\n"
@@ -30477,52 +30493,54 @@
3047730493
/*
3047830494
** DOT-COMMAND: .mode
3047930495
**
3048030496
** USAGE: .mode [MODE] [OPTIONS]
3048130497
**
30482
-** Change the output mode to MODE and/or apply OPTIONS to the
30483
-** output mode. If no arguments, show the current output mode
30484
-** and relevant options.
30498
+** Change the output mode to MODE and/or apply OPTIONS to the output mode.
30499
+** Arguments are processed from left to right. If no arguments, show the
30500
+** current output mode and relevant options.
3048530501
**
3048630502
** Options:
3048730503
** --align STRING Set the alignment of text in columnar modes
3048830504
** String consists of characters 'L', 'C', 'R'
3048930505
** meaning "left", "centered", and "right", with
3049030506
** one letter per column starting from the left.
3049130507
** Unspecified alignment defaults to 'L'.
30508
+** --blob-quote ARG ARG can be "auto", "text", "sql", "hex", "tcl",
30509
+** "json", or "size". Default is "auto".
3049230510
** --charlimit N Set the maximum number of output characters to
3049330511
** show for any single SQL value to N. Longer values
3049430512
** truncated. Zero means "no limit".
3049530513
** --colsep STRING Use STRING as the column separator
3049630514
** --escape ESC Enable/disable escaping of control characters
30497
-** in output. ESC can be "off", "ascii", or
30498
-** "symbol".
30515
+** found in the output. ESC can be "off", "ascii",
30516
+** or "symbol".
3049930517
** --linelimit N Set the maximum number of output lines to show for
3050030518
** any single SQL value to N. Longer values are
3050130519
** truncated. Zero means "no limit". Only works
3050230520
** in "line" mode and in columnar modes.
30521
+** --limits L,C Shorthand for "--linelimit L --charlimit C".
30522
+** Or "off" to mean "0,0". Or "on" for "5,300".
3050330523
** --list List available modes
30504
-** --no-limits Shorthand to turn off --linelimit, --charlimit,
30505
-** and --screenwidth.
3050630524
** --null STRING Render SQL NULL values as the given string
3050730525
** --once Setting changes to the right are reverted after
3050830526
** the next SQL command.
3050930527
** --quote ARG Enable/disable quoting of text. ARG can be
3051030528
** "off", "on", "sql", "csv", "html", "tcl",
3051130529
** or "json". "off" means show the text as-is.
30512
-** "on and "sql" are synonyms.
30530
+** "on" is an alias for "sql".
3051330531
** --reset Changes all mode settings back to their default.
3051430532
** --rowsep STRING Use STRING as the row separator
30515
-** --screenwidth N Declare the screen width of the output device
30533
+** --sw|--screenwidth N Declare the screen width of the output device
3051630534
** to be N characters. An attempt may be made to
3051730535
** wrap output text to fit within this limit. Zero
3051830536
** means "no limit". Or N can be "auto" to set the
3051930537
** width automatically.
3052030538
** --tablename NAME Set the name of the table for "insert" mode.
3052130539
** --tag NAME Save mode to the left as NAME.
3052230540
** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
30523
-** --title ARG Whether or not to show column headers, and if so
30541
+** --title ARG Whether or not to show column headers, and if so
3052430542
** how to encode them. ARG can be "off", "on",
3052530543
** "sql", "csv", "html", "tcl", or "json".
3052630544
** -v|--verbose Verbose output
3052730545
** --widths LIST Set the columns widths for columnar modes. The
3052830546
** argument is a list of integers, one for each
@@ -30592,10 +30610,23 @@
3059230610
if( nErr ){
3059330611
dotCmdError(p, i, "bad alignment string",
3059430612
"Should contain only characters L, C, and R.");
3059530613
return 1;
3059630614
}
30615
+ }else if( pickStr(z,0,"-blob","-blob-quote","")>=0 ){
30616
+ if( (++i)>=nArg ){
30617
+ dotCmdError(p, i-1, "missing argument", 0);
30618
+ return 1;
30619
+ }
30620
+ k = pickStr(azArg[i], 0,
30621
+ "auto", "text", "sql", "hex", "tcl", "json", "size", "");
30622
+ /* 0 1 2 3 4 5 6
30623
+ ** Must match QRF_BLOB_xxxx values. See also tag-20251124a */
30624
+ if( k>=0 ){
30625
+ p->mode.spec.eBlob = k & 0xff;
30626
+ }
30627
+ chng = 1;
3059730628
}else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
3059830629
int w; /* 0 1 */
3059930630
if( i+1>=nArg ){
3060030631
dotCmdError(p, i, "missing argument", 0);
3060130632
return 1;
@@ -30622,22 +30653,45 @@
3062230653
}
3062330654
chng = 1;
3062430655
}else if( optionMatch(z,"escape") ){
3062530656
/* See similar code at tag-20250224-1 */
3062630657
char *zErr = 0;
30627
- if( i+1>=nArg ){
30628
- dotCmdError(p, i, "missing argument", 0);
30658
+ if( (++i)>=nArg ){
30659
+ dotCmdError(p, i-1, "missing argument", 0);
3062930660
return 1;
30630
- }
30631
- i++; /* 0 1 2 <-- One less than QRF_ESC_ */
30661
+ } /* 0 1 2 <-- One less than QRF_ESC_ */
3063230662
k = pickStr(azArg[i],&zErr,"off","ascii","symbol","");
3063330663
if( k<0 ){
3063430664
dotCmdError(p, i, "unknown escape type", "%s", zErr);
3063530665
sqlite3_free(zErr);
3063630666
return 1;
3063730667
}
3063830668
p->mode.spec.eEsc = k+1;
30669
+ chng = 1;
30670
+ }else if( optionMatch(z,"limits") ){
30671
+ if( (++i)>=nArg ){
30672
+ dotCmdError(p, i-1, "missing argument", 0);
30673
+ return 1;
30674
+ }
30675
+ k = pickStr(azArg[i],0,"on","off","");
30676
+ if( k==0 ){
30677
+ p->mode.spec.nLineLimit = 5;
30678
+ p->mode.spec.nCharLimit = 300;
30679
+ }else if( k==1 ){
30680
+ p->mode.spec.nLineLimit = 0;
30681
+ p->mode.spec.nCharLimit = 0;
30682
+ }else{
30683
+ int L, C;
30684
+ int nNum = sscanf(azArg[i], "%d,%d", &L, &C);
30685
+ if( nNum!=2 || L<0 || C<0 ){
30686
+ dotCmdError(p, i, "bad argument", "Should be \"L,C\" where L and C"
30687
+ " are unsigned integers");
30688
+ return 1;
30689
+ }
30690
+ p->mode.spec.nLineLimit = L;
30691
+ p->mode.spec.nCharLimit = C;
30692
+ }
3063930693
chng = 1;
3064030694
}else if( optionMatch(z,"list") ){
3064130695
int ii;
3064230696
cli_puts("available modes:", p->out);
3064330697
for(ii=0; ii<ArraySize(aModeInfo); ii++){
@@ -30646,24 +30700,20 @@
3064630700
}
3064730701
for(ii=0; ii<p->nSavedModes; ii++){
3064830702
cli_printf(p->out, " %s", p->aSavedModes[ii].zTag);
3064930703
}
3065030704
cli_puts(" batch tty\n", p->out);
30705
+ chng = 1; /* Not really a change, but we still want to suppress the
30706
+ ** "current mode" output */
3065130707
}else if( optionMatch(z,"once") ){
3065230708
p->nPopMode = 0;
3065330709
modePush(p);
3065430710
p->nPopMode = 1;
3065530711
}else if( optionMatch(z,"noquote") ){
3065630712
/* (undocumented legacy) --noquote always turns quoting off */
3065730713
p->mode.spec.eText = QRF_TEXT_Plain;
30658
- p->mode.spec.eBlob = QRF_BLOB_Text;
30659
- chng = 1;
30660
- }else if( optionMatch(z,"no-limits") ){
30661
- p->mode.spec.nLineLimit = 0;
30662
- p->mode.spec.nCharLimit = 0;
30663
- p->mode.spec.nScreenWidth = 0;
30664
- p->mode.bAutoScreenWidth = 0;
30714
+ p->mode.spec.eBlob = QRF_BLOB_Auto;
3066530715
chng = 1;
3066630716
}else if( optionMatch(z,"quote") ){
3066730717
if( i+1<nArg
3066830718
&& azArg[i+1][0]!='-'
3066930719
&& (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0)
@@ -30687,59 +30737,54 @@
3068730737
/* (Legacy) no following boolean argument. Turn quoting on */
3068830738
k = 1;
3068930739
}
3069030740
switch( k ){
3069130741
case 1: /* on */
30742
+ modeSetStr(&p->mode.spec.zNull, "NULL");
30743
+ /* Fall through */
3069230744
case 2: /* sql */
3069330745
p->mode.spec.eText = QRF_TEXT_Sql;
30694
- p->mode.spec.eBlob = QRF_BLOB_Sql;
3069530746
break;
3069630747
case 3: /* csv */
3069730748
p->mode.spec.eText = QRF_TEXT_Csv;
30698
- p->mode.spec.eBlob = QRF_BLOB_Text;
3069930749
break;
3070030750
case 4: /* html */
3070130751
p->mode.spec.eText = QRF_TEXT_Html;
30702
- p->mode.spec.eBlob = QRF_BLOB_Text;
3070330752
break;
3070430753
case 5: /* tcl */
3070530754
p->mode.spec.eText = QRF_TEXT_Tcl;
30706
- p->mode.spec.eBlob = QRF_BLOB_Text;
3070730755
break;
3070830756
case 6: /* json */
3070930757
p->mode.spec.eText = QRF_TEXT_Json;
30710
- p->mode.spec.eBlob = QRF_BLOB_Json;
3071130758
break;
30712
- default: /* off */
30759
+ default: /* off */
3071330760
p->mode.spec.eText = QRF_TEXT_Plain;
30714
- p->mode.spec.eBlob = QRF_BLOB_Text;
3071530761
break;
3071630762
}
3071730763
chng = 1;
3071830764
}else if( optionMatch(z,"reset") ){
3071930765
int saved_eMode = p->mode.eMode;
3072030766
modeFree(&p->mode);
3072130767
modeChange(p, saved_eMode);
30722
- }else if( optionMatch(z,"screenwidth") ){
30723
- if( i+1>=nArg ){
30724
- dotCmdError(p, i, "missing argument", 0);
30768
+ }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
30769
+ if( (++i)>=nArg ){
30770
+ dotCmdError(p, i-1, "missing argument", 0);
3072530771
return 1;
3072630772
}
30727
- k = pickStr(azArg[i+1],0,"off","auto","");
30773
+ k = pickStr(azArg[i],0,"off","auto","");
3072830774
if( k==0 ){
3072930775
p->mode.bAutoScreenWidth = 0;
3073030776
p->mode.spec.nScreenWidth = 0;
3073130777
}else if( k==1 ){
3073230778
p->mode.bAutoScreenWidth = 1;
3073330779
}else{
30734
- i64 w = integerValue(azArg[i+1]);
30780
+ i64 w = integerValue(azArg[i]);
3073530781
p->mode.bAutoScreenWidth = 0;
3073630782
if( w<0 ) w = 0;
3073730783
if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
3073830784
p->mode.spec.nScreenWidth = w;
3073930785
}
30740
- i++;
3074130786
chng = 1;
3074230787
}else if( optionMatch(z,"tag") ){
3074330788
size_t nByte;
3074430789
int n;
3074530790
const char *zTag;
@@ -30880,11 +30925,19 @@
3088030925
unsigned char a = p->mode.spec.aAlign[ii];
3088130926
sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]);
3088230927
}
3088330928
sqlite3_str_append(pDesc, "\"", 1);
3088430929
}
30885
- if( bAll || p->mode.spec.nCharLimit>0 ){
30930
+ if( bAll || p->mode.spec.eBlob!=QRF_BLOB_Auto ){
30931
+ const char *azBQuote[] =
30932
+ { "auto", "text", "sql", "hex", "tcl", "json", "size" };
30933
+ /* 0 1 2 3 4 5 6
30934
+ ** Must match QRF_BLOB_xxxx values. See all instances of tag-20251124a */
30935
+ u8 e = p->mode.spec.eBlob;
30936
+ sqlite3_str_appendf(pDesc, " --blob-quote %s", azBQuote[e]);
30937
+ }
30938
+ if( !bAll && p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit>0 ){
3088630939
sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit);
3088730940
}
3088830941
zSetting = aModeStr[pI->eCSep];
3088930942
if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){
3089030943
sqlite3_str_appendf(pDesc, " --colsep ");
@@ -30891,11 +30944,19 @@
3089130944
append_c_string(pDesc, p->mode.spec.zColumnSep);
3089230945
}
3089330946
if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
3089430947
sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
3089530948
}
30896
- if( bAll || (p->mode.spec.nLineLimit>0 && pI->eCx>0) ){
30949
+ if( bAll || (p->mode.spec.nLineLimit>0 && p->mode.spec.nCharLimit>0) ){
30950
+ if( p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit==0 ){
30951
+ sqlite3_str_appendf(pDesc, " --limits off");
30952
+ }else{
30953
+ sqlite3_str_appendf(pDesc, " --limits %d,%d",
30954
+ p->mode.spec.nLineLimit, p->mode.spec.nCharLimit);
30955
+ }
30956
+ }else
30957
+ if( p->mode.spec.nCharLimit==0 && p->mode.spec.nLineLimit>0 && pI->eCx>0 ){
3089730958
sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit);
3089830959
}
3089930960
zSetting = aModeStr[pI->eNull];
3090030961
if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){
3090130962
sqlite3_str_appendf(pDesc, " --null ");
3090230963
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -701,11 +701,10 @@
701 unsigned char eTitle; /* Quating style for the text of column names */
702 unsigned char eBlob; /* Quoting style for BLOBs */
703 unsigned char bTitles; /* True to show column names */
704 unsigned char bWordWrap; /* Try to wrap on word boundaries */
705 unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
706 unsigned char bTextNull; /* Apply eText encoding to zNull[] */
707 unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
708 unsigned char eTitleAlign; /* Alignment for column headers */
709 unsigned char bSplitColumn; /* Wrap single-column output into many columns */
710 short int nWrap; /* Wrap columns wider than this */
711 short int nScreenWidth; /* Maximum overall table width */
@@ -787,10 +786,11 @@
787 #define QRF_BLOB_Text 1 /* Display content exactly as it is */
788 #define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
789 #define QRF_BLOB_Hex 3 /* Hexadecimal representation */
790 #define QRF_BLOB_Tcl 4 /* "\000" notation */
791 #define QRF_BLOB_Json 5 /* A JSON string */
 
792
793 /*
794 ** Control-character escape modes.
795 ** Allowed values for sqlite3_qrf_spec.eEsc
796 */
@@ -1841,24 +1841,25 @@
1841 zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf];
1842 zVal[j+5] = "0123456789abcdef"[(c)&0xf];
1843 }
1844 }
1845 break;
 
 
 
 
 
1846 }
1847 default: {
1848 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1849 qrfEncodeText(p, pOut, zTxt);
1850 }
1851 }
1852 break;
1853 }
1854 case SQLITE_NULL: {
1855 if( p->spec.bTextNull==QRF_Yes ){
1856 qrfEncodeText(p, pOut, p->spec.zNull);
1857 }else{
1858 sqlite3_str_appendall(pOut, p->spec.zNull);
1859 }
1860 break;
1861 }
1862 case SQLITE_TEXT: {
1863 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1864 qrfEncodeText(p, pOut, zTxt);
@@ -2690,21 +2691,23 @@
2690 colSep = "|";
2691 rowSep = "|\n";
2692 }
2693 qrfRowSeparator(p->pOut, &data, '+');
2694 break;
2695 case QRF_STYLE_Column:
 
2696 rowStart = "";
2697 if( data.nMargin<2 ){
2698 colSep = " ";
2699 }else if( data.nMargin<=5 ){
2700 colSep = " " + (5-data.nMargin);
2701 }else{
2702 colSep = " ";
2703 }
2704 rowSep = "\n";
2705 break;
 
2706 default: /*case QRF_STYLE_Markdown:*/
2707 if( data.nMargin ){
2708 rowStart = "| ";
2709 colSep = " | ";
2710 rowSep = " |\n";
@@ -3277,10 +3280,15 @@
3277 if( p->spec.zNull==0 ) p->spec.zNull = "";
3278 p->mxWidth = p->spec.nScreenWidth;
3279 if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3280 p->mxHeight = p->spec.nLineLimit;
3281 if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
 
 
 
 
 
3282 qrf_reinit:
3283 switch( p->spec.eStyle ){
3284 case QRF_Auto: {
3285 switch( sqlite3_stmt_isexplain(pStmt) ){
3286 case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3295,11 +3303,10 @@
3295 break;
3296 }
3297 case QRF_STYLE_JObject:
3298 case QRF_STYLE_Json: {
3299 p->spec.eText = QRF_TEXT_Json;
3300 p->spec.eBlob = QRF_BLOB_Json;
3301 p->spec.zNull = "null";
3302 break;
3303 }
3304 case QRF_STYLE_Html: {
3305 p->spec.eText = QRF_TEXT_Html;
@@ -3306,29 +3313,26 @@
3306 p->spec.zNull = "null";
3307 break;
3308 }
3309 case QRF_STYLE_Insert: {
3310 p->spec.eText = QRF_TEXT_Sql;
3311 p->spec.eBlob = QRF_BLOB_Sql;
3312 p->spec.zNull = "NULL";
3313 if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){
3314 p->spec.zTableName = "tab";
3315 }
3316 break;
3317 }
3318 case QRF_STYLE_Csv: {
3319 p->spec.eStyle = QRF_STYLE_List;
3320 p->spec.eText = QRF_TEXT_Csv;
3321 p->spec.eBlob = QRF_BLOB_Text;
3322 p->spec.zColumnSep = ",";
3323 p->spec.zRowSep = "\r\n";
3324 p->spec.zNull = "";
3325 break;
3326 }
3327 case QRF_STYLE_Quote: {
3328 p->spec.eText = QRF_TEXT_Sql;
3329 p->spec.eBlob = QRF_BLOB_Sql;
3330 p->spec.zNull = "NULL";
3331 p->spec.zColumnSep = ",";
3332 p->spec.zRowSep = "\n";
3333 break;
3334 }
@@ -24153,47 +24157,48 @@
24153 "", "NULL", "null", "\"\"" };
24154 /* 9 10 11 12 */
24155
24156 static const ModeInfo aModeInfo[] = {
24157 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
24158 { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 },
24159 { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 },
24160 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 },
24161 { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 },
24162 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 },
24163 { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 },
24164 { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 },
24165 { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 },
24166 { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 },
24167 { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 },
24168 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 },
24169 { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 },
24170 { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 },
24171 { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 },
24172 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 },
24173 { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 },
24174 { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 },
24175 { "split", 0, 0, 9, 1, 1, 1, 1, 2, 2 },
24176 { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 },
24177 { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 },
24178 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 },
24179 { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 }
24180 }; /* | / / | / / | | \
24181 ** | / / | / / | | \_ 2: columnar
24182 ** Index into aModeStr[] | / / | | 1: line
24183 ** | / / | | 0: other
24184 ** | / / | \
24185 ** text encoding |/ | show | \
24186 ** v-------------------' | hdrs? | The QRF style
24187 ** 0: n/a blob | v-----'
24188 ** 1: plain v_---------' 0: n/a
24189 ** 2: sql 0: n/a 1: no
24190 ** 3: csv 1: as-text 2: yes
24191 ** 4: html 2: sql
24192 ** 5: c 3: hex
24193 ** 6: json 4: c
24194 ** 5: json
 
24195 ******************************************************************/
24196 /*
24197 ** These are the column/row/line separators used by the various
24198 ** import/export modes.
24199 */
@@ -25879,10 +25884,17 @@
25879 assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) );
25880 eStyle = aModeInfo[pArg->mode.eMode].eStyle;
25881 if( pArg->mode.bAutoScreenWidth ){
25882 spec.nScreenWidth = shellScreenWidth();
25883 }
 
 
 
 
 
 
 
25884
25885 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
25886 if( pArg->expert.pExpert ){
25887 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
25888 return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
@@ -26246,10 +26258,12 @@
26246
26247
26248 savedMode = p->mode;
26249 p->mode.spec.zTableName = (char*)zTable;
26250 p->mode.eMode = MODE_Insert;
 
 
26251 p->mode.spec.bTitles = QRF_No;
26252 rc = shell_exec(p, sSelect.zTxt, 0);
26253 if( (rc&0xff)==SQLITE_CORRUPT ){
26254 cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
26255 toggleSelectOrder(p->db);
@@ -26596,52 +26610,54 @@
26596 " -v Verbose mode\n"
26597 },
26598 { ".mode",
26599 "USAGE: .mode [MODE] [OPTIONS]\n"
26600 "\n"
26601 "Change the output mode to MODE and/or apply OPTIONS to the\n"
26602 "output mode. If no arguments, show the current output mode\n"
26603 "and relevant options.\n"
26604 "\n"
26605 "Options:\n"
26606 " --align STRING Set the alignment of text in columnar modes\n"
26607 " String consists of characters 'L', 'C', 'R'\n"
26608 " meaning \"left\", \"centered\", and \"right\", with\n"
26609 " one letter per column starting from the left.\n"
26610 " Unspecified alignment defaults to 'L'.\n"
 
 
26611 " --charlimit N Set the maximum number of output characters to\n"
26612 " show for any single SQL value to N. Longer values\n"
26613 " truncated. Zero means \"no limit\".\n"
26614 " --colsep STRING Use STRING as the column separator\n"
26615 " --escape ESC Enable/disable escaping of control characters\n"
26616 " in output. ESC can be \"off\", \"ascii\", or\n"
26617 " \"symbol\".\n"
26618 " --linelimit N Set the maximum number of output lines to show for\n"
26619 " any single SQL value to N. Longer values are\n"
26620 " truncated. Zero means \"no limit\". Only works\n"
26621 " in \"line\" mode and in columnar modes.\n"
 
 
26622 " --list List available modes\n"
26623 " --no-limits Shorthand to turn off --linelimit, --charlimit,\n"
26624 " and --screenwidth.\n"
26625 " --null STRING Render SQL NULL values as the given string\n"
26626 " --once Setting changes to the right are reverted after\n"
26627 " the next SQL command.\n"
26628 " --quote ARG Enable/disable quoting of text. ARG can be\n"
26629 " \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n"
26630 " or \"json\". \"off\" means show the text as-is.\n"
26631 " \"on and \"sql\" are synonyms.\n"
26632 " --reset Changes all mode settings back to their default.\n"
26633 " --rowsep STRING Use STRING as the row separator\n"
26634 " --screenwidth N Declare the screen width of the output device\n"
26635 " to be N characters. An attempt may be made to\n"
26636 " wrap output text to fit within this limit. Zero\n"
26637 " means \"no limit\". Or N can be \"auto\" to set the\n"
26638 " width automatically.\n"
26639 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
26640 " --tag NAME Save mode to the left as NAME.\n"
26641 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
26642 " --title ARG Whether or not to show column headers, and if so\n"
26643 " how to encode them. ARG can be \"off\", \"on\",\n"
26644 " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
26645 " -v|--verbose Verbose output\n"
26646 " --widths LIST Set the columns widths for columnar modes. The\n"
26647 " argument is a list of integers, one for each\n"
@@ -30477,52 +30493,54 @@
30477 /*
30478 ** DOT-COMMAND: .mode
30479 **
30480 ** USAGE: .mode [MODE] [OPTIONS]
30481 **
30482 ** Change the output mode to MODE and/or apply OPTIONS to the
30483 ** output mode. If no arguments, show the current output mode
30484 ** and relevant options.
30485 **
30486 ** Options:
30487 ** --align STRING Set the alignment of text in columnar modes
30488 ** String consists of characters 'L', 'C', 'R'
30489 ** meaning "left", "centered", and "right", with
30490 ** one letter per column starting from the left.
30491 ** Unspecified alignment defaults to 'L'.
 
 
30492 ** --charlimit N Set the maximum number of output characters to
30493 ** show for any single SQL value to N. Longer values
30494 ** truncated. Zero means "no limit".
30495 ** --colsep STRING Use STRING as the column separator
30496 ** --escape ESC Enable/disable escaping of control characters
30497 ** in output. ESC can be "off", "ascii", or
30498 ** "symbol".
30499 ** --linelimit N Set the maximum number of output lines to show for
30500 ** any single SQL value to N. Longer values are
30501 ** truncated. Zero means "no limit". Only works
30502 ** in "line" mode and in columnar modes.
 
 
30503 ** --list List available modes
30504 ** --no-limits Shorthand to turn off --linelimit, --charlimit,
30505 ** and --screenwidth.
30506 ** --null STRING Render SQL NULL values as the given string
30507 ** --once Setting changes to the right are reverted after
30508 ** the next SQL command.
30509 ** --quote ARG Enable/disable quoting of text. ARG can be
30510 ** "off", "on", "sql", "csv", "html", "tcl",
30511 ** or "json". "off" means show the text as-is.
30512 ** "on and "sql" are synonyms.
30513 ** --reset Changes all mode settings back to their default.
30514 ** --rowsep STRING Use STRING as the row separator
30515 ** --screenwidth N Declare the screen width of the output device
30516 ** to be N characters. An attempt may be made to
30517 ** wrap output text to fit within this limit. Zero
30518 ** means "no limit". Or N can be "auto" to set the
30519 ** width automatically.
30520 ** --tablename NAME Set the name of the table for "insert" mode.
30521 ** --tag NAME Save mode to the left as NAME.
30522 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
30523 ** --title ARG Whether or not to show column headers, and if so
30524 ** how to encode them. ARG can be "off", "on",
30525 ** "sql", "csv", "html", "tcl", or "json".
30526 ** -v|--verbose Verbose output
30527 ** --widths LIST Set the columns widths for columnar modes. The
30528 ** argument is a list of integers, one for each
@@ -30592,10 +30610,23 @@
30592 if( nErr ){
30593 dotCmdError(p, i, "bad alignment string",
30594 "Should contain only characters L, C, and R.");
30595 return 1;
30596 }
 
 
 
 
 
 
 
 
 
 
 
 
 
30597 }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
30598 int w; /* 0 1 */
30599 if( i+1>=nArg ){
30600 dotCmdError(p, i, "missing argument", 0);
30601 return 1;
@@ -30622,22 +30653,45 @@
30622 }
30623 chng = 1;
30624 }else if( optionMatch(z,"escape") ){
30625 /* See similar code at tag-20250224-1 */
30626 char *zErr = 0;
30627 if( i+1>=nArg ){
30628 dotCmdError(p, i, "missing argument", 0);
30629 return 1;
30630 }
30631 i++; /* 0 1 2 <-- One less than QRF_ESC_ */
30632 k = pickStr(azArg[i],&zErr,"off","ascii","symbol","");
30633 if( k<0 ){
30634 dotCmdError(p, i, "unknown escape type", "%s", zErr);
30635 sqlite3_free(zErr);
30636 return 1;
30637 }
30638 p->mode.spec.eEsc = k+1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30639 chng = 1;
30640 }else if( optionMatch(z,"list") ){
30641 int ii;
30642 cli_puts("available modes:", p->out);
30643 for(ii=0; ii<ArraySize(aModeInfo); ii++){
@@ -30646,24 +30700,20 @@
30646 }
30647 for(ii=0; ii<p->nSavedModes; ii++){
30648 cli_printf(p->out, " %s", p->aSavedModes[ii].zTag);
30649 }
30650 cli_puts(" batch tty\n", p->out);
 
 
30651 }else if( optionMatch(z,"once") ){
30652 p->nPopMode = 0;
30653 modePush(p);
30654 p->nPopMode = 1;
30655 }else if( optionMatch(z,"noquote") ){
30656 /* (undocumented legacy) --noquote always turns quoting off */
30657 p->mode.spec.eText = QRF_TEXT_Plain;
30658 p->mode.spec.eBlob = QRF_BLOB_Text;
30659 chng = 1;
30660 }else if( optionMatch(z,"no-limits") ){
30661 p->mode.spec.nLineLimit = 0;
30662 p->mode.spec.nCharLimit = 0;
30663 p->mode.spec.nScreenWidth = 0;
30664 p->mode.bAutoScreenWidth = 0;
30665 chng = 1;
30666 }else if( optionMatch(z,"quote") ){
30667 if( i+1<nArg
30668 && azArg[i+1][0]!='-'
30669 && (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0)
@@ -30687,59 +30737,54 @@
30687 /* (Legacy) no following boolean argument. Turn quoting on */
30688 k = 1;
30689 }
30690 switch( k ){
30691 case 1: /* on */
 
 
30692 case 2: /* sql */
30693 p->mode.spec.eText = QRF_TEXT_Sql;
30694 p->mode.spec.eBlob = QRF_BLOB_Sql;
30695 break;
30696 case 3: /* csv */
30697 p->mode.spec.eText = QRF_TEXT_Csv;
30698 p->mode.spec.eBlob = QRF_BLOB_Text;
30699 break;
30700 case 4: /* html */
30701 p->mode.spec.eText = QRF_TEXT_Html;
30702 p->mode.spec.eBlob = QRF_BLOB_Text;
30703 break;
30704 case 5: /* tcl */
30705 p->mode.spec.eText = QRF_TEXT_Tcl;
30706 p->mode.spec.eBlob = QRF_BLOB_Text;
30707 break;
30708 case 6: /* json */
30709 p->mode.spec.eText = QRF_TEXT_Json;
30710 p->mode.spec.eBlob = QRF_BLOB_Json;
30711 break;
30712 default: /* off */
30713 p->mode.spec.eText = QRF_TEXT_Plain;
30714 p->mode.spec.eBlob = QRF_BLOB_Text;
30715 break;
30716 }
30717 chng = 1;
30718 }else if( optionMatch(z,"reset") ){
30719 int saved_eMode = p->mode.eMode;
30720 modeFree(&p->mode);
30721 modeChange(p, saved_eMode);
30722 }else if( optionMatch(z,"screenwidth") ){
30723 if( i+1>=nArg ){
30724 dotCmdError(p, i, "missing argument", 0);
30725 return 1;
30726 }
30727 k = pickStr(azArg[i+1],0,"off","auto","");
30728 if( k==0 ){
30729 p->mode.bAutoScreenWidth = 0;
30730 p->mode.spec.nScreenWidth = 0;
30731 }else if( k==1 ){
30732 p->mode.bAutoScreenWidth = 1;
30733 }else{
30734 i64 w = integerValue(azArg[i+1]);
30735 p->mode.bAutoScreenWidth = 0;
30736 if( w<0 ) w = 0;
30737 if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30738 p->mode.spec.nScreenWidth = w;
30739 }
30740 i++;
30741 chng = 1;
30742 }else if( optionMatch(z,"tag") ){
30743 size_t nByte;
30744 int n;
30745 const char *zTag;
@@ -30880,11 +30925,19 @@
30880 unsigned char a = p->mode.spec.aAlign[ii];
30881 sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]);
30882 }
30883 sqlite3_str_append(pDesc, "\"", 1);
30884 }
30885 if( bAll || p->mode.spec.nCharLimit>0 ){
 
 
 
 
 
 
 
 
30886 sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit);
30887 }
30888 zSetting = aModeStr[pI->eCSep];
30889 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){
30890 sqlite3_str_appendf(pDesc, " --colsep ");
@@ -30891,11 +30944,19 @@
30891 append_c_string(pDesc, p->mode.spec.zColumnSep);
30892 }
30893 if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
30894 sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
30895 }
30896 if( bAll || (p->mode.spec.nLineLimit>0 && pI->eCx>0) ){
 
 
 
 
 
 
 
 
30897 sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit);
30898 }
30899 zSetting = aModeStr[pI->eNull];
30900 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){
30901 sqlite3_str_appendf(pDesc, " --null ");
30902
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -701,11 +701,10 @@
701 unsigned char eTitle; /* Quating style for the text of column names */
702 unsigned char eBlob; /* Quoting style for BLOBs */
703 unsigned char bTitles; /* True to show column names */
704 unsigned char bWordWrap; /* Try to wrap on word boundaries */
705 unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
 
706 unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
707 unsigned char eTitleAlign; /* Alignment for column headers */
708 unsigned char bSplitColumn; /* Wrap single-column output into many columns */
709 short int nWrap; /* Wrap columns wider than this */
710 short int nScreenWidth; /* Maximum overall table width */
@@ -787,10 +786,11 @@
786 #define QRF_BLOB_Text 1 /* Display content exactly as it is */
787 #define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
788 #define QRF_BLOB_Hex 3 /* Hexadecimal representation */
789 #define QRF_BLOB_Tcl 4 /* "\000" notation */
790 #define QRF_BLOB_Json 5 /* A JSON string */
791 #define QRF_BLOB_Size 6 /* Display the blob size only */
792
793 /*
794 ** Control-character escape modes.
795 ** Allowed values for sqlite3_qrf_spec.eEsc
796 */
@@ -1841,24 +1841,25 @@
1841 zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf];
1842 zVal[j+5] = "0123456789abcdef"[(c)&0xf];
1843 }
1844 }
1845 break;
1846 }
1847 case QRF_BLOB_Size: {
1848 int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
1849 sqlite3_str_appendf(pOut, "(%d-byte blob)", nBlob);
1850 break;
1851 }
1852 default: {
1853 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1854 qrfEncodeText(p, pOut, zTxt);
1855 }
1856 }
1857 break;
1858 }
1859 case SQLITE_NULL: {
1860 sqlite3_str_appendall(pOut, p->spec.zNull);
 
 
 
 
1861 break;
1862 }
1863 case SQLITE_TEXT: {
1864 const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
1865 qrfEncodeText(p, pOut, zTxt);
@@ -2690,21 +2691,23 @@
2691 colSep = "|";
2692 rowSep = "|\n";
2693 }
2694 qrfRowSeparator(p->pOut, &data, '+');
2695 break;
2696 case QRF_STYLE_Column: {
2697 static const char zSpace[] = " ";
2698 rowStart = "";
2699 if( data.nMargin<2 ){
2700 colSep = " ";
2701 }else if( data.nMargin<=5 ){
2702 colSep = &zSpace[5-data.nMargin];
2703 }else{
2704 colSep = zSpace;
2705 }
2706 rowSep = "\n";
2707 break;
2708 }
2709 default: /*case QRF_STYLE_Markdown:*/
2710 if( data.nMargin ){
2711 rowStart = "| ";
2712 colSep = " | ";
2713 rowSep = " |\n";
@@ -3277,10 +3280,15 @@
3280 if( p->spec.zNull==0 ) p->spec.zNull = "";
3281 p->mxWidth = p->spec.nScreenWidth;
3282 if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
3283 p->mxHeight = p->spec.nLineLimit;
3284 if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
3285 if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3286 if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3287 if( p->spec.eText>QRF_TEXT_Json ) p->spec.eText = QRF_Auto;
3288 if( p->spec.eTitle>QRF_TEXT_Json ) p->spec.eTitle = QRF_Auto;
3289 if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto;
3290 qrf_reinit:
3291 switch( p->spec.eStyle ){
3292 case QRF_Auto: {
3293 switch( sqlite3_stmt_isexplain(pStmt) ){
3294 case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3295,11 +3303,10 @@
3303 break;
3304 }
3305 case QRF_STYLE_JObject:
3306 case QRF_STYLE_Json: {
3307 p->spec.eText = QRF_TEXT_Json;
 
3308 p->spec.zNull = "null";
3309 break;
3310 }
3311 case QRF_STYLE_Html: {
3312 p->spec.eText = QRF_TEXT_Html;
@@ -3306,29 +3313,26 @@
3313 p->spec.zNull = "null";
3314 break;
3315 }
3316 case QRF_STYLE_Insert: {
3317 p->spec.eText = QRF_TEXT_Sql;
 
3318 p->spec.zNull = "NULL";
3319 if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){
3320 p->spec.zTableName = "tab";
3321 }
3322 break;
3323 }
3324 case QRF_STYLE_Csv: {
3325 p->spec.eStyle = QRF_STYLE_List;
3326 p->spec.eText = QRF_TEXT_Csv;
 
3327 p->spec.zColumnSep = ",";
3328 p->spec.zRowSep = "\r\n";
3329 p->spec.zNull = "";
3330 break;
3331 }
3332 case QRF_STYLE_Quote: {
3333 p->spec.eText = QRF_TEXT_Sql;
 
3334 p->spec.zNull = "NULL";
3335 p->spec.zColumnSep = ",";
3336 p->spec.zRowSep = "\n";
3337 break;
3338 }
@@ -24153,47 +24157,48 @@
24157 "", "NULL", "null", "\"\"" };
24158 /* 9 10 11 12 */
24159
24160 static const ModeInfo aModeInfo[] = {
24161 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
24162 { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0 },
24163 { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2 },
24164 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 },
24165 { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2 },
24166 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 },
24167 { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0 },
24168 { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0 },
24169 { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0 },
24170 { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0 },
24171 { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0 },
24172 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 },
24173 { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 },
24174 { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0 },
24175 { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2 },
24176 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 },
24177 { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2 },
24178 { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0 },
24179 { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2 },
24180 { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2 },
24181 { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0 },
24182 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 },
24183 { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0 }
24184 }; /* | / / | / / | | \
24185 ** | / / | / / | | \_ 2: columnar
24186 ** Index into aModeStr[] | / / | | 1: line
24187 ** | / / | | 0: other
24188 ** | / / | \
24189 ** text encoding |/ | show | \
24190 ** v-------------------' | hdrs? | The QRF style
24191 ** 0: n/a blob | v-----'
24192 ** 1: plain v_---------' 0: n/a
24193 ** 2: sql 0: auto 1: no
24194 ** 3: csv 1: as-text 2: yes
24195 ** 4: html 2: sql
24196 ** 5: c 3: hex
24197 ** 6: json 4: c
24198 ** 5: json
24199 ** 6: size
24200 ******************************************************************/
24201 /*
24202 ** These are the column/row/line separators used by the various
24203 ** import/export modes.
24204 */
@@ -25879,10 +25884,17 @@
25884 assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) );
25885 eStyle = aModeInfo[pArg->mode.eMode].eStyle;
25886 if( pArg->mode.bAutoScreenWidth ){
25887 spec.nScreenWidth = shellScreenWidth();
25888 }
25889 if( spec.eBlob==QRF_BLOB_Auto ){
25890 switch( spec.eText ){
25891 case QRF_TEXT_Sql: spec.eBlob = QRF_BLOB_Sql; break;
25892 case QRF_TEXT_Json: spec.eBlob = QRF_BLOB_Json; break;
25893 default: spec.eBlob = QRF_BLOB_Text; break;
25894 }
25895 }
25896
25897 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
25898 if( pArg->expert.pExpert ){
25899 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
25900 return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
@@ -26246,10 +26258,12 @@
26258
26259
26260 savedMode = p->mode;
26261 p->mode.spec.zTableName = (char*)zTable;
26262 p->mode.eMode = MODE_Insert;
26263 p->mode.spec.eText = QRF_TEXT_Sql;
26264 p->mode.spec.eBlob = QRF_BLOB_Sql;
26265 p->mode.spec.bTitles = QRF_No;
26266 rc = shell_exec(p, sSelect.zTxt, 0);
26267 if( (rc&0xff)==SQLITE_CORRUPT ){
26268 cli_puts("/****** CORRUPTION ERROR *******/\n", p->out);
26269 toggleSelectOrder(p->db);
@@ -26596,52 +26610,54 @@
26610 " -v Verbose mode\n"
26611 },
26612 { ".mode",
26613 "USAGE: .mode [MODE] [OPTIONS]\n"
26614 "\n"
26615 "Change the output mode to MODE and/or apply OPTIONS to the output mode.\n"
26616 "Arguments are processed from left to right. If no arguments, show the\n"
26617 "current output mode and relevant options.\n"
26618 "\n"
26619 "Options:\n"
26620 " --align STRING Set the alignment of text in columnar modes\n"
26621 " String consists of characters 'L', 'C', 'R'\n"
26622 " meaning \"left\", \"centered\", and \"right\", with\n"
26623 " one letter per column starting from the left.\n"
26624 " Unspecified alignment defaults to 'L'.\n"
26625 " --blob-quote ARG ARG can be \"auto\", \"text\", \"sql\", \"hex\", \"tcl\",\n"
26626 " \"json\", or \"size\". Default is \"auto\".\n"
26627 " --charlimit N Set the maximum number of output characters to\n"
26628 " show for any single SQL value to N. Longer values\n"
26629 " truncated. Zero means \"no limit\".\n"
26630 " --colsep STRING Use STRING as the column separator\n"
26631 " --escape ESC Enable/disable escaping of control characters\n"
26632 " found in the output. ESC can be \"off\", \"ascii\",\n"
26633 " or \"symbol\".\n"
26634 " --linelimit N Set the maximum number of output lines to show for\n"
26635 " any single SQL value to N. Longer values are\n"
26636 " truncated. Zero means \"no limit\". Only works\n"
26637 " in \"line\" mode and in columnar modes.\n"
26638 " --limits L,C Shorthand for \"--linelimit L --charlimit C\".\n"
26639 " Or \"off\" to mean \"0,0\". Or \"on\" for \"5,300\".\n"
26640 " --list List available modes\n"
 
 
26641 " --null STRING Render SQL NULL values as the given string\n"
26642 " --once Setting changes to the right are reverted after\n"
26643 " the next SQL command.\n"
26644 " --quote ARG Enable/disable quoting of text. ARG can be\n"
26645 " \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n"
26646 " or \"json\". \"off\" means show the text as-is.\n"
26647 " \"on\" is an alias for \"sql\".\n"
26648 " --reset Changes all mode settings back to their default.\n"
26649 " --rowsep STRING Use STRING as the row separator\n"
26650 " --sw|--screenwidth N Declare the screen width of the output device\n"
26651 " to be N characters. An attempt may be made to\n"
26652 " wrap output text to fit within this limit. Zero\n"
26653 " means \"no limit\". Or N can be \"auto\" to set the\n"
26654 " width automatically.\n"
26655 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
26656 " --tag NAME Save mode to the left as NAME.\n"
26657 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
26658 " --title ARG Whether or not to show column headers, and if so\n"
26659 " how to encode them. ARG can be \"off\", \"on\",\n"
26660 " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
26661 " -v|--verbose Verbose output\n"
26662 " --widths LIST Set the columns widths for columnar modes. The\n"
26663 " argument is a list of integers, one for each\n"
@@ -30477,52 +30493,54 @@
30493 /*
30494 ** DOT-COMMAND: .mode
30495 **
30496 ** USAGE: .mode [MODE] [OPTIONS]
30497 **
30498 ** Change the output mode to MODE and/or apply OPTIONS to the output mode.
30499 ** Arguments are processed from left to right. If no arguments, show the
30500 ** current output mode and relevant options.
30501 **
30502 ** Options:
30503 ** --align STRING Set the alignment of text in columnar modes
30504 ** String consists of characters 'L', 'C', 'R'
30505 ** meaning "left", "centered", and "right", with
30506 ** one letter per column starting from the left.
30507 ** Unspecified alignment defaults to 'L'.
30508 ** --blob-quote ARG ARG can be "auto", "text", "sql", "hex", "tcl",
30509 ** "json", or "size". Default is "auto".
30510 ** --charlimit N Set the maximum number of output characters to
30511 ** show for any single SQL value to N. Longer values
30512 ** truncated. Zero means "no limit".
30513 ** --colsep STRING Use STRING as the column separator
30514 ** --escape ESC Enable/disable escaping of control characters
30515 ** found in the output. ESC can be "off", "ascii",
30516 ** or "symbol".
30517 ** --linelimit N Set the maximum number of output lines to show for
30518 ** any single SQL value to N. Longer values are
30519 ** truncated. Zero means "no limit". Only works
30520 ** in "line" mode and in columnar modes.
30521 ** --limits L,C Shorthand for "--linelimit L --charlimit C".
30522 ** Or "off" to mean "0,0". Or "on" for "5,300".
30523 ** --list List available modes
 
 
30524 ** --null STRING Render SQL NULL values as the given string
30525 ** --once Setting changes to the right are reverted after
30526 ** the next SQL command.
30527 ** --quote ARG Enable/disable quoting of text. ARG can be
30528 ** "off", "on", "sql", "csv", "html", "tcl",
30529 ** or "json". "off" means show the text as-is.
30530 ** "on" is an alias for "sql".
30531 ** --reset Changes all mode settings back to their default.
30532 ** --rowsep STRING Use STRING as the row separator
30533 ** --sw|--screenwidth N Declare the screen width of the output device
30534 ** to be N characters. An attempt may be made to
30535 ** wrap output text to fit within this limit. Zero
30536 ** means "no limit". Or N can be "auto" to set the
30537 ** width automatically.
30538 ** --tablename NAME Set the name of the table for "insert" mode.
30539 ** --tag NAME Save mode to the left as NAME.
30540 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
30541 ** --title ARG Whether or not to show column headers, and if so
30542 ** how to encode them. ARG can be "off", "on",
30543 ** "sql", "csv", "html", "tcl", or "json".
30544 ** -v|--verbose Verbose output
30545 ** --widths LIST Set the columns widths for columnar modes. The
30546 ** argument is a list of integers, one for each
@@ -30592,10 +30610,23 @@
30610 if( nErr ){
30611 dotCmdError(p, i, "bad alignment string",
30612 "Should contain only characters L, C, and R.");
30613 return 1;
30614 }
30615 }else if( pickStr(z,0,"-blob","-blob-quote","")>=0 ){
30616 if( (++i)>=nArg ){
30617 dotCmdError(p, i-1, "missing argument", 0);
30618 return 1;
30619 }
30620 k = pickStr(azArg[i], 0,
30621 "auto", "text", "sql", "hex", "tcl", "json", "size", "");
30622 /* 0 1 2 3 4 5 6
30623 ** Must match QRF_BLOB_xxxx values. See also tag-20251124a */
30624 if( k>=0 ){
30625 p->mode.spec.eBlob = k & 0xff;
30626 }
30627 chng = 1;
30628 }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
30629 int w; /* 0 1 */
30630 if( i+1>=nArg ){
30631 dotCmdError(p, i, "missing argument", 0);
30632 return 1;
@@ -30622,22 +30653,45 @@
30653 }
30654 chng = 1;
30655 }else if( optionMatch(z,"escape") ){
30656 /* See similar code at tag-20250224-1 */
30657 char *zErr = 0;
30658 if( (++i)>=nArg ){
30659 dotCmdError(p, i-1, "missing argument", 0);
30660 return 1;
30661 } /* 0 1 2 <-- One less than QRF_ESC_ */
 
30662 k = pickStr(azArg[i],&zErr,"off","ascii","symbol","");
30663 if( k<0 ){
30664 dotCmdError(p, i, "unknown escape type", "%s", zErr);
30665 sqlite3_free(zErr);
30666 return 1;
30667 }
30668 p->mode.spec.eEsc = k+1;
30669 chng = 1;
30670 }else if( optionMatch(z,"limits") ){
30671 if( (++i)>=nArg ){
30672 dotCmdError(p, i-1, "missing argument", 0);
30673 return 1;
30674 }
30675 k = pickStr(azArg[i],0,"on","off","");
30676 if( k==0 ){
30677 p->mode.spec.nLineLimit = 5;
30678 p->mode.spec.nCharLimit = 300;
30679 }else if( k==1 ){
30680 p->mode.spec.nLineLimit = 0;
30681 p->mode.spec.nCharLimit = 0;
30682 }else{
30683 int L, C;
30684 int nNum = sscanf(azArg[i], "%d,%d", &L, &C);
30685 if( nNum!=2 || L<0 || C<0 ){
30686 dotCmdError(p, i, "bad argument", "Should be \"L,C\" where L and C"
30687 " are unsigned integers");
30688 return 1;
30689 }
30690 p->mode.spec.nLineLimit = L;
30691 p->mode.spec.nCharLimit = C;
30692 }
30693 chng = 1;
30694 }else if( optionMatch(z,"list") ){
30695 int ii;
30696 cli_puts("available modes:", p->out);
30697 for(ii=0; ii<ArraySize(aModeInfo); ii++){
@@ -30646,24 +30700,20 @@
30700 }
30701 for(ii=0; ii<p->nSavedModes; ii++){
30702 cli_printf(p->out, " %s", p->aSavedModes[ii].zTag);
30703 }
30704 cli_puts(" batch tty\n", p->out);
30705 chng = 1; /* Not really a change, but we still want to suppress the
30706 ** "current mode" output */
30707 }else if( optionMatch(z,"once") ){
30708 p->nPopMode = 0;
30709 modePush(p);
30710 p->nPopMode = 1;
30711 }else if( optionMatch(z,"noquote") ){
30712 /* (undocumented legacy) --noquote always turns quoting off */
30713 p->mode.spec.eText = QRF_TEXT_Plain;
30714 p->mode.spec.eBlob = QRF_BLOB_Auto;
 
 
 
 
 
 
30715 chng = 1;
30716 }else if( optionMatch(z,"quote") ){
30717 if( i+1<nArg
30718 && azArg[i+1][0]!='-'
30719 && (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0)
@@ -30687,59 +30737,54 @@
30737 /* (Legacy) no following boolean argument. Turn quoting on */
30738 k = 1;
30739 }
30740 switch( k ){
30741 case 1: /* on */
30742 modeSetStr(&p->mode.spec.zNull, "NULL");
30743 /* Fall through */
30744 case 2: /* sql */
30745 p->mode.spec.eText = QRF_TEXT_Sql;
 
30746 break;
30747 case 3: /* csv */
30748 p->mode.spec.eText = QRF_TEXT_Csv;
 
30749 break;
30750 case 4: /* html */
30751 p->mode.spec.eText = QRF_TEXT_Html;
 
30752 break;
30753 case 5: /* tcl */
30754 p->mode.spec.eText = QRF_TEXT_Tcl;
 
30755 break;
30756 case 6: /* json */
30757 p->mode.spec.eText = QRF_TEXT_Json;
 
30758 break;
30759 default: /* off */
30760 p->mode.spec.eText = QRF_TEXT_Plain;
 
30761 break;
30762 }
30763 chng = 1;
30764 }else if( optionMatch(z,"reset") ){
30765 int saved_eMode = p->mode.eMode;
30766 modeFree(&p->mode);
30767 modeChange(p, saved_eMode);
30768 }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
30769 if( (++i)>=nArg ){
30770 dotCmdError(p, i-1, "missing argument", 0);
30771 return 1;
30772 }
30773 k = pickStr(azArg[i],0,"off","auto","");
30774 if( k==0 ){
30775 p->mode.bAutoScreenWidth = 0;
30776 p->mode.spec.nScreenWidth = 0;
30777 }else if( k==1 ){
30778 p->mode.bAutoScreenWidth = 1;
30779 }else{
30780 i64 w = integerValue(azArg[i]);
30781 p->mode.bAutoScreenWidth = 0;
30782 if( w<0 ) w = 0;
30783 if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
30784 p->mode.spec.nScreenWidth = w;
30785 }
 
30786 chng = 1;
30787 }else if( optionMatch(z,"tag") ){
30788 size_t nByte;
30789 int n;
30790 const char *zTag;
@@ -30880,11 +30925,19 @@
30925 unsigned char a = p->mode.spec.aAlign[ii];
30926 sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]);
30927 }
30928 sqlite3_str_append(pDesc, "\"", 1);
30929 }
30930 if( bAll || p->mode.spec.eBlob!=QRF_BLOB_Auto ){
30931 const char *azBQuote[] =
30932 { "auto", "text", "sql", "hex", "tcl", "json", "size" };
30933 /* 0 1 2 3 4 5 6
30934 ** Must match QRF_BLOB_xxxx values. See all instances of tag-20251124a */
30935 u8 e = p->mode.spec.eBlob;
30936 sqlite3_str_appendf(pDesc, " --blob-quote %s", azBQuote[e]);
30937 }
30938 if( !bAll && p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit>0 ){
30939 sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit);
30940 }
30941 zSetting = aModeStr[pI->eCSep];
30942 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){
30943 sqlite3_str_appendf(pDesc, " --colsep ");
@@ -30891,11 +30944,19 @@
30944 append_c_string(pDesc, p->mode.spec.zColumnSep);
30945 }
30946 if( bAll || p->mode.spec.eEsc!=QRF_Auto ){
30947 sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]);
30948 }
30949 if( bAll || (p->mode.spec.nLineLimit>0 && p->mode.spec.nCharLimit>0) ){
30950 if( p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit==0 ){
30951 sqlite3_str_appendf(pDesc, " --limits off");
30952 }else{
30953 sqlite3_str_appendf(pDesc, " --limits %d,%d",
30954 p->mode.spec.nLineLimit, p->mode.spec.nCharLimit);
30955 }
30956 }else
30957 if( p->mode.spec.nCharLimit==0 && p->mode.spec.nLineLimit>0 && pI->eCx>0 ){
30958 sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit);
30959 }
30960 zSetting = aModeStr[pI->eNull];
30961 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){
30962 sqlite3_str_appendf(pDesc, " --null ");
30963
+10 -10
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 6d01f9f49eef5f7d4bddadc458691b6ca36e with changes in files:
21
+** d4c1d3e30b774802a7abd5f61807a690fb5b with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470470
#define SQLITE_VERSION "3.52.0"
471471
#define SQLITE_VERSION_NUMBER 3052000
472
-#define SQLITE_SOURCE_ID "2025-11-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca"
472
+#define SQLITE_SOURCE_ID "2025-11-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2025-11-23T10:55:38.669Z"
475
+#define SQLITE_SCM_DATETIME "2025-11-25T13:58:36.873Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -127193,12 +127193,12 @@
127193127193
** but does not include the null terminator.
127194127194
**
127195127195
** The estimate is conservative. It might be larger that what is
127196127196
** really needed.
127197127197
*/
127198
-static int identLength(const char *z){
127199
- int n;
127198
+static i64 identLength(const char *z){
127199
+ i64 n;
127200127200
for(n=0; *z; n++, z++){
127201127201
if( *z=='"' ){ n++; }
127202127202
}
127203127203
return n + 2;
127204127204
}
@@ -149983,12 +149983,12 @@
149983149983
}
149984149984
}
149985149985
}
149986149986
}
149987149987
if( zType ){
149988
- const i64 k = sqlite3Strlen30(zType);
149989
- n = sqlite3Strlen30(pCol->zCnName);
149988
+ const i64 k = strlen(zType);
149989
+ n = strlen(pCol->zCnName);
149990149990
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
149991149991
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
149992149992
if( pCol->zCnName ){
149993149993
memcpy(&pCol->zCnName[n+1], zType, k+1);
149994149994
pCol->colFlags |= COLFLAG_HASTYPE;
@@ -202711,13 +202711,13 @@
202711202711
/*
202712202712
** An instance of the following data structure is used to build doclists
202713202713
** incrementally. See function fts3PendingListAppend() for details.
202714202714
*/
202715202715
struct PendingList {
202716
- int nData;
202716
+ sqlite3_int64 nData;
202717202717
char *aData;
202718
- int nSpace;
202718
+ sqlite3_int64 nSpace;
202719202719
sqlite3_int64 iLastDocid;
202720202720
sqlite3_int64 iLastCol;
202721202721
sqlite3_int64 iLastPos;
202722202722
};
202723202723
@@ -261263,11 +261263,11 @@
261263261263
int nArg, /* Number of args */
261264261264
sqlite3_value **apUnused /* Function arguments */
261265261265
){
261266261266
assert( nArg==0 );
261267261267
UNUSED_PARAM2(nArg, apUnused);
261268
- sqlite3_result_text(pCtx, "fts5: 2025-11-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca", -1, SQLITE_TRANSIENT);
261268
+ sqlite3_result_text(pCtx, "fts5: 2025-11-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7", -1, SQLITE_TRANSIENT);
261269261269
}
261270261270
261271261271
/*
261272261272
** Implementation of fts5_locale(LOCALE, TEXT) function.
261273261273
**
261274261274
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -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 ** 6d01f9f49eef5f7d4bddadc458691b6ca36e with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
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-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-11-23T10:55:38.669Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -127193,12 +127193,12 @@
127193 ** but does not include the null terminator.
127194 **
127195 ** The estimate is conservative. It might be larger that what is
127196 ** really needed.
127197 */
127198 static int identLength(const char *z){
127199 int n;
127200 for(n=0; *z; n++, z++){
127201 if( *z=='"' ){ n++; }
127202 }
127203 return n + 2;
127204 }
@@ -149983,12 +149983,12 @@
149983 }
149984 }
149985 }
149986 }
149987 if( zType ){
149988 const i64 k = sqlite3Strlen30(zType);
149989 n = sqlite3Strlen30(pCol->zCnName);
149990 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
149991 pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
149992 if( pCol->zCnName ){
149993 memcpy(&pCol->zCnName[n+1], zType, k+1);
149994 pCol->colFlags |= COLFLAG_HASTYPE;
@@ -202711,13 +202711,13 @@
202711 /*
202712 ** An instance of the following data structure is used to build doclists
202713 ** incrementally. See function fts3PendingListAppend() for details.
202714 */
202715 struct PendingList {
202716 int nData;
202717 char *aData;
202718 int nSpace;
202719 sqlite3_int64 iLastDocid;
202720 sqlite3_int64 iLastCol;
202721 sqlite3_int64 iLastPos;
202722 };
202723
@@ -261263,11 +261263,11 @@
261263 int nArg, /* Number of args */
261264 sqlite3_value **apUnused /* Function arguments */
261265 ){
261266 assert( nArg==0 );
261267 UNUSED_PARAM2(nArg, apUnused);
261268 sqlite3_result_text(pCtx, "fts5: 2025-11-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca", -1, SQLITE_TRANSIENT);
261269 }
261270
261271 /*
261272 ** Implementation of fts5_locale(LOCALE, TEXT) function.
261273 **
261274
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -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 ** d4c1d3e30b774802a7abd5f61807a690fb5b with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
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-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-11-25T13:58:36.873Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -127193,12 +127193,12 @@
127193 ** but does not include the null terminator.
127194 **
127195 ** The estimate is conservative. It might be larger that what is
127196 ** really needed.
127197 */
127198 static i64 identLength(const char *z){
127199 i64 n;
127200 for(n=0; *z; n++, z++){
127201 if( *z=='"' ){ n++; }
127202 }
127203 return n + 2;
127204 }
@@ -149983,12 +149983,12 @@
149983 }
149984 }
149985 }
149986 }
149987 if( zType ){
149988 const i64 k = strlen(zType);
149989 n = strlen(pCol->zCnName);
149990 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
149991 pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
149992 if( pCol->zCnName ){
149993 memcpy(&pCol->zCnName[n+1], zType, k+1);
149994 pCol->colFlags |= COLFLAG_HASTYPE;
@@ -202711,13 +202711,13 @@
202711 /*
202712 ** An instance of the following data structure is used to build doclists
202713 ** incrementally. See function fts3PendingListAppend() for details.
202714 */
202715 struct PendingList {
202716 sqlite3_int64 nData;
202717 char *aData;
202718 sqlite3_int64 nSpace;
202719 sqlite3_int64 iLastDocid;
202720 sqlite3_int64 iLastCol;
202721 sqlite3_int64 iLastPos;
202722 };
202723
@@ -261263,11 +261263,11 @@
261263 int nArg, /* Number of args */
261264 sqlite3_value **apUnused /* Function arguments */
261265 ){
261266 assert( nArg==0 );
261267 UNUSED_PARAM2(nArg, apUnused);
261268 sqlite3_result_text(pCtx, "fts5: 2025-11-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7", -1, SQLITE_TRANSIENT);
261269 }
261270
261271 /*
261272 ** Implementation of fts5_locale(LOCALE, TEXT) function.
261273 **
261274
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.52.0"
150150
#define SQLITE_VERSION_NUMBER 3052000
151
-#define SQLITE_SOURCE_ID "2025-11-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca"
151
+#define SQLITE_SOURCE_ID "2025-11-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2025-11-23T10:55:38.669Z"
154
+#define SQLITE_SCM_DATETIME "2025-11-25T13:58:36.873Z"
155155
156156
/*
157157
** CAPI3REF: Run-Time Library Version Numbers
158158
** KEYWORDS: sqlite3_version sqlite3_sourceid
159159
**
160160
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
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-23 10:55:38 6d01f9f49eef5f7d4bddadc458691b6ca36e277bae1d4b43b60a128a44e3faca"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-11-23T10:55:38.669Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
160
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
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-25 13:58:36 d4c1d3e30b774802a7abd5f61807a690fb5be7617459f3dbd7ec1efceb6125d7"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-11-25T13:58:36.873Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
160
+19 -33
--- src/xsystem.c
+++ src/xsystem.c
@@ -29,10 +29,11 @@
2929
** header file, and that might be confused with an actual system header
3030
** file.
3131
*/
3232
#include "config.h"
3333
#include "xsystem.h"
34
+#include "qrf.h"
3435
#include <time.h>
3536
3637
3738
/* Date and time */
3839
void xsystem_date(int argc, char **argv){
@@ -76,10 +77,17 @@
7677
#define LS_MTIME 0x004 /* -t Sort by mtime, newest first */
7778
#define LS_SIZE 0x008 /* -S Sort by size, largest first */
7879
#define LS_COMMA 0x010 /* -m Comma-separated list */
7980
#define LS_DIRONLY 0x020 /* -d Show just directory name, not content */
8081
#define LS_ALL 0x040 /* -a Show all entries */
82
+
83
+/* xWrite() callback from QRF
84
+*/
85
+static int xsystem_write(void *NotUsed, const char *zText, sqlite3_int64 n){
86
+ fossil_puts(zText, 0, (int)n);
87
+ return SQLITE_OK;
88
+}
8189
8290
/* Helper function for xsystem_ls(): Make entries in the LS table
8391
** for every file or directory zName.
8492
**
8593
** If zName is a directory, load all files contained within that directory.
@@ -236,45 +244,23 @@
236244
fossil_free(zSql);
237245
sqlite3_finalize(pStmt);
238246
if( sumW>0 ) fossil_print("\n");
239247
}else{
240248
/* Column mode with just filenames */
241
- int nCol, mxWidth, iRow, nSp, nRow;
249
+ sqlite3_qrf_spec spec;
242250
char *zSql;
243
- sqlite3_prepare_v2(db, "SELECT max(dlen),count(*) FROM ls",-1,
244
- &pStmt,0);
245
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
246
- mxWidth = sqlite3_column_int(pStmt,0);
247
- nCol = (terminal_get_width(80)+1)/(mxWidth+2);
248
- if( nCol<1 ) nCol = 1;
249
- nRow = (sqlite3_column_int(pStmt,1)+nCol-1)/nCol;
250
- }else{
251
- nCol = 1;
252
- mxWidth = 100;
253
- nRow = 2000000;
254
- }
255
- sqlite3_finalize(pStmt);
256
- zSql = mprintf("WITH sfn(ii,fn,mtime) AS "
257
- "(SELECT row_number()OVER(ORDER BY %s)-1,fn,mtime FROM ls)"
258
- "SELECT ii/%d,ii%%%d, fn FROM sfn ORDER BY 2,1",
259
- xsystem_ls_orderby(mFlags), nRow, nRow);
251
+ memset(&spec, 0, sizeof(spec));
252
+ spec.iVersion = 1;
253
+ spec.xWrite = xsystem_write;
254
+ spec.eStyle = QRF_STYLE_Column;
255
+ spec.bSplitColumn = QRF_Yes;
256
+ spec.bTitles = QRF_No;
257
+ spec.nScreenWidth = terminal_get_width(80);
258
+ zSql = mprintf("SELECT fn FROM ls ORDER BY %s", xsystem_ls_orderby(mFlags));
260259
sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
261
- nSp = 0;
262
- iRow = -1;
263
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
264
- const char *zFN = (const char*)sqlite3_column_text(pStmt, 2);
265
- int thisRow = sqlite3_column_int(pStmt,1);
266
- if( iRow!=thisRow ){
267
- if( iRow>=0 ) fossil_print("\n");
268
- iRow = thisRow;
269
- }else{
270
- if( nSp ) fossil_print("%*s",nSp,"");
271
- }
272
- fossil_print("%s", zFN);
273
- nSp = mxWidth - (int)strlen(zFN) + 2;
274
- }
275
- fossil_print("\n");
260
+ fossil_free(zSql);
261
+ sqlite3_format_query_result(pStmt, &spec, 0);
276262
sqlite3_finalize(pStmt);
277263
}
278264
sqlite3_exec(db, "DELETE FROM ls;", 0, 0, 0);
279265
}
280266
281267
--- src/xsystem.c
+++ src/xsystem.c
@@ -29,10 +29,11 @@
29 ** header file, and that might be confused with an actual system header
30 ** file.
31 */
32 #include "config.h"
33 #include "xsystem.h"
 
34 #include <time.h>
35
36
37 /* Date and time */
38 void xsystem_date(int argc, char **argv){
@@ -76,10 +77,17 @@
76 #define LS_MTIME 0x004 /* -t Sort by mtime, newest first */
77 #define LS_SIZE 0x008 /* -S Sort by size, largest first */
78 #define LS_COMMA 0x010 /* -m Comma-separated list */
79 #define LS_DIRONLY 0x020 /* -d Show just directory name, not content */
80 #define LS_ALL 0x040 /* -a Show all entries */
 
 
 
 
 
 
 
81
82 /* Helper function for xsystem_ls(): Make entries in the LS table
83 ** for every file or directory zName.
84 **
85 ** If zName is a directory, load all files contained within that directory.
@@ -236,45 +244,23 @@
236 fossil_free(zSql);
237 sqlite3_finalize(pStmt);
238 if( sumW>0 ) fossil_print("\n");
239 }else{
240 /* Column mode with just filenames */
241 int nCol, mxWidth, iRow, nSp, nRow;
242 char *zSql;
243 sqlite3_prepare_v2(db, "SELECT max(dlen),count(*) FROM ls",-1,
244 &pStmt,0);
245 if( sqlite3_step(pStmt)==SQLITE_ROW ){
246 mxWidth = sqlite3_column_int(pStmt,0);
247 nCol = (terminal_get_width(80)+1)/(mxWidth+2);
248 if( nCol<1 ) nCol = 1;
249 nRow = (sqlite3_column_int(pStmt,1)+nCol-1)/nCol;
250 }else{
251 nCol = 1;
252 mxWidth = 100;
253 nRow = 2000000;
254 }
255 sqlite3_finalize(pStmt);
256 zSql = mprintf("WITH sfn(ii,fn,mtime) AS "
257 "(SELECT row_number()OVER(ORDER BY %s)-1,fn,mtime FROM ls)"
258 "SELECT ii/%d,ii%%%d, fn FROM sfn ORDER BY 2,1",
259 xsystem_ls_orderby(mFlags), nRow, nRow);
260 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
261 nSp = 0;
262 iRow = -1;
263 while( sqlite3_step(pStmt)==SQLITE_ROW ){
264 const char *zFN = (const char*)sqlite3_column_text(pStmt, 2);
265 int thisRow = sqlite3_column_int(pStmt,1);
266 if( iRow!=thisRow ){
267 if( iRow>=0 ) fossil_print("\n");
268 iRow = thisRow;
269 }else{
270 if( nSp ) fossil_print("%*s",nSp,"");
271 }
272 fossil_print("%s", zFN);
273 nSp = mxWidth - (int)strlen(zFN) + 2;
274 }
275 fossil_print("\n");
276 sqlite3_finalize(pStmt);
277 }
278 sqlite3_exec(db, "DELETE FROM ls;", 0, 0, 0);
279 }
280
281
--- src/xsystem.c
+++ src/xsystem.c
@@ -29,10 +29,11 @@
29 ** header file, and that might be confused with an actual system header
30 ** file.
31 */
32 #include "config.h"
33 #include "xsystem.h"
34 #include "qrf.h"
35 #include <time.h>
36
37
38 /* Date and time */
39 void xsystem_date(int argc, char **argv){
@@ -76,10 +77,17 @@
77 #define LS_MTIME 0x004 /* -t Sort by mtime, newest first */
78 #define LS_SIZE 0x008 /* -S Sort by size, largest first */
79 #define LS_COMMA 0x010 /* -m Comma-separated list */
80 #define LS_DIRONLY 0x020 /* -d Show just directory name, not content */
81 #define LS_ALL 0x040 /* -a Show all entries */
82
83 /* xWrite() callback from QRF
84 */
85 static int xsystem_write(void *NotUsed, const char *zText, sqlite3_int64 n){
86 fossil_puts(zText, 0, (int)n);
87 return SQLITE_OK;
88 }
89
90 /* Helper function for xsystem_ls(): Make entries in the LS table
91 ** for every file or directory zName.
92 **
93 ** If zName is a directory, load all files contained within that directory.
@@ -236,45 +244,23 @@
244 fossil_free(zSql);
245 sqlite3_finalize(pStmt);
246 if( sumW>0 ) fossil_print("\n");
247 }else{
248 /* Column mode with just filenames */
249 sqlite3_qrf_spec spec;
250 char *zSql;
251 memset(&spec, 0, sizeof(spec));
252 spec.iVersion = 1;
253 spec.xWrite = xsystem_write;
254 spec.eStyle = QRF_STYLE_Column;
255 spec.bSplitColumn = QRF_Yes;
256 spec.bTitles = QRF_No;
257 spec.nScreenWidth = terminal_get_width(80);
258 zSql = mprintf("SELECT fn FROM ls ORDER BY %s", xsystem_ls_orderby(mFlags));
 
 
 
 
 
 
 
 
 
259 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
260 fossil_free(zSql);
261 sqlite3_format_query_result(pStmt, &spec, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
262 sqlite3_finalize(pStmt);
263 }
264 sqlite3_exec(db, "DELETE FROM ls;", 0, 0, 0);
265 }
266
267

Keyboard Shortcuts

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