Fossil SCM

Merge the latest SQLite trunk version, which includes the sort-by-float patch, for beta testing. Fossil does lots of sorting by float.

drh 2026-08-04 15:01 UTC trunk
Commit 1ec45d0dea0fca98da2034a207f93520d4317526b448208d75e6f22808f015fc
+65 -17
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5241,10 +5241,12 @@
52415241
int rc;
52425242
int n;
52435243
const char *z;
52445244
SHA3Context cx;
52455245
int iSize;
5246
+ int isRecursive = 0;
5247
+ int *pIsRecursive;
52465248
52475249
if( argc==1 ){
52485250
iSize = 256;
52495251
}else{
52505252
iSize = sqlite3_value_int(argv[1]);
@@ -5254,10 +5256,15 @@
52545256
return;
52555257
}
52565258
}
52575259
if( zSql==0 ) return;
52585260
SHA3Init(&cx, iSize);
5261
+ pIsRecursive = (int*)sqlite3_get_clientdata(db,"sha3_query()");
5262
+ if( pIsRecursive ){
5263
+ *pIsRecursive = 1;
5264
+ return;
5265
+ }
52595266
while( zSql[0] ){
52605267
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
52615268
if( rc ){
52625269
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
52635270
zSql, sqlite3_errmsg(db));
@@ -5280,19 +5287,25 @@
52805287
sha3_step_vformat(&cx,"S%d:",n);
52815288
SHA3Update(&cx,(unsigned char*)z,n);
52825289
}
52835290
52845291
/* Compute a hash over the result of the query */
5292
+ sqlite3_set_clientdata(db, "sha3_query()", &isRecursive, 0);
52855293
while( SQLITE_ROW==sqlite3_step(pStmt) ){
52865294
SHA3Update(&cx,(const unsigned char*)"R",1);
52875295
for(i=0; i<nCol; i++){
52885296
sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
52895297
}
52905298
}
52915299
sqlite3_finalize(pStmt);
5300
+ sqlite3_set_clientdata(db, "sha3_query()", 0, 0);
52925301
}
5293
- sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5302
+ if( isRecursive ){
5303
+ sqlite3_result_error(context, "recursive use of sha3_query()", -1);
5304
+ }else{
5305
+ sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5306
+ }
52945307
}
52955308
52965309
/*
52975310
** xStep function for sha3_agg().
52985311
*/
@@ -5643,11 +5656,14 @@
56435656
if( eType==SQLITE_BLOB ){
56445657
pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
56455658
}else{
56465659
pData = (const unsigned char*)sqlite3_value_text(argv[0]);
56475660
}
5648
- if( pData==0 ) return;
5661
+ if( pData==0 ){
5662
+ if( nByte ) return;
5663
+ pData = (const unsigned char*)"";
5664
+ }
56495665
hash_step(&cx, pData, nByte);
56505666
if( sqlite3_user_data(context)!=0 ){
56515667
/* sha1b() - binary result */
56525668
hash_finish(&cx, zOut, 1);
56535669
sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5683,13 +5699,20 @@
56835699
int rc;
56845700
int n;
56855701
const char *z;
56865702
SHA1Context cx;
56875703
char zOut[44];
5704
+ int isRecursive = 0;
5705
+ int *pIsRecursive;
56885706
56895707
assert( argc==1 );
56905708
if( zSql==0 ) return;
5709
+ pIsRecursive = sqlite3_get_clientdata(db, "sha1_query()");
5710
+ if( pIsRecursive ){
5711
+ *pIsRecursive = 1;
5712
+ return;
5713
+ }
56915714
hash_init(&cx);
56925715
while( zSql[0] ){
56935716
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
56945717
if( rc ){
56955718
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5712,10 +5735,11 @@
57125735
n = (int)strlen(z);
57135736
hash_step_vformat(&cx,"S%d:",n);
57145737
hash_step(&cx,(unsigned char*)z,n);
57155738
57165739
/* Compute a hash over the result of the query */
5740
+ sqlite3_set_clientdata(db, "sha1_query()", &isRecursive, 0);
57175741
while( SQLITE_ROW==sqlite3_step(pStmt) ){
57185742
hash_step(&cx,(const unsigned char*)"R",1);
57195743
for(i=0; i<nCol; i++){
57205744
switch( sqlite3_column_type(pStmt,i) ){
57215745
case SQLITE_NULL: {
@@ -5766,13 +5790,18 @@
57665790
}
57675791
}
57685792
}
57695793
}
57705794
sqlite3_finalize(pStmt);
5795
+ sqlite3_set_clientdata(db, "sha1_query()", 0, 0);
57715796
}
57725797
hash_finish(&cx, zOut, 0);
5773
- sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5798
+ if( isRecursive ){
5799
+ sqlite3_result_error(context, "recursive use of sha1_query()", -1);
5800
+ }else{
5801
+ sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5802
+ }
57745803
}
57755804
57765805
57775806
#ifdef _WIN32
57785807
@@ -11982,11 +12011,13 @@
1198212011
int iAmt,
1198312012
sqlite_int64 iOfst
1198412013
){
1198512014
ApndFile *paf = (ApndFile *)pFile;
1198612015
sqlite_int64 iWriteEnd = iOfst + iAmt;
11987
- if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
12016
+ if( iWriteEnd + paf->iPgOne >= APND_MAX_SIZE-APND_MARK_SIZE ){
12017
+ return SQLITE_FULL;
12018
+ }
1198812019
pFile = ORIGFILE(pFile);
1198912020
/* If append-mark is absent or will be overwritten, write it. */
1199012021
if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
1199112022
int rc = apndWriteMark(paf, pFile, iWriteEnd);
1199212023
if( SQLITE_OK!=rc ) return rc;
@@ -12400,10 +12431,12 @@
1240012431
**
1240112432
** * No support for encryption
1240212433
** * No support for ZIP archives spanning multiple files
1240312434
** * No support for zip64 extensions
1240412435
** * Only the "inflate/deflate" (zlib) compression method is supported
12436
+** * No support for transactions. ROLLBACK is the same as COMMIT.
12437
+** A crash mid-transaction can leave the ZIP archive in a corrupt state.
1240512438
*/
1240612439
/* #include "sqlite3ext.h" */
1240712440
SQLITE_EXTENSION_INIT1
1240812441
#include <stdio.h>
1240912442
#include <string.h>
@@ -19927,15 +19960,28 @@
1992719960
/*
1992819961
** Write a percentage into the output. The number written should show
1992919962
** two or three significant digits, with the decimal point being the fourth
1993019963
** character.
1993119964
*/
19932
-static void diskusedPercent(DiskUsed *p, double r){
19965
+static void diskusedPercent(
19966
+ DiskUsed *p, /* Context of the disk-usage analysis */
19967
+ sqlite3_int64 num, /* Numerator of the fraction */
19968
+ sqlite3_int64 denom /* Denominator of the fraction. Might be zero! */
19969
+){
1993319970
char zNum[100];
1993419971
char *zDP;
1993519972
int nLeadingDigit;
1993619973
int sz;
19974
+ double r;
19975
+ if( num==0 ){
19976
+ r = 0.0;
19977
+ }else if( denom==0 ){
19978
+ sqlite3_str_appendchar(p->pOut, 1, '\n');
19979
+ return;
19980
+ }else{
19981
+ r = num*100.0/(double)denom;
19982
+ }
1993719983
sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
1993819984
sz = (int)strlen(zNum);
1993919985
zDP = strchr(zNum, '.');
1994019986
if( zDP==0 ){
1994119987
memcpy(zNum+sz,".0",3);
@@ -20034,19 +20080,19 @@
2003420080
(total_pages*100.0)/(double)nPage);
2003520081
diskusedLine(p, "Number of entries", "%lld\n", nentry);
2003620082
storage = total_pages*pgsz;
2003720083
diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
2003820084
diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
20039
- diskusedPercent(p, payload*100.0/(double)storage);
20085
+ diskusedPercent(p, payload, storage);
2004020086
if( ovfl_cnt>0 ){
2004120087
diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
20042
- diskusedPercent(p, ovfl_payload*100.0/(double)payload);
20088
+ diskusedPercent(p, ovfl_payload, payload);
2004320089
}
2004420090
total_unused = leaf_unused + int_unused + ovfl_unused;
2004520091
total_meta = storage - payload - total_unused;
2004620092
diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
20047
- diskusedPercent(p, total_meta*100.0/(double)storage);
20093
+ diskusedPercent(p, total_meta, storage);
2004820094
if( cnt==1 ){
2004920095
diskusedLine(p, "B-tree depth", "%lld\n", depth);
2005020096
if( int_cell>1 ){
2005120097
diskusedLine(p, "Average fanout", "%.1f\n",
2005220098
(double)(int_cell+int_pages)/(double)int_pages);
@@ -20061,11 +20107,11 @@
2006120107
(double)total_meta/(double)nentry);
2006220108
}
2006320109
diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
2006420110
if( nentry>0 ){
2006520111
diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
20066
- diskusedPercent(p, ovfl_cnt*100.0/(double)nentry);
20112
+ diskusedPercent(p, ovfl_cnt, nentry);
2006720113
}
2006820114
if( int_pages>0 ){
2006920115
diskusedLine(p, "Index pages used", "%lld\n", int_pages);
2007020116
}
2007120117
diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
@@ -20079,11 +20125,11 @@
2007920125
diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
2008020126
if( ovfl_cnt ){
2008120127
diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
2008220128
}
2008320129
diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
20084
- diskusedPercent(p, total_unused*100.0/(double)storage);
20130
+ diskusedPercent(p, total_unused, storage);
2008520131
}
2008620132
return diskusedStmtFinish(p, rc, pStmt);
2008720133
}
2008820134
2008920135
/*
@@ -20242,17 +20288,17 @@
2024220288
nPageInUse = 0;
2024320289
rc = diskusedSqlInt(&s, &nPageInUse,
2024420290
"SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
2024520291
if( rc ) return;
2024620292
diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20247
- diskusedPercent(&s, (nPageInUse*100.0)/(double)nPage);
20293
+ diskusedPercent(&s, nPageInUse, nPage);
2024820294
2024920295
nFreeList = 0;
2025020296
rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
2025120297
if( rc ) return;
2025220298
diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20253
- diskusedPercent(&s, (nFreeList*100.0)/(double)nPage);
20299
+ diskusedPercent(&s, nFreeList, nPage);
2025420300
2025520301
ii = 0;
2025620302
rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
2025720303
if( rc ) return;
2025820304
if( ii==0 || nPage<=1 ){
@@ -20261,11 +20307,11 @@
2026120307
double rPtrsPerPage = pgsz/5;
2026220308
double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
2026320309
ii = (sqlite3_int64)ceil(rAvPage);
2026420310
}
2026520311
diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20266
- diskusedPercent(&s, (ii*100.0)/(double)nPage);
20312
+ diskusedPercent(&s, ii, nPage);
2026720313
2026820314
ii = 0;
2026920315
rc = diskusedSqlInt(&s, &ii,
2027020316
"SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
2027120317
s.zSchema);
@@ -20300,11 +20346,11 @@
2030020346
"SELECT sum(payload) FROM temp.%s"
2030120347
" WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
2030220348
s.zSU);
2030320349
if( rc ) return;
2030420350
diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
20305
- diskusedPercent(&s, ii*100.0/(double)(pgsz*nPage));
20351
+ diskusedPercent(&s, ii, pgsz*nPage);
2030620352
2030720353
diskusedTitle(&s, "Page counts for all tables with their indexes");
2030820354
pStmt = diskusedPrepare(&s,
2030920355
"SELECT upper(tblname),\n"
2031020356
" sum(int_pages+leaf_pages+ovfl_pages)\n"
@@ -20315,11 +20361,11 @@
2031520361
s.zSU);
2031620362
if( pStmt==0 ) return;
2031720363
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
2031820364
sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
2031920365
diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20320
- diskusedPercent(&s, (nn*100.0)/(double)nPage);
20366
+ diskusedPercent(&s, nn, nPage);
2032120367
}
2032220368
if( diskusedStmtFinish(&s, rc, pStmt) ) return;
2032320369
2032420370
diskusedTitle(&s, "Page counts for all tables and indexes separately");
2032520371
pStmt = diskusedPrepare(&s,
@@ -20332,11 +20378,11 @@
2033220378
s.zSU);
2033320379
if( pStmt==0 ) return;
2033420380
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
2033520381
sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
2033620382
diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20337
- diskusedPercent(&s, (nn*100.0)/(double)nPage);
20383
+ diskusedPercent(&s, nn, nPage);
2033820384
}
2033920385
if( diskusedStmtFinish(&s, rc, pStmt) ) return;
2034020386
2034120387
rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
2034220388
if( rc ) return;
@@ -26260,11 +26306,12 @@
2626026306
double r = sqlite3_value_double(apVal[0]);
2626126307
int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
2626226308
char z[400];
2626326309
if( n<1 ) n = 1;
2626426310
if( n>350 ) n = 350;
26265
- sprintf(z, "%#+.*e", n, r);
26311
+ z[sizeof(z)-1] = 0;
26312
+ snprintf(z, sizeof(z)-1, "%#+.*e", n, r);
2626626313
sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
2626726314
}
2626826315
2626926316
/*
2627026317
** SQL function: shell_add_schema(S,X)
@@ -38468,10 +38515,11 @@
3846838515
}
3846938516
argv[argc] = 0;
3847038517
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
3847138518
GetConsoleMode(hOut, &mode);
3847238519
SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
38520
+ _setmode(_fileno(stdout),_O_BINARY); /* Bug 2026-08-03T08:52:42Z */
3847338521
rc = utf8_main(argc, argv);
3847438522
for(i=0; i<argc; i++) free(orig[i]);
3847538523
free(argv);
3847638524
return rc;
3847738525
}
3847838526
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5241,10 +5241,12 @@
5241 int rc;
5242 int n;
5243 const char *z;
5244 SHA3Context cx;
5245 int iSize;
 
 
5246
5247 if( argc==1 ){
5248 iSize = 256;
5249 }else{
5250 iSize = sqlite3_value_int(argv[1]);
@@ -5254,10 +5256,15 @@
5254 return;
5255 }
5256 }
5257 if( zSql==0 ) return;
5258 SHA3Init(&cx, iSize);
 
 
 
 
 
