Fossil SCM

Update the built-in SQLite to the latest trunk version that include improvements to the CLI, and especially the "--titles always" option.

drh 2026-07-08 16:08 UTC trunk
Commit ee873715cc5f293bc907f7a09d0b5297fe94e5e17ac37f18d5f62210d6b96cf2
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,12 @@
5555
char *(*xRender)(void*,sqlite3_value*); /* Render a value */
5656
int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
5757
void *pRenderArg; /* First argument to the xRender callback */
5858
void *pWriteArg; /* First argument to the xWrite callback */
5959
char **pzOutput; /* Storage location for output string */
60
+ /* The following are available in iVersion 2 and later */
61
+ unsigned char bRowCount; /* Show the number of rows at end of each query */
6062
/* Additional fields may be added in the future */
6163
};
6264
6365
/*
6466
** Interfaces
@@ -143,10 +145,15 @@
143145
#define QRF_SW_On 2 /* This setting is forced on */
144146
#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
145147
#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
146148
#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
147149
150
+/*
151
+** Additional value allowed for bTitles
152
+*/
153
+#define QRF_Always 3 /* Always show titles, even if no rows */
154
+
148155
/*
149156
** Possible alignment values alignment settings
150157
**
151158
** Horizontal Vertial
152159
** ---------- -------- */
153160
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,12 @@
55 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
56 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
57 void *pRenderArg; /* First argument to the xRender callback */
58 void *pWriteArg; /* First argument to the xWrite callback */
59 char **pzOutput; /* Storage location for output string */
 
 
60 /* Additional fields may be added in the future */
61 };
62
63 /*
64 ** Interfaces
@@ -143,10 +145,15 @@
143 #define QRF_SW_On 2 /* This setting is forced on */
144 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
145 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
146 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
147
 
 
 
 
 