5259 while( zSql[0] ){
5260 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5261 if( rc ){
5262 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
5263 zSql, sqlite3_errmsg(db));
@@ -5280,19 +5287,25 @@
5280 sha3_step_vformat(&cx,"S%d:",n);
5281 SHA3Update(&cx,(unsigned char*)z,n);
5282 }
5283
5284 /* Compute a hash over the result of the query */
 
5285 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5286 SHA3Update(&cx,(const unsigned char*)"R",1);
5287 for(i=0; i<nCol; i++){
5288 sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
5289 }
5290 }
5291 sqlite3_finalize(pStmt);
 
5292 }
5293 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
 
 
 
 
5294 }
5295
5296 /*
5297 ** xStep function for sha3_agg().
5298 */
@@ -5643,11 +5656,14 @@
5643 if( eType==SQLITE_BLOB ){
5644 pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
5645 }else{
5646 pData = (const unsigned char*)sqlite3_value_text(argv[0]);
5647 }
5648 if( pData==0 ) return;
 
 
 
5649 hash_step(&cx, pData, nByte);
5650 if( sqlite3_user_data(context)!=0 ){
5651 /* sha1b() - binary result */
5652 hash_finish(&cx, zOut, 1);
5653 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5683,13 +5699,20 @@
5683 int rc;
5684 int n;
5685 const char *z;
5686 SHA1Context cx;
5687 char zOut[44];
 
 
5688
5689 assert( argc==1 );
5690 if( zSql==0 ) return;
 
 
 
 
 
5691 hash_init(&cx);
5692 while( zSql[0] ){
5693 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5694 if( rc ){
5695 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5712,10 +5735,11 @@
5712 n = (int)strlen(z);
5713 hash_step_vformat(&cx,"S%d:",n);
5714 hash_step(&cx,(unsigned char*)z,n);
5715
5716 /* Compute a hash over the result of the query */
 
5717 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5718 hash_step(&cx,(const unsigned char*)"R",1);
5719 for(i=0; i<nCol; i++){
5720 switch( sqlite3_column_type(pStmt,i) ){
5721 case SQLITE_NULL: {
@@ -5766,13 +5790,18 @@
5766 }
5767 }
5768 }
5769 }
5770 sqlite3_finalize(pStmt);
 
5771 }
5772 hash_finish(&cx, zOut, 0);
5773 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
 
 
 
 
5774 }
5775
5776
5777 #ifdef _WIN32
5778
@@ -11982,11 +12011,13 @@
11982 int iAmt,
11983 sqlite_int64 iOfst
11984 ){
11985 ApndFile *paf = (ApndFile *)pFile;
11986 sqlite_int64 iWriteEnd = iOfst + iAmt;
11987 if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
 
 
11988 pFile = ORIGFILE(pFile);
11989 /* If append-mark is absent or will be overwritten, write it. */
11990 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
11991 int rc = apndWriteMark(paf, pFile, iWriteEnd);
11992 if( SQLITE_OK!=rc ) return rc;
@@ -12400,10 +12431,12 @@
12400 **
12401 ** * No support for encryption
12402 ** * No support for ZIP archives spanning multiple files
12403 ** * No support for zip64 extensions
12404 ** * Only the "inflate/deflate" (zlib) compression method is supported
 
 
12405 */
12406 /* #include "sqlite3ext.h" */
12407 SQLITE_EXTENSION_INIT1
12408 #include <stdio.h>
12409 #include <string.h>
@@ -19927,15 +19960,28 @@
19927 /*
19928 ** Write a percentage into the output. The number written should show
19929 ** two or three significant digits, with the decimal point being the fourth
19930 ** character.
19931 */
19932 static void diskusedPercent(DiskUsed *p, double r){
 
 
 
 
19933 char zNum[100];
19934 char *zDP;
19935 int nLeadingDigit;
19936 int sz;
 
 
 
 
 
 
 
 
 
19937 sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
19938 sz = (int)strlen(zNum);
19939 zDP = strchr(zNum, '.');
19940 if( zDP==0 ){
19941 memcpy(zNum+sz,".0",3);
@@ -20034,19 +20080,19 @@
20034 (total_pages*100.0)/(double)nPage);
20035 diskusedLine(p, "Number of entries", "%lld\n", nentry);
20036 storage = total_pages*pgsz;
20037 diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
20038 diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
20039 diskusedPercent(p, payload*100.0/(double)storage);
20040 if( ovfl_cnt>0 ){
20041 diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
20042 diskusedPercent(p, ovfl_payload*100.0/(double)payload);
20043 }
20044 total_unused = leaf_unused + int_unused + ovfl_unused;
20045 total_meta = storage - payload - total_unused;
20046 diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
20047 diskusedPercent(p, total_meta*100.0/(double)storage);
20048 if( cnt==1 ){
20049 diskusedLine(p, "B-tree depth", "%lld\n", depth);
20050 if( int_cell>1 ){
20051 diskusedLine(p, "Average fanout", "%.1f\n",
20052 (double)(int_cell+int_pages)/(double)int_pages);
@@ -20061,11 +20107,11 @@
20061 (double)total_meta/(double)nentry);
20062 }
20063 diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
20064 if( nentry>0 ){
20065 diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
20066 diskusedPercent(p, ovfl_cnt*100.0/(double)nentry);
20067 }
20068 if( int_pages>0 ){
20069 diskusedLine(p, "Index pages used", "%lld\n", int_pages);
20070 }
20071 diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
@@ -20079,11 +20125,11 @@
20079 diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
20080 if( ovfl_cnt ){
20081 diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
20082 }
20083 diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
20084 diskusedPercent(p, total_unused*100.0/(double)storage);
20085 }
20086 return diskusedStmtFinish(p, rc, pStmt);
20087 }
20088
20089 /*
@@ -20242,17 +20288,17 @@
20242 nPageInUse = 0;
20243 rc = diskusedSqlInt(&s, &nPageInUse,
20244 "SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
20245 if( rc ) return;
20246 diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20247 diskusedPercent(&s, (nPageInUse*100.0)/(double)nPage);
20248
20249 nFreeList = 0;
20250 rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
20251 if( rc ) return;
20252 diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20253 diskusedPercent(&s, (nFreeList*100.0)/(double)nPage);
20254
20255 ii = 0;
20256 rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
20257 if( rc ) return;
20258 if( ii==0 || nPage<=1 ){
@@ -20261,11 +20307,11 @@
20261 double rPtrsPerPage = pgsz/5;
20262 double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
20263 ii = (sqlite3_int64)ceil(rAvPage);
20264 }
20265 diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20266 diskusedPercent(&s, (ii*100.0)/(double)nPage);
20267
20268 ii = 0;
20269 rc = diskusedSqlInt(&s, &ii,
20270 "SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
20271 s.zSchema);
@@ -20300,11 +20346,11 @@
20300 "SELECT sum(payload) FROM temp.%s"
20301 " WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
20302 s.zSU);
20303 if( rc ) return;
20304 diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
20305 diskusedPercent(&s, ii*100.0/(double)(pgsz*nPage));
20306
20307 diskusedTitle(&s, "Page counts for all tables with their indexes");
20308 pStmt = diskusedPrepare(&s,
20309 "SELECT upper(tblname),\n"
20310 " sum(int_pages+leaf_pages+ovfl_pages)\n"
@@ -20315,11 +20361,11 @@
20315 s.zSU);
20316 if( pStmt==0 ) return;
20317 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20318 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20319 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20320 diskusedPercent(&s, (nn*100.0)/(double)nPage);
20321 }
20322 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20323
20324 diskusedTitle(&s, "Page counts for all tables and indexes separately");
20325 pStmt = diskusedPrepare(&s,
@@ -20332,11 +20378,11 @@
20332 s.zSU);
20333 if( pStmt==0 ) return;
20334 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20335 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20336 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20337 diskusedPercent(&s, (nn*100.0)/(double)nPage);
20338 }
20339 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20340
20341 rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
20342 if( rc ) return;
@@ -26260,11 +26306,12 @@
26260 double r = sqlite3_value_double(apVal[0]);
26261 int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
26262 char z[400];
26263 if( n<1 ) n = 1;
26264 if( n>350 ) n = 350;
26265 sprintf(z, "%#+.*e", n, r);
 
26266 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
26267 }
26268
26269 /*
26270 ** SQL function: shell_add_schema(S,X)
@@ -38468,10 +38515,11 @@
38468 }
38469 argv[argc] = 0;
38470 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
38471 GetConsoleMode(hOut, &mode);
38472 SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
 
38473 rc = utf8_main(argc, argv);
38474 for(i=0; i<argc; i++) free(orig[i]);
38475 free(argv);
38476 return rc;
38477 }
38478
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -5241,10 +5241,12 @@
5241 int rc;
5242 int n;
5243 const char *z;
5244 SHA3Context cx;
5245 int iSize;
5246 int isRecursive = 0;
5247 int *pIsRecursive;
5248
5249 if( argc==1 ){
5250 iSize = 256;
5251 }else{
5252 iSize = sqlite3_value_int(argv[1]);
@@ -5254,10 +5256,15 @@
5256 return;
5257 }
5258 }
5259 if( zSql==0 ) return;
5260 SHA3Init(&cx, iSize);
5261 pIsRecursive = (int*)sqlite3_get_clientdata(db,"sha3_query()");
5262 if( pIsRecursive ){
5263 *pIsRecursive = 1;
5264 return;
5265 }
5266 while( zSql[0] ){
5267 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5268 if( rc ){
5269 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
5270 zSql, sqlite3_errmsg(db));
@@ -5280,19 +5287,25 @@
5287 sha3_step_vformat(&cx,"S%d:",n);
5288 SHA3Update(&cx,(unsigned char*)z,n);
5289 }
5290
5291 /* Compute a hash over the result of the query */
5292 sqlite3_set_clientdata(db, "sha3_query()", &isRecursive, 0);
5293 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5294 SHA3Update(&cx,(const unsigned char*)"R",1);
5295 for(i=0; i<nCol; i++){
5296 sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
5297 }
5298 }
5299 sqlite3_finalize(pStmt);
5300 sqlite3_set_clientdata(db, "sha3_query()", 0, 0);
5301 }
5302 if( isRecursive ){
5303 sqlite3_result_error(context, "recursive use of sha3_query()", -1);
5304 }else{
5305 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
5306 }
5307 }
5308
5309 /*
5310 ** xStep function for sha3_agg().
5311 */
@@ -5643,11 +5656,14 @@
5656 if( eType==SQLITE_BLOB ){
5657 pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
5658 }else{
5659 pData = (const unsigned char*)sqlite3_value_text(argv[0]);
5660 }
5661 if( pData==0 ){
5662 if( nByte ) return;
5663 pData = (const unsigned char*)"";
5664 }
5665 hash_step(&cx, pData, nByte);
5666 if( sqlite3_user_data(context)!=0 ){
5667 /* sha1b() - binary result */
5668 hash_finish(&cx, zOut, 1);
5669 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
@@ -5683,13 +5699,20 @@
5699 int rc;
5700 int n;
5701 const char *z;
5702 SHA1Context cx;
5703 char zOut[44];
5704 int isRecursive = 0;
5705 int *pIsRecursive;
5706
5707 assert( argc==1 );
5708 if( zSql==0 ) return;
5709 pIsRecursive = sqlite3_get_clientdata(db, "sha1_query()");
5710 if( pIsRecursive ){
5711 *pIsRecursive = 1;
5712 return;
5713 }
5714 hash_init(&cx);
5715 while( zSql[0] ){
5716 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
5717 if( rc ){
5718 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
@@ -5712,10 +5735,11 @@
5735 n = (int)strlen(z);
5736 hash_step_vformat(&cx,"S%d:",n);
5737 hash_step(&cx,(unsigned char*)z,n);
5738
5739 /* Compute a hash over the result of the query */
5740 sqlite3_set_clientdata(db, "sha1_query()", &isRecursive, 0);
5741 while( SQLITE_ROW==sqlite3_step(pStmt) ){
5742 hash_step(&cx,(const unsigned char*)"R",1);
5743 for(i=0; i<nCol; i++){
5744 switch( sqlite3_column_type(pStmt,i) ){
5745 case SQLITE_NULL: {
@@ -5766,13 +5790,18 @@
5790 }
5791 }
5792 }
5793 }
5794 sqlite3_finalize(pStmt);
5795 sqlite3_set_clientdata(db, "sha1_query()", 0, 0);
5796 }
5797 hash_finish(&cx, zOut, 0);
5798 if( isRecursive ){
5799 sqlite3_result_error(context, "recursive use of sha1_query()", -1);
5800 }else{
5801 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
5802 }
5803 }
5804
5805
5806 #ifdef _WIN32
5807
@@ -11982,11 +12011,13 @@
12011 int iAmt,
12012 sqlite_int64 iOfst
12013 ){
12014 ApndFile *paf = (ApndFile *)pFile;
12015 sqlite_int64 iWriteEnd = iOfst + iAmt;
12016 if( iWriteEnd + paf->iPgOne >= APND_MAX_SIZE-APND_MARK_SIZE ){
12017 return SQLITE_FULL;
12018 }
12019 pFile = ORIGFILE(pFile);
12020 /* If append-mark is absent or will be overwritten, write it. */
12021 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
12022 int rc = apndWriteMark(paf, pFile, iWriteEnd);
12023 if( SQLITE_OK!=rc ) return rc;
@@ -12400,10 +12431,12 @@
12431 **
12432 ** * No support for encryption
12433 ** * No support for ZIP archives spanning multiple files
12434 ** * No support for zip64 extensions
12435 ** * Only the "inflate/deflate" (zlib) compression method is supported
12436 ** * No support for transactions. ROLLBACK is the same as COMMIT.
12437 ** A crash mid-transaction can leave the ZIP archive in a corrupt state.
12438 */
12439 /* #include "sqlite3ext.h" */
12440 SQLITE_EXTENSION_INIT1
12441 #include <stdio.h>
12442 #include <string.h>
@@ -19927,15 +19960,28 @@
19960 /*
19961 ** Write a percentage into the output. The number written should show
19962 ** two or three significant digits, with the decimal point being the fourth
19963 ** character.
19964 */
19965 static void diskusedPercent(
19966 DiskUsed *p, /* Context of the disk-usage analysis */
19967 sqlite3_int64 num, /* Numerator of the fraction */
19968 sqlite3_int64 denom /* Denominator of the fraction. Might be zero! */
19969 ){
19970 char zNum[100];
19971 char *zDP;
19972 int nLeadingDigit;
19973 int sz;
19974 double r;
19975 if( num==0 ){
19976 r = 0.0;
19977 }else if( denom==0 ){
19978 sqlite3_str_appendchar(p->pOut, 1, '\n');
19979 return;
19980 }else{
19981 r = num*100.0/(double)denom;
19982 }
19983 sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
19984 sz = (int)strlen(zNum);
19985 zDP = strchr(zNum, '.');
19986 if( zDP==0 ){
19987 memcpy(zNum+sz,".0",3);
@@ -20034,19 +20080,19 @@
20080 (total_pages*100.0)/(double)nPage);
20081 diskusedLine(p, "Number of entries", "%lld\n", nentry);
20082 storage = total_pages*pgsz;
20083 diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
20084 diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
20085 diskusedPercent(p, payload, storage);
20086 if( ovfl_cnt>0 ){
20087 diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
20088 diskusedPercent(p, ovfl_payload, payload);
20089 }
20090 total_unused = leaf_unused + int_unused + ovfl_unused;
20091 total_meta = storage - payload - total_unused;
20092 diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
20093 diskusedPercent(p, total_meta, storage);
20094 if( cnt==1 ){
20095 diskusedLine(p, "B-tree depth", "%lld\n", depth);
20096 if( int_cell>1 ){
20097 diskusedLine(p, "Average fanout", "%.1f\n",
20098 (double)(int_cell+int_pages)/(double)int_pages);
@@ -20061,11 +20107,11 @@
20107 (double)total_meta/(double)nentry);
20108 }
20109 diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
20110 if( nentry>0 ){
20111 diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
20112 diskusedPercent(p, ovfl_cnt, nentry);
20113 }
20114 if( int_pages>0 ){
20115 diskusedLine(p, "Index pages used", "%lld\n", int_pages);
20116 }
20117 diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
@@ -20079,11 +20125,11 @@
20125 diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
20126 if( ovfl_cnt ){
20127 diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
20128 }
20129 diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
20130 diskusedPercent(p, total_unused, storage);
20131 }
20132 return diskusedStmtFinish(p, rc, pStmt);
20133 }
20134
20135 /*
@@ -20242,17 +20288,17 @@
20288 nPageInUse = 0;
20289 rc = diskusedSqlInt(&s, &nPageInUse,
20290 "SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
20291 if( rc ) return;
20292 diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
20293 diskusedPercent(&s, nPageInUse, nPage);
20294
20295 nFreeList = 0;
20296 rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
20297 if( rc ) return;
20298 diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
20299 diskusedPercent(&s, nFreeList, nPage);
20300
20301 ii = 0;
20302 rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
20303 if( rc ) return;
20304 if( ii==0 || nPage<=1 ){
@@ -20261,11 +20307,11 @@
20307 double rPtrsPerPage = pgsz/5;
20308 double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
20309 ii = (sqlite3_int64)ceil(rAvPage);
20310 }
20311 diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
20312 diskusedPercent(&s, ii, nPage);
20313
20314 ii = 0;
20315 rc = diskusedSqlInt(&s, &ii,
20316 "SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
20317 s.zSchema);
@@ -20300,11 +20346,11 @@
20346 "SELECT sum(payload) FROM temp.%s"
20347 " WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
20348 s.zSU);
20349 if( rc ) return;
20350 diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
20351 diskusedPercent(&s, ii, pgsz*nPage);
20352
20353 diskusedTitle(&s, "Page counts for all tables with their indexes");
20354 pStmt = diskusedPrepare(&s,
20355 "SELECT upper(tblname),\n"
20356 " sum(int_pages+leaf_pages+ovfl_pages)\n"
@@ -20315,11 +20361,11 @@
20361 s.zSU);
20362 if( pStmt==0 ) return;
20363 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20364 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20365 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20366 diskusedPercent(&s, nn, nPage);
20367 }
20368 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20369
20370 diskusedTitle(&s, "Page counts for all tables and indexes separately");
20371 pStmt = diskusedPrepare(&s,
@@ -20332,11 +20378,11 @@
20378 s.zSU);
20379 if( pStmt==0 ) return;
20380 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
20381 sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
20382 diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
20383 diskusedPercent(&s, nn, nPage);
20384 }
20385 if( diskusedStmtFinish(&s, rc, pStmt) ) return;
20386
20387 rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
20388 if( rc ) return;
@@ -26260,11 +26306,12 @@
26306 double r = sqlite3_value_double(apVal[0]);
26307 int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
26308 char z[400];
26309 if( n<1 ) n = 1;
26310 if( n>350 ) n = 350;
26311 z[sizeof(z)-1] = 0;
26312 snprintf(z, sizeof(z)-1, "%#+.*e", n, r);
26313 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
26314 }
26315
26316 /*
26317 ** SQL function: shell_add_schema(S,X)
@@ -38468,10 +38515,11 @@
38515 }
38516 argv[argc] = 0;
38517 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
38518 GetConsoleMode(hOut, &mode);
38519 SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
38520 _setmode(_fileno(stdout),_O_BINARY); /* Bug 2026-08-03T08:52:42Z */
38521 rc = utf8_main(argc, argv);
38522 for(i=0; i<argc; i++) free(orig[i]);
38523 free(argv);
38524 return rc;
38525 }
38526
+249 -35
--- 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
-** 2f1f4f73535386549c12694dc57cfe555eec with changes in files:
21
+** bdc841de10fef65b627deb8b770702c97617 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-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d"
472
+#define SQLITE_SOURCE_ID "2026-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2026-07-24T16:28:47.830Z"
475
+#define SQLITE_SCM_DATETIME "2026-08-04T14:55:51.598Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -96610,11 +96610,11 @@
9661096610
}else if( p->flags & MEM_Real ){
9661196611
h += sqlite3VdbeIntValue(p);
9661296612
}else if( p->flags & MEM_Str ){
9661396613
u64 x;
9661496614
h += p->n;
96615
- if( p->n >= sizeof(x) ){
96615
+ if( p->n >= (int)sizeof(x) ){
9661696616
memcpy(&x, p->z, sizeof(x));
9661796617
h += x;
9661896618
memcpy(&x, p->z + p->n - sizeof(x), sizeof(x));
9661996619
h += x;
9662096620
}else{
@@ -96624,11 +96624,11 @@
9662496624
}
9662596625
}else if( p->flags & MEM_Blob ){
9662696626
int n = p->n;
9662796627
u64 x = 0;
9662896628
if( n ){
96629
- memcpy(&x, p->z, MIN(n, sizeof(x)));
96629
+ memcpy(&x, p->z, MIN(n, (int)sizeof(x)));
9663096630
h += x;
9663196631
}
9663296632
h += n;
9663396633
if( p->flags & MEM_Zero ) h += p->u.nZero;
9663496634
}
@@ -106272,10 +106272,11 @@
106272106272
/* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */
106273106273
#define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask))
106274106274
106275106275
#define SORTER_TYPE_INTEGER 0x01
106276106276
#define SORTER_TYPE_TEXT 0x02
106277
+#define SORTER_TYPE_REAL 0x04
106277106278
106278106279
/*
106279106280
** An instance of the following object is used to read records out of a
106280106281
** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
106281106282
** aKey might point into aMap or into aBuffer. If neither of those locations
@@ -106844,10 +106845,182 @@
106844106845
res = res * -1;
106845106846
}
106846106847
106847106848
return res;
106848106849
}
106850
+
106851
+/* Helper function for vdbeSorterCompareReal().
106852
+**
106853
+** The first elements of both pKey1 and pKey2 have been decoded into double
106854
+** values r1 and r2. Do the comparison between those keys and return the
106855
+** result. If r1==r2, break the tie with a comparison of subsequent elements
106856
+** from each key.
106857
+*/
106858
+static int vdbeSorterFinishRealCompare(
106859
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106860
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106861
+ const void *pKey1, int nKey1, /* Left side of comparison */
106862
+ const void *pKey2, int nKey2, /* Right side of comparison */
106863
+ double r1, /* REAL value of first element of pKey1 */
106864
+ double r2 /* REAL value of first element of pKey2 */
106865
+){
106866
+ int res;
106867
+ if( r1<r2 ){
106868
+ res = -1;
106869
+ }else if( r1>r2 ){
106870
+ res = +1;
106871
+ }else{
106872
+ res = 0;
106873
+ }
106874
+ assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 );
106875
+ if( res==0 ){
106876
+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
106877
+ res = vdbeSorterCompareTail(
106878
+ pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
106879
+ );
106880
+ }
106881
+ }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
106882
+ assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
106883
+ res = res * -1;
106884
+ }
106885
+ return res;
106886
+}
106887
+
106888
+/* Helper function for vdbeSorterCompareReal().
106889
+**
106890
+** Read the bits of an 8-byte big-endian IEEE-754 value and store them
106891
+** into a u64. Do any necessary byte-swapping so that the bits are in
106892
+** the right order for the host machine.
106893
+**
106894
+** Copied and slightly modified from the readInt64() routine in rtree.c
106895
+*/
106896
+static u64 vdbeSorterDecodeU64(const u8 *p){
106897
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
106898
+ u64 x;
106899
+ memcpy(&x, p, 8);
106900
+ return _byteswap_uint64(x);
106901
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
106902
+ u64 x;
106903
+ memcpy(&x, p, 8);
106904
+ return __builtin_bswap64(x);
106905
+#elif SQLITE_BYTEORDER==4321
106906
+ i64 x;
106907
+ memcpy(&x, p, 8);
106908
+ return x;
106909
+#else
106910
+ return (i64)(
106911
+ (((u64)p[0]) << 56) +
106912
+ (((u64)p[1]) << 48) +
106913
+ (((u64)p[2]) << 40) +
106914
+ (((u64)p[3]) << 32) +
106915
+ (((u64)p[4]) << 24) +
106916
+ (((u64)p[5]) << 16) +
106917
+ (((u64)p[6]) << 8) +
106918
+ (((u64)p[7]) << 0)
106919
+ );
106920
+#endif
106921
+}
106922
+
106923
+/* Helper function for vdbeSorterCompareReal().
106924
+**
106925
+** Buffer p[] is a record where the first term is guaranteed to be either
106926
+** a floating-point value, or an integer stand-in for a floating point
106927
+** value (a MEM_IntReal). Whatever its format, extract the value and
106928
+** return it.
106929
+*/
106930
+static double vdbeSorterGetReal(const u8 *p){
106931
+ double r; /* the return value */
106932
+
106933
+ assert( p[0]<0x80 ); /* 1-byte headers: nAllField<13 */
106934
+ assert( p[1]>0 && p[1]<10 ); /* first fields proven numeric */
106935
+
106936
+ if( p[1]==7 ){
106937
+ u64 x = vdbeSorterDecodeU64(p + p[0]);
106938
+ swapMixedEndianFloat(x);
106939
+ assert( !IsNaN(x) );
106940
+ memcpy(&r, &x, sizeof(r));
106941
+ }else{
106942
+ Mem m;
106943
+ m.u.i = 0;
106944
+ sqlite3VdbeSerialGet(p + p[0], p[1], &m);
106945
+ assert( m.flags==MEM_Int );
106946
+ r = (double)m.u.i;
106947
+ }
106948
+ return r;
106949
+}
106950
+
106951
+/* Helper function for vdbeSorterCompareReal()
106952
+**
106953
+** This routine handles the case of comparing two floating-point values
106954
+** where one or both of the floating-point are represented by integers.
106955
+** In other words, where one both is an MEM_RealInt.
106956
+**
106957
+** This subroutine is factored out from vdbeSorterCompareReal() for
106958
+** efficiency. If inlined into vdbeSorterCompareReal(), this routine
106959
+** will use extra stack space and consume CPU cycles setting up and
106960
+** breaking down that stack space, even if in the common case where
106961
+** this path is not used.
106962
+*/
106963
+static SQLITE_NOINLINE int vdbeSorterCompareRealInt(
106964
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106965
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106966
+ const void *pKey1, int nKey1, /* Left side of comparison */
106967
+ const void *pKey2, int nKey2 /* Right side of comparison */
106968
+){
106969
+ const u8 * const p1 = (const u8 * const)pKey1;
106970
+ const u8 * const p2 = (const u8 * const)pKey2;
106971
+ double r1 = vdbeSorterGetReal(p1);
106972
+ double r2 = vdbeSorterGetReal(p2);
106973
+ return vdbeSorterFinishRealCompare(pTask,pbKey2Cached,
106974
+ pKey1,nKey1,pKey2,nKey2,r1,r2);
106975
+}
106976
+
106977
+/*
106978
+** Comparison function optimized for the case where the first term
106979
+** of both keys are either MEM_Real or MEM_RealInt.
106980
+**
106981
+** See also vdbeSorterCompareInt() for MEM_Int values and
106982
+** vdbeSorterCompareText() for MEM_Str values. The general
106983
+** case is vdbeSorterCompare() which handles anything, but is slower.
106984
+*/
106985
+static int vdbeSorterCompareReal(
106986
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106987
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106988
+ const void *pKey1, int nKey1, /* Left side of comparison */
106989
+ const void *pKey2, int nKey2 /* Right side of comparison */
106990
+){
106991
+ const u8*const p1 = (const u8*const)pKey1; /* Left key record */
106992
+ const u8*const p2 = (const u8*const)pKey2; /* Right key record */
106993
+ u64 x; /* A real value stored as an integer */
106994
+ double r1; /* First element of pKey1 */
106995
+ double r2; /* First element of pKey2 */
106996
+
106997
+ assert( p1[0]<0x80 && p2[0]<0x80 ); /* 1-byte headers: nAllField<13 */
106998
+ assert( p1[1]>0 && p1[1]<10 ); /* first field guaranteed numeric */
106999
+ assert( p2[1]>0 && p2[1]<10 ); /* first field guaranteed numeric */
107000
+
107001
+ if( p1[1]!=7 || p2[1]!=7 ){
107002
+ /* One or both floating point values are stored as INTEGER (MEM_RealInt).
107003
+ ** Handle this case separately for efficiency */
107004
+ return vdbeSorterCompareRealInt(pTask,
107005
+ pbKey2Cached, pKey1,nKey1, pKey2,nKey2
107006
+ );
107007
+ }
107008
+ assert( p1[0]<=nKey1-8 && p2[0]<=nKey2-8 );
107009
+
107010
+ x = vdbeSorterDecodeU64(p1 + *p1);
107011
+ swapMixedEndianFloat(x);
107012
+ assert( !IsNaN(x) );
107013
+ memcpy(&r1, &x, sizeof(r1));
107014
+ x = vdbeSorterDecodeU64(p2 + *p2);
107015
+ swapMixedEndianFloat(x);
107016
+ assert( !IsNaN(x) );
107017
+ memcpy(&r2, &x, sizeof(r2));
107018
+ return vdbeSorterFinishRealCompare(pTask,
107019
+ pbKey2Cached, pKey1,nKey1, pKey2,nKey2, r1, r2
107020
+ );
107021
+}
106849107022
106850107023
/*
106851107024
** Initialize the temporary index cursor just opened as a sorter cursor.
106852107025
**
106853107026
** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
@@ -106967,11 +107140,11 @@
106967107140
106968107141
if( pKeyInfo->nAllField<13
106969107142
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
106970107143
&& (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
106971107144
){
106972
- pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
107145
+ pSorter->typeMask = SORTER_TYPE_INTEGER|SORTER_TYPE_TEXT|SORTER_TYPE_REAL;
106973107146
}
106974107147
}
106975107148
106976107149
return rc;
106977107150
}
@@ -107339,14 +107512,16 @@
107339107512
/*
107340107513
** Return the SorterCompare function to compare values collected by the
107341107514
** sorter object passed as the only argument.
107342107515
*/
107343107516
static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
107344
- if( p->typeMask==SORTER_TYPE_INTEGER ){
107517
+ if( p->typeMask & SORTER_TYPE_INTEGER ){
107345107518
return vdbeSorterCompareInt;
107346
- }else if( p->typeMask==SORTER_TYPE_TEXT ){
107519
+ }else if( p->typeMask & SORTER_TYPE_TEXT ){
107347107520
return vdbeSorterCompareText;
107521
+ }else if( p->typeMask & SORTER_TYPE_REAL ){
107522
+ return vdbeSorterCompareReal;
107348107523
}
107349107524
return vdbeSorterCompare;
107350107525
}
107351107526
107352107527
/*
@@ -107740,12 +107915,16 @@
107740107915
int t; /* serial type of first record field */
107741107916
107742107917
assert( pCsr->eCurType==CURTYPE_SORTER );
107743107918
pSorter = pCsr->uc.pSorter;
107744107919
getVarint32NR((const u8*)&pVal->z[1], t);
107745
- if( t>0 && t<10 && t!=7 ){
107746
- pSorter->typeMask &= SORTER_TYPE_INTEGER;
107920
+ if( t>0 && t<10 ){
107921
+ if( t==7 ){
107922
+ pSorter->typeMask &= SORTER_TYPE_REAL;
107923
+ }else{
107924
+ pSorter->typeMask &= (SORTER_TYPE_INTEGER|SORTER_TYPE_REAL);
107925
+ }
107747107926
}else if( t>10 && (t & 0x01) ){
107748107927
pSorter->typeMask &= SORTER_TYPE_TEXT;
107749107928
}else{
107750107929
pSorter->typeMask = 0;
107751107930
}
@@ -115337,14 +115516,12 @@
115337115516
int i;
115338115517
if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
115339115518
if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
115340115519
p = pX->x.pSelect;
115341115520
if( p->pPrior ) return 0; /* Not a compound SELECT */
115342
- if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
115343
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
115344
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
115345
- return 0; /* No DISTINCT keyword and no aggregate functions */
115521
+ if( p->selFlags & SF_Aggregate ){
115522
+ return 0; /* No GROUP BY keyword or aggregate functions */
115346115523
}
115347115524
assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
115348115525
if( p->pLimit ) return 0; /* Has no LIMIT clause */
115349115526
if( p->pWhere ) return 0; /* Has no WHERE clause */
115350115527
pSrc = p->pSrc;
@@ -116424,11 +116601,25 @@
116424116601
/* If this IN operator will use an index, then the order of columns in the
116425116602
** vector might be different from the order in the index. In that case,
116426116603
** we need to reorder the LHS values to be in index order. Run Affinity
116427116604
** before reordering the columns, so that the affinity is correct.
116428116605
*/
116429
- sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
116606
+ if( nVector==1 ){
116607
+ char aff = zAff[0];
116608
+ if( aff>=SQLITE_AFF_TEXT && aff!=sqlite3ExprAffinity(pLeft) ){
116609
+ /* The OP_Affinity below may change the value. In this case, create a
116610
+ ** copy of rLhs to run OP_Affinity on, in case the original register
116611
+ ** is used again (e.g. if it is TK_AGG_COLUMN). */
116612
+ int rTmp = sqlite3GetTempReg(pParse);
116613
+ sqlite3VdbeAddOp3(v, OP_Copy, rLhs, rTmp, 0);
116614
+ rLhs = rTmp;
116615
+ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, 1, 0, zAff, 1);
116616
+ }
116617
+ }else{
116618
+ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
116619
+ }
116620
+
116430116621
for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
116431116622
if( i!=nVector ){
116432116623
/* Need to reorder the LHS fields according to aiMap */
116433116624
int rLhsOrig = rLhs;
116434116625
rLhs = sqlite3GetTempRange(pParse, nVector);
@@ -136450,11 +136641,11 @@
136450136641
}else{
136451136642
i++;
136452136643
}
136453136644
}while( i<iGt );
136454136645
136455
- assert( iLt>0 && iLt<iGt && iGt<n );
136646
+ assert( iLt>0 && iLt<iGt && (unsigned)iGt<n );
136456136647
testcase( iGt>iLt+1 );
136457136648
assert( a[iLt]==rPivot );
136458136649
assert( a[iLt-1]<=rPivot );
136459136650
assert( a[iGt]>=rPivot );
136460136651
assert( a[iLt+1]>=rPivot );
@@ -156097,10 +156288,11 @@
156097156288
p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere);
156098156289
pSub->pWhere = 0;
156099156290
}
156100156291
pSub->pSrc = 0;
156101156292
sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
156293
+ recomputeColumnsUsed(p, &p->pSrc->a[p->pSrc->nSrc-1]);
156102156294
#if TREETRACE_ENABLED
156103156295
if( sqlite3TreeTrace & 0x100000 ){
156104156296
TREETRACE(0x100000,pParse,p,
156105156297
("After EXISTS-to-JOIN optimization:\n"));
156106156298
sqlite3TreeViewSelect(0, p, 0);
@@ -156114,14 +156306,14 @@
156114156306
/*
156115156307
** Type used for Walker callbacks by selectCheckOnClauses().
156116156308
*/
156117156309
typedef struct CheckOnCtx CheckOnCtx;
156118156310
struct CheckOnCtx {
156119
- SrcList *pSrc; /* SrcList for this context */
156120
- int iJoin; /* Cursor numbers must be =< than this */
156121
- int bFuncArg; /* True for table-function arg */
156122
- CheckOnCtx *pParent; /* Parent context */
156311
+ SrcList *pSrc; /* SrcList for this context */
156312
+ int iJoin; /* Cursors must be left of this one, if not zero */
156313
+ int bFuncArg; /* True for table-function arg */
156314
+ CheckOnCtx *pParent; /* Parent context */
156123156315
};
156124156316
156125156317
/*
156126156318
** True if the SrcList passed as the only argument contains at least
156127156319
** one RIGHT or FULL JOIN. False otherwise.
@@ -156162,23 +156354,29 @@
156162156354
if( pExpr->op==TK_COLUMN ){
156163156355
/* A column expression. Find the SrcList (if any) to which it refers.
156164156356
** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
156165156357
** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
156166156358
** does not refer to a table to the right of CheckOnCtx.iJoin. */
156359
+ int iTab = pExpr->iTable;
156167156360
do {
156168156361
SrcList *pSrc = pCtx->pSrc;
156169156362
int nSrc = pSrc->nSrc;
156170
- int iTab = pExpr->iTable;
156171156363
int ii;
156172156364
for(ii=0; ii<nSrc && pSrc->a[ii].iCursor!=iTab; ii++){}
156173156365
if( ii<nSrc ){
156174
- if( pCtx->iJoin && iTab>pCtx->iJoin ){
156175
- sqlite3ErrorMsg(pWalker->pParse,
156176
- "%s references tables to its right",
156177
- (pCtx->bFuncArg ? "table-function argument" : "ON clause")
156178
- );
156179
- return WRC_Abort;
156366
+ /* pSrc is the FROM clause that contains iTab */
156367
+ if( pCtx->iJoin ){
156368
+ for(ii--; ii>=0 && pSrc->a[ii].iCursor!=pCtx->iJoin; ii--){}
156369
+ if( ii>=0 ){
156370
+ /* Table iJoin appears to the left of table iTab in the SrcList.
156371
+ ** Therefore the expression refers to a table to its right. */
156372
+ sqlite3ErrorMsg(pWalker->pParse,
156373
+ "%s references tables to its right",
156374
+ (pCtx->bFuncArg ? "table-function argument" : "ON clause")
156375
+ );
156376
+ return WRC_Abort;
156377
+ }
156180156378
}
156181156379
break;
156182156380
}
156183156381
pCtx = pCtx->pParent;
156184156382
}while( pCtx );
@@ -164626,11 +164824,16 @@
164626164824
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
164627164825
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
164628164826
testcase( pTerm->wtFlags & TERM_VIRTUAL );
164629164827
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
164630164828
if( r1!=regBase+j ){
164631
- if( nReg==1 ){
164829
+ /* If this routine is being called as part of a RIGHT JOIN loop, then
164830
+ ** register r1 may be used by the body of the loop that the RIGHT JOIN
164831
+ ** will jump back into (e.g. if pTerm is a sub-query). This can cause
164832
+ ** problems if (say) the affinity of r1 is modified by the caller of
164833
+ ** this routine. So, always take a copy of the value in this case. */
164834
+ if( nReg==1 && pParse->withinRJSubrtn==0 ){
164632164835
sqlite3ReleaseTempReg(pParse, regBase);
164633164836
regBase = r1;
164634164837
}else{
164635164838
sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
164636164839
}
@@ -167811,10 +168014,11 @@
167811168014
#endif
167812168015
pMaskSet = &pWInfo->sMaskSet;
167813168016
pExpr = pTerm->pExpr;
167814168017
assert( pExpr!=0 ); /* Because malloc() has not failed */
167815168018
assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
168019
+exprAnalyze_restart:
167816168020
pMaskSet->bVarSelect = 0;
167817168021
prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
167818168022
op = pExpr->op;
167819168023
if( op==TK_IN ){
167820168024
assert( pExpr->pRight==0 );
@@ -167977,10 +168181,15 @@
167977168181
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
167978168182
/* Analyze a term that is composed of two or more subterms connected by
167979168183
** an OR operator.
167980168184
*/
167981168185
else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){
168186
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
168187
+ if( pAlt!=pExpr ){
168188
+ pTerm->pExpr = pExpr = sqlite3ExprSkipCollateAndLikely(pAlt);
168189
+ goto exprAnalyze_restart;
168190
+ }
167982168191
assert( pWC->op==TK_AND );
167983168192
exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
167984168193
pTerm = &pWC->a[idxTerm];
167985168194
}
167986168195
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -168165,10 +168374,11 @@
168165168374
&& ALWAYS( ExprUseXSelect(pExpr) )
168166168375
&& (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values))
168167168376
#ifndef SQLITE_OMIT_WINDOWFUNC
168168168377
&& pExpr->x.pSelect->pWin==0
168169168378
#endif
168379
+ && (pExpr->x.pSelect->selFlags & SF_MinMaxAgg)==0
168170168380
&& pWC->op==TK_AND
168171168381
&& pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild)
168172168382
/* ^-- See bug 2026-06-04T10:00:49Z */
168173168383
){
168174168384
int i;
@@ -197537,10 +197747,11 @@
197537197747
static void fts3SnippetFunc(
197538197748
sqlite3_context *pContext, /* SQLite function call context */
197539197749
int nVal, /* Size of apVal[] array */
197540197750
sqlite3_value **apVal /* Array of arguments */
197541197751
){
197752
+ Fts3Table *pTab = 0;
197542197753
Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
197543197754
const char *zStart = "<b>";
197544197755
const char *zEnd = "</b>";
197545197756
const char *zEllipsis = "<b>...</b>";
197546197757
int iCol = -1;
@@ -197555,10 +197766,11 @@
197555197766
sqlite3_result_error(pContext,
197556197767
"wrong number of arguments to function snippet()", -1);
197557197768
return;
197558197769
}
197559197770
if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
197771
+ pTab = (Fts3Table *)pCsr->base.pVtab;
197560197772
197561197773
switch( nVal ){
197562197774
case 6: nToken = sqlite3_value_int(apVal[5]);
197563197775
/* no break */ deliberate_fall_through
197564197776
case 5: iCol = sqlite3_value_int(apVal[4]);
@@ -197569,11 +197781,11 @@
197569197781
/* no break */ deliberate_fall_through
197570197782
case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
197571197783
}
197572197784
if( !zEllipsis || !zEnd || !zStart ){
197573197785
sqlite3_result_error_nomem(pContext);
197574
- }else if( nToken==0 ){
197786
+ }else if( nToken==0 || iCol>=pTab->nColumn ){
197575197787
sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
197576197788
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
197577197789
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
197578197790
}
197579197791
}
@@ -201149,11 +201361,11 @@
201149201361
*/
201150201362
iCol = pParse->iDefaultCol;
201151201363
iColLen = 0;
201152201364
for(ii=0; ii<pParse->nCol; ii++){
201153201365
const char *zStr = pParse->azCol[ii];
201154
- int nStr = (int)strlen(zStr);
201366
+ int nStr = zStr ? (int)strlen(zStr) : 0;
201155201367
if( nInput>nStr && zInput[nStr]==':'
201156201368
&& sqlite3_strnicmp(zStr, zInput, nStr)==0
201157201369
){
201158201370
iCol = ii;
201159201371
iColLen = (int)((zInput - z) + nStr + 1);
@@ -201864,11 +202076,13 @@
201864202076
rc = fts3ExprParseUnbalanced(
201865202077
pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
201866202078
);
201867202079
}
201868202080
201869
- if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
202081
+ if( rc==SQLITE_OK && fts3ExprCheckDepth(pExpr, SQLITE_FTS3_MAX_EXPR_DEPTH) ){
202082
+ sqlite3_result_error(context, "Expression nested too deep", -1);
202083
+ }else if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
201870202084
sqlite3_result_error(context, "Error parsing expression", -1);
201871202085
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
201872202086
sqlite3_result_error_nomem(context);
201873202087
}else{
201874202088
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
@@ -256851,24 +257065,24 @@
256851257065
Fts5Buffer out;
256852257066
256853257067
(void)nBuf;
256854257068
memset(&out, 0, sizeof(out));
256855257069
assert( nBuf==1 );
256856
- sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
257070
+ sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9);
256857257071
if( p->rc ) return;
256858257072
256859257073
fts5NextRowid(p1, &i1, &iRowid1);
256860257074
fts5NextRowid(p2, &i2, &iRowid2);
256861257075
while( i1>=0 || i2>=0 ){
256862257076
if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
256863257077
assert( iOut==0 || iRowid1>iOut );
256864
- fts5BufferSafeAppendVarint(&out, iRowid1 - iOut);
257078
+ fts5BufferSafeAppendVarint(&out, (u64)iRowid1 - (u64)iOut);
256865257079
iOut = iRowid1;
256866257080
fts5NextRowid(p1, &i1, &iRowid1);
256867257081
}else{
256868257082
assert( iOut==0 || iRowid2>iOut );
256869
- fts5BufferSafeAppendVarint(&out, iRowid2 - iOut);
257083
+ fts5BufferSafeAppendVarint(&out, (u64)iRowid2 - (u64)iOut);
256870257084
iOut = iRowid2;
256871257085
if( i1>=0 && iRowid1==iRowid2 ){
256872257086
fts5NextRowid(p1, &i1, &iRowid1);
256873257087
}
256874257088
fts5NextRowid(p2, &i2, &iRowid2);
@@ -263950,11 +264164,11 @@
263950264164
int nArg, /* Number of args */
263951264165
sqlite3_value **apUnused /* Function arguments */
263952264166
){
263953264167
assert( nArg==0 );
263954264168
UNUSED_PARAM2(nArg, apUnused);
263955
- sqlite3_result_text(pCtx, "fts5: 2026-07-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d", -1, SQLITE_TRANSIENT);
264169
+ sqlite3_result_text(pCtx, "fts5: 2026-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744", -1, SQLITE_TRANSIENT);
263956264170
}
263957264171
263958264172
/*
263959264173
** Implementation of fts5_locale(LOCALE, TEXT) function.
263960264174
**
263961264175
--- 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 ** 2f1f4f73535386549c12694dc57cfe555eec 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-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2026-07-24T16:28:47.830Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -96610,11 +96610,11 @@
96610 }else if( p->flags & MEM_Real ){
96611 h += sqlite3VdbeIntValue(p);
96612 }else if( p->flags & MEM_Str ){
96613 u64 x;
96614 h += p->n;
96615 if( p->n >= sizeof(x) ){
96616 memcpy(&x, p->z, sizeof(x));
96617 h += x;
96618 memcpy(&x, p->z + p->n - sizeof(x), sizeof(x));
96619 h += x;
96620 }else{
@@ -96624,11 +96624,11 @@
96624 }
96625 }else if( p->flags & MEM_Blob ){
96626 int n = p->n;
96627 u64 x = 0;
96628 if( n ){
96629 memcpy(&x, p->z, MIN(n, sizeof(x)));
96630 h += x;
96631 }
96632 h += n;
96633 if( p->flags & MEM_Zero ) h += p->u.nZero;
96634 }
@@ -106272,10 +106272,11 @@
106272 /* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */
106273 #define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask))
106274
106275 #define SORTER_TYPE_INTEGER 0x01
106276 #define SORTER_TYPE_TEXT 0x02
 
106277
106278 /*
106279 ** An instance of the following object is used to read records out of a
106280 ** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
106281 ** aKey might point into aMap or into aBuffer. If neither of those locations
@@ -106844,10 +106845,182 @@
106844 res = res * -1;
106845 }
106846
106847 return res;
106848 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106849
106850 /*
106851 ** Initialize the temporary index cursor just opened as a sorter cursor.
106852 **
106853 ** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
@@ -106967,11 +107140,11 @@
106967
106968 if( pKeyInfo->nAllField<13
106969 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
106970 && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
106971 ){
106972 pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
106973 }
106974 }
106975
106976 return rc;
106977 }
@@ -107339,14 +107512,16 @@
107339 /*
107340 ** Return the SorterCompare function to compare values collected by the
107341 ** sorter object passed as the only argument.
107342 */
107343 static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
107344 if( p->typeMask==SORTER_TYPE_INTEGER ){
107345 return vdbeSorterCompareInt;
107346 }else if( p->typeMask==SORTER_TYPE_TEXT ){
107347 return vdbeSorterCompareText;
 
 
107348 }
107349 return vdbeSorterCompare;
107350 }
107351
107352 /*
@@ -107740,12 +107915,16 @@
107740 int t; /* serial type of first record field */
107741
107742 assert( pCsr->eCurType==CURTYPE_SORTER );
107743 pSorter = pCsr->uc.pSorter;
107744 getVarint32NR((const u8*)&pVal->z[1], t);
107745 if( t>0 && t<10 && t!=7 ){
107746 pSorter->typeMask &= SORTER_TYPE_INTEGER;
 
 
 
 
107747 }else if( t>10 && (t & 0x01) ){
107748 pSorter->typeMask &= SORTER_TYPE_TEXT;
107749 }else{
107750 pSorter->typeMask = 0;
107751 }
@@ -115337,14 +115516,12 @@
115337 int i;
115338 if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
115339 if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
115340 p = pX->x.pSelect;
115341 if( p->pPrior ) return 0; /* Not a compound SELECT */
115342 if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
115343 testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
115344 testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
115345 return 0; /* No DISTINCT keyword and no aggregate functions */
115346 }
115347 assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
115348 if( p->pLimit ) return 0; /* Has no LIMIT clause */
115349 if( p->pWhere ) return 0; /* Has no WHERE clause */
115350 pSrc = p->pSrc;
@@ -116424,11 +116601,25 @@
116424 /* If this IN operator will use an index, then the order of columns in the
116425 ** vector might be different from the order in the index. In that case,
116426 ** we need to reorder the LHS values to be in index order. Run Affinity
116427 ** before reordering the columns, so that the affinity is correct.
116428 */
116429 sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116430 for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
116431 if( i!=nVector ){
116432 /* Need to reorder the LHS fields according to aiMap */
116433 int rLhsOrig = rLhs;
116434 rLhs = sqlite3GetTempRange(pParse, nVector);
@@ -136450,11 +136641,11 @@
136450 }else{
136451 i++;
136452 }
136453 }while( i<iGt );
136454
136455 assert( iLt>0 && iLt<iGt && iGt<n );
136456 testcase( iGt>iLt+1 );
136457 assert( a[iLt]==rPivot );
136458 assert( a[iLt-1]<=rPivot );
136459 assert( a[iGt]>=rPivot );
136460 assert( a[iLt+1]>=rPivot );
@@ -156097,10 +156288,11 @@
156097 p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere);
156098 pSub->pWhere = 0;
156099 }
156100 pSub->pSrc = 0;
156101 sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
 