148 /*
149 ** Possible alignment values alignment settings
150 **
151 ** Horizontal Vertial
152 ** ---------- -------- */
153
--- extsrc/qrf.h
+++ extsrc/qrf.h
@@ -55,10 +55,12 @@
55 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
56 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
57 void *pRenderArg; /* First argument to the xRender callback */
58 void *pWriteArg; /* First argument to the xWrite callback */
59 char **pzOutput; /* Storage location for output string */
60 /* The following are available in iVersion 2 and later */
61 unsigned char bRowCount; /* Show the number of rows at end of each query */
62 /* Additional fields may be added in the future */
63 };
64
65 /*
66 ** Interfaces
@@ -143,10 +145,15 @@
145 #define QRF_SW_On 2 /* This setting is forced on */
146 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
147 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
148 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
149
150 /*
151 ** Additional value allowed for bTitles
152 */
153 #define QRF_Always 3 /* Always show titles, even if no rows */
154
155 /*
156 ** Possible alignment values alignment settings
157 **
158 ** Horizontal Vertial
159 ** ---------- -------- */
160
+435 -91
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -23,10 +23,11 @@
2323
** ext/misc/shathree.c
2424
** ext/misc/sqlar.c
2525
** ext/misc/sqlite3_stdio.c
2626
** ext/misc/sqlite3_stdio.h
2727
** ext/misc/stmtrand.c
28
+** ext/misc/strdup.c
2829
** ext/misc/uint.c
2930
** ext/misc/vfstrace.c
3031
** ext/misc/windirent.h
3132
** ext/misc/zipfile.c
3233
** ext/qrf/qrf.c
@@ -733,10 +734,12 @@
733734
char *(*xRender)(void*,sqlite3_value*); /* Render a value */
734735
int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
735736
void *pRenderArg; /* First argument to the xRender callback */
736737
void *pWriteArg; /* First argument to the xWrite callback */
737738
char **pzOutput; /* Storage location for output string */
739
+ /* The following are available in iVersion 2 and later */
740
+ unsigned char bRowCount; /* Show the number of rows at end of each query */
738741
/* Additional fields may be added in the future */
739742
};
740743
741744
/*
742745
** Interfaces
@@ -821,10 +824,15 @@
821824
#define QRF_SW_On 2 /* This setting is forced on */
822825
#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
823826
#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
824827
#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
825828
829
+/*
830
+** Additional value allowed for bTitles
831
+*/
832
+#define QRF_Always 3 /* Always show titles, even if no rows */
833
+
826834
/*
827835
** Possible alignment values alignment settings
828836
**
829837
** Horizontal Vertial
830838
** ---------- -------- */
@@ -2527,10 +2535,14 @@
25272535
/* Doubled horizontal lines: */
25282536
#define DBL_24 "\342\225\220" /* U+2550 === */
25292537
#define DBL_123 "\342\225\236" /* U+255e |= */
25302538
#define DBL_134 "\342\225\241" /* U+2561 =| */
25312539
#define DBL_1234 "\342\225\252" /* U+256a =|= */
2540
+#define DBL_12 "\342\225\230" /* U+2558 `= */
2541
+#define DBL_14 "\342\225\233" /* U+255b =' */
2542
+#define DBL_124 "\342\225\247" /* U+2567 ='= */
2543
+
25322544
25332545
/* Draw horizontal line N characters long using unicode box
25342546
** characters
25352547
*/
25362548
static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2549,16 +2561,16 @@
25492561
25502562
/*
25512563
** Draw a horizontal separator for a QRF_STYLE_Box table.
25522564
*/
25532565
static void qrfBoxSeparator(
2554
- sqlite3_str *pOut,
2555
- qrfColData *p,
2556
- const char *zSep1,
2557
- const char *zSep2,
2558
- const char *zSep3,
2559
- int bDbl
2566
+ sqlite3_str *pOut, /* Output to this sqlite3_str */
2567
+ qrfColData *p, /* Columnar data */
2568
+ const char *zSep1, /* Left margin */
2569
+ const char *zSep2, /* Column separator */
2570
+ const char *zSep3, /* Right margin */
2571
+ int bDbl /* True for double-lines */
25602572
){
25612573
int i;
25622574
if( p->nCol>0 ){
25632575
int useBorder = p->p->spec.bBorder!=QRF_No;
25642576
if( useBorder ){
@@ -2573,10 +2585,36 @@
25732585
sqlite3_str_appendall(pOut, zSep3);
25742586
}
25752587
}
25762588
sqlite3_str_append(pOut, "\n", 1);
25772589
}
2590
+
2591
+/*
2592
+** Draw a horizontal separator for a QRF_STYLE_Column table.
2593
+** This style of separator is only used for separating the title
2594
+** from the content.
2595
+*/
2596
+static void qrfColumnSeparator(
2597
+ sqlite3_str *pOut, /* Output to this sqlite3_str */
2598
+ qrfColData *p, /* Columnar data */
2599
+ const char *colSep, /* Column separator text */
2600
+ int szColSep, /* Size of zColSep in bytes */
2601
+ const char *rowSep, /* Row separator text */
2602
+ int szRowSep /* Size of zRowSep in bytes */
2603
+){
2604
+ int j;
2605
+ int nColumn = p->nCol;
2606
+ for(j=0; j<nColumn; j++){
2607
+ sqlite3_str_appendchar(pOut, p->a[j].w, '-');
2608
+ if( j<nColumn-1 ){
2609
+ sqlite3_str_append(pOut, colSep, szColSep);
2610
+ }else{
2611
+ qrfRTrim(pOut);
2612
+ sqlite3_str_append(pOut, rowSep, szRowSep);
2613
+ }
2614
+ }
2615
+}
25782616
25792617
/*
25802618
** Load into pData the default alignment for the body of a table.
25812619
*/
25822620
static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2831,11 +2869,25 @@
28312869
sqlite3_str *pStr; /* Temporary rendering */
28322870
qrfColData data; /* Columnar layout data */
28332871
int bRTrim; /* Trim trailing space */
28342872
28352873
rc = sqlite3_step(p->pStmt);
2836
- if( rc!=SQLITE_ROW || nColumn==0 ){
2874
+ if( nColumn==0 ){
2875
+ return; /* Not a query. No results every shown. */
2876
+ }
2877
+ if( rc==SQLITE_DONE && nColumn>0 ){
2878
+ /* Empty query */
2879
+ if( p->spec.bTitles==QRF_Always ){
2880
+ /* fall through into the columnar logic below */
2881
+ }else{
2882
+ if( p->spec.bRowCount==QRF_Yes ){
2883
+ sqlite3_str_appendf(p->pOut, "(0 rows)\n");
2884
+ qrfWrite(p);
2885
+ }
2886
+ return; /* No output, other than the row count */
2887
+ }
2888
+ }else if( rc!=SQLITE_ROW ){
28372889
return; /* No output */
28382890
}
28392891
28402892
/* Initialize the data container */
28412893
memset(&data, 0, sizeof(data));
@@ -2848,12 +2900,12 @@
28482900
}
28492901
memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
28502902
if( qrfColDataEnlarge(&data) ) return;
28512903
assert( data.az!=0 );
28522904
2853
- /* Load the column header names and all cell content into data */
2854
- if( p->spec.bTitles==QRF_Yes ){
2905
+ /* Load the column header names into data */
2906
+ if( p->spec.bTitles>=QRF_Yes ){
28552907
unsigned char saved_eText = p->spec.eText;
28562908
p->spec.eText = p->spec.eTitle;
28572909
memset(data.abNum, 0, nColumn);
28582910
for(i=0; i<nColumn; i++){
28592911
const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2874,13 +2926,14 @@
28742926
data.n++;
28752927
if( w>data.a[i].mxW ) data.a[i].mxW = w;
28762928
if( nNL ) data.bMultiRow = 1;
28772929
}
28782930
p->spec.eText = saved_eText;
2879
- p->nRow++;
28802931
}
2881
- do{
2932
+
2933
+ /* Load query results into data */
2934
+ while( rc==SQLITE_ROW && p->iErr==SQLITE_OK ){
28822935
if( data.n+nColumn > data.nAlloc ){
28832936
if( qrfColDataEnlarge(&data) ) return;
28842937
}
28852938
for(i=0; i<nColumn; i++){
28862939
char *z;
@@ -2897,11 +2950,12 @@
28972950
data.n++;
28982951
if( w>data.a[i].mxW ) data.a[i].mxW = w;
28992952
if( nNL ) data.bMultiRow = 1;
29002953
}
29012954
p->nRow++;
2902
- }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
2955
+ rc = sqlite3_step(p->pStmt);
2956
+ }
29032957
if( p->iErr ){
29042958
qrfColDataFree(&data);
29052959
return;
29062960
}
29072961
@@ -3105,11 +3159,11 @@
31053159
/* Draw either (1) the separator between the title line and the body
31063160
** of the table, or (2) separators between individual rows of the table
31073161
** body. isTitleDataSeparator will be true if we are doing (1).
31083162
*/
31093163
if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3110
- int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
3164
+ int isTitleDataSeparator = (i==0 && p->spec.bTitles>=QRF_Yes);
31113165
if( isTitleDataSeparator ){
31123166
qrfLoadAlignment(&data, p);
31133167
}
31143168
switch( p->spec.eStyle ){
31153169
case QRF_STYLE_Table: {
@@ -3132,19 +3186,12 @@
31323186
}
31333187
break;
31343188
}
31353189
case QRF_STYLE_Column: {
31363190
if( isTitleDataSeparator ){
3137
- for(j=0; j<nColumn; j++){
3138
- sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
3139
- if( j<nColumn-1 ){
3140
- sqlite3_str_append(p->pOut, colSep, szColSep);
3141
- }else{
3142
- qrfRTrim(p->pOut);
3143
- sqlite3_str_append(p->pOut, rowSep, szRowSep);
3144
- }
3145
- }
3191
+ qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3192
+ rowSep, szRowSep);
31463193
}else if( data.bMultiRow ){
31473194
qrfRTrim(p->pOut);
31483195
sqlite3_str_append(p->pOut, "\n", 1);
31493196
}
31503197
break;
@@ -3152,20 +3199,39 @@
31523199
}
31533200
}
31543201
}
31553202
31563203
/* Draw the line across the bottom of the table */
3157
- if( p->spec.bBorder!=QRF_No ){
3204
+ if( p->spec.bBorder!=QRF_No || p->nRow==0 ){
31583205
switch( p->spec.eStyle ){
31593206
case QRF_STYLE_Box:
3160
- qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3207
+ if( p->nRow>0 ){
3208
+ qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3209
+ }else{
3210
+ qrfBoxSeparator(p->pOut, &data, DBL_12, DBL_124, DBL_14, 1);
3211
+ }
31613212
break;
31623213
case QRF_STYLE_Table:
31633214
qrfRowSeparator(p->pOut, &data, '+');
31643215
break;
3216
+ case QRF_STYLE_Markdown:
3217
+ if( p->nRow==0 ){
3218
+ qrfRowSeparator(p->pOut, &data, '|');
3219
+ }
3220
+ break;
3221
+ case QRF_STYLE_Column:
3222
+ if( p->nRow==0 ){
3223
+ qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3224
+ rowSep, szRowSep);
3225
+ }
3226
+ break;
31653227
}
31663228
}
3229
+ if( p->spec.bRowCount==QRF_Yes ){
3230
+ sqlite3_int64 n = p->nRow;
3231
+ sqlite3_str_appendf(p->pOut, "(%lld row%s)\n", n, n==1 ? "" : "s");
3232
+ }
31673233
qrfWrite(p);
31683234
31693235
qrfColDataFree(&data);
31703236
return;
31713237
}
@@ -3412,10 +3478,49 @@
34123478
sqlite3_str_append(p->pOut, ":", 1);
34133479
qrfRenderValue(p, p->pOut, i);
34143480
}
34153481
qrfWrite(p);
34163482
}
3483
+
3484
+/*
3485
+** Render a title row (a row containing column names) if the spec
3486
+** calls for one and if it makes sense for the eStyle. Title rows
3487
+** do not make sense for some eStyles, such as QRF_STYLE_Off,
3488
+** QRF_STYLE_Count, QRF_STYLE_Json, and similar.
3489
+*/
3490
+static void qrfSimpleTitle(Qrf *p){
3491
+ assert( p->nRow==0 );
3492
+ assert( p->spec.bTitles>=QRF_Yes );
3493
+ switch( p->spec.eStyle ){
3494
+ case QRF_STYLE_Html: {
3495
+ int i;
3496
+ sqlite3_str_append(p->pOut, "<TR>", 4);
3497
+ for(i=0; i<p->nCol; i++){
3498
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
3499
+ sqlite3_str_append(p->pOut, "\n<TH>", 5);
3500
+ qrfEncodeText(p, p->pOut, zCName);
3501
+ }
3502
+ sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3503
+ break;
3504
+ }
3505
+ case QRF_STYLE_Quote:
3506
+ case QRF_STYLE_List: {
3507
+ int i;
3508
+ int saved_eText = p->spec.eText;
3509
+ p->spec.eText = p->spec.eTitle;
3510
+ for(i=0; i<p->nCol; i++){
3511
+ const char *zCName = sqlite3_column_name(p->pStmt, i);
3512
+ if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3513
+ qrfEncodeText(p, p->pOut, zCName);
3514
+ }
3515
+ sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3516
+ qrfWrite(p);
3517
+ p->spec.eText = saved_eText;
3518
+ break;
3519
+ }
3520
+ }
3521
+}
34173522
34183523
/*
34193524
** Render a single row of output for non-columnar styles - any
34203525
** style that lets us render row by row as the content is received
34213526
** from the query.
@@ -3445,18 +3550,12 @@
34453550
}
34463551
qrfOneJsonRow(p);
34473552
break;
34483553
}
34493554
case QRF_STYLE_Html: {
3450
- if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3451
- sqlite3_str_append(p->pOut, "<TR>", 4);
3452
- for(i=0; i<p->nCol; i++){
3453
- const char *zCName = sqlite3_column_name(p->pStmt, i);
3454
- sqlite3_str_append(p->pOut, "\n<TH>", 5);
3455
- qrfEncodeText(p, p->pOut, zCName);
3456
- }
3457
- sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3555
+ if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3556
+ qrfSimpleTitle(p);
34583557
}
34593558
sqlite3_str_append(p->pOut, "<TR>", 4);
34603559
for(i=0; i<p->nCol; i++){
34613560
sqlite3_str_append(p->pOut, "\n<TD>", 5);
34623561
qrfRenderValue(p, p->pOut, i);
@@ -3476,11 +3575,11 @@
34763575
if( qrf_need_quote(p->spec.zTableName) ){
34773576
sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
34783577
}else{
34793578
sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
34803579
}
3481
- if( p->spec.bTitles==QRF_Yes ){
3580
+ if( p->spec.bTitles>=QRF_Yes ){
34823581
for(i=0; i<p->nCol; i++){
34833582
const char *zCName = sqlite3_column_name(p->pStmt, i);
34843583
if( qrf_need_quote(zCName) ){
34853584
sqlite3_str_appendf(p->pOut, "%c\"%w\"",
34863585
i==0 ? '(' : ',', zCName);
@@ -3576,21 +3675,12 @@
35763675
if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
35773676
qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
35783677
break;
35793678
}
35803679
default: { /* QRF_STYLE_List */
3581
- if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3582
- int saved_eText = p->spec.eText;
3583
- p->spec.eText = p->spec.eTitle;
3584
- for(i=0; i<p->nCol; i++){
3585
- const char *zCName = sqlite3_column_name(p->pStmt, i);
3586
- if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3587
- qrfEncodeText(p, p->pOut, zCName);
3588
- }
3589
- sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3590
- qrfWrite(p);
3591
- p->spec.eText = saved_eText;
3680
+ if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3681
+ qrfSimpleTitle(p);
35923682
}
35933683
for(i=0; i<p->nCol; i++){
35943684
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
35953685
qrfRenderValue(p, p->pOut, i);
35963686
}
@@ -3612,11 +3702,11 @@
36123702
char **pzErr /* Write errors here */
36133703
){
36143704
size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
36153705
memset(p, 0, sizeof(*p));
36163706
p->pzErr = pzErr;
3617
- if( pSpec->iVersion>1 ){
3707
+ if( pSpec->iVersion>2 ){
36183708
qrfError(p, SQLITE_ERROR,
36193709
"unusable sqlite3_qrf_spec.iVersion (%d)",
36203710
pSpec->iVersion);
36213711
return;
36223712
}
@@ -3640,10 +3730,13 @@
36403730
if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
36413731
if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
36423732
if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
36433733
if( p->spec.eTitle>QRF_TEXT_Relaxed ) p->spec.eTitle = QRF_Auto;
36443734
if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto;
3735
+ if( pSpec->iVersion<=1 ){
3736
+ p->spec.bRowCount = 0;
3737
+ }
36453738
qrf_reinit:
36463739
switch( p->spec.eStyle ){
36473740
case QRF_Auto: {
36483741
switch( sqlite3_stmt_isexplain(pStmt) ){
36493742
case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3898,10 +3991,34 @@
38983991
default: {
38993992
/* Non-columnar modes where the output can occur after each row
39003993
** of result is received */
39013994
while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
39023995
qrfOneSimpleRow(&qrf);
3996
+ }
3997
+ if( qrf.nCol>0 && qrf.nRow==0 && qrf.spec.bTitles==QRF_Always ){
3998
+ qrfSimpleTitle(&qrf);
3999
+ }
4000
+ if( qrf.nCol>0 && qrf.spec.bRowCount==QRF_Yes ){
4001
+ const char *zPlural = qrf.nRow==1 ? "" : "s";
4002
+ switch( qrf.spec.eStyle ){
4003
+ case QRF_STYLE_Line:
4004
+ if( qrf.nRow>0 ) sqlite3_str_append(qrf.pOut, "\n", 1);
4005
+ /* Fall through */
4006
+ case QRF_STYLE_Csv:
4007
+ case QRF_STYLE_List:
4008
+ case QRF_STYLE_Quote:
4009
+ sqlite3_str_appendf(qrf.pOut,"(%lld row%s)\n",qrf.nRow,zPlural);
4010
+ break;
4011
+ case QRF_STYLE_Html:
4012
+ sqlite3_str_appendf(qrf.pOut,"<!-- %lld row%s -->\n",
4013
+ qrf.nRow, zPlural);
4014
+ break;
4015
+ case QRF_STYLE_Insert:
4016
+ sqlite3_str_appendf(qrf.pOut,"/* %lld row%s inserted */\n",
4017
+ qrf.nRow, zPlural);
4018
+ break;
4019
+ }
39034020
}
39044021
break;
39054022
}
39064023
}
39074024
qrfResetStmt(&qrf);
@@ -10602,11 +10719,15 @@
1060210719
sqlite3_result_error_nomem(ctx);
1060310720
return SQLITE_NOMEM;
1060410721
}
1060510722
}
1060610723
10607
- sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10724
+ if( n>0 ){
10725
+ sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10726
+ }else{
10727
+ sqlite3_result_null(ctx);
10728
+ }
1060810729
if( aBuf!=aStatic ) sqlite3_free(aBuf);
1060910730
#endif
1061010731
}else{
1061110732
readFileContents(ctx, pCur->zPath);
1061210733
}
@@ -17600,10 +17721,13 @@
1760017721
else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
1760117722
while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
1760217723
iRet++;
1760317724
}
1760417725
}
17726
+ else if( c==0 ){
17727
+ iRet = 0;
17728
+ }
1760517729
1760617730
return iRet;
1760717731
}
1760817732
1760917733
/*
@@ -18039,10 +18163,27 @@
1803918163
intckFinalize(p, pStmt);
1804018164
1804118165
if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
1804218166
return zRet;
1804318167
}
18168
+
18169
+/*
18170
+** Register or unregister special SQL functions implemented by intck.
18171
+**
18172
+** Normally the custom SQL functions used by intck are only available
18173
+** in between sqlite3_intck_open() and sqlite3_intck_close(). However,
18174
+** for testing and debugging, it is sometimes useful to make those
18175
+** functions available generally. This routine provides as a separate
18176
+** interface in order to provide that capability.
18177
+*/
18178
+int sqlite3_intck_register(sqlite3 *db, int bCreate){
18179
+ int rc;
18180
+ rc = sqlite3_create_function(db, "parse_create_index",
18181
+ 2, SQLITE_UTF8, 0, bCreate ? intckParseCreateIndexFunc : 0, 0, 0
18182
+ );
18183
+ return rc;
18184
+}
1804418185
1804518186
/*
1804618187
** Open a new integrity-check object.
1804718188
*/
1804818189
int sqlite3_intck_open(
@@ -18061,13 +18202,11 @@
1806118202
}else{
1806218203
memset(pNew, 0, sizeof(*pNew));
1806318204
pNew->db = db;
1806418205
pNew->zDb = (const char*)&pNew[1];
1806518206
memcpy(&pNew[1], zDb, nDb+1);
18066
- rc = sqlite3_create_function(db, "parse_create_index",
18067
- 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
18068
- );
18207
+ rc = sqlite3_intck_register(db, 1);
1806918208
if( rc!=SQLITE_OK ){
1807018209
sqlite3_intck_close(pNew);
1807118210
pNew = 0;
1807218211
}
1807318212
}
@@ -18080,13 +18219,11 @@
1808018219
** Free the integrity-check object.
1808118220
*/
1808218221
void sqlite3_intck_close(sqlite3_intck *p){
1808318222
if( p ){
1808418223
sqlite3_finalize(p->pCheck);
18085
- sqlite3_create_function(
18086
- p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
18087
- );
18224
+ sqlite3_intck_register(p->db, 0);
1808818225
sqlite3_free(p->zObj);
1808918226
sqlite3_free(p->zKey);
1809018227
sqlite3_free(p->zTestSql);
1809118228
sqlite3_free(p->zErr);
1809218229
sqlite3_free(p->zMessage);
@@ -20370,10 +20507,122 @@
2037020507
0, diskusedFunc, 0, 0);
2037120508
return rc;
2037220509
}
2037320510
2037420511
/************************* End ext/misc/diskused.c ********************/
20512
+/************************* Begin ext/misc/strdup.c ******************/
20513
+/*
20514
+** 2026-07-04
20515
+**
20516
+** The author disclaims copyright to this source code. In place of
20517
+** a legal notice, here is a blessing:
20518
+**
20519
+** May you do good and not evil.
20520
+** May you find forgiveness for yourself and forgive others.
20521
+** May you share freely, never taking more than you give.
20522
+**
20523
+******************************************************************************
20524
+**
20525
+** Since this module was written (coincidentally) on the 250th anniversary
20526
+** of the signing of the Declaration of Independence of The United States,
20527
+** it seems fitting to quote from that document:
20528
+**
20529
+** We hold these truths to be self-evident, that all men are created
20530
+** equal, that they are endowed by their Creator with certain unalienable
20531
+** Rights, that among these are Life, Liberty and the pursuit of Happiness
20532
+** - That to secure these rights, Governments are instituted among Men,
20533
+** deriving their just powers from the consent of the governed,....
20534
+**
20535
+** Two core ideas that (1) rights come from God and not from government,
20536
+** and that (2) there should not be special privileged classes of people
20537
+** were radical thoughts then, and are indeed disputed even today. Many
20538
+** people still hold that human rights derive from the beneficence of
20539
+** government and that certain classes of people have special rights and
20540
+** privileges not available to all. Yet, were it not for the crazy ideas
20541
+** espoused in the original Declaration of Independence, this software
20542
+** project, and indeed most of modern technology, would not exist.
20543
+**
20544
+** Therefore let us give thanks for the bold leadership and vision
20545
+** demonstrated by the authors of the American Revolution, 250 years ago
20546
+** this day.
20547
+**
20548
+******************************************************************************
20549
+**
20550
+** Implementation of the strdup() SQL function. strdup() makes a copy
20551
+** of its argument (a string or a BLOB) into memory obtained directly
20552
+** from system malloc() (not from sqlite3_malloc()) and sized exactly
20553
+** to hold the string or BLOB. This is intended for testing purposes,
20554
+** particularly testing with ASAN. This function serves no practical
20555
+** purpose beyond testing and not not intended for production use.
20556
+**
20557
+** NULL, BLOB, and TEXT values come through as NULL, BLOB, and TEXT,
20558
+** respectively. Numeric values are rendered as strings and come out
20559
+** as text.
20560
+*/
20561
+/* #include "sqlite3ext.h" */
20562
+SQLITE_EXTENSION_INIT1
20563
+#include <assert.h>
20564
+#include <string.h>
20565
+#include <stdlib.h>
20566
+
20567
+/*
20568
+** Make a copy of a string or BLOB in memory obtained from malloc().
20569
+*/
20570
+static void strdupfunc(
20571
+ sqlite3_context *context,
20572
+ int argc,
20573
+ sqlite3_value **argv
20574
+){
20575
+ const unsigned char *zIn;
20576
+ int nIn;
20577
+ unsigned char *zOut;
20578
+
20579
+ assert( argc==1 );
20580
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
20581
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
20582
+ zIn = (const unsigned char*)sqlite3_value_blob(argv[0]);
20583
+ nIn = sqlite3_value_bytes(argv[0]);
20584
+ zOut = malloc( nIn==0 ? 1 : nIn );
20585
+ if( zOut==0 ){
20586
+ sqlite3_result_error_nomem(context);
20587
+ return;
20588
+ }
20589
+ if( nIn>0 ) memcpy(zOut, zIn, nIn);
20590
+ sqlite3_result_blob(context, zOut, nIn, free);
20591
+ }else{
20592
+ zIn = (const unsigned char*)sqlite3_value_text(argv[0]);
20593
+ if( zIn==0 ) return;
20594
+ nIn = (int)strlen((char*)zIn);
20595
+ zOut = malloc( nIn+1 );
20596
+ if( zOut==0 ){
20597
+ sqlite3_result_error_nomem(context);
20598
+ return;
20599
+ }
20600
+ memcpy(zOut, zIn, nIn);
20601
+ zOut[nIn] = 0;
20602
+ sqlite3_result_text64(context, (char*)zOut, nIn, free,
20603
+ SQLITE_UTF8_ZT);
20604
+ }
20605
+}
20606
+
20607
+#ifdef _WIN32
20608
+
20609
+#endif
20610
+int sqlite3_strdup_init(
20611
+ sqlite3 *db,
20612
+ char **pzErrMsg,
20613
+ const sqlite3_api_routines *pApi
20614
+){
20615
+ int rc = SQLITE_OK;
20616
+ SQLITE_EXTENSION_INIT2(pApi);
20617
+ (void)pzErrMsg; /* Unused parameter */
20618
+ rc = sqlite3_create_function(db, "strdup", 1, SQLITE_UTF8,
20619
+ 0, strdupfunc, 0, 0);
20620
+ return rc;
20621
+}
20622
+
20623
+/************************* End ext/misc/strdup.c ********************/
2037520624
2037620625
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
2037720626
#define SQLITE_SHELL_HAVE_RECOVER 1
2037820627
#else
2037920628
#define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24837,11 +25086,11 @@
2483725086
unsigned char eHdr; /* Default header encoding. */
2483825087
unsigned char eBlob; /* Default blob encoding. */
2483925088
unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
2484025089
unsigned char eStyle; /* Underlying QRF style */
2484125090
unsigned char eCx; /* 0: other, 1: line, 2: columnar */
24842
- unsigned char mFlg; /* Flags. 1=border-off 2=split-column */
25091
+ unsigned char mFlg; /* Flags. 1=border-off 2=split-column 4=rowcount */
2484325092
};
2484425093
2484525094
/* String constants used by built-in modes */
2484625095
static const char *aModeStr[] =
2484725096
/* 0 1 2 3 4 5 6 7 8 */
@@ -24850,45 +25099,45 @@
2485025099
/* 9 10 11 12 13 */
2485125100
2485225101
static const ModeInfo aModeInfo[] = {
2485325102
/* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
2485425103
{ "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
24855
- { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2, 0 },
25104
+ { "box", 0, 0, 9, 1, 1, 0, 3, 1, 2, 0 },
2485625105
{ "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
24857
- { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2, 0 },
25106
+ { "column", 0, 0, 9, 1, 1, 0, 3, 2, 2, 0 },
2485825107
{ "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
2485925108
{ "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
24860
- { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 },
25109
+ { "html", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 },
2486125110
{ "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
2486225111
{ "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
2486325112
{ "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
2486425113
{ "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
2486525114
{ "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
2486625115
{ "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
24867
- { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2, 0 },
25116
+ { "markdown", 0, 0, 9, 1, 1, 0, 3, 13, 2, 0 },
2486825117
{ "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
24869
- { "psql", 0, 0, 9, 1, 1, 0, 2, 19, 2, 1 },
24870
- { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2, 0 },
25118
+ { "psql", 0, 0, 9, 1, 1, 0, 3, 19, 2, 5 },
25119
+ { "qbox", 0, 0, 10, 2, 1, 0, 3, 1, 2, 0 },
2487125120
{ "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
2487225121
{ "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
24873
- { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2, 0 },
25122
+ { "table", 0, 0, 9, 1, 1, 0, 3, 19, 2, 0 },
2487425123
{ "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
2487525124
{ "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
24876
- { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 }
24877
-}; /* | / / | / / | | \
24878
- ** | / / | / / | | \_ 2: columnar
24879
- ** Index into aModeStr[] | / / | | 1: line
24880
- ** | / / | | 0: other
24881
- ** | / / | \
24882
- ** text encoding |/ | show | \
24883
- ** v-------------------' | hdrs? | The QRF style
24884
- ** 0: n/a blob | v-----'
24885
- ** 1: plain v----------' 0: n/a
24886
- ** 2: sql 0: auto 1: no
24887
- ** 3: csv 1: as-text 2: yes
24888
- ** 4: html 2: sql
24889
- ** 5: c 3: hex
25125
+ { "www", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 }
25126
+}; /* | / / | / / | | / \____
25127
+ ** | / / | / / | | / |
25128
+ ** Index into aModeStr[] | / / | | 2: columnar |
25129
+ ** | / / | | 1: line |
25130
+ ** | / / | | 0: other |
25131
+ ** text encoding |/ | show | | |
25132
+ ** v-------------------' | hdrs? | The QRF style |
25133
+ ** 0: n/a blob | v-----' /
25134
+ ** 1: plain v----------' 0: n/a _________/
25135
+ ** 2: sql 0: auto 1: no |
25136
+ ** 3: csv 1: as-text 2: yes 1: border-off
25137
+ ** 4: html 2: sql 3: always 2: split-column
25138
+ ** 5: c 3: hex 4: rowcount
2489025139
** 6: json 4: c
2489125140
** 5: json
2489225141
** 6: size
2489325142
******************************************************************/
2489425143
@@ -26316,11 +26565,11 @@
2631626565
free(p->spec.zColumnSep);
2631726566
free(p->spec.zRowSep);
2631826567
free(p->spec.zTableName);
2631926568
free(p->spec.zNull);
2632026569
memset(p, 0, sizeof(*p));
26321
- p->spec.iVersion = 1;
26570
+ p->spec.iVersion = 2;
2632226571
p->autoExplain = autoExplain;
2632326572
}
2632426573
2632526574
/*
2632626575
** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26441,10 +26690,15 @@
2644126690
pM->spec.bSplitColumn = QRF_Yes;
2644226691
pM->bAutoScreenWidth = 1;
2644326692
}else{
2644426693
pM->spec.bSplitColumn = QRF_No;
2644526694
}
26695
+ if( pI->mFlg & 0x04 ){
26696
+ pM->spec.bRowCount = QRF_Yes;
26697
+ }else{
26698
+ pM->spec.bRowCount = QRF_No;
26699
+ }
2644626700
}else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
2644726701
modeFree(&p->mode);
2644826702
modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
2644926703
}else if( eMode==MODE_BATCH ){
2645026704
u8 mFlags = p->mode.mFlags;
@@ -26470,11 +26724,11 @@
2647026724
/*
2647126725
** Set the mode to the default. It assumed that the mode has
2647226726
** already been freed and zeroed prior to calling this routine.
2647326727
*/
2647426728
static void modeDefault(ShellState *p){
26475
- p->mode.spec.iVersion = 1;
26729
+ p->mode.spec.iVersion = 2;
2647626730
p->mode.autoExplain = 1;
2647726731
if( stdin_is_interactive || stdout_is_console ){
2647826732
modeChange(p, MODE_TTY);
2647926733
}else{
2648026734
modeChange(p, MODE_BATCH);
@@ -28836,10 +29090,11 @@
2883629090
" --quote ARG Enable/disable quoting of text. ARG can be\n"
2883729091
" \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
2883829092
" \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
2883929093
" \"on\" is an alias for \"sql\".\n"
2884029094
" --reset Changes all mode settings back to their default.\n"
29095
+" --rowcount BOOLEAN Show \"(N rows)\" at the end of query results.\n"
2884129096
" --rowsep STRING Use STRING as the row separator\n"
2884229097
" --sw|--screenwidth N Declare the screen width of the output device\n"
2884329098
" to be N characters. An attempt may be made to\n"
2884429099
" wrap output text to fit within this limit. Zero\n"
2884529100
" means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28847,11 +29102,11 @@
2884729102
" --tablename NAME Set the name of the table for \"insert\" mode.\n"
2884829103
" --tag NAME Save mode to the left as NAME.\n"
2884929104
" --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
2885029105
" --title ARG Whether or not to show column headers, and if so\n"
2885129106
" how to encode them. ARG can be \"off\", \"on\",\n"
28852
-" \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
29107
+" \"always\", \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
2885329108
" --titlelimit N Limit the length of column titles to N characters.\n"
2885429109
" -v|--verbose Verbose output\n"
2885529110
" --widths LIST Set the columns widths for columnar modes. The\n"
2885629111
" argument is a list of integers, one for each\n"
2885729112
" column. A \"0\" width means use a dynamic width\n"
@@ -29553,10 +29808,11 @@
2955329808
sqlite3_base85_init(p->db, 0, 0);
2955429809
sqlite3_regexp_init(p->db, 0, 0);
2955529810
sqlite3_ieee_init(p->db, 0, 0);
2955629811
sqlite3_series_init(p->db, 0, 0);
2955729812
sqlite3_diskused_init(p->db, 0, 0);
29813
+ sqlite3_strdup_init(p->db, 0, 0);
2955829814
#ifndef SQLITE_SHELL_FIDDLE
2955929815
sqlite3_fileio_init(p->db, 0, 0);
2956029816
sqlite3_completion_init(p->db, 0, 0);
2956129817
#endif
2956229818
#ifdef SQLITE_HAVE_ZLIB
@@ -33007,14 +33263,16 @@
3300733263
/*
3300833264
** This function computes what to show the user about the configured
3300933265
** titles (or column-names). Output is an integer between 0 and 3:
3301033266
**
3301133267
** 0: The titles do not matter. Never show anything.
33012
-** 1: Show "--titles off"
33013
-** 2: Show "--titles on"
33014
-** 3: Show "--title VALUE" where VALUE is an encoding method
33268
+** 1: Show "--title off"
33269
+** 2: Show "--title on"
33270
+** 3: Show "--title always"
33271
+** 4: Show "--title VALUE" where VALUE is an encoding method
3301533272
** to use, one of: plain sql csv html tcl json
33273
+** 5: Show "--title VALUE" as in 3, followed by "--title always"
3301633274
**
3301733275
** Inputs are:
3301833276
**
3301933277
** spec.bTitles (bT) Whether or not to show the titles
3302033278
** spec.eTitle (eT) The actual encoding to be used for titles
@@ -33047,11 +33305,27 @@
3304733305
if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
3304833306
if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
3304933307
if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
3305033308
if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
3305133309
33052
- return v & 3; /* Return the selected truth-table entry */
33310
+ v &= 3;
33311
+ /* At this point v means:
33312
+ ** 0: The titles do not matter. Never show anything.
33313
+ ** 1: Show "--title off"
33314
+ ** 2: Show "--title on"
33315
+ ** 3: Show "--title VALUE" where VALUE is an encoding method
33316
+ ** to use, one of: plain sql csv html tcl json
33317
+ ** If bTitles is QRF_Always, convert 2->3, 3->5. If bTitles is not
33318
+ ** QRF_Always, convert 3->4.
33319
+ */
33320
+ if( p->mode.spec.bTitles==QRF_Always ){
33321
+ if( v==3 ) v = 5;
33322
+ if( v==2 ) v = 3;
33323
+ }else{
33324
+ if( v==3 ) v = 4;
33325
+ }
33326
+ return v;
3305333327
}
3305433328
3305533329
/*
3305633330
** DOT-COMMAND: .mode
3305733331
**
@@ -33095,10 +33369,11 @@
3309533369
** --quote ARG Enable/disable quoting of text. ARG can be
3309633370
** "off", "on", "sql", "relaxed", "csv", "html",
3309733371
** "tcl", or "json". "off" means show the text as-is.
3309833372
** "on" is an alias for "sql".
3309933373
** --reset Changes all mode settings back to their default.
33374
+** --rowcount BOOLEAN Show "(N rows)" at the end of query results.
3310033375
** --rowsep STRING Use STRING as the row separator
3310133376
** --sw|--screenwidth N Declare the screen width of the output device
3310233377
** to be N characters. An attempt may be made to
3310333378
** wrap output text to fit within this limit. Zero
3310433379
** means "no limit". Or N can be "auto" to set the
@@ -33106,11 +33381,11 @@
3310633381
** --tablename NAME Set the name of the table for "insert" mode.
3310733382
** --tag NAME Save mode to the left as NAME.
3310833383
** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
3310933384
** --title ARG Whether or not to show column headers, and if so
3311033385
** how to encode them. ARG can be "off", "on",
33111
-** "sql", "csv", "html", "tcl", or "json".
33386
+** "always", "sql", "csv", "html", "tcl", or "json".
3311233387
** --titlelimit N Limit the length of column titles to N characters.
3311333388
** -v|--verbose Verbose output
3311433389
** --widths LIST Set the columns widths for columnar modes. The
3311533390
** argument is a list of integers, one for each
3311633391
** column. A "0" width means use a dynamic width
@@ -33334,10 +33609,17 @@
3333433609
chng = 1;
3333533610
}else if( optionMatch(z,"reset") ){
3333633611
int saved_eMode = p->mode.eMode;
3333733612
modeFree(&p->mode);
3333833613
modeChange(p, saved_eMode);
33614
+ }else if( optionMatch(z,"rowcount") ){
33615
+ if( i+1>=nArg ){
33616
+ dotCmdError(p, i, "missing argument", 0);
33617
+ return 1;
33618
+ }
33619
+ p->mode.spec.bRowCount = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33620
+ chng = 1;
3333933621
}else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
3334033622
if( (++i)>=nArg ){
3334133623
dotCmdError(p, i-1, "missing argument", 0);
3334233624
return 1;
3334333625
}
@@ -33387,25 +33669,63 @@
3338733669
return 1;
3338833670
}
3338933671
p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
3339033672
chng = 1;
3339133673
}else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
33674
+ /* The --titles option controls two fields of the
33675
+ ** sqlite3_qrf_spec object: eTitle and bTitles.
33676
+ **
33677
+ ** --titles eTitle bTitles
33678
+ ** -------- --------------- ---------------------
33679
+ ** "off" (unchanged) QRF_Off
33680
+ ** "on" (unchanged) QRF_On
33681
+ ** "always" (unchanged) QRF_Always
33682
+ ** "auto", (default) (default)
33683
+ ** "plain" QRF_TEXT_Plain QRF_Always or QRF_On
33684
+ ** "sql" QRF_TEXT_Sql QRF_Always or QRF_On
33685
+ ** "csv" QRF_TEXT_Csv QRF_Always or QRF_On
33686
+ ** "html" QRF_TEXT_Html QRF_Always or QRF_On
33687
+ ** "tcl" QRF_TEXT_Tcl QRF_Always or QRF_On
33688
+ ** "json" QRF_TEXT_Json QRF_Always or QRF_On
33689
+ **
33690
+ ** This mapping is different from the -title option to the "format"
33691
+ ** method of the TCL interface. In this mapping:
33692
+ **
33693
+ ** * "off", "on", and "always" affect only bTitles and leave
33694
+ ** eTitle unchanged
33695
+ **
33696
+ ** * "auto" sets both bTitles and eTitle to the default value
33697
+ ** in aModeInfo[] according to the current --style.
33698
+ **
33699
+ ** * "plain" through "json" set eTitle but leave bTitles
33700
+ ** unchanged if it is not QRF_Off. If bTitles is QRF_Off,
33701
+ ** then it is changed QRF_Always.
33702
+ */
3339233703
char *zErr = 0;
3339333704
if( i+1>=nArg ){
3339433705
dotCmdError(p, i, "missing argument", 0);
3339533706
return 1;
3339633707
}
3339733708
k = pickStr(azArg[++i],&zErr,
33398
- "off","on","plain","sql","csv","html","tcl","json","");
33399
- /* 0 1 2 3 4 5 6 7 */
33709
+ "off","on","always","auto","plain","sql","csv","html","tcl","json","");
33710
+ /* 0 1 2 3 4 5 6 7 8 9 */
3340033711
if( k<0 ){
3340133712
dotCmdError(p, i, "bad --titles value","%z", zErr);
3340233713
return 1;
3340333714
}
33404
- p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
3340533715
p->mode.mFlags &= ~MFLG_HDR;
33406
- p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
33716
+ if( k<=2 ){
33717
+ p->mode.spec.bTitles = QRF_No+k;
33718
+ }else if( k==3 ){
33719
+ p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
33720
+ p->mode.spec.bTitles = aModeInfo[p->mode.eMode].bHdr;
33721
+ }else{
33722
+ p->mode.spec.eTitle = (k-4)+QRF_TEXT_Plain;
33723
+ if( p->mode.spec.bTitles==QRF_No ){
33724
+ p->mode.spec.bTitles = QRF_Always;
33725
+ }
33726
+ }
3340733727
chng = 1;
3340833728
}else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
3340933729
int nWidth = 0;
3341033730
short int *aWidth;
3341133731
const char *zW;
@@ -33556,10 +33876,16 @@
3355633876
if( bAll
3355733877
|| (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
3355833878
){
3355933879
sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
3356033880
}
33881
+ if( bAll
33882
+ || ((p->mode.spec.bRowCount==QRF_Yes) != ((pI->mFlg&4)!=0))
33883
+ ){
33884
+ sqlite3_str_appendf(pDesc," --rowcount %s",
33885
+ p->mode.spec.bRowCount==QRF_Yes ? "on" : "off");
33886
+ }
3356133887
zSetting = aModeStr[pI->eRSep];
3356233888
if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
3356333889
sqlite3_str_appendf(pDesc, " --rowsep ");
3356433890
append_c_string(pDesc, p->mode.spec.zRowSep);
3356533891
}
@@ -33585,14 +33911,19 @@
3358533911
if( k==1 ){
3358633912
sqlite3_str_appendall(pDesc, " --titles off");
3358733913
}else if( k==2 ){
3358833914
sqlite3_str_appendall(pDesc, " --titles on");
3358933915
}else if( k==3 ){
33916
+ sqlite3_str_appendall(pDesc, " --titles always");
33917
+ }else if( k>=4 ){
3359033918
static const char *azTitle[] =
3359133919
{ "plain", "sql", "csv", "html", "tcl", "json"};
3359233920
sqlite3_str_appendf(pDesc, " --titles %s",
3359333921
azTitle[p->mode.spec.eTitle-1]);
33922
+ if( k==5 ){
33923
+ sqlite3_str_appendf(pDesc, " --titles always");
33924
+ }
3359433925
}
3359533926
if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
3359633927
int ii;
3359733928
const char *zSep = " --widths ";
3359833929
for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34910,15 +35241,19 @@
3491035241
}
3491135242
}else
3491235243
3491335244
if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
3491435245
if( nArg==2 ){
34915
- p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35246
+ if( cli_strcmp(azArg[1],"always")==0 ){
35247
+ p->mode.spec.bTitles = QRF_Always;
35248
+ }else{
35249
+ p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35250
+ }
3491635251
p->mode.mFlags |= MFLG_HDR;
3491735252
p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
3491835253
}else{
34919
- eputz("Usage: .headers on|off\n");
35254
+ eputz("Usage: .headers off|on|always\n");
3492035255
rc = 1;
3492135256
}
3492235257
}else
3492335258
3492435259
if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -35122,13 +35457,21 @@
3512235457
sqlite3_str_free(pSql);
3512335458
}else
3512435459
3512535460
if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
3512635461
i64 iArg = 0;
35462
+ open_db(p, 0);
3512735463
if( nArg==2 ){
3512835464
iArg = integerValue(azArg[1]);
35129
- if( iArg==0 ) iArg = -1;
35465
+ if( iArg==0 ){
35466
+ if( cli_strcmp(azArg[1],"register")==0 ){
35467
+ sqlite3_intck_register(p->db, 1);
35468
+ rc = 0;
35469
+ goto meta_command_exit;
35470
+ }
35471
+ iArg = -1;
35472
+ }
3513035473
}
3513135474
if( (nArg!=1 && nArg!=2) || iArg<0 ){
3513235475
cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
3513335476
rc = 1;
3513435477
goto meta_command_exit;
@@ -36502,11 +36845,12 @@
3650236845
azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
3650336846
cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
3650436847
cli_printf(p->out, "%12.12s: %s\n","explain",
3650536848
p->mode.autoExplain ? "auto" : "off");
3650636849
cli_printf(p->out, "%12.12s: %s\n","headers",
36507
- azBool[p->mode.spec.bTitles==QRF_Yes]);
36850
+ p->mode.spec.bTitles==QRF_Always ? "always" :
36851
+ azBool[p->mode.spec.bTitles==QRF_Yes]);
3650836852
if( p->mode.spec.eStyle==QRF_STYLE_Column
3650936853
|| p->mode.spec.eStyle==QRF_STYLE_Box
3651036854
|| p->mode.spec.eStyle==QRF_STYLE_Table
3651136855
|| p->mode.spec.eStyle==QRF_STYLE_Markdown
3651236856
){
@@ -38576,11 +38920,11 @@
3857638920
cmdline_option_value(argc,argv,++i));
3857738921
}else if( cli_strcmp(z,"-nullvalue")==0 ){
3857838922
modeSetStr(&data.mode.spec.zNull,
3857938923
cmdline_option_value(argc,argv,++i));
3858038924
}else if( cli_strcmp(z,"-header")==0 ){
38581
- data.mode.spec.bTitles = QRF_Yes;
38925
+ data.mode.spec.bTitles = QRF_Always;
3858238926
data.mode.mFlags |= MFLG_HDR;
3858338927
}else if( cli_strcmp(z,"-noheader")==0 ){
3858438928
data.mode.spec.bTitles = QRF_No;
3858538929
data.mode.mFlags |= MFLG_HDR;
3858638930
}else if( cli_strcmp(z,"-echo")==0 ){
3858738931
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -23,10 +23,11 @@
23 ** ext/misc/shathree.c
24 ** ext/misc/sqlar.c
25 ** ext/misc/sqlite3_stdio.c
26 ** ext/misc/sqlite3_stdio.h
27 ** ext/misc/stmtrand.c
 
28 ** ext/misc/uint.c
29 ** ext/misc/vfstrace.c
30 ** ext/misc/windirent.h
31 ** ext/misc/zipfile.c
32 ** ext/qrf/qrf.c
@@ -733,10 +734,12 @@
733 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
734 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
735 void *pRenderArg; /* First argument to the xRender callback */
736 void *pWriteArg; /* First argument to the xWrite callback */
737 char **pzOutput; /* Storage location for output string */
 
 
738 /* Additional fields may be added in the future */
739 };
740
741 /*
742 ** Interfaces
@@ -821,10 +824,15 @@
821 #define QRF_SW_On 2 /* This setting is forced on */
822 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
823 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
824 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
825
 
 
 
 
 
826 /*
827 ** Possible alignment values alignment settings
828 **
829 ** Horizontal Vertial
830 ** ---------- -------- */
@@ -2527,10 +2535,14 @@
2527 /* Doubled horizontal lines: */
2528 #define DBL_24 "\342\225\220" /* U+2550 === */
2529 #define DBL_123 "\342\225\236" /* U+255e |= */
2530 #define DBL_134 "\342\225\241" /* U+2561 =| */
2531 #define DBL_1234 "\342\225\252" /* U+256a =|= */
 
 
 
 
2532
2533 /* Draw horizontal line N characters long using unicode box
2534 ** characters
2535 */
2536 static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2549,16 +2561,16 @@
2549
2550 /*
2551 ** Draw a horizontal separator for a QRF_STYLE_Box table.
2552 */
2553 static void qrfBoxSeparator(
2554 sqlite3_str *pOut,
2555 qrfColData *p,
2556 const char *zSep1,
2557 const char *zSep2,
2558 const char *zSep3,
2559 int bDbl
2560 ){
2561 int i;
2562 if( p->nCol>0 ){
2563 int useBorder = p->p->spec.bBorder!=QRF_No;
2564 if( useBorder ){
@@ -2573,10 +2585,36 @@
2573 sqlite3_str_appendall(pOut, zSep3);
2574 }
2575 }
2576 sqlite3_str_append(pOut, "\n", 1);
2577 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2578
2579 /*
2580 ** Load into pData the default alignment for the body of a table.
2581 */
2582 static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2831,11 +2869,25 @@
2831 sqlite3_str *pStr; /* Temporary rendering */
2832 qrfColData data; /* Columnar layout data */
2833 int bRTrim; /* Trim trailing space */
2834
2835 rc = sqlite3_step(p->pStmt);
2836 if( rc!=SQLITE_ROW || nColumn==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2837 return; /* No output */
2838 }
2839
2840 /* Initialize the data container */
2841 memset(&data, 0, sizeof(data));
@@ -2848,12 +2900,12 @@
2848 }
2849 memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2850 if( qrfColDataEnlarge(&data) ) return;
2851 assert( data.az!=0 );
2852
2853 /* Load the column header names and all cell content into data */
2854 if( p->spec.bTitles==QRF_Yes ){
2855 unsigned char saved_eText = p->spec.eText;
2856 p->spec.eText = p->spec.eTitle;
2857 memset(data.abNum, 0, nColumn);
2858 for(i=0; i<nColumn; i++){
2859 const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2874,13 +2926,14 @@
2874 data.n++;
2875 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2876 if( nNL ) data.bMultiRow = 1;
2877 }
2878 p->spec.eText = saved_eText;
2879 p->nRow++;
2880 }
2881 do{
 
 
2882 if( data.n+nColumn > data.nAlloc ){
2883 if( qrfColDataEnlarge(&data) ) return;
2884 }
2885 for(i=0; i<nColumn; i++){
2886 char *z;
@@ -2897,11 +2950,12 @@
2897 data.n++;
2898 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2899 if( nNL ) data.bMultiRow = 1;
2900 }
2901 p->nRow++;
2902 }while( sqlite3_step(p->pStmt)==SQLITE_ROW && p->iErr==SQLITE_OK );
 