156102 #if TREETRACE_ENABLED
156103 if( sqlite3TreeTrace & 0x100000 ){
156104 TREETRACE(0x100000,pParse,p,
156105 ("After EXISTS-to-JOIN optimization:\n"));
156106 sqlite3TreeViewSelect(0, p, 0);
@@ -156114,14 +156306,14 @@
156114 /*
156115 ** Type used for Walker callbacks by selectCheckOnClauses().
156116 */
156117 typedef struct CheckOnCtx CheckOnCtx;
156118 struct CheckOnCtx {
156119 SrcList *pSrc; /* SrcList for this context */
156120 int iJoin; /* Cursor numbers must be =< than this */
156121 int bFuncArg; /* True for table-function arg */
156122 CheckOnCtx *pParent; /* Parent context */
156123 };
156124
156125 /*
156126 ** True if the SrcList passed as the only argument contains at least
156127 ** one RIGHT or FULL JOIN. False otherwise.
@@ -156162,23 +156354,29 @@
156162 if( pExpr->op==TK_COLUMN ){
156163 /* A column expression. Find the SrcList (if any) to which it refers.
156164 ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
156165 ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
156166 ** does not refer to a table to the right of CheckOnCtx.iJoin. */
 
156167 do {
156168 SrcList *pSrc = pCtx->pSrc;
156169 int nSrc = pSrc->nSrc;
156170 int iTab = pExpr->iTable;
156171 int ii;
156172 for(ii=0; ii<nSrc && pSrc->a[ii].iCursor!=iTab; ii++){}
156173 if( ii<nSrc ){
156174 if( pCtx->iJoin && iTab>pCtx->iJoin ){
156175 sqlite3ErrorMsg(pWalker->pParse,
156176 "%s references tables to its right",
156177 (pCtx->bFuncArg ? "table-function argument" : "ON clause")
156178 );
156179 return WRC_Abort;
 
 
 
 
 
 
156180 }
156181 break;
156182 }
156183 pCtx = pCtx->pParent;
156184 }while( pCtx );
@@ -164626,11 +164824,16 @@
164626 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
164627 testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
164628 testcase( pTerm->wtFlags & TERM_VIRTUAL );
164629 r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
164630 if( r1!=regBase+j ){
164631 if( nReg==1 ){
 
 
 
 
 
164632 sqlite3ReleaseTempReg(pParse, regBase);
164633 regBase = r1;
164634 }else{
164635 sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
164636 }
@@ -167811,10 +168014,11 @@
167811 #endif
167812 pMaskSet = &pWInfo->sMaskSet;
167813 pExpr = pTerm->pExpr;
167814 assert( pExpr!=0 ); /* Because malloc() has not failed */
167815 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
 
167816 pMaskSet->bVarSelect = 0;
167817 prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
167818 op = pExpr->op;
167819 if( op==TK_IN ){
167820 assert( pExpr->pRight==0 );
@@ -167977,10 +168181,15 @@
167977 #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
167978 /* Analyze a term that is composed of two or more subterms connected by
167979 ** an OR operator.
167980 */
167981 else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){
 
 
 
 
 
167982 assert( pWC->op==TK_AND );
167983 exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
167984 pTerm = &pWC->a[idxTerm];
167985 }
167986 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -168165,10 +168374,11 @@
168165 && ALWAYS( ExprUseXSelect(pExpr) )
168166 && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values))
168167 #ifndef SQLITE_OMIT_WINDOWFUNC
168168 && pExpr->x.pSelect->pWin==0
168169 #endif
 