2903 if( p->iErr ){
2904 qrfColDataFree(&data);
2905 return;
2906 }
2907
@@ -3105,11 +3159,11 @@
3105 /* Draw either (1) the separator between the title line and the body
3106 ** of the table, or (2) separators between individual rows of the table
3107 ** body. isTitleDataSeparator will be true if we are doing (1).
3108 */
3109 if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3110 int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes);
3111 if( isTitleDataSeparator ){
3112 qrfLoadAlignment(&data, p);
3113 }
3114 switch( p->spec.eStyle ){
3115 case QRF_STYLE_Table: {
@@ -3132,19 +3186,12 @@
3132 }
3133 break;
3134 }
3135 case QRF_STYLE_Column: {
3136 if( isTitleDataSeparator ){
3137 for(j=0; j<nColumn; j++){
3138 sqlite3_str_appendchar(p->pOut, data.a[j].w, '-');
3139 if( j<nColumn-1 ){
3140 sqlite3_str_append(p->pOut, colSep, szColSep);
3141 }else{
3142 qrfRTrim(p->pOut);
3143 sqlite3_str_append(p->pOut, rowSep, szRowSep);
3144 }
3145 }
3146 }else if( data.bMultiRow ){
3147 qrfRTrim(p->pOut);
3148 sqlite3_str_append(p->pOut, "\n", 1);
3149 }
3150 break;
@@ -3152,20 +3199,39 @@
3152 }
3153 }
3154 }
3155
3156 /* Draw the line across the bottom of the table */
3157 if( p->spec.bBorder!=QRF_No ){
3158 switch( p->spec.eStyle ){
3159 case QRF_STYLE_Box:
3160 qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
 
 
 
 
3161 break;
3162 case QRF_STYLE_Table:
3163 qrfRowSeparator(p->pOut, &data, '+');
3164 break;
 
 
 
 
 
 
 
 
 
 
 
3165 }
3166 }
 
 
 
 
3167 qrfWrite(p);
3168
3169 qrfColDataFree(&data);
3170 return;
3171 }
@@ -3412,10 +3478,49 @@
3412 sqlite3_str_append(p->pOut, ":", 1);
3413 qrfRenderValue(p, p->pOut, i);
3414 }
3415 qrfWrite(p);
3416 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3417
3418 /*
3419 ** Render a single row of output for non-columnar styles - any
3420 ** style that lets us render row by row as the content is received
3421 ** from the query.
@@ -3445,18 +3550,12 @@
3445 }
3446 qrfOneJsonRow(p);
3447 break;
3448 }
3449 case QRF_STYLE_Html: {
3450 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3451 sqlite3_str_append(p->pOut, "<TR>", 4);
3452 for(i=0; i<p->nCol; i++){
3453 const char *zCName = sqlite3_column_name(p->pStmt, i);
3454 sqlite3_str_append(p->pOut, "\n<TH>", 5);
3455 qrfEncodeText(p, p->pOut, zCName);
3456 }
3457 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3458 }
3459 sqlite3_str_append(p->pOut, "<TR>", 4);
3460 for(i=0; i<p->nCol; i++){
3461 sqlite3_str_append(p->pOut, "\n<TD>", 5);
3462 qrfRenderValue(p, p->pOut, i);
@@ -3476,11 +3575,11 @@
3476 if( qrf_need_quote(p->spec.zTableName) ){
3477 sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
3478 }else{
3479 sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
3480 }
3481 if( p->spec.bTitles==QRF_Yes ){
3482 for(i=0; i<p->nCol; i++){
3483 const char *zCName = sqlite3_column_name(p->pStmt, i);
3484 if( qrf_need_quote(zCName) ){
3485 sqlite3_str_appendf(p->pOut, "%c\"%w\"",
3486 i==0 ? '(' : ',', zCName);
@@ -3576,21 +3675,12 @@
3576 if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3577 qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3578 break;
3579 }
3580 default: { /* QRF_STYLE_List */
3581 if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){
3582 int saved_eText = p->spec.eText;
3583 p->spec.eText = p->spec.eTitle;
3584 for(i=0; i<p->nCol; i++){
3585 const char *zCName = sqlite3_column_name(p->pStmt, i);
3586 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3587 qrfEncodeText(p, p->pOut, zCName);
3588 }
3589 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3590 qrfWrite(p);
3591 p->spec.eText = saved_eText;
3592 }
3593 for(i=0; i<p->nCol; i++){
3594 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3595 qrfRenderValue(p, p->pOut, i);
3596 }
@@ -3612,11 +3702,11 @@
3612 char **pzErr /* Write errors here */
3613 ){
3614 size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3615 memset(p, 0, sizeof(*p));
3616 p->pzErr = pzErr;
3617 if( pSpec->iVersion>1 ){
3618 qrfError(p, SQLITE_ERROR,
3619 "unusable sqlite3_qrf_spec.iVersion (%d)",
3620 pSpec->iVersion);
3621 return;
3622 }
@@ -3640,10 +3730,13 @@
3640 if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3641 if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3642 if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
3643 if( p->spec.eTitle>QRF_TEXT_Relaxed ) p->spec.eTitle = QRF_Auto;
3644 if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto;
 
 
 
3645 qrf_reinit:
3646 switch( p->spec.eStyle ){
3647 case QRF_Auto: {
3648 switch( sqlite3_stmt_isexplain(pStmt) ){
3649 case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3898,10 +3991,34 @@
3898 default: {
3899 /* Non-columnar modes where the output can occur after each row
3900 ** of result is received */
3901 while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
3902 qrfOneSimpleRow(&qrf);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3903 }
3904 break;
3905 }
3906 }
3907 qrfResetStmt(&qrf);
@@ -10602,11 +10719,15 @@
10602 sqlite3_result_error_nomem(ctx);
10603 return SQLITE_NOMEM;
10604 }
10605 }
10606
10607 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
 
 
 
 
10608 if( aBuf!=aStatic ) sqlite3_free(aBuf);
10609 #endif
10610 }else{
10611 readFileContents(ctx, pCur->zPath);
10612 }
@@ -17600,10 +17721,13 @@
17600 else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
17601 while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
17602 iRet++;
17603 }
17604 }
 
 
 
17605
17606 return iRet;
17607 }
17608
17609 /*
@@ -18039,10 +18163,27 @@
18039 intckFinalize(p, pStmt);
18040
18041 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
18042 return zRet;
18043 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18044
18045 /*
18046 ** Open a new integrity-check object.
18047 */
18048 int sqlite3_intck_open(
@@ -18061,13 +18202,11 @@
18061 }else{
18062 memset(pNew, 0, sizeof(*pNew));
18063 pNew->db = db;
18064 pNew->zDb = (const char*)&pNew[1];
18065 memcpy(&pNew[1], zDb, nDb+1);
18066 rc = sqlite3_create_function(db, "parse_create_index",
18067 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
18068 );
18069 if( rc!=SQLITE_OK ){
18070 sqlite3_intck_close(pNew);
18071 pNew = 0;
18072 }
18073 }
@@ -18080,13 +18219,11 @@
18080 ** Free the integrity-check object.
18081 */
18082 void sqlite3_intck_close(sqlite3_intck *p){
18083 if( p ){
18084 sqlite3_finalize(p->pCheck);
18085 sqlite3_create_function(
18086 p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
18087 );
18088 sqlite3_free(p->zObj);
18089 sqlite3_free(p->zKey);
18090 sqlite3_free(p->zTestSql);
18091 sqlite3_free(p->zErr);
18092 sqlite3_free(p->zMessage);
@@ -20370,10 +20507,122 @@
20370 0, diskusedFunc, 0, 0);
20371 return rc;
20372 }
20373
20374 /************************* End ext/misc/diskused.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20375
20376 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
20377 #define SQLITE_SHELL_HAVE_RECOVER 1
20378 #else
20379 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24837,11 +25086,11 @@
24837 unsigned char eHdr; /* Default header encoding. */
24838 unsigned char eBlob; /* Default blob encoding. */
24839 unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
24840 unsigned char eStyle; /* Underlying QRF style */
24841 unsigned char eCx; /* 0: other, 1: line, 2: columnar */
24842 unsigned char mFlg; /* Flags. 1=border-off 2=split-column */
24843 };
24844
24845 /* String constants used by built-in modes */
24846 static const char *aModeStr[] =
24847 /* 0 1 2 3 4 5 6 7 8 */
@@ -24850,45 +25099,45 @@
24850 /* 9 10 11 12 13 */
24851
24852 static const ModeInfo aModeInfo[] = {
24853 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
24854 { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
24855 { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2, 0 },
24856 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
24857 { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2, 0 },
24858 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
24859 { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
24860 { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 },
24861 { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
24862 { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
24863 { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
24864 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
24865 { "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
24866 { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
24867 { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2, 0 },
24868 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
24869 { "psql", 0, 0, 9, 1, 1, 0, 2, 19, 2, 1 },
24870 { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2, 0 },
24871 { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
24872 { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
24873 { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2, 0 },
24874 { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
24875 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
24876 { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0, 0 }
24877 }; /* | / / | / / | | \
24878 ** | / / | / / | | \_ 2: columnar
24879 ** Index into aModeStr[] | / / | | 1: line
24880 ** | / / | | 0: other
24881 ** | / / | \
24882 ** text encoding |/ | show | \
24883 ** v-------------------' | hdrs? | The QRF style
24884 ** 0: n/a blob | v-----'
24885 ** 1: plain v----------' 0: n/a
24886 ** 2: sql 0: auto 1: no
24887 ** 3: csv 1: as-text 2: yes
24888 ** 4: html 2: sql
24889 ** 5: c 3: hex
24890 ** 6: json 4: c
24891 ** 5: json
24892 ** 6: size
24893 ******************************************************************/
24894
@@ -26316,11 +26565,11 @@
26316 free(p->spec.zColumnSep);
26317 free(p->spec.zRowSep);
26318 free(p->spec.zTableName);
26319 free(p->spec.zNull);
26320 memset(p, 0, sizeof(*p));
26321 p->spec.iVersion = 1;
26322 p->autoExplain = autoExplain;
26323 }
26324
26325 /*
26326 ** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26441,10 +26690,15 @@
26441 pM->spec.bSplitColumn = QRF_Yes;
26442 pM->bAutoScreenWidth = 1;
26443 }else{
26444 pM->spec.bSplitColumn = QRF_No;
26445 }
 
 
 
 
 
26446 }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
26447 modeFree(&p->mode);
26448 modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
26449 }else if( eMode==MODE_BATCH ){
26450 u8 mFlags = p->mode.mFlags;
@@ -26470,11 +26724,11 @@
26470 /*
26471 ** Set the mode to the default. It assumed that the mode has
26472 ** already been freed and zeroed prior to calling this routine.
26473 */
26474 static void modeDefault(ShellState *p){
26475 p->mode.spec.iVersion = 1;
26476 p->mode.autoExplain = 1;
26477 if( stdin_is_interactive || stdout_is_console ){
26478 modeChange(p, MODE_TTY);
26479 }else{
26480 modeChange(p, MODE_BATCH);
@@ -28836,10 +29090,11 @@
28836 " --quote ARG Enable/disable quoting of text. ARG can be\n"
28837 " \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
28838 " \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
28839 " \"on\" is an alias for \"sql\".\n"
28840 " --reset Changes all mode settings back to their default.\n"
 
28841 " --rowsep STRING Use STRING as the row separator\n"
28842 " --sw|--screenwidth N Declare the screen width of the output device\n"
28843 " to be N characters. An attempt may be made to\n"
28844 " wrap output text to fit within this limit. Zero\n"
28845 " means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28847,11 +29102,11 @@
28847 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
28848 " --tag NAME Save mode to the left as NAME.\n"
28849 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
28850 " --title ARG Whether or not to show column headers, and if so\n"
28851 " how to encode them. ARG can be \"off\", \"on\",\n"
28852 " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
28853 " --titlelimit N Limit the length of column titles to N characters.\n"
28854 " -v|--verbose Verbose output\n"
28855 " --widths LIST Set the columns widths for columnar modes. The\n"
28856 " argument is a list of integers, one for each\n"
28857 " column. A \"0\" width means use a dynamic width\n"
@@ -29553,10 +29808,11 @@
29553 sqlite3_base85_init(p->db, 0, 0);
29554 sqlite3_regexp_init(p->db, 0, 0);
29555 sqlite3_ieee_init(p->db, 0, 0);
29556 sqlite3_series_init(p->db, 0, 0);
29557 sqlite3_diskused_init(p->db, 0, 0);
 
29558 #ifndef SQLITE_SHELL_FIDDLE
29559 sqlite3_fileio_init(p->db, 0, 0);
29560 sqlite3_completion_init(p->db, 0, 0);
29561 #endif
29562 #ifdef SQLITE_HAVE_ZLIB
@@ -33007,14 +33263,16 @@
33007 /*
33008 ** This function computes what to show the user about the configured
33009 ** titles (or column-names). Output is an integer between 0 and 3:
33010 **
33011 ** 0: The titles do not matter. Never show anything.
33012 ** 1: Show "--titles off"
33013 ** 2: Show "--titles on"
33014 ** 3: Show "--title VALUE" where VALUE is an encoding method
 
33015 ** to use, one of: plain sql csv html tcl json
 
33016 **
33017 ** Inputs are:
33018 **
33019 ** spec.bTitles (bT) Whether or not to show the titles
33020 ** spec.eTitle (eT) The actual encoding to be used for titles
@@ -33047,11 +33305,27 @@
33047 if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
33048 if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
33049 if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
33050 if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
33051
33052 return v & 3; /* Return the selected truth-table entry */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33053 }
33054
33055 /*
33056 ** DOT-COMMAND: .mode
33057 **
@@ -33095,10 +33369,11 @@
33095 ** --quote ARG Enable/disable quoting of text. ARG can be
33096 ** "off", "on", "sql", "relaxed", "csv", "html",
33097 ** "tcl", or "json". "off" means show the text as-is.
33098 ** "on" is an alias for "sql".
33099 ** --reset Changes all mode settings back to their default.
 
33100 ** --rowsep STRING Use STRING as the row separator
33101 ** --sw|--screenwidth N Declare the screen width of the output device
33102 ** to be N characters. An attempt may be made to
33103 ** wrap output text to fit within this limit. Zero
33104 ** means "no limit". Or N can be "auto" to set the
@@ -33106,11 +33381,11 @@
33106 ** --tablename NAME Set the name of the table for "insert" mode.
33107 ** --tag NAME Save mode to the left as NAME.
33108 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
33109 ** --title ARG Whether or not to show column headers, and if so
33110 ** how to encode them. ARG can be "off", "on",
33111 ** "sql", "csv", "html", "tcl", or "json".
33112 ** --titlelimit N Limit the length of column titles to N characters.
33113 ** -v|--verbose Verbose output
33114 ** --widths LIST Set the columns widths for columnar modes. The
33115 ** argument is a list of integers, one for each
33116 ** column. A "0" width means use a dynamic width
@@ -33334,10 +33609,17 @@
33334 chng = 1;
33335 }else if( optionMatch(z,"reset") ){
33336 int saved_eMode = p->mode.eMode;
33337 modeFree(&p->mode);
33338 modeChange(p, saved_eMode);
 
 
 
 
 
 
 
33339 }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
33340 if( (++i)>=nArg ){
33341 dotCmdError(p, i-1, "missing argument", 0);
33342 return 1;
33343 }
@@ -33387,25 +33669,63 @@
33387 return 1;
33388 }
33389 p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33390 chng = 1;
33391 }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33392 char *zErr = 0;
33393 if( i+1>=nArg ){
33394 dotCmdError(p, i, "missing argument", 0);
33395 return 1;
33396 }
33397 k = pickStr(azArg[++i],&zErr,
33398 "off","on","plain","sql","csv","html","tcl","json","");
33399 /* 0 1 2 3 4 5 6 7 */
33400 if( k<0 ){
33401 dotCmdError(p, i, "bad --titles value","%z", zErr);
33402 return 1;
33403 }
33404 p->mode.spec.bTitles = k>=1 ? QRF_Yes : QRF_No;
33405 p->mode.mFlags &= ~MFLG_HDR;
33406 p->mode.spec.eTitle = k>1 ? k-1 : aModeInfo[p->mode.eMode].eHdr;
 
 
 
 
 
 
 
 
 
 
33407 chng = 1;
33408 }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
33409 int nWidth = 0;
33410 short int *aWidth;
33411 const char *zW;
@@ -33556,10 +33876,16 @@
33556 if( bAll
33557 || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
33558 ){
33559 sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
33560 }
 
 
 
 
 
 
33561 zSetting = aModeStr[pI->eRSep];
33562 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
33563 sqlite3_str_appendf(pDesc, " --rowsep ");
33564 append_c_string(pDesc, p->mode.spec.zRowSep);
33565 }
@@ -33585,14 +33911,19 @@
33585 if( k==1 ){
33586 sqlite3_str_appendall(pDesc, " --titles off");
33587 }else if( k==2 ){
33588 sqlite3_str_appendall(pDesc, " --titles on");
33589 }else if( k==3 ){
 
 
33590 static const char *azTitle[] =
33591 { "plain", "sql", "csv", "html", "tcl", "json"};
33592 sqlite3_str_appendf(pDesc, " --titles %s",
33593 azTitle[p->mode.spec.eTitle-1]);
 
 
 
33594 }
33595 if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
33596 int ii;
33597 const char *zSep = " --widths ";
33598 for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34910,15 +35241,19 @@
34910 }
34911 }else
34912
34913 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
34914 if( nArg==2 ){
34915 p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
 
 
 
 
34916 p->mode.mFlags |= MFLG_HDR;
34917 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
34918 }else{
34919 eputz("Usage: .headers on|off\n");
34920 rc = 1;
34921 }
34922 }else
34923
34924 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -35122,13 +35457,21 @@
35122 sqlite3_str_free(pSql);
35123 }else
35124
35125 if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
35126 i64 iArg = 0;
 
35127 if( nArg==2 ){
35128 iArg = integerValue(azArg[1]);
35129 if( iArg==0 ) iArg = -1;
 
 
 
 
 
 
 
35130 }
35131 if( (nArg!=1 && nArg!=2) || iArg<0 ){
35132 cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
35133 rc = 1;
35134 goto meta_command_exit;
@@ -36502,11 +36845,12 @@
36502 azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
36503 cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
36504 cli_printf(p->out, "%12.12s: %s\n","explain",
36505 p->mode.autoExplain ? "auto" : "off");
36506 cli_printf(p->out, "%12.12s: %s\n","headers",
36507 azBool[p->mode.spec.bTitles==QRF_Yes]);
 
36508 if( p->mode.spec.eStyle==QRF_STYLE_Column
36509 || p->mode.spec.eStyle==QRF_STYLE_Box
36510 || p->mode.spec.eStyle==QRF_STYLE_Table
36511 || p->mode.spec.eStyle==QRF_STYLE_Markdown
36512 ){
@@ -38576,11 +38920,11 @@
38576 cmdline_option_value(argc,argv,++i));
38577 }else if( cli_strcmp(z,"-nullvalue")==0 ){
38578 modeSetStr(&data.mode.spec.zNull,
38579 cmdline_option_value(argc,argv,++i));
38580 }else if( cli_strcmp(z,"-header")==0 ){
38581 data.mode.spec.bTitles = QRF_Yes;
38582 data.mode.mFlags |= MFLG_HDR;
38583 }else if( cli_strcmp(z,"-noheader")==0 ){
38584 data.mode.spec.bTitles = QRF_No;
38585 data.mode.mFlags |= MFLG_HDR;
38586 }else if( cli_strcmp(z,"-echo")==0 ){
38587
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -23,10 +23,11 @@
23 ** ext/misc/shathree.c
24 ** ext/misc/sqlar.c
25 ** ext/misc/sqlite3_stdio.c
26 ** ext/misc/sqlite3_stdio.h
27 ** ext/misc/stmtrand.c
28 ** ext/misc/strdup.c
29 ** ext/misc/uint.c
30 ** ext/misc/vfstrace.c
31 ** ext/misc/windirent.h
32 ** ext/misc/zipfile.c
33 ** ext/qrf/qrf.c
@@ -733,10 +734,12 @@
734 char *(*xRender)(void*,sqlite3_value*); /* Render a value */
735 int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
736 void *pRenderArg; /* First argument to the xRender callback */
737 void *pWriteArg; /* First argument to the xWrite callback */
738 char **pzOutput; /* Storage location for output string */
739 /* The following are available in iVersion 2 and later */
740 unsigned char bRowCount; /* Show the number of rows at end of each query */
741 /* Additional fields may be added in the future */
742 };
743
744 /*
745 ** Interfaces
@@ -821,10 +824,15 @@
824 #define QRF_SW_On 2 /* This setting is forced on */
825 #define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
826 #define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
827 #define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
828
829 /*
830 ** Additional value allowed for bTitles
831 */
832 #define QRF_Always 3 /* Always show titles, even if no rows */
833
834 /*
835 ** Possible alignment values alignment settings
836 **
837 ** Horizontal Vertial
838 ** ---------- -------- */
@@ -2527,10 +2535,14 @@
2535 /* Doubled horizontal lines: */
2536 #define DBL_24 "\342\225\220" /* U+2550 === */
2537 #define DBL_123 "\342\225\236" /* U+255e |= */
2538 #define DBL_134 "\342\225\241" /* U+2561 =| */
2539 #define DBL_1234 "\342\225\252" /* U+256a =|= */
2540 #define DBL_12 "\342\225\230" /* U+2558 `= */
2541 #define DBL_14 "\342\225\233" /* U+255b =' */
2542 #define DBL_124 "\342\225\247" /* U+2567 ='= */
2543
2544
2545 /* Draw horizontal line N characters long using unicode box
2546 ** characters
2547 */
2548 static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
@@ -2549,16 +2561,16 @@
2561
2562 /*
2563 ** Draw a horizontal separator for a QRF_STYLE_Box table.
2564 */
2565 static void qrfBoxSeparator(
2566 sqlite3_str *pOut, /* Output to this sqlite3_str */
2567 qrfColData *p, /* Columnar data */
2568 const char *zSep1, /* Left margin */
2569 const char *zSep2, /* Column separator */
2570 const char *zSep3, /* Right margin */
2571 int bDbl /* True for double-lines */
2572 ){
2573 int i;
2574 if( p->nCol>0 ){
2575 int useBorder = p->p->spec.bBorder!=QRF_No;
2576 if( useBorder ){
@@ -2573,10 +2585,36 @@
2585 sqlite3_str_appendall(pOut, zSep3);
2586 }
2587 }
2588 sqlite3_str_append(pOut, "\n", 1);
2589 }
2590
2591 /*
2592 ** Draw a horizontal separator for a QRF_STYLE_Column table.
2593 ** This style of separator is only used for separating the title
2594 ** from the content.
2595 */
2596 static void qrfColumnSeparator(
2597 sqlite3_str *pOut, /* Output to this sqlite3_str */
2598 qrfColData *p, /* Columnar data */
2599 const char *colSep, /* Column separator text */
2600 int szColSep, /* Size of zColSep in bytes */
2601 const char *rowSep, /* Row separator text */
2602 int szRowSep /* Size of zRowSep in bytes */
2603 ){
2604 int j;
2605 int nColumn = p->nCol;
2606 for(j=0; j<nColumn; j++){
2607 sqlite3_str_appendchar(pOut, p->a[j].w, '-');
2608 if( j<nColumn-1 ){
2609 sqlite3_str_append(pOut, colSep, szColSep);
2610 }else{
2611 qrfRTrim(pOut);
2612 sqlite3_str_append(pOut, rowSep, szRowSep);
2613 }
2614 }
2615 }
2616
2617 /*
2618 ** Load into pData the default alignment for the body of a table.
2619 */
2620 static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
@@ -2831,11 +2869,25 @@
2869 sqlite3_str *pStr; /* Temporary rendering */
2870 qrfColData data; /* Columnar layout data */
2871 int bRTrim; /* Trim trailing space */
2872
2873 rc = sqlite3_step(p->pStmt);
2874 if( nColumn==0 ){
2875 return; /* Not a query. No results every shown. */
2876 }
2877 if( rc==SQLITE_DONE && nColumn>0 ){
2878 /* Empty query */
2879 if( p->spec.bTitles==QRF_Always ){
2880 /* fall through into the columnar logic below */
2881 }else{
2882 if( p->spec.bRowCount==QRF_Yes ){
2883 sqlite3_str_appendf(p->pOut, "(0 rows)\n");
2884 qrfWrite(p);
2885 }
2886 return; /* No output, other than the row count */
2887 }
2888 }else if( rc!=SQLITE_ROW ){
2889 return; /* No output */
2890 }
2891
2892 /* Initialize the data container */
2893 memset(&data, 0, sizeof(data));
@@ -2848,12 +2900,12 @@
2900 }
2901 memset(data.a, 0, nColumn*sizeof(struct qrfPerCol) );
2902 if( qrfColDataEnlarge(&data) ) return;
2903 assert( data.az!=0 );
2904
2905 /* Load the column header names into data */
2906 if( p->spec.bTitles>=QRF_Yes ){
2907 unsigned char saved_eText = p->spec.eText;
2908 p->spec.eText = p->spec.eTitle;
2909 memset(data.abNum, 0, nColumn);
2910 for(i=0; i<nColumn; i++){
2911 const char *z = (const char*)sqlite3_column_name(p->pStmt,i);
@@ -2874,13 +2926,14 @@
2926 data.n++;
2927 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2928 if( nNL ) data.bMultiRow = 1;
2929 }
2930 p->spec.eText = saved_eText;
 
2931 }
2932
2933 /* Load query results into data */
2934 while( rc==SQLITE_ROW && p->iErr==SQLITE_OK ){
2935 if( data.n+nColumn > data.nAlloc ){
2936 if( qrfColDataEnlarge(&data) ) return;
2937 }
2938 for(i=0; i<nColumn; i++){
2939 char *z;
@@ -2897,11 +2950,12 @@
2950 data.n++;
2951 if( w>data.a[i].mxW ) data.a[i].mxW = w;
2952 if( nNL ) data.bMultiRow = 1;
2953 }
2954 p->nRow++;
2955 rc = sqlite3_step(p->pStmt);
2956 }
2957 if( p->iErr ){
2958 qrfColDataFree(&data);
2959 return;
2960 }
2961
@@ -3105,11 +3159,11 @@
3159 /* Draw either (1) the separator between the title line and the body
3160 ** of the table, or (2) separators between individual rows of the table
3161 ** body. isTitleDataSeparator will be true if we are doing (1).
3162 */
3163 if( (i==0 || data.bMultiRow) && i+nColumn<data.n ){
3164 int isTitleDataSeparator = (i==0 && p->spec.bTitles>=QRF_Yes);
3165 if( isTitleDataSeparator ){
3166 qrfLoadAlignment(&data, p);
3167 }
3168 switch( p->spec.eStyle ){
3169 case QRF_STYLE_Table: {
@@ -3132,19 +3186,12 @@
3186 }
3187 break;
3188 }
3189 case QRF_STYLE_Column: {
3190 if( isTitleDataSeparator ){
3191 qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3192 rowSep, szRowSep);
 
 
 
 
 
 
 
3193 }else if( data.bMultiRow ){
3194 qrfRTrim(p->pOut);
3195 sqlite3_str_append(p->pOut, "\n", 1);
3196 }
3197 break;
@@ -3152,20 +3199,39 @@
3199 }
3200 }
3201 }
3202
3203 /* Draw the line across the bottom of the table */
3204 if( p->spec.bBorder!=QRF_No || p->nRow==0 ){
3205 switch( p->spec.eStyle ){
3206 case QRF_STYLE_Box:
3207 if( p->nRow>0 ){
3208 qrfBoxSeparator(p->pOut, &data, BOX_R12, BOX_124, BOX_R14, 0);
3209 }else{
3210 qrfBoxSeparator(p->pOut, &data, DBL_12, DBL_124, DBL_14, 1);
3211 }
3212 break;
3213 case QRF_STYLE_Table:
3214 qrfRowSeparator(p->pOut, &data, '+');
3215 break;
3216 case QRF_STYLE_Markdown:
3217 if( p->nRow==0 ){
3218 qrfRowSeparator(p->pOut, &data, '|');
3219 }
3220 break;
3221 case QRF_STYLE_Column:
3222 if( p->nRow==0 ){
3223 qrfColumnSeparator(p->pOut, &data, colSep, szColSep,
3224 rowSep, szRowSep);
3225 }
3226 break;
3227 }
3228 }
3229 if( p->spec.bRowCount==QRF_Yes ){
3230 sqlite3_int64 n = p->nRow;
3231 sqlite3_str_appendf(p->pOut, "(%lld row%s)\n", n, n==1 ? "" : "s");
3232 }
3233 qrfWrite(p);
3234
3235 qrfColDataFree(&data);
3236 return;
3237 }
@@ -3412,10 +3478,49 @@
3478 sqlite3_str_append(p->pOut, ":", 1);
3479 qrfRenderValue(p, p->pOut, i);
3480 }
3481 qrfWrite(p);
3482 }
3483
3484 /*
3485 ** Render a title row (a row containing column names) if the spec
3486 ** calls for one and if it makes sense for the eStyle. Title rows
3487 ** do not make sense for some eStyles, such as QRF_STYLE_Off,
3488 ** QRF_STYLE_Count, QRF_STYLE_Json, and similar.
3489 */
3490 static void qrfSimpleTitle(Qrf *p){
3491 assert( p->nRow==0 );
3492 assert( p->spec.bTitles>=QRF_Yes );
3493 switch( p->spec.eStyle ){
3494 case QRF_STYLE_Html: {
3495 int i;
3496 sqlite3_str_append(p->pOut, "<TR>", 4);
3497 for(i=0; i<p->nCol; i++){
3498 const char *zCName = sqlite3_column_name(p->pStmt, i);
3499 sqlite3_str_append(p->pOut, "\n<TH>", 5);
3500 qrfEncodeText(p, p->pOut, zCName);
3501 }
3502 sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
3503 break;
3504 }
3505 case QRF_STYLE_Quote:
3506 case QRF_STYLE_List: {
3507 int i;
3508 int saved_eText = p->spec.eText;
3509 p->spec.eText = p->spec.eTitle;
3510 for(i=0; i<p->nCol; i++){
3511 const char *zCName = sqlite3_column_name(p->pStmt, i);
3512 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3513 qrfEncodeText(p, p->pOut, zCName);
3514 }
3515 sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
3516 qrfWrite(p);
3517 p->spec.eText = saved_eText;
3518 break;
3519 }
3520 }
3521 }
3522
3523 /*
3524 ** Render a single row of output for non-columnar styles - any
3525 ** style that lets us render row by row as the content is received
3526 ** from the query.
@@ -3445,18 +3550,12 @@
3550 }
3551 qrfOneJsonRow(p);
3552 break;
3553 }
3554 case QRF_STYLE_Html: {
3555 if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3556 qrfSimpleTitle(p);
 
 
 
 
 
 
3557 }
3558 sqlite3_str_append(p->pOut, "<TR>", 4);
3559 for(i=0; i<p->nCol; i++){
3560 sqlite3_str_append(p->pOut, "\n<TD>", 5);
3561 qrfRenderValue(p, p->pOut, i);
@@ -3476,11 +3575,11 @@
3575 if( qrf_need_quote(p->spec.zTableName) ){
3576 sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
3577 }else{
3578 sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
3579 }
3580 if( p->spec.bTitles>=QRF_Yes ){
3581 for(i=0; i<p->nCol; i++){
3582 const char *zCName = sqlite3_column_name(p->pStmt, i);
3583 if( qrf_need_quote(zCName) ){
3584 sqlite3_str_appendf(p->pOut, "%c\"%w\"",
3585 i==0 ? '(' : ',', zCName);
@@ -3576,21 +3675,12 @@
3675 if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
3676 qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
3677 break;
3678 }
3679 default: { /* QRF_STYLE_List */
3680 if( p->nRow==0 && p->spec.bTitles>=QRF_Yes ){
3681 qrfSimpleTitle(p);
 
 
 
 
 
 
 
 
 
3682 }
3683 for(i=0; i<p->nCol; i++){
3684 if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
3685 qrfRenderValue(p, p->pOut, i);
3686 }
@@ -3612,11 +3702,11 @@
3702 char **pzErr /* Write errors here */
3703 ){
3704 size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
3705 memset(p, 0, sizeof(*p));
3706 p->pzErr = pzErr;
3707 if( pSpec->iVersion>2 ){
3708 qrfError(p, SQLITE_ERROR,
3709 "unusable sqlite3_qrf_spec.iVersion (%d)",
3710 pSpec->iVersion);
3711 return;
3712 }
@@ -3640,10 +3730,13 @@
3730 if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
3731 if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto;
3732 if( p->spec.eText>QRF_TEXT_Relaxed ) p->spec.eText = QRF_Auto;
3733 if( p->spec.eTitle>QRF_TEXT_Relaxed ) p->spec.eTitle = QRF_Auto;
3734 if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto;
3735 if( pSpec->iVersion<=1 ){
3736 p->spec.bRowCount = 0;
3737 }
3738 qrf_reinit:
3739 switch( p->spec.eStyle ){
3740 case QRF_Auto: {
3741 switch( sqlite3_stmt_isexplain(pStmt) ){
3742 case 0: p->spec.eStyle = QRF_STYLE_Box; break;
@@ -3898,10 +3991,34 @@
3991 default: {
3992 /* Non-columnar modes where the output can occur after each row
3993 ** of result is received */
3994 while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
3995 qrfOneSimpleRow(&qrf);
3996 }
3997 if( qrf.nCol>0 && qrf.nRow==0 && qrf.spec.bTitles==QRF_Always ){
3998 qrfSimpleTitle(&qrf);
3999 }
4000 if( qrf.nCol>0 && qrf.spec.bRowCount==QRF_Yes ){
4001 const char *zPlural = qrf.nRow==1 ? "" : "s";
4002 switch( qrf.spec.eStyle ){
4003 case QRF_STYLE_Line:
4004 if( qrf.nRow>0 ) sqlite3_str_append(qrf.pOut, "\n", 1);
4005 /* Fall through */
4006 case QRF_STYLE_Csv:
4007 case QRF_STYLE_List:
4008 case QRF_STYLE_Quote:
4009 sqlite3_str_appendf(qrf.pOut,"(%lld row%s)\n",qrf.nRow,zPlural);
4010 break;
4011 case QRF_STYLE_Html:
4012 sqlite3_str_appendf(qrf.pOut,"<!-- %lld row%s -->\n",
4013 qrf.nRow, zPlural);
4014 break;
4015 case QRF_STYLE_Insert:
4016 sqlite3_str_appendf(qrf.pOut,"/* %lld row%s inserted */\n",
4017 qrf.nRow, zPlural);
4018 break;
4019 }
4020 }
4021 break;
4022 }
4023 }
4024 qrfResetStmt(&qrf);
@@ -10602,11 +10719,15 @@
10719 sqlite3_result_error_nomem(ctx);
10720 return SQLITE_NOMEM;
10721 }
10722 }
10723
10724 if( n>0 ){
10725 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
10726 }else{
10727 sqlite3_result_null(ctx);
10728 }
10729 if( aBuf!=aStatic ) sqlite3_free(aBuf);
10730 #endif
10731 }else{
10732 readFileContents(ctx, pCur->zPath);
10733 }
@@ -17600,10 +17721,13 @@
17721 else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
17722 while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
17723 iRet++;
17724 }
17725 }
17726 else if( c==0 ){
17727 iRet = 0;
17728 }
17729
17730 return iRet;
17731 }
17732
17733 /*
@@ -18039,10 +18163,27 @@
18163 intckFinalize(p, pStmt);
18164
18165 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
18166 return zRet;
18167 }
18168
18169 /*
18170 ** Register or unregister special SQL functions implemented by intck.
18171 **
18172 ** Normally the custom SQL functions used by intck are only available
18173 ** in between sqlite3_intck_open() and sqlite3_intck_close(). However,
18174 ** for testing and debugging, it is sometimes useful to make those
18175 ** functions available generally. This routine provides as a separate
18176 ** interface in order to provide that capability.
18177 */
18178 int sqlite3_intck_register(sqlite3 *db, int bCreate){
18179 int rc;
18180 rc = sqlite3_create_function(db, "parse_create_index",
18181 2, SQLITE_UTF8, 0, bCreate ? intckParseCreateIndexFunc : 0, 0, 0
18182 );
18183 return rc;
18184 }
18185
18186 /*
18187 ** Open a new integrity-check object.
18188 */
18189 int sqlite3_intck_open(
@@ -18061,13 +18202,11 @@
18202 }else{
18203 memset(pNew, 0, sizeof(*pNew));
18204 pNew->db = db;
18205 pNew->zDb = (const char*)&pNew[1];
18206 memcpy(&pNew[1], zDb, nDb+1);
18207 rc = sqlite3_intck_register(db, 1);
 
 
18208 if( rc!=SQLITE_OK ){
18209 sqlite3_intck_close(pNew);
18210 pNew = 0;
18211 }
18212 }
@@ -18080,13 +18219,11 @@
18219 ** Free the integrity-check object.
18220 */
18221 void sqlite3_intck_close(sqlite3_intck *p){
18222 if( p ){
18223 sqlite3_finalize(p->pCheck);
18224 sqlite3_intck_register(p->db, 0);
 
 
18225 sqlite3_free(p->zObj);
18226 sqlite3_free(p->zKey);
18227 sqlite3_free(p->zTestSql);
18228 sqlite3_free(p->zErr);
18229 sqlite3_free(p->zMessage);
@@ -20370,10 +20507,122 @@
20507 0, diskusedFunc, 0, 0);
20508 return rc;
20509 }
20510
20511 /************************* End ext/misc/diskused.c ********************/
20512 /************************* Begin ext/misc/strdup.c ******************/
20513 /*
20514 ** 2026-07-04
20515 **
20516 ** The author disclaims copyright to this source code. In place of
20517 ** a legal notice, here is a blessing:
20518 **
20519 ** May you do good and not evil.
20520 ** May you find forgiveness for yourself and forgive others.
20521 ** May you share freely, never taking more than you give.
20522 **
20523 ******************************************************************************
20524 **
20525 ** Since this module was written (coincidentally) on the 250th anniversary
20526 ** of the signing of the Declaration of Independence of The United States,
20527 ** it seems fitting to quote from that document:
20528 **
20529 ** We hold these truths to be self-evident, that all men are created
20530 ** equal, that they are endowed by their Creator with certain unalienable
20531 ** Rights, that among these are Life, Liberty and the pursuit of Happiness
20532 ** - That to secure these rights, Governments are instituted among Men,
20533 ** deriving their just powers from the consent of the governed,....
20534 **
20535 ** Two core ideas that (1) rights come from God and not from government,
20536 ** and that (2) there should not be special privileged classes of people
20537 ** were radical thoughts then, and are indeed disputed even today. Many
20538 ** people still hold that human rights derive from the beneficence of
20539 ** government and that certain classes of people have special rights and
20540 ** privileges not available to all. Yet, were it not for the crazy ideas
20541 ** espoused in the original Declaration of Independence, this software
20542 ** project, and indeed most of modern technology, would not exist.
20543 **
20544 ** Therefore let us give thanks for the bold leadership and vision
20545 ** demonstrated by the authors of the American Revolution, 250 years ago
20546 ** this day.
20547 **
20548 ******************************************************************************
20549 **
20550 ** Implementation of the strdup() SQL function. strdup() makes a copy
20551 ** of its argument (a string or a BLOB) into memory obtained directly
20552 ** from system malloc() (not from sqlite3_malloc()) and sized exactly
20553 ** to hold the string or BLOB. This is intended for testing purposes,
20554 ** particularly testing with ASAN. This function serves no practical
20555 ** purpose beyond testing and not not intended for production use.
20556 **
20557 ** NULL, BLOB, and TEXT values come through as NULL, BLOB, and TEXT,
20558 ** respectively. Numeric values are rendered as strings and come out
20559 ** as text.
20560 */
20561 /* #include "sqlite3ext.h" */
20562 SQLITE_EXTENSION_INIT1
20563 #include <assert.h>
20564 #include <string.h>
20565 #include <stdlib.h>
20566
20567 /*
20568 ** Make a copy of a string or BLOB in memory obtained from malloc().
20569 */
20570 static void strdupfunc(
20571 sqlite3_context *context,
20572 int argc,
20573 sqlite3_value **argv
20574 ){
20575 const unsigned char *zIn;
20576 int nIn;
20577 unsigned char *zOut;
20578
20579 assert( argc==1 );
20580 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
20581 if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
20582 zIn = (const unsigned char*)sqlite3_value_blob(argv[0]);
20583 nIn = sqlite3_value_bytes(argv[0]);
20584 zOut = malloc( nIn==0 ? 1 : nIn );
20585 if( zOut==0 ){
20586 sqlite3_result_error_nomem(context);
20587 return;
20588 }
20589 if( nIn>0 ) memcpy(zOut, zIn, nIn);
20590 sqlite3_result_blob(context, zOut, nIn, free);
20591 }else{
20592 zIn = (const unsigned char*)sqlite3_value_text(argv[0]);
20593 if( zIn==0 ) return;
20594 nIn = (int)strlen((char*)zIn);
20595 zOut = malloc( nIn+1 );
20596 if( zOut==0 ){
20597 sqlite3_result_error_nomem(context);
20598 return;
20599 }
20600 memcpy(zOut, zIn, nIn);
20601 zOut[nIn] = 0;
20602 sqlite3_result_text64(context, (char*)zOut, nIn, free,
20603 SQLITE_UTF8_ZT);
20604 }
20605 }
20606
20607 #ifdef _WIN32
20608
20609 #endif
20610 int sqlite3_strdup_init(
20611 sqlite3 *db,
20612 char **pzErrMsg,
20613 const sqlite3_api_routines *pApi
20614 ){
20615 int rc = SQLITE_OK;
20616 SQLITE_EXTENSION_INIT2(pApi);
20617 (void)pzErrMsg; /* Unused parameter */
20618 rc = sqlite3_create_function(db, "strdup", 1, SQLITE_UTF8,
20619 0, strdupfunc, 0, 0);
20620 return rc;
20621 }
20622
20623 /************************* End ext/misc/strdup.c ********************/
20624
20625 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
20626 #define SQLITE_SHELL_HAVE_RECOVER 1
20627 #else
20628 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24837,11 +25086,11 @@
25086 unsigned char eHdr; /* Default header encoding. */
25087 unsigned char eBlob; /* Default blob encoding. */
25088 unsigned char bHdr; /* Show headers by default. 0: n/a, 1: no 2: yes */
25089 unsigned char eStyle; /* Underlying QRF style */
25090 unsigned char eCx; /* 0: other, 1: line, 2: columnar */
25091 unsigned char mFlg; /* Flags. 1=border-off 2=split-column 4=rowcount */
25092 };
25093
25094 /* String constants used by built-in modes */
25095 static const char *aModeStr[] =
25096 /* 0 1 2 3 4 5 6 7 8 */
@@ -24850,45 +25099,45 @@
25099 /* 9 10 11 12 13 */
25100
25101 static const ModeInfo aModeInfo[] = {
25102 /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
25103 { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0, 0 },
25104 { "box", 0, 0, 9, 1, 1, 0, 3, 1, 2, 0 },
25105 { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0, 0 },
25106 { "column", 0, 0, 9, 1, 1, 0, 3, 2, 2, 0 },
25107 { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
25108 { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0, 0 },
25109 { "html", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 },
25110 { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0, 0 },
25111 { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 },
25112 { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 },
25113 { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 },
25114 { "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 },
25115 { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 },
25116 { "markdown", 0, 0, 9, 1, 1, 0, 3, 13, 2, 0 },
25117 { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 },
25118 { "psql", 0, 0, 9, 1, 1, 0, 3, 19, 2, 5 },
25119 { "qbox", 0, 0, 10, 2, 1, 0, 3, 1, 2, 0 },
25120 { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0, 0 },
25121 { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2, 2 },
25122 { "table", 0, 0, 9, 1, 1, 0, 3, 19, 2, 0 },
25123 { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0, 0 },
25124 { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0, 0 },
25125 { "www", 0, 0, 9, 4, 4, 0, 3, 7, 0, 0 }
25126 }; /* | / / | / / | | / \____
25127 ** | / / | / / | | / |
25128 ** Index into aModeStr[] | / / | | 2: columnar |
25129 ** | / / | | 1: line |
25130 ** | / / | | 0: other |
25131 ** text encoding |/ | show | | |
25132 ** v-------------------' | hdrs? | The QRF style |
25133 ** 0: n/a blob | v-----' /
25134 ** 1: plain v----------' 0: n/a _________/
25135 ** 2: sql 0: auto 1: no |
25136 ** 3: csv 1: as-text 2: yes 1: border-off
25137 ** 4: html 2: sql 3: always 2: split-column
25138 ** 5: c 3: hex 4: rowcount
25139 ** 6: json 4: c
25140 ** 5: json
25141 ** 6: size
25142 ******************************************************************/
25143
@@ -26316,11 +26565,11 @@
26565 free(p->spec.zColumnSep);
26566 free(p->spec.zRowSep);
26567 free(p->spec.zTableName);
26568 free(p->spec.zNull);
26569 memset(p, 0, sizeof(*p));
26570 p->spec.iVersion = 2;
26571 p->autoExplain = autoExplain;
26572 }
26573
26574 /*
26575 ** Duplicate Mode pSrc into pDest. pDest is assumed to be
@@ -26441,10 +26690,15 @@
26690 pM->spec.bSplitColumn = QRF_Yes;
26691 pM->bAutoScreenWidth = 1;
26692 }else{
26693 pM->spec.bSplitColumn = QRF_No;
26694 }
26695 if( pI->mFlg & 0x04 ){
26696 pM->spec.bRowCount = QRF_Yes;
26697 }else{
26698 pM->spec.bRowCount = QRF_No;
26699 }
26700 }else if( eMode>=MODE_USER && eMode-MODE_USER<p->nSavedModes ){
26701 modeFree(&p->mode);
26702 modeDup(&p->mode, &p->aSavedModes[eMode-MODE_USER].mode);
26703 }else if( eMode==MODE_BATCH ){
26704 u8 mFlags = p->mode.mFlags;
@@ -26470,11 +26724,11 @@
26724 /*
26725 ** Set the mode to the default. It assumed that the mode has
26726 ** already been freed and zeroed prior to calling this routine.
26727 */
26728 static void modeDefault(ShellState *p){
26729 p->mode.spec.iVersion = 2;
26730 p->mode.autoExplain = 1;
26731 if( stdin_is_interactive || stdout_is_console ){
26732 modeChange(p, MODE_TTY);
26733 }else{
26734 modeChange(p, MODE_BATCH);
@@ -28836,10 +29090,11 @@
29090 " --quote ARG Enable/disable quoting of text. ARG can be\n"
29091 " \"off\", \"on\", \"sql\", \"relaxed\", \"csv\", \"html\",\n"
29092 " \"tcl\", or \"json\". \"off\" means show the text as-is.\n"
29093 " \"on\" is an alias for \"sql\".\n"
29094 " --reset Changes all mode settings back to their default.\n"
29095 " --rowcount BOOLEAN Show \"(N rows)\" at the end of query results.\n"
29096 " --rowsep STRING Use STRING as the row separator\n"
29097 " --sw|--screenwidth N Declare the screen width of the output device\n"
29098 " to be N characters. An attempt may be made to\n"
29099 " wrap output text to fit within this limit. Zero\n"
29100 " means \"no limit\". Or N can be \"auto\" to set the\n"
@@ -28847,11 +29102,11 @@
29102 " --tablename NAME Set the name of the table for \"insert\" mode.\n"
29103 " --tag NAME Save mode to the left as NAME.\n"
29104 " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n"
29105 " --title ARG Whether or not to show column headers, and if so\n"
29106 " how to encode them. ARG can be \"off\", \"on\",\n"
29107 " \"always\", \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n"
29108 " --titlelimit N Limit the length of column titles to N characters.\n"
29109 " -v|--verbose Verbose output\n"
29110 " --widths LIST Set the columns widths for columnar modes. The\n"
29111 " argument is a list of integers, one for each\n"
29112 " column. A \"0\" width means use a dynamic width\n"
@@ -29553,10 +29808,11 @@
29808 sqlite3_base85_init(p->db, 0, 0);
29809 sqlite3_regexp_init(p->db, 0, 0);
29810 sqlite3_ieee_init(p->db, 0, 0);
29811 sqlite3_series_init(p->db, 0, 0);
29812 sqlite3_diskused_init(p->db, 0, 0);
29813 sqlite3_strdup_init(p->db, 0, 0);
29814 #ifndef SQLITE_SHELL_FIDDLE
29815 sqlite3_fileio_init(p->db, 0, 0);
29816 sqlite3_completion_init(p->db, 0, 0);
29817 #endif
29818 #ifdef SQLITE_HAVE_ZLIB
@@ -33007,14 +33263,16 @@
33263 /*
33264 ** This function computes what to show the user about the configured
33265 ** titles (or column-names). Output is an integer between 0 and 3:
33266 **
33267 ** 0: The titles do not matter. Never show anything.
33268 ** 1: Show "--title off"
33269 ** 2: Show "--title on"
33270 ** 3: Show "--title always"
33271 ** 4: Show "--title VALUE" where VALUE is an encoding method
33272 ** to use, one of: plain sql csv html tcl json
33273 ** 5: Show "--title VALUE" as in 3, followed by "--title always"
33274 **
33275 ** Inputs are:
33276 **
33277 ** spec.bTitles (bT) Whether or not to show the titles
33278 ** spec.eTitle (eT) The actual encoding to be used for titles
@@ -33047,11 +33305,27 @@
33305 if( eT!=eH ) v >>= 32; /* Encoding disagree in upper 4-bytes */
33306 if( bT!=bH ) v >>= 16; /* ON/OFF disagree in upper 2-byte pairs */
33307 if( bT<2 ) v >>= 8; /* ON in even bytes, OFF in odd bytes (1st byte 0) */
33308 if( !bAll ) v >>= 4; /* bAll values are in the lower half-byte */
33309
33310 v &= 3;
33311 /* At this point v means:
33312 ** 0: The titles do not matter. Never show anything.
33313 ** 1: Show "--title off"
33314 ** 2: Show "--title on"
33315 ** 3: Show "--title VALUE" where VALUE is an encoding method
33316 ** to use, one of: plain sql csv html tcl json
33317 ** If bTitles is QRF_Always, convert 2->3, 3->5. If bTitles is not
33318 ** QRF_Always, convert 3->4.
33319 */
33320 if( p->mode.spec.bTitles==QRF_Always ){
33321 if( v==3 ) v = 5;
33322 if( v==2 ) v = 3;
33323 }else{
33324 if( v==3 ) v = 4;
33325 }
33326 return v;
33327 }
33328
33329 /*
33330 ** DOT-COMMAND: .mode
33331 **
@@ -33095,10 +33369,11 @@
33369 ** --quote ARG Enable/disable quoting of text. ARG can be
33370 ** "off", "on", "sql", "relaxed", "csv", "html",
33371 ** "tcl", or "json". "off" means show the text as-is.
33372 ** "on" is an alias for "sql".
33373 ** --reset Changes all mode settings back to their default.
33374 ** --rowcount BOOLEAN Show "(N rows)" at the end of query results.
33375 ** --rowsep STRING Use STRING as the row separator
33376 ** --sw|--screenwidth N Declare the screen width of the output device
33377 ** to be N characters. An attempt may be made to
33378 ** wrap output text to fit within this limit. Zero
33379 ** means "no limit". Or N can be "auto" to set the
@@ -33106,11 +33381,11 @@
33381 ** --tablename NAME Set the name of the table for "insert" mode.
33382 ** --tag NAME Save mode to the left as NAME.
33383 ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.
33384 ** --title ARG Whether or not to show column headers, and if so
33385 ** how to encode them. ARG can be "off", "on",
33386 ** "always", "sql", "csv", "html", "tcl", or "json".
33387 ** --titlelimit N Limit the length of column titles to N characters.
33388 ** -v|--verbose Verbose output
33389 ** --widths LIST Set the columns widths for columnar modes. The
33390 ** argument is a list of integers, one for each
33391 ** column. A "0" width means use a dynamic width
@@ -33334,10 +33609,17 @@
33609 chng = 1;
33610 }else if( optionMatch(z,"reset") ){
33611 int saved_eMode = p->mode.eMode;
33612 modeFree(&p->mode);
33613 modeChange(p, saved_eMode);
33614 }else if( optionMatch(z,"rowcount") ){
33615 if( i+1>=nArg ){
33616 dotCmdError(p, i, "missing argument", 0);
33617 return 1;
33618 }
33619 p->mode.spec.bRowCount = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33620 chng = 1;
33621 }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){
33622 if( (++i)>=nArg ){
33623 dotCmdError(p, i-1, "missing argument", 0);
33624 return 1;
33625 }
@@ -33387,25 +33669,63 @@
33669 return 1;
33670 }
33671 p->mode.spec.bTextJsonb = booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
33672 chng = 1;
33673 }else if( optionMatch(z,"titles") || optionMatch(z,"title") ){
33674 /* The --titles option controls two fields of the
33675 ** sqlite3_qrf_spec object: eTitle and bTitles.
33676 **
33677 ** --titles eTitle bTitles
33678 ** -------- --------------- ---------------------
33679 ** "off" (unchanged) QRF_Off
33680 ** "on" (unchanged) QRF_On
33681 ** "always" (unchanged) QRF_Always
33682 ** "auto", (default) (default)
33683 ** "plain" QRF_TEXT_Plain QRF_Always or QRF_On
33684 ** "sql" QRF_TEXT_Sql QRF_Always or QRF_On
33685 ** "csv" QRF_TEXT_Csv QRF_Always or QRF_On
33686 ** "html" QRF_TEXT_Html QRF_Always or QRF_On
33687 ** "tcl" QRF_TEXT_Tcl QRF_Always or QRF_On
33688 ** "json" QRF_TEXT_Json QRF_Always or QRF_On
33689 **
33690 ** This mapping is different from the -title option to the "format"
33691 ** method of the TCL interface. In this mapping:
33692 **
33693 ** * "off", "on", and "always" affect only bTitles and leave
33694 ** eTitle unchanged
33695 **
33696 ** * "auto" sets both bTitles and eTitle to the default value
33697 ** in aModeInfo[] according to the current --style.
33698 **
33699 ** * "plain" through "json" set eTitle but leave bTitles
33700 ** unchanged if it is not QRF_Off. If bTitles is QRF_Off,
33701 ** then it is changed QRF_Always.
33702 */
33703 char *zErr = 0;
33704 if( i+1>=nArg ){
33705 dotCmdError(p, i, "missing argument", 0);
33706 return 1;
33707 }
33708 k = pickStr(azArg[++i],&zErr,
33709 "off","on","always","auto","plain","sql","csv","html","tcl","json","");
33710 /* 0 1 2 3 4 5 6 7 8 9 */
33711 if( k<0 ){
33712 dotCmdError(p, i, "bad --titles value","%z", zErr);
33713 return 1;
33714 }
 
33715 p->mode.mFlags &= ~MFLG_HDR;
33716 if( k<=2 ){
33717 p->mode.spec.bTitles = QRF_No+k;
33718 }else if( k==3 ){
33719 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
33720 p->mode.spec.bTitles = aModeInfo[p->mode.eMode].bHdr;
33721 }else{
33722 p->mode.spec.eTitle = (k-4)+QRF_TEXT_Plain;
33723 if( p->mode.spec.bTitles==QRF_No ){
33724 p->mode.spec.bTitles = QRF_Always;
33725 }
33726 }
33727 chng = 1;
33728 }else if( optionMatch(z,"widths") || optionMatch(z,"width") ){
33729 int nWidth = 0;
33730 short int *aWidth;
33731 const char *zW;
@@ -33556,10 +33876,16 @@
33876 if( bAll
33877 || (pI->eText!=p->mode.spec.eText && (pI->eText>1 || p->mode.spec.eText>1))
33878 ){
33879 sqlite3_str_appendf(pDesc," --quote %s",qrfQuoteNames[p->mode.spec.eText]);
33880 }
33881 if( bAll
33882 || ((p->mode.spec.bRowCount==QRF_Yes) != ((pI->mFlg&4)!=0))
33883 ){
33884 sqlite3_str_appendf(pDesc," --rowcount %s",
33885 p->mode.spec.bRowCount==QRF_Yes ? "on" : "off");
33886 }
33887 zSetting = aModeStr[pI->eRSep];
33888 if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zRowSep)!=0) ){
33889 sqlite3_str_appendf(pDesc, " --rowsep ");
33890 append_c_string(pDesc, p->mode.spec.zRowSep);
33891 }
@@ -33585,14 +33911,19 @@
33911 if( k==1 ){
33912 sqlite3_str_appendall(pDesc, " --titles off");
33913 }else if( k==2 ){
33914 sqlite3_str_appendall(pDesc, " --titles on");
33915 }else if( k==3 ){
33916 sqlite3_str_appendall(pDesc, " --titles always");
33917 }else if( k>=4 ){
33918 static const char *azTitle[] =
33919 { "plain", "sql", "csv", "html", "tcl", "json"};
33920 sqlite3_str_appendf(pDesc, " --titles %s",
33921 azTitle[p->mode.spec.eTitle-1]);
33922 if( k==5 ){
33923 sqlite3_str_appendf(pDesc, " --titles always");
33924 }
33925 }
33926 if( p->mode.spec.nWidth>0 && (bAll || pI->eCx==2) ){
33927 int ii;
33928 const char *zSep = " --widths ";
33929 for(ii=0; ii<p->mode.spec.nWidth; ii++){
@@ -34910,15 +35241,19 @@
35241 }
35242 }else
35243
35244 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
35245 if( nArg==2 ){
35246 if( cli_strcmp(azArg[1],"always")==0 ){
35247 p->mode.spec.bTitles = QRF_Always;
35248 }else{
35249 p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No;
35250 }
35251 p->mode.mFlags |= MFLG_HDR;
35252 p->mode.spec.eTitle = aModeInfo[p->mode.eMode].eHdr;
35253 }else{
35254 eputz("Usage: .headers off|on|always\n");
35255 rc = 1;
35256 }
35257 }else
35258
35259 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
@@ -35122,13 +35457,21 @@
35457 sqlite3_str_free(pSql);
35458 }else
35459
35460 if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){
35461 i64 iArg = 0;
35462 open_db(p, 0);
35463 if( nArg==2 ){
35464 iArg = integerValue(azArg[1]);
35465 if( iArg==0 ){
35466 if( cli_strcmp(azArg[1],"register")==0 ){
35467 sqlite3_intck_register(p->db, 1);
35468 rc = 0;
35469 goto meta_command_exit;
35470 }
35471 iArg = -1;
35472 }
35473 }
35474 if( (nArg!=1 && nArg!=2) || iArg<0 ){
35475 cli_printf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n");
35476 rc = 1;
35477 goto meta_command_exit;
@@ -36502,11 +36845,12 @@
36845 azBool[(p->mode.mFlags & MFLG_ECHO)!=0]);
36846 cli_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->mode.autoEQP&3]);
36847 cli_printf(p->out, "%12.12s: %s\n","explain",
36848 p->mode.autoExplain ? "auto" : "off");
36849 cli_printf(p->out, "%12.12s: %s\n","headers",
36850 p->mode.spec.bTitles==QRF_Always ? "always" :
36851 azBool[p->mode.spec.bTitles==QRF_Yes]);
36852 if( p->mode.spec.eStyle==QRF_STYLE_Column
36853 || p->mode.spec.eStyle==QRF_STYLE_Box
36854 || p->mode.spec.eStyle==QRF_STYLE_Table
36855 || p->mode.spec.eStyle==QRF_STYLE_Markdown
36856 ){
@@ -38576,11 +38920,11 @@
38920 cmdline_option_value(argc,argv,++i));
38921 }else if( cli_strcmp(z,"-nullvalue")==0 ){
38922 modeSetStr(&data.mode.spec.zNull,
38923 cmdline_option_value(argc,argv,++i));
38924 }else if( cli_strcmp(z,"-header")==0 ){
38925 data.mode.spec.bTitles = QRF_Always;
38926 data.mode.mFlags |= MFLG_HDR;
38927 }else if( cli_strcmp(z,"-noheader")==0 ){
38928 data.mode.spec.bTitles = QRF_No;
38929 data.mode.mFlags |= MFLG_HDR;
38930 }else if( cli_strcmp(z,"-echo")==0 ){
38931
+55 -36
--- 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
-** 88901fffcd445ccb97e4e379ea15d8b06d87 with changes in files:
21
+** c8aa208bf5b00f3ab93c5edd510dfd0d7edd with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470470
#define SQLITE_VERSION "3.54.0"
471471
#define SQLITE_VERSION_NUMBER 3054000
472
-#define SQLITE_SOURCE_ID "2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f"
472
+#define SQLITE_SOURCE_ID "2026-07-08 15:43:42 c8aa208bf5b00f3ab93c5edd510dfd0d7edd271c064f159616ee409b308f7eb9"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2026-07-01T12:11:41.802Z"
475
+#define SQLITE_SCM_DATETIME "2026-07-08T15:43:42.959Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -110677,17 +110677,20 @@
110677110677
if( cnt==1 ){
110678110678
assert( pNC!=0 );
110679110679
#ifndef SQLITE_OMIT_AUTHORIZATION
110680110680
if( db->xAuth ){
110681110681
if( pFJMatch ){
110682
+ int ii;
110682110683
assert( pExpr->op==TK_FUNCTION );
110683110684
assert( sqlite3_stricmp(pExpr->u.zToken,"coalesce")==0 );
110684110685
assert( pExpr->x.pList==pFJMatch );
110685110686
assert( pFJMatch->nExpr>0 );
110686
- pExpr = pFJMatch->a[0].pExpr;
110687
- }
110688
- if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){
110687
+ for(ii=0; ii<pFJMatch->nExpr; ii++){
110688
+ assert( pFJMatch->a[0].pExpr->op==TK_COLUMN );
110689
+ sqlite3AuthRead(pParse, pFJMatch->a[0].pExpr, pSchema, pNC->pSrcList);
110690
+ }
110691
+ }else if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){
110689110692
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
110690110693
}
110691110694
}
110692110695
#endif
110693110696
/* Increment the nRef value on all name contexts from TopNC up to
@@ -210435,12 +210438,12 @@
210435210438
210436210439
/* If there is insufficient space allocated at StrBuffer.z, use realloc()
210437210440
** to grow the buffer until so that it is big enough to accommodate the
210438210441
** appended data.
210439210442
*/
210440
- if( pStr->n+nAppend+1>=pStr->nAlloc ){
210441
- sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
210443
+ if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){
210444
+ i64 nAlloc = pStr->nAlloc+(i64)nAppend+100;
210442210445
char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
210443210446
if( !zNew ){
210444210447
return SQLITE_NOMEM;
210445210448
}
210446210449
pStr->z = zNew;
@@ -214640,11 +214643,12 @@
214640214643
u32 k = 0;
214641214644
const char *zIn = (const char*)&pParse->aBlob[i+n];
214642214645
if( sz==0 ) goto malformed_jsonb;
214643214646
if( zIn[0]=='-' ){
214644214647
jsonAppendChar(pOut, '-');
214645
- k++;
214648
+ if( sz<=1 ) goto malformed_jsonb;
214649
+ k = 1;
214646214650
}
214647214651
if( zIn[k]=='.' ){
214648214652
jsonAppendChar(pOut, '0');
214649214653
}
214650214654
for(; k<sz; k++){
@@ -217603,11 +217607,13 @@
217603217607
*/
217604217608
static int jsonSkipLabel(JsonEachCursor *p){
217605217609
if( p->eType==JSONB_OBJECT ){
217606217610
u32 sz = 0;
217607217611
u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
217608
- return p->i + n + sz;
217612
+ sz += p->i + n;
217613
+ if( sz >= p->sParse.nBlob ) sz = p->i;
217614
+ return sz;
217609217615
}else{
217610217616
return p->i;
217611217617
}
217612217618
}
217613217619
@@ -226573,31 +226579,31 @@
226573226579
int lenSrc, /* Length of the source file */
226574226580
const char *zDelta, /* Delta to apply to the pattern */
226575226581
int lenDelta, /* Length of the delta */
226576226582
char *zOut /* Write the output into this preallocated buffer */
226577226583
){
226578
- unsigned int limit;
226579
- unsigned int total = 0;
226584
+ sqlite3_uint64 limit;
226585
+ sqlite3_uint64 total = 0;
226580226586
#if RBU_ENABLE_DELTA_CKSUM
226581226587
char *zOrigOut = zOut;
226582226588
#endif
226583226589
226584226590
limit = rbuDeltaGetInt(&zDelta, &lenDelta);
226585226591
if( lenDelta<=0 || *zDelta!='\n' ){
226586226592
/* ERROR: size integer not terminated by "\n" */
226587226593
return -1;
226588226594
}
226589
- zDelta++; lenDelta--;
226590
- while( *zDelta && lenDelta>0 ){
226595
+ zDelta++; lenDelta--; /* Skip the \n */
226596
+ while( lenDelta>0 && zDelta[0] ){
226591226597
unsigned int cnt, ofst;
226592226598
cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
226593226599
if( lenDelta<=0 ) return -1;
226594226600
switch( zDelta[0] ){
226595226601
case '@': {
226596226602
zDelta++; lenDelta--;
226597226603
ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
226598
- if( lenDelta>0 || zDelta[0]!=',' ){
226604
+ if( lenDelta>0 && zDelta[0]!=',' ){
226599226605
/* ERROR: copy command not terminated by ',' */
226600226606
return -1;
226601226607
}
226602226608
zDelta++; lenDelta--;
226603226609
total += cnt;
@@ -226618,11 +226624,11 @@
226618226624
total += cnt;
226619226625
if( total>limit ){
226620226626
/* ERROR: insert command gives an output larger than predicted */
226621226627
return -1;
226622226628
}
226623
- if( (i64)cnt>(i64)lenDelta ){
226629
+ if( cnt>lenDelta ){
226624226630
/* ERROR: insert count exceeds size of delta */
226625226631
return -1;
226626226632
}
226627226633
memcpy(zOut, zDelta, cnt);
226628226634
zOut += cnt;
@@ -228631,17 +228637,17 @@
228631228637
char *zWhere = rbuObjIterGetWhere(p, pIter);
228632228638
char *zSet = rbuObjIterGetSetlist(p, pIter, zMask);
228633228639
char *zUpdate = 0;
228634228640
228635228641
pUp->zMask = (char*)&pUp[1];
228636
- memcpy(pUp->zMask, zMask, pIter->nTblCol);
228637228642
pUp->pNext = pIter->pRbuUpdate;
228638228643
pIter->pRbuUpdate = pUp;
228639228644
228640228645
if( zSet ){
228641228646
const char *zPrefix = "";
228642
-
228647
+ assert( p->rc==SQLITE_OK );
228648
+ memcpy(pUp->zMask, zMask, pIter->nTblCol);
228643228649
if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
228644228650
zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
228645228651
zPrefix, pIter->zTbl, zSet, zWhere
228646228652
);
228647228653
p->rc = prepareFreeAndCollectError(
@@ -228727,10 +228733,13 @@
228727228733
pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
228728228734
break;
228729228735
228730228736
case RBU_STATE_ROW:
228731228737
pRet->nRow = sqlite3_column_int(pStmt, 1);
228738
+ if( pRet->nRow<0 ){
228739
+ rc = SQLITE_CORRUPT;
228740
+ }
228732228741
break;
228733228742
228734228743
case RBU_STATE_PROGRESS:
228735228744
pRet->nProgress = sqlite3_column_int64(pStmt, 1);
228736228745
break;
@@ -239976,11 +239985,16 @@
239976239985
int nRec;
239977239986
int rc = SQLITE_OK;
239978239987
239979239988
pIter->in.bNoDiscard = 1;
239980239989
while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
239981
- rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
239990
+ if( bRebase && pIter->bPatchset ){
239991
+ /* A patchset may not be used as a rebase */
239992
+ rc = SQLITE_ERROR;
239993
+ }else{
239994
+ rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
239995
+ }
239982239996
if( rc!=SQLITE_OK ) break;
239983239997
}
239984239998
239985239999
if( rc==SQLITE_OK ) rc = pIter->rc;
239986240000
return rc;
@@ -240353,17 +240367,18 @@
240353240367
int bData = 0;
240354240368
u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
240355240369
int i;
240356240370
u8 *a1 = aRec;
240357240371
u8 *a2 = aChange;
240372
+ u8 *a2Eof = &a2[nChange];
240358240373
240359240374
*pOut++ = SQLITE_UPDATE;
240360240375
*pOut++ = pIter->bIndirect;
240361240376
for(i=0; i<pIter->nCol; i++){
240362240377
int n1 = sessionSerialLen(a1);
240363
- int n2 = sessionSerialLen(a2);
240364
- if( pIter->abPK[i] || a2[0]==0 ){
240378
+ int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2);
240379
+ if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){
240365240380
if( !pIter->abPK[i] && a1[0] ) bData = 1;
240366240381
memcpy(pOut, a1, n1);
240367240382
pOut += n1;
240368240383
}else if( a2[0]!=0xFF && a1[0] ){
240369240384
bData = 1;
@@ -240560,12 +240575,12 @@
240560240575
*/
240561240576
SQLITE_API int sqlite3rebaser_configure(
240562240577
sqlite3_rebaser *p,
240563240578
int nRebase, const void *pRebase
240564240579
){
240565
- sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240566240580
int rc; /* Return code */
240581
+ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240567240582
rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
240568240583
if( rc==SQLITE_OK ){
240569240584
rc = sessionChangesetToHash(pIter, &p->grp, 1);
240570240585
}
240571240586
sqlite3changeset_finalize(pIter);
@@ -255674,11 +255689,11 @@
255674255689
255675255690
iNext = fts5GetU16(&aPg[0]);
255676255691
if( iNext!=0 ){
255677255692
*pbLastInDoclist = 0;
255678255693
}
255679
- if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){
255694
+ if( iNext==0 && pLeaf->szLeaf<pLeaf->nn ){
255680255695
fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
255681255696
}
255682255697
255683255698
if( iNext==0 ){
255684255699
/* The page contains no terms or rowids. Replace it with an empty
@@ -262777,23 +262792,27 @@
262777262792
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
262778262793
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
262779262794
262780262795
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
262781262796
Fts5Sorter *pSorter = pCsr->pSorter;
262782
- int n;
262783
- if( pSorter ){
262784
- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
262785
- n = pSorter->aIdx[iPhrase] - i1;
262786
- pIter->a = &pSorter->aPoslist[i1];
262797
+ if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
262798
+ rc = SQLITE_RANGE;
262787262799
}else{
262788
- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
262789
- }
262790
- if( rc==SQLITE_OK ){
262791
- assert( pIter->a || n==0 );
262792
- pIter->b = (pIter->a ? &pIter->a[n] : 0);
262793
- *piCol = 0;
262794
- fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
262800
+ int n;
262801
+ if( pSorter ){
262802
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
262803
+ n = pSorter->aIdx[iPhrase] - i1;
262804
+ pIter->a = &pSorter->aPoslist[i1];
262805
+ }else{
262806
+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
262807
+ }
262808
+ if( rc==SQLITE_OK ){
262809
+ assert( pIter->a || n==0 );
262810
+ pIter->b = (pIter->a ? &pIter->a[n] : 0);
262811
+ *piCol = 0;
262812
+ fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
262813
+ }
262795262814
}
262796262815
}else{
262797262816
int n;
262798262817
rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
262799262818
if( rc==SQLITE_OK ){
@@ -263697,11 +263716,11 @@
263697263716
int nArg, /* Number of args */
263698263717
sqlite3_value **apUnused /* Function arguments */
263699263718
){
263700263719
assert( nArg==0 );
263701263720
UNUSED_PARAM2(nArg, apUnused);
263702
- sqlite3_result_text(pCtx, "fts5: 2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f", -1, SQLITE_TRANSIENT);
263721
+ sqlite3_result_text(pCtx, "fts5: 2026-07-07 14:53:53 c3b0fff1b76b8c354b34fef17ff639968698e97234d6ab7af15e0e1a835486e9", -1, SQLITE_TRANSIENT);
263703263722
}
263704263723
263705263724
/*
263706263725
** Implementation of fts5_locale(LOCALE, TEXT) function.
263707263726
**
263708263727
--- 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 ** 88901fffcd445ccb97e4e379ea15d8b06d87 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.54.0"
471 #define SQLITE_VERSION_NUMBER 3054000
472 #define SQLITE_SOURCE_ID "2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2026-07-01T12:11:41.802Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -110677,17 +110677,20 @@
110677 if( cnt==1 ){
110678 assert( pNC!=0 );
110679 #ifndef SQLITE_OMIT_AUTHORIZATION
110680 if( db->xAuth ){
110681 if( pFJMatch ){
 
110682 assert( pExpr->op==TK_FUNCTION );
110683 assert( sqlite3_stricmp(pExpr->u.zToken,"coalesce")==0 );
110684 assert( pExpr->x.pList==pFJMatch );
110685 assert( pFJMatch->nExpr>0 );
110686 pExpr = pFJMatch->a[0].pExpr;
110687 }
110688 if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){
 
 
110689 sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
110690 }
110691 }
110692 #endif
110693 /* Increment the nRef value on all name contexts from TopNC up to
@@ -210435,12 +210438,12 @@
210435
210436 /* If there is insufficient space allocated at StrBuffer.z, use realloc()
210437 ** to grow the buffer until so that it is big enough to accommodate the
210438 ** appended data.
210439 */
210440 if( pStr->n+nAppend+1>=pStr->nAlloc ){
210441 sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
210442 char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
210443 if( !zNew ){
210444 return SQLITE_NOMEM;
210445 }
210446 pStr->z = zNew;
@@ -214640,11 +214643,12 @@
214640 u32 k = 0;
214641 const char *zIn = (const char*)&pParse->aBlob[i+n];
214642 if( sz==0 ) goto malformed_jsonb;
214643 if( zIn[0]=='-' ){
214644 jsonAppendChar(pOut, '-');
214645 k++;
 
214646 }
214647 if( zIn[k]=='.' ){
214648 jsonAppendChar(pOut, '0');
214649 }
214650 for(; k<sz; k++){
@@ -217603,11 +217607,13 @@
217603 */
217604 static int jsonSkipLabel(JsonEachCursor *p){
217605 if( p->eType==JSONB_OBJECT ){
217606 u32 sz = 0;
217607 u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
217608 return p->i + n + sz;
 
 
217609 }else{
217610 return p->i;
217611 }
217612 }
217613
@@ -226573,31 +226579,31 @@
226573 int lenSrc, /* Length of the source file */
226574 const char *zDelta, /* Delta to apply to the pattern */
226575 int lenDelta, /* Length of the delta */
226576 char *zOut /* Write the output into this preallocated buffer */
226577 ){
226578 unsigned int limit;
226579 unsigned int total = 0;
226580 #if RBU_ENABLE_DELTA_CKSUM
226581 char *zOrigOut = zOut;
226582 #endif
226583
226584 limit = rbuDeltaGetInt(&zDelta, &lenDelta);
226585 if( lenDelta<=0 || *zDelta!='\n' ){
226586 /* ERROR: size integer not terminated by "\n" */
226587 return -1;
226588 }
226589 zDelta++; lenDelta--;
226590 while( *zDelta && lenDelta>0 ){
226591 unsigned int cnt, ofst;
226592 cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
226593 if( lenDelta<=0 ) return -1;
226594 switch( zDelta[0] ){
226595 case '@': {
226596 zDelta++; lenDelta--;
226597 ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
226598 if( lenDelta>0 || zDelta[0]!=',' ){
226599 /* ERROR: copy command not terminated by ',' */
226600 return -1;
226601 }
226602 zDelta++; lenDelta--;
226603 total += cnt;
@@ -226618,11 +226624,11 @@
226618 total += cnt;
226619 if( total>limit ){
226620 /* ERROR: insert command gives an output larger than predicted */
226621 return -1;
226622 }
226623 if( (i64)cnt>(i64)lenDelta ){
226624 /* ERROR: insert count exceeds size of delta */
226625 return -1;
226626 }
226627 memcpy(zOut, zDelta, cnt);
226628 zOut += cnt;
@@ -228631,17 +228637,17 @@
228631 char *zWhere = rbuObjIterGetWhere(p, pIter);
228632 char *zSet = rbuObjIterGetSetlist(p, pIter, zMask);
228633 char *zUpdate = 0;
228634
228635 pUp->zMask = (char*)&pUp[1];
228636 memcpy(pUp->zMask, zMask, pIter->nTblCol);
228637 pUp->pNext = pIter->pRbuUpdate;
228638 pIter->pRbuUpdate = pUp;
228639
228640 if( zSet ){
228641 const char *zPrefix = "";
228642
 
228643 if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
228644 zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
228645 zPrefix, pIter->zTbl, zSet, zWhere
228646 );
228647 p->rc = prepareFreeAndCollectError(
@@ -228727,10 +228733,13 @@
228727 pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
228728 break;
228729
228730 case RBU_STATE_ROW:
228731 pRet->nRow = sqlite3_column_int(pStmt, 1);
 
 
 
228732 break;
228733
228734 case RBU_STATE_PROGRESS:
228735 pRet->nProgress = sqlite3_column_int64(pStmt, 1);
228736 break;
@@ -239976,11 +239985,16 @@
239976 int nRec;
239977 int rc = SQLITE_OK;
239978
239979 pIter->in.bNoDiscard = 1;
239980 while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
239981 rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
 
 
 
 
 
239982 if( rc!=SQLITE_OK ) break;
239983 }
239984
239985 if( rc==SQLITE_OK ) rc = pIter->rc;
239986 return rc;
@@ -240353,17 +240367,18 @@
240353 int bData = 0;
240354 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
240355 int i;
240356 u8 *a1 = aRec;
240357 u8 *a2 = aChange;
 
240358
240359 *pOut++ = SQLITE_UPDATE;
240360 *pOut++ = pIter->bIndirect;
240361 for(i=0; i<pIter->nCol; i++){
240362 int n1 = sessionSerialLen(a1);
240363 int n2 = sessionSerialLen(a2);
240364 if( pIter->abPK[i] || a2[0]==0 ){
240365 if( !pIter->abPK[i] && a1[0] ) bData = 1;
240366 memcpy(pOut, a1, n1);
240367 pOut += n1;
240368 }else if( a2[0]!=0xFF && a1[0] ){
240369 bData = 1;
@@ -240560,12 +240575,12 @@
240560 */
240561 SQLITE_API int sqlite3rebaser_configure(
240562 sqlite3_rebaser *p,
240563 int nRebase, const void *pRebase
240564 ){
240565 sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240566 int rc; /* Return code */
 
240567 rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
240568 if( rc==SQLITE_OK ){
240569 rc = sessionChangesetToHash(pIter, &p->grp, 1);
240570 }
240571 sqlite3changeset_finalize(pIter);
@@ -255674,11 +255689,11 @@
255674
255675 iNext = fts5GetU16(&aPg[0]);
255676 if( iNext!=0 ){
255677 *pbLastInDoclist = 0;
255678 }
255679 if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){
255680 fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
255681 }
255682
255683 if( iNext==0 ){
255684 /* The page contains no terms or rowids. Replace it with an empty
@@ -262777,23 +262792,27 @@
262777 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
262778 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
262779
262780 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
262781 Fts5Sorter *pSorter = pCsr->pSorter;
262782 int n;
262783 if( pSorter ){
262784 int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
262785 n = pSorter->aIdx[iPhrase] - i1;
262786 pIter->a = &pSorter->aPoslist[i1];
262787 }else{
262788 rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
262789 }
262790 if( rc==SQLITE_OK ){
262791 assert( pIter->a || n==0 );
262792 pIter->b = (pIter->a ? &pIter->a[n] : 0);
262793 *piCol = 0;
262794 fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
 
 
 
 
 
 
 
262795 }
262796 }else{
262797 int n;
262798 rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
262799 if( rc==SQLITE_OK ){
@@ -263697,11 +263716,11 @@
263697 int nArg, /* Number of args */
263698 sqlite3_value **apUnused /* Function arguments */
263699 ){
263700 assert( nArg==0 );
263701 UNUSED_PARAM2(nArg, apUnused);
263702 sqlite3_result_text(pCtx, "fts5: 2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f", -1, SQLITE_TRANSIENT);
263703 }
263704
263705 /*
263706 ** Implementation of fts5_locale(LOCALE, TEXT) function.
263707 **
263708
--- 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 ** c8aa208bf5b00f3ab93c5edd510dfd0d7edd 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.54.0"
471 #define SQLITE_VERSION_NUMBER 3054000
472 #define SQLITE_SOURCE_ID "2026-07-08 15:43:42 c8aa208bf5b00f3ab93c5edd510dfd0d7edd271c064f159616ee409b308f7eb9"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2026-07-08T15:43:42.959Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -110677,17 +110677,20 @@
110677 if( cnt==1 ){
110678 assert( pNC!=0 );
110679 #ifndef SQLITE_OMIT_AUTHORIZATION
110680 if( db->xAuth ){
110681 if( pFJMatch ){
110682 int ii;
110683 assert( pExpr->op==TK_FUNCTION );
110684 assert( sqlite3_stricmp(pExpr->u.zToken,"coalesce")==0 );
110685 assert( pExpr->x.pList==pFJMatch );
110686 assert( pFJMatch->nExpr>0 );
110687 for(ii=0; ii<pFJMatch->nExpr; ii++){
110688 assert( pFJMatch->a[0].pExpr->op==TK_COLUMN );
110689 sqlite3AuthRead(pParse, pFJMatch->a[0].pExpr, pSchema, pNC->pSrcList);
110690 }
110691 }else if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){
110692 sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
110693 }
110694 }
110695 #endif
110696 /* Increment the nRef value on all name contexts from TopNC up to
@@ -210435,12 +210438,12 @@
210438
210439 /* If there is insufficient space allocated at StrBuffer.z, use realloc()
210440 ** to grow the buffer until so that it is big enough to accommodate the
210441 ** appended data.
210442 */
210443 if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){
210444 i64 nAlloc = pStr->nAlloc+(i64)nAppend+100;
210445 char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
210446 if( !zNew ){
210447 return SQLITE_NOMEM;
210448 }
210449 pStr->z = zNew;
@@ -214640,11 +214643,12 @@
214643 u32 k = 0;
214644 const char *zIn = (const char*)&pParse->aBlob[i+n];
214645 if( sz==0 ) goto malformed_jsonb;
214646 if( zIn[0]=='-' ){
214647 jsonAppendChar(pOut, '-');
214648 if( sz<=1 ) goto malformed_jsonb;
214649 k = 1;
214650 }
214651 if( zIn[k]=='.' ){
214652 jsonAppendChar(pOut, '0');
214653 }
214654 for(; k<sz; k++){
@@ -217603,11 +217607,13 @@
217607 */
217608 static int jsonSkipLabel(JsonEachCursor *p){
217609 if( p->eType==JSONB_OBJECT ){
217610 u32 sz = 0;
217611 u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
217612 sz += p->i + n;
217613 if( sz >= p->sParse.nBlob ) sz = p->i;
217614 return sz;
217615 }else{
217616 return p->i;
217617 }
217618 }
217619
@@ -226573,31 +226579,31 @@
226579 int lenSrc, /* Length of the source file */
226580 const char *zDelta, /* Delta to apply to the pattern */
226581 int lenDelta, /* Length of the delta */
226582 char *zOut /* Write the output into this preallocated buffer */
226583 ){
226584 sqlite3_uint64 limit;
226585 sqlite3_uint64 total = 0;
226586 #if RBU_ENABLE_DELTA_CKSUM
226587 char *zOrigOut = zOut;
226588 #endif
226589
226590 limit = rbuDeltaGetInt(&zDelta, &lenDelta);
226591 if( lenDelta<=0 || *zDelta!='\n' ){
226592 /* ERROR: size integer not terminated by "\n" */
226593 return -1;
226594 }
226595 zDelta++; lenDelta--; /* Skip the \n */
226596 while( lenDelta>0 && zDelta[0] ){
226597 unsigned int cnt, ofst;
226598 cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
226599 if( lenDelta<=0 ) return -1;
226600 switch( zDelta[0] ){
226601 case '@': {
226602 zDelta++; lenDelta--;
226603 ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
226604 if( lenDelta>0 && zDelta[0]!=',' ){
226605 /* ERROR: copy command not terminated by ',' */
226606 return -1;
226607 }
226608 zDelta++; lenDelta--;
226609 total += cnt;
@@ -226618,11 +226624,11 @@
226624 total += cnt;
226625 if( total>limit ){
226626 /* ERROR: insert command gives an output larger than predicted */
226627 return -1;
226628 }
226629 if( cnt>lenDelta ){
226630 /* ERROR: insert count exceeds size of delta */
226631 return -1;
226632 }
226633 memcpy(zOut, zDelta, cnt);
226634 zOut += cnt;
@@ -228631,17 +228637,17 @@
228637 char *zWhere = rbuObjIterGetWhere(p, pIter);
228638 char *zSet = rbuObjIterGetSetlist(p, pIter, zMask);
228639 char *zUpdate = 0;
228640
228641 pUp->zMask = (char*)&pUp[1];
 
228642 pUp->pNext = pIter->pRbuUpdate;
228643 pIter->pRbuUpdate = pUp;
228644
228645 if( zSet ){
228646 const char *zPrefix = "";
228647 assert( p->rc==SQLITE_OK );
228648 memcpy(pUp->zMask, zMask, pIter->nTblCol);
228649 if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
228650 zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
228651 zPrefix, pIter->zTbl, zSet, zWhere
228652 );
228653 p->rc = prepareFreeAndCollectError(
@@ -228727,10 +228733,13 @@
228733 pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
228734 break;
228735
228736 case RBU_STATE_ROW:
228737 pRet->nRow = sqlite3_column_int(pStmt, 1);
228738 if( pRet->nRow<0 ){
228739 rc = SQLITE_CORRUPT;
228740 }
228741 break;
228742
228743 case RBU_STATE_PROGRESS:
228744 pRet->nProgress = sqlite3_column_int64(pStmt, 1);
228745 break;
@@ -239976,11 +239985,16 @@
239985 int nRec;
239986 int rc = SQLITE_OK;
239987
239988 pIter->in.bNoDiscard = 1;
239989 while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
239990 if( bRebase && pIter->bPatchset ){
239991 /* A patchset may not be used as a rebase */
239992 rc = SQLITE_ERROR;
239993 }else{
239994 rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
239995 }
239996 if( rc!=SQLITE_OK ) break;
239997 }
239998
239999 if( rc==SQLITE_OK ) rc = pIter->rc;
240000 return rc;
@@ -240353,17 +240367,18 @@
240367 int bData = 0;
240368 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
240369 int i;
240370 u8 *a1 = aRec;
240371 u8 *a2 = aChange;
240372 u8 *a2Eof = &a2[nChange];
240373
240374 *pOut++ = SQLITE_UPDATE;
240375 *pOut++ = pIter->bIndirect;
240376 for(i=0; i<pIter->nCol; i++){
240377 int n1 = sessionSerialLen(a1);
240378 int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2);
240379 if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){
240380 if( !pIter->abPK[i] && a1[0] ) bData = 1;
240381 memcpy(pOut, a1, n1);
240382 pOut += n1;
240383 }else if( a2[0]!=0xFF && a1[0] ){
240384 bData = 1;
@@ -240560,12 +240575,12 @@
240575 */
240576 SQLITE_API int sqlite3rebaser_configure(
240577 sqlite3_rebaser *p,
240578 int nRebase, const void *pRebase
240579 ){
 
240580 int rc; /* Return code */
240581 sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240582 rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
240583 if( rc==SQLITE_OK ){
240584 rc = sessionChangesetToHash(pIter, &p->grp, 1);
240585 }
240586 sqlite3changeset_finalize(pIter);
@@ -255674,11 +255689,11 @@
255689
255690 iNext = fts5GetU16(&aPg[0]);
255691 if( iNext!=0 ){
255692 *pbLastInDoclist = 0;
255693 }
255694 if( iNext==0 && pLeaf->szLeaf<pLeaf->nn ){
255695 fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
255696 }
255697
255698 if( iNext==0 ){
255699 /* The page contains no terms or rowids. Replace it with an empty
@@ -262777,23 +262792,27 @@
262792 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
262793 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
262794
262795 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
262796 Fts5Sorter *pSorter = pCsr->pSorter;
262797 if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
262798 rc = SQLITE_RANGE;
 
 
 
262799 }else{
262800 int n;
262801 if( pSorter ){
262802 int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
262803 n = pSorter->aIdx[iPhrase] - i1;
262804 pIter->a = &pSorter->aPoslist[i1];
262805 }else{
262806 rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
262807 }
262808 if( rc==SQLITE_OK ){
262809 assert( pIter->a || n==0 );
262810 pIter->b = (pIter->a ? &pIter->a[n] : 0);
262811 *piCol = 0;
262812 fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
262813 }
262814 }
262815 }else{
262816 int n;
262817 rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
262818 if( rc==SQLITE_OK ){
@@ -263697,11 +263716,11 @@
263716 int nArg, /* Number of args */
263717 sqlite3_value **apUnused /* Function arguments */
263718 ){
263719 assert( nArg==0 );
263720 UNUSED_PARAM2(nArg, apUnused);
263721 sqlite3_result_text(pCtx, "fts5: 2026-07-07 14:53:53 c3b0fff1b76b8c354b34fef17ff639968698e97234d6ab7af15e0e1a835486e9", -1, SQLITE_TRANSIENT);
263722 }
263723
263724 /*
263725 ** Implementation of fts5_locale(LOCALE, TEXT) function.
263726 **
263727
--- 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.54.0"
150150
#define SQLITE_VERSION_NUMBER 3054000
151
-#define SQLITE_SOURCE_ID "2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f"
151
+#define SQLITE_SOURCE_ID "2026-07-08 15:43:42 c8aa208bf5b00f3ab93c5edd510dfd0d7edd271c064f159616ee409b308f7eb9"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2026-07-01T12:11:41.802Z"
154
+#define SQLITE_SCM_DATETIME "2026-07-08T15:43:42.959Z"
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.54.0"
150 #define SQLITE_VERSION_NUMBER 3054000
151 #define SQLITE_SOURCE_ID "2026-07-01 12:11:41 88901fffcd445ccb97e4e379ea15d8b06d87b8170cad0f717c909944ff21851f"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2026-07-01T12:11:41.802Z"
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.54.0"
150 #define SQLITE_VERSION_NUMBER 3054000
151 #define SQLITE_SOURCE_ID "2026-07-08 15:43:42 c8aa208bf5b00f3ab93c5edd510dfd0d7edd271c064f159616ee409b308f7eb9"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2026-07-08T15:43:42.959Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
160

Keyboard Shortcuts

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