168170 && pWC->op==TK_AND
168171 && pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild)
168172 /* ^-- See bug 2026-06-04T10:00:49Z */
168173 ){
168174 int i;
@@ -197537,10 +197747,11 @@
197537 static void fts3SnippetFunc(
197538 sqlite3_context *pContext, /* SQLite function call context */
197539 int nVal, /* Size of apVal[] array */
197540 sqlite3_value **apVal /* Array of arguments */
197541 ){
 
197542 Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
197543 const char *zStart = "<b>";
197544 const char *zEnd = "</b>";
197545 const char *zEllipsis = "<b>...</b>";
197546 int iCol = -1;
@@ -197555,10 +197766,11 @@
197555 sqlite3_result_error(pContext,
197556 "wrong number of arguments to function snippet()", -1);
197557 return;
197558 }
197559 if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
 
197560
197561 switch( nVal ){
197562 case 6: nToken = sqlite3_value_int(apVal[5]);
197563 /* no break */ deliberate_fall_through
197564 case 5: iCol = sqlite3_value_int(apVal[4]);
@@ -197569,11 +197781,11 @@
197569 /* no break */ deliberate_fall_through
197570 case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
197571 }
197572 if( !zEllipsis || !zEnd || !zStart ){
197573 sqlite3_result_error_nomem(pContext);
197574 }else if( nToken==0 ){
197575 sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
197576 }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
197577 sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
197578 }
197579 }
@@ -201149,11 +201361,11 @@
201149 */
201150 iCol = pParse->iDefaultCol;
201151 iColLen = 0;
201152 for(ii=0; ii<pParse->nCol; ii++){
201153 const char *zStr = pParse->azCol[ii];
201154 int nStr = (int)strlen(zStr);
201155 if( nInput>nStr && zInput[nStr]==':'
201156 && sqlite3_strnicmp(zStr, zInput, nStr)==0
201157 ){
201158 iCol = ii;
201159 iColLen = (int)((zInput - z) + nStr + 1);
@@ -201864,11 +202076,13 @@
201864 rc = fts3ExprParseUnbalanced(
201865 pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
201866 );
201867 }
201868
201869 if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
 
 
201870 sqlite3_result_error(context, "Error parsing expression", -1);
201871 }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
201872 sqlite3_result_error_nomem(context);
201873 }else{
201874 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
@@ -256851,24 +257065,24 @@
256851 Fts5Buffer out;
256852
256853 (void)nBuf;
256854 memset(&out, 0, sizeof(out));
256855 assert( nBuf==1 );
256856 sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
256857 if( p->rc ) return;
256858
256859 fts5NextRowid(p1, &i1, &iRowid1);
256860 fts5NextRowid(p2, &i2, &iRowid2);
256861 while( i1>=0 || i2>=0 ){
256862 if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
256863 assert( iOut==0 || iRowid1>iOut );
256864 fts5BufferSafeAppendVarint(&out, iRowid1 - iOut);
256865 iOut = iRowid1;
256866 fts5NextRowid(p1, &i1, &iRowid1);
256867 }else{
256868 assert( iOut==0 || iRowid2>iOut );
256869 fts5BufferSafeAppendVarint(&out, iRowid2 - iOut);
256870 iOut = iRowid2;
256871 if( i1>=0 && iRowid1==iRowid2 ){
256872 fts5NextRowid(p1, &i1, &iRowid1);
256873 }
256874 fts5NextRowid(p2, &i2, &iRowid2);
@@ -263950,11 +264164,11 @@
263950 int nArg, /* Number of args */
263951 sqlite3_value **apUnused /* Function arguments */
263952 ){
263953 assert( nArg==0 );
263954 UNUSED_PARAM2(nArg, apUnused);
263955 sqlite3_result_text(pCtx, "fts5: 2026-07-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d", -1, SQLITE_TRANSIENT);
263956 }
263957
263958 /*
263959 ** Implementation of fts5_locale(LOCALE, TEXT) function.
263960 **
263961
--- 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 ** bdc841de10fef65b627deb8b770702c97617 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-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2026-08-04T14:55:51.598Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -96610,11 +96610,11 @@
96610 }else if( p->flags & MEM_Real ){
96611 h += sqlite3VdbeIntValue(p);
96612 }else if( p->flags & MEM_Str ){
96613 u64 x;
96614 h += p->n;
96615 if( p->n >= (int)sizeof(x) ){
96616 memcpy(&x, p->z, sizeof(x));
96617 h += x;
96618 memcpy(&x, p->z + p->n - sizeof(x), sizeof(x));
96619 h += x;
96620 }else{
@@ -96624,11 +96624,11 @@
96624 }
96625 }else if( p->flags & MEM_Blob ){
96626 int n = p->n;
96627 u64 x = 0;
96628 if( n ){
96629 memcpy(&x, p->z, MIN(n, (int)sizeof(x)));
96630 h += x;
96631 }
96632 h += n;
96633 if( p->flags & MEM_Zero ) h += p->u.nZero;
96634 }
@@ -106272,10 +106272,11 @@
106272 /* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */
106273 #define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask))
106274
106275 #define SORTER_TYPE_INTEGER 0x01
106276 #define SORTER_TYPE_TEXT 0x02
106277 #define SORTER_TYPE_REAL 0x04
106278
106279 /*
106280 ** An instance of the following object is used to read records out of a
106281 ** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
106282 ** aKey might point into aMap or into aBuffer. If neither of those locations
@@ -106844,10 +106845,182 @@
106845 res = res * -1;
106846 }
106847
106848 return res;
106849 }
106850
106851 /* Helper function for vdbeSorterCompareReal().
106852 **
106853 ** The first elements of both pKey1 and pKey2 have been decoded into double
106854 ** values r1 and r2. Do the comparison between those keys and return the
106855 ** result. If r1==r2, break the tie with a comparison of subsequent elements
106856 ** from each key.
106857 */
106858 static int vdbeSorterFinishRealCompare(
106859 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106860 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106861 const void *pKey1, int nKey1, /* Left side of comparison */
106862 const void *pKey2, int nKey2, /* Right side of comparison */
106863 double r1, /* REAL value of first element of pKey1 */
106864 double r2 /* REAL value of first element of pKey2 */
106865 ){
106866 int res;
106867 if( r1<r2 ){
106868 res = -1;
106869 }else if( r1>r2 ){
106870 res = +1;
106871 }else{
106872 res = 0;
106873 }
106874 assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 );
106875 if( res==0 ){
106876 if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
106877 res = vdbeSorterCompareTail(
106878 pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
106879 );
106880 }
106881 }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
106882 assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
106883 res = res * -1;
106884 }
106885 return res;
106886 }
106887
106888 /* Helper function for vdbeSorterCompareReal().
106889 **
106890 ** Read the bits of an 8-byte big-endian IEEE-754 value and store them
106891 ** into a u64. Do any necessary byte-swapping so that the bits are in
106892 ** the right order for the host machine.
106893 **
106894 ** Copied and slightly modified from the readInt64() routine in rtree.c
106895 */
106896 static u64 vdbeSorterDecodeU64(const u8 *p){
106897 #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
106898 u64 x;
106899 memcpy(&x, p, 8);
106900 return _byteswap_uint64(x);
106901 #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
106902 u64 x;
106903 memcpy(&x, p, 8);
106904 return __builtin_bswap64(x);
106905 #elif SQLITE_BYTEORDER==4321
106906 i64 x;
106907 memcpy(&x, p, 8);
106908 return x;
106909 #else
106910 return (i64)(
106911 (((u64)p[0]) << 56) +
106912 (((u64)p[1]) << 48) +
106913 (((u64)p[2]) << 40) +
106914 (((u64)p[3]) << 32) +
106915 (((u64)p[4]) << 24) +
106916 (((u64)p[5]) << 16) +
106917 (((u64)p[6]) << 8) +
106918 (((u64)p[7]) << 0)
106919 );
106920 #endif
106921 }
106922
106923 /* Helper function for vdbeSorterCompareReal().
106924 **
106925 ** Buffer p[] is a record where the first term is guaranteed to be either
106926 ** a floating-point value, or an integer stand-in for a floating point
106927 ** value (a MEM_IntReal). Whatever its format, extract the value and
106928 ** return it.
106929 */
106930 static double vdbeSorterGetReal(const u8 *p){
106931 double r; /* the return value */
106932
106933 assert( p[0]<0x80 ); /* 1-byte headers: nAllField<13 */
106934 assert( p[1]>0 && p[1]<10 ); /* first fields proven numeric */
106935
106936 if( p[1]==7 ){
106937 u64 x = vdbeSorterDecodeU64(p + p[0]);
106938 swapMixedEndianFloat(x);
106939 assert( !IsNaN(x) );
106940 memcpy(&r, &x, sizeof(r));
106941 }else{
106942 Mem m;
106943 m.u.i = 0;
106944 sqlite3VdbeSerialGet(p + p[0], p[1], &m);
106945 assert( m.flags==MEM_Int );
106946 r = (double)m.u.i;
106947 }
106948 return r;
106949 }
106950
106951 /* Helper function for vdbeSorterCompareReal()
106952 **
106953 ** This routine handles the case of comparing two floating-point values
106954 ** where one or both of the floating-point are represented by integers.
106955 ** In other words, where one both is an MEM_RealInt.
106956 **
106957 ** This subroutine is factored out from vdbeSorterCompareReal() for
106958 ** efficiency. If inlined into vdbeSorterCompareReal(), this routine
106959 ** will use extra stack space and consume CPU cycles setting up and
106960 ** breaking down that stack space, even if in the common case where
106961 ** this path is not used.
106962 */
106963 static SQLITE_NOINLINE int vdbeSorterCompareRealInt(
106964 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106965 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106966 const void *pKey1, int nKey1, /* Left side of comparison */
106967 const void *pKey2, int nKey2 /* Right side of comparison */
106968 ){
106969 const u8 * const p1 = (const u8 * const)pKey1;
106970 const u8 * const p2 = (const u8 * const)pKey2;
106971 double r1 = vdbeSorterGetReal(p1);
106972 double r2 = vdbeSorterGetReal(p2);
106973 return vdbeSorterFinishRealCompare(pTask,pbKey2Cached,
106974 pKey1,nKey1,pKey2,nKey2,r1,r2);
106975 }
106976
106977 /*
106978 ** Comparison function optimized for the case where the first term
106979 ** of both keys are either MEM_Real or MEM_RealInt.
106980 **
106981 ** See also vdbeSorterCompareInt() for MEM_Int values and
106982 ** vdbeSorterCompareText() for MEM_Str values. The general
106983 ** case is vdbeSorterCompare() which handles anything, but is slower.
106984 */
106985 static int vdbeSorterCompareReal(
106986 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
106987 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
106988 const void *pKey1, int nKey1, /* Left side of comparison */
106989 const void *pKey2, int nKey2 /* Right side of comparison */
106990 ){
106991 const u8*const p1 = (const u8*const)pKey1; /* Left key record */
106992 const u8*const p2 = (const u8*const)pKey2; /* Right key record */
106993 u64 x; /* A real value stored as an integer */
106994 double r1; /* First element of pKey1 */
106995 double r2; /* First element of pKey2 */
106996
106997 assert( p1[0]<0x80 && p2[0]<0x80 ); /* 1-byte headers: nAllField<13 */
106998 assert( p1[1]>0 && p1[1]<10 ); /* first field guaranteed numeric */
106999 assert( p2[1]>0 && p2[1]<10 ); /* first field guaranteed numeric */
107000
107001 if( p1[1]!=7 || p2[1]!=7 ){
107002 /* One or both floating point values are stored as INTEGER (MEM_RealInt).
107003 ** Handle this case separately for efficiency */
107004 return vdbeSorterCompareRealInt(pTask,
107005 pbKey2Cached, pKey1,nKey1, pKey2,nKey2
107006 );
107007 }
107008 assert( p1[0]<=nKey1-8 && p2[0]<=nKey2-8 );
107009
107010 x = vdbeSorterDecodeU64(p1 + *p1);
107011 swapMixedEndianFloat(x);
107012 assert( !IsNaN(x) );
107013 memcpy(&r1, &x, sizeof(r1));
107014 x = vdbeSorterDecodeU64(p2 + *p2);
107015 swapMixedEndianFloat(x);
107016 assert( !IsNaN(x) );
107017 memcpy(&r2, &x, sizeof(r2));
107018 return vdbeSorterFinishRealCompare(pTask,
107019 pbKey2Cached, pKey1,nKey1, pKey2,nKey2, r1, r2
107020 );
107021 }
107022
107023 /*
107024 ** Initialize the temporary index cursor just opened as a sorter cursor.
107025 **
107026 ** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
@@ -106967,11 +107140,11 @@
107140
107141 if( pKeyInfo->nAllField<13
107142 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
107143 && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
107144 ){
107145 pSorter->typeMask = SORTER_TYPE_INTEGER|SORTER_TYPE_TEXT|SORTER_TYPE_REAL;
107146 }
107147 }
107148
107149 return rc;
107150 }
@@ -107339,14 +107512,16 @@
107512 /*
107513 ** Return the SorterCompare function to compare values collected by the
107514 ** sorter object passed as the only argument.
107515 */
107516 static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
107517 if( p->typeMask & SORTER_TYPE_INTEGER ){
107518 return vdbeSorterCompareInt;
107519 }else if( p->typeMask & SORTER_TYPE_TEXT ){
107520 return vdbeSorterCompareText;
107521 }else if( p->typeMask & SORTER_TYPE_REAL ){
107522 return vdbeSorterCompareReal;
107523 }
107524 return vdbeSorterCompare;
107525 }
107526
107527 /*
@@ -107740,12 +107915,16 @@
107915 int t; /* serial type of first record field */
107916
107917 assert( pCsr->eCurType==CURTYPE_SORTER );
107918 pSorter = pCsr->uc.pSorter;
107919 getVarint32NR((const u8*)&pVal->z[1], t);
107920 if( t>0 && t<10 ){
107921 if( t==7 ){
107922 pSorter->typeMask &= SORTER_TYPE_REAL;
107923 }else{
107924 pSorter->typeMask &= (SORTER_TYPE_INTEGER|SORTER_TYPE_REAL);
107925 }
107926 }else if( t>10 && (t & 0x01) ){
107927 pSorter->typeMask &= SORTER_TYPE_TEXT;
107928 }else{
107929 pSorter->typeMask = 0;
107930 }
@@ -115337,14 +115516,12 @@
115516 int i;
115517 if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
115518 if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
115519 p = pX->x.pSelect;
115520 if( p->pPrior ) return 0; /* Not a compound SELECT */
115521 if( p->selFlags & SF_Aggregate ){
115522 return 0; /* No GROUP BY keyword or aggregate functions */
 
 
115523 }
115524 assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
115525 if( p->pLimit ) return 0; /* Has no LIMIT clause */
115526 if( p->pWhere ) return 0; /* Has no WHERE clause */
115527 pSrc = p->pSrc;
@@ -116424,11 +116601,25 @@
116601 /* If this IN operator will use an index, then the order of columns in the
116602 ** vector might be different from the order in the index. In that case,
116603 ** we need to reorder the LHS values to be in index order. Run Affinity
116604 ** before reordering the columns, so that the affinity is correct.
116605 */
116606 if( nVector==1 ){
116607 char aff = zAff[0];
116608 if( aff>=SQLITE_AFF_TEXT && aff!=sqlite3ExprAffinity(pLeft) ){
116609 /* The OP_Affinity below may change the value. In this case, create a
116610 ** copy of rLhs to run OP_Affinity on, in case the original register
116611 ** is used again (e.g. if it is TK_AGG_COLUMN). */
116612 int rTmp = sqlite3GetTempReg(pParse);
116613 sqlite3VdbeAddOp3(v, OP_Copy, rLhs, rTmp, 0);
116614 rLhs = rTmp;
116615 sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, 1, 0, zAff, 1);
116616 }
116617 }else{
116618 sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
116619 }
116620
116621 for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
116622 if( i!=nVector ){
116623 /* Need to reorder the LHS fields according to aiMap */
116624 int rLhsOrig = rLhs;
116625 rLhs = sqlite3GetTempRange(pParse, nVector);
@@ -136450,11 +136641,11 @@
136641 }else{
136642 i++;
136643 }
136644 }while( i<iGt );
136645
136646 assert( iLt>0 && iLt<iGt && (unsigned)iGt<n );
136647 testcase( iGt>iLt+1 );
136648 assert( a[iLt]==rPivot );
136649 assert( a[iLt-1]<=rPivot );
136650 assert( a[iGt]>=rPivot );
136651 assert( a[iLt+1]>=rPivot );
@@ -156097,10 +156288,11 @@
156288 p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere);
156289 pSub->pWhere = 0;
156290 }
156291 pSub->pSrc = 0;
156292 sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
156293 recomputeColumnsUsed(p, &p->pSrc->a[p->pSrc->nSrc-1]);
156294 #if TREETRACE_ENABLED
156295 if( sqlite3TreeTrace & 0x100000 ){
156296 TREETRACE(0x100000,pParse,p,
156297 ("After EXISTS-to-JOIN optimization:\n"));
156298 sqlite3TreeViewSelect(0, p, 0);
@@ -156114,14 +156306,14 @@
156306 /*
156307 ** Type used for Walker callbacks by selectCheckOnClauses().
156308 */
156309 typedef struct CheckOnCtx CheckOnCtx;
156310 struct CheckOnCtx {
156311 SrcList *pSrc; /* SrcList for this context */
156312 int iJoin; /* Cursors must be left of this one, if not zero */
156313 int bFuncArg; /* True for table-function arg */
156314 CheckOnCtx *pParent; /* Parent context */
156315 };
156316
156317 /*
156318 ** True if the SrcList passed as the only argument contains at least
156319 ** one RIGHT or FULL JOIN. False otherwise.
@@ -156162,23 +156354,29 @@
156354 if( pExpr->op==TK_COLUMN ){
156355 /* A column expression. Find the SrcList (if any) to which it refers.
156356 ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
156357 ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
156358 ** does not refer to a table to the right of CheckOnCtx.iJoin. */
156359 int iTab = pExpr->iTable;
156360 do {
156361 SrcList *pSrc = pCtx->pSrc;
156362 int nSrc = pSrc->nSrc;
 
156363 int ii;
156364 for(ii=0; ii<nSrc && pSrc->a[ii].iCursor!=iTab; ii++){}
156365 if( ii<nSrc ){
156366 /* pSrc is the FROM clause that contains iTab */
156367 if( pCtx->iJoin ){
156368 for(ii--; ii>=0 && pSrc->a[ii].iCursor!=pCtx->iJoin; ii--){}
156369 if( ii>=0 ){
156370 /* Table iJoin appears to the left of table iTab in the SrcList.
156371 ** Therefore the expression refers to a table to its right. */
156372 sqlite3ErrorMsg(pWalker->pParse,
156373 "%s references tables to its right",
156374 (pCtx->bFuncArg ? "table-function argument" : "ON clause")
156375 );
156376 return WRC_Abort;
156377 }
156378 }
156379 break;
156380 }
156381 pCtx = pCtx->pParent;
156382 }while( pCtx );
@@ -164626,11 +164824,16 @@
164824 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
164825 testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
164826 testcase( pTerm->wtFlags & TERM_VIRTUAL );
164827 r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
164828 if( r1!=regBase+j ){
164829 /* If this routine is being called as part of a RIGHT JOIN loop, then
164830 ** register r1 may be used by the body of the loop that the RIGHT JOIN
164831 ** will jump back into (e.g. if pTerm is a sub-query). This can cause
164832 ** problems if (say) the affinity of r1 is modified by the caller of
164833 ** this routine. So, always take a copy of the value in this case. */
164834 if( nReg==1 && pParse->withinRJSubrtn==0 ){
164835 sqlite3ReleaseTempReg(pParse, regBase);
164836 regBase = r1;
164837 }else{
164838 sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
164839 }
@@ -167811,10 +168014,11 @@
168014 #endif
168015 pMaskSet = &pWInfo->sMaskSet;
168016 pExpr = pTerm->pExpr;
168017 assert( pExpr!=0 ); /* Because malloc() has not failed */
168018 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
168019 exprAnalyze_restart:
168020 pMaskSet->bVarSelect = 0;
168021 prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
168022 op = pExpr->op;
168023 if( op==TK_IN ){
168024 assert( pExpr->pRight==0 );
@@ -167977,10 +168181,15 @@
168181 #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
168182 /* Analyze a term that is composed of two or more subterms connected by
168183 ** an OR operator.
168184 */
168185 else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){
168186 Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
168187 if( pAlt!=pExpr ){
168188 pTerm->pExpr = pExpr = sqlite3ExprSkipCollateAndLikely(pAlt);
168189 goto exprAnalyze_restart;
168190 }
168191 assert( pWC->op==TK_AND );
168192 exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
168193 pTerm = &pWC->a[idxTerm];
168194 }
168195 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -168165,10 +168374,11 @@
168374 && ALWAYS( ExprUseXSelect(pExpr) )
168375 && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values))
168376 #ifndef SQLITE_OMIT_WINDOWFUNC
168377 && pExpr->x.pSelect->pWin==0
168378 #endif
168379 && (pExpr->x.pSelect->selFlags & SF_MinMaxAgg)==0
168380 && pWC->op==TK_AND
168381 && pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild)
168382 /* ^-- See bug 2026-06-04T10:00:49Z */
168383 ){
168384 int i;
@@ -197537,10 +197747,11 @@
197747 static void fts3SnippetFunc(
197748 sqlite3_context *pContext, /* SQLite function call context */
197749 int nVal, /* Size of apVal[] array */
197750 sqlite3_value **apVal /* Array of arguments */
197751 ){
197752 Fts3Table *pTab = 0;
197753 Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
197754 const char *zStart = "<b>";
197755 const char *zEnd = "</b>";
197756 const char *zEllipsis = "<b>...</b>";
197757 int iCol = -1;
@@ -197555,10 +197766,11 @@
197766 sqlite3_result_error(pContext,
197767 "wrong number of arguments to function snippet()", -1);
197768 return;
197769 }
197770 if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
197771 pTab = (Fts3Table *)pCsr->base.pVtab;
197772
197773 switch( nVal ){
197774 case 6: nToken = sqlite3_value_int(apVal[5]);
197775 /* no break */ deliberate_fall_through
197776 case 5: iCol = sqlite3_value_int(apVal[4]);
@@ -197569,11 +197781,11 @@
197781 /* no break */ deliberate_fall_through
197782 case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
197783 }
197784 if( !zEllipsis || !zEnd || !zStart ){
197785 sqlite3_result_error_nomem(pContext);
197786 }else if( nToken==0 || iCol>=pTab->nColumn ){
197787 sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
197788 }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
197789 sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
197790 }
197791 }
@@ -201149,11 +201361,11 @@
201361 */
201362 iCol = pParse->iDefaultCol;
201363 iColLen = 0;
201364 for(ii=0; ii<pParse->nCol; ii++){
201365 const char *zStr = pParse->azCol[ii];
201366 int nStr = zStr ? (int)strlen(zStr) : 0;
201367 if( nInput>nStr && zInput[nStr]==':'
201368 && sqlite3_strnicmp(zStr, zInput, nStr)==0
201369 ){
201370 iCol = ii;
201371 iColLen = (int)((zInput - z) + nStr + 1);
@@ -201864,11 +202076,13 @@
202076 rc = fts3ExprParseUnbalanced(
202077 pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
202078 );
202079 }
202080
202081 if( rc==SQLITE_OK && fts3ExprCheckDepth(pExpr, SQLITE_FTS3_MAX_EXPR_DEPTH) ){
202082 sqlite3_result_error(context, "Expression nested too deep", -1);
202083 }else if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
202084 sqlite3_result_error(context, "Error parsing expression", -1);
202085 }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
202086 sqlite3_result_error_nomem(context);
202087 }else{
202088 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
@@ -256851,24 +257065,24 @@
257065 Fts5Buffer out;
257066
257067 (void)nBuf;
257068 memset(&out, 0, sizeof(out));
257069 assert( nBuf==1 );
257070 sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9);
257071 if( p->rc ) return;
257072
257073 fts5NextRowid(p1, &i1, &iRowid1);
257074 fts5NextRowid(p2, &i2, &iRowid2);
257075 while( i1>=0 || i2>=0 ){
257076 if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
257077 assert( iOut==0 || iRowid1>iOut );
257078 fts5BufferSafeAppendVarint(&out, (u64)iRowid1 - (u64)iOut);
257079 iOut = iRowid1;
257080 fts5NextRowid(p1, &i1, &iRowid1);
257081 }else{
257082 assert( iOut==0 || iRowid2>iOut );
257083 fts5BufferSafeAppendVarint(&out, (u64)iRowid2 - (u64)iOut);
257084 iOut = iRowid2;
257085 if( i1>=0 && iRowid1==iRowid2 ){
257086 fts5NextRowid(p1, &i1, &iRowid1);
257087 }
257088 fts5NextRowid(p2, &i2, &iRowid2);
@@ -263950,11 +264164,11 @@
264164 int nArg, /* Number of args */
264165 sqlite3_value **apUnused /* Function arguments */
264166 ){
264167 assert( nArg==0 );
264168 UNUSED_PARAM2(nArg, apUnused);
264169 sqlite3_result_text(pCtx, "fts5: 2026-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744", -1, SQLITE_TRANSIENT);
264170 }
264171
264172 /*
264173 ** Implementation of fts5_locale(LOCALE, TEXT) function.
264174 **
264175
--- 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-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d"
151
+#define SQLITE_SOURCE_ID "2026-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2026-07-24T16:28:47.830Z"
154
+#define SQLITE_SCM_DATETIME "2026-08-04T14:55:51.598Z"
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-24 16:28:47 2f1f4f73535386549c12694dc57cfe555eec689ae6824c6241aaf8d5befcd74d"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2026-07-24T16:28:47.830Z"
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-08-04 14:55:51 bdc841de10fef65b627deb8b770702c976174a66af847c96ebecf24d91798744"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2026-08-04T14:55:51.598Z"
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