Fossil SCM

Sync with trunk.

florian 2025-09-26 12:53 diff-keyboard-navigation merge
Commit f3ff04466dc298c3d331158bec6371f37b88f8205da1138baf398e63db7becf7
+124 -51
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -653,18 +653,31 @@
653653
654654
/* Return the current wall-clock time in microseconds since the
655655
** Unix epoch (1970-01-01T00:00:00Z)
656656
*/
657657
static sqlite3_int64 timeOfDay(void){
658
-#if defined(_WIN32)
658
+#if defined(_WIN64)
659659
sqlite3_uint64 t;
660660
FILETIME tm;
661661
GetSystemTimePreciseAsFileTime(&tm);
662662
t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime;
663663
t += 116444736000000000LL;
664664
t /= 10;
665665
return t;
666
+#elif defined(_WIN32)
667
+ static sqlite3_vfs *clockVfs = 0;
668
+ sqlite3_int64 t;
669
+ if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
670
+ if( clockVfs==0 ) return 0; /* Never actually happens */
671
+ if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
672
+ clockVfs->xCurrentTimeInt64(clockVfs, &t);
673
+ }else{
674
+ double r;
675
+ clockVfs->xCurrentTime(clockVfs, &r);
676
+ t = (sqlite3_int64)(r*86400000.0);
677
+ }
678
+ return t*1000;
666679
#else
667680
struct timeval sNow;
668681
(void)gettimeofday(&sNow,0);
669682
return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec;
670683
#endif
@@ -710,11 +723,11 @@
710723
static void endTimer(FILE *out){
711724
if( enableTimer ){
712725
sqlite3_int64 iEnd = timeOfDay();
713726
struct rusage sEnd;
714727
getrusage(RUSAGE_SELF, &sEnd);
715
- sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
728
+ sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
716729
(iEnd - iBegin)*0.000001,
717730
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
718731
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
719732
}
720733
}
@@ -789,14 +802,23 @@
789802
static void endTimer(FILE *out){
790803
if( enableTimer && getProcessTimesAddr){
791804
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
792805
sqlite3_int64 ftWallEnd = timeOfDay();
793806
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
807
+#ifdef _WIN64
808
+ /* microsecond precision on 64-bit windows */
794809
sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
795810
(ftWallEnd - ftWallBegin)*0.000001,
796811
timeDiff(&ftUserBegin, &ftUserEnd),
797812
timeDiff(&ftKernelBegin, &ftKernelEnd));
813
+#else
814
+ /* millisecond precisino on 32-bit windows */
815
+ sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
816
+ (ftWallEnd - ftWallBegin)*0.000001,
817
+ timeDiff(&ftUserBegin, &ftUserEnd),
818
+ timeDiff(&ftKernelBegin, &ftKernelEnd));
819
+#endif
798820
}
799821
}
800822
801823
#define BEGIN_TIMER beginTimer()
802824
#define END_TIMER(X) endTimer(X)
@@ -1132,11 +1154,11 @@
11321154
}
11331155
if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
11341156
&& (z[3] & 0xc0)==0x80
11351157
){
11361158
*pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1137
- | (z[4] & 0x3f);
1159
+ | (z[3] & 0x3f);
11381160
return 4;
11391161
}
11401162
*pU = 0;
11411163
return 1;
11421164
}
@@ -1195,18 +1217,28 @@
11951217
** since with %*.*s the width is measured in bytes, not characters.
11961218
**
11971219
** Take into account zero-width and double-width Unicode characters.
11981220
** In other words, a zero-width character does not count toward the
11991221
** the w limit. A double-width character counts as two.
1222
+**
1223
+** w should normally be a small number. A couple hundred at most. This
1224
+** routine caps w at 100 million to avoid integer overflow issues.
12001225
*/
12011226
static void utf8_width_print(FILE *out, int w, const char *zUtf){
12021227
const unsigned char *a = (const unsigned char*)zUtf;
1228
+ static const int mxW = 10000000;
12031229
unsigned char c;
12041230
int i = 0;
12051231
int n = 0;
12061232
int k;
1207
- int aw = w<0 ? -w : w;
1233
+ int aw;
1234
+ if( w<-mxW ){
1235
+ w = -mxW;
1236
+ }else if( w>mxW ){
1237
+ w= mxW;
1238
+ }
1239
+ aw = w<0 ? -w : w;
12081240
if( zUtf==0 ) zUtf = "";
12091241
while( (c = a[i])!=0 ){
12101242
if( (c&0xc0)==0xc0 ){
12111243
int u;
12121244
int len = decodeUtf8(a+i, &u);
@@ -1329,11 +1361,11 @@
13291361
13301362
/*
13311363
** This routine reads a line of text from FILE in, stores
13321364
** the text in memory obtained from malloc() and returns a pointer
13331365
** to the text. NULL is returned at end of file, or if malloc()
1334
-** fails.
1366
+** fails, or if the length of the line is longer than about a gigabyte.
13351367
**
13361368
** If zLine is not NULL then it is a malloced buffer returned from
13371369
** a previous call to this routine that may be reused.
13381370
*/
13391371
static char *local_getline(char *zLine, FILE *in){
@@ -1340,10 +1372,14 @@
13401372
int nLine = zLine==0 ? 0 : 100;
13411373
int n = 0;
13421374
13431375
while( 1 ){
13441376
if( n+100>nLine ){
1377
+ if( nLine>=1073741773 ){
1378
+ free(zLine);
1379
+ return 0;
1380
+ }
13451381
nLine = nLine*2 + 100;
13461382
zLine = realloc(zLine, nLine);
13471383
shell_check_oom(zLine);
13481384
}
13491385
if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){
@@ -1423,14 +1459,18 @@
14231459
return -1;
14241460
}
14251461
14261462
/*
14271463
** Interpret zArg as an integer value, possibly with suffixes.
1464
+**
1465
+** If the value specified by zArg is outside the range of values that
1466
+** can be represented using a 64-bit twos-complement integer, then return
1467
+** the nearest representable value.
14281468
*/
14291469
static sqlite3_int64 integerValue(const char *zArg){
1430
- sqlite3_int64 v = 0;
1431
- static const struct { char *zSuffix; int iMult; } aMult[] = {
1470
+ sqlite3_uint64 v = 0;
1471
+ static const struct { char *zSuffix; unsigned int iMult; } aMult[] = {
14321472
{ "KiB", 1024 },
14331473
{ "MiB", 1024*1024 },
14341474
{ "GiB", 1024*1024*1024 },
14351475
{ "KB", 1000 },
14361476
{ "MB", 1000000 },
@@ -1449,26 +1489,34 @@
14491489
}
14501490
if( zArg[0]=='0' && zArg[1]=='x' ){
14511491
int x;
14521492
zArg += 2;
14531493
while( (x = hexDigitValue(zArg[0]))>=0 ){
1494
+ if( v > 0x0fffffffffffffffULL ) goto integer_overflow;
14541495
v = (v<<4) + x;
14551496
zArg++;
14561497
}
14571498
}else{
14581499
while( IsDigit(zArg[0]) ){
1459
- v = v*10 + zArg[0] - '0';
1500
+ if( v>=922337203685477580 ){
1501
+ if( v>922337203685477580 || zArg[0]>='8' ) goto integer_overflow;
1502
+ }
1503
+ v = v*10 + (zArg[0] - '0');
14601504
zArg++;
14611505
}
14621506
}
14631507
for(i=0; i<ArraySize(aMult); i++){
14641508
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1509
+ if( 0x7fffffffffffffffULL/aMult[i].iMult < v ) goto integer_overflow;
14651510
v *= aMult[i].iMult;
14661511
break;
14671512
}
14681513
}
1469
- return isNeg? -v : v;
1514
+ if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
1515
+ return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
1516
+integer_overflow:
1517
+ return isNeg ? 0x8000000000000000LL : 0x7fffffffffffffffLL;
14701518
}
14711519
14721520
/*
14731521
** A variable length string to which one can append text.
14741522
*/
@@ -3700,10 +3748,14 @@
37003748
memset(p->a, 0, iExp);
37013749
p->nDigit += iExp;
37023750
p->nFrac += iExp;
37033751
}
37043752
}
3753
+ if( p->sign ){
3754
+ for(i=0; i<p->nDigit && p->a[i]==0; i++){}
3755
+ if( i>=p->nDigit ) p->sign = 0;
3756
+ }
37053757
return p;
37063758
37073759
new_from_text_failed:
37083760
if( p ){
37093761
if( p->a ) sqlite3_free(p->a);
@@ -3902,17 +3954,25 @@
39023954
** pA!=0
39033955
** pA->isNull==0
39043956
** pB!=0
39053957
** pB->isNull==0
39063958
*/
3907
-static int decimal_cmp(const Decimal *pA, const Decimal *pB){
3959
+static int decimal_cmp(Decimal *pA, Decimal *pB){
39083960
int nASig, nBSig, rc, n;
3961
+ while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){
3962
+ pA->nDigit--;
3963
+ pA->nFrac--;
3964
+ }
3965
+ while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){
3966
+ pB->nDigit--;
3967
+ pB->nFrac--;
3968
+ }
39093969
if( pA->sign!=pB->sign ){
39103970
return pA->sign ? -1 : +1;
39113971
}
39123972
if( pA->sign ){
3913
- const Decimal *pTemp = pA;
3973
+ Decimal *pTemp = pA;
39143974
pA = pB;
39153975
pB = pTemp;
39163976
}
39173977
nASig = pA->nDigit - pA->nFrac;
39183978
nBSig = pB->nDigit - pB->nFrac;
@@ -4157,11 +4217,11 @@
41574217
r = -r;
41584218
}else{
41594219
isNeg = 0;
41604220
}
41614221
memcpy(&a,&r,sizeof(a));
4162
- if( a==0 ){
4222
+ if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){
41634223
e = 0;
41644224
m = 0;
41654225
}else{
41664226
e = a>>52;
41674227
m = a & ((((sqlite3_int64)1)<<52)-1);
@@ -5150,20 +5210,21 @@
51505210
return pOut;
51515211
}
51525212
51535213
/* This function does the work for the SQLite base64(x) UDF. */
51545214
static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
5155
- int nb, nc, nv = sqlite3_value_bytes(av[0]);
5215
+ int nb, nv = sqlite3_value_bytes(av[0]);
5216
+ sqlite3_int64 nc;
51565217
int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
51575218
SQLITE_LIMIT_LENGTH, -1);
51585219
char *cBuf;
51595220
u8 *bBuf;
51605221
assert(na==1);
51615222
switch( sqlite3_value_type(av[0]) ){
51625223
case SQLITE_BLOB:
51635224
nb = nv;
5164
- nc = 4*(nv+2/3); /* quads needed */
5225
+ nc = 4*((nv+2)/3); /* quads needed */
51655226
nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */
51665227
if( nvMax < nc ){
51675228
sqlite3_result_error(context, "blob expanded to base64 too big", -1);
51685229
return;
51695230
}
@@ -5835,10 +5896,13 @@
58355896
}
58365897
memcpy(&a,&r,sizeof(a));
58375898
if( a==0 ){
58385899
e = 0;
58395900
m = 0;
5901
+ }else if( a==(sqlite3_int64)0x8000000000000000LL ){
5902
+ e = -1996;
5903
+ m = -1;
58405904
}else{
58415905
e = a>>52;
58425906
m = a & ((((sqlite3_int64)1)<<52)-1);
58435907
if( e==0 ){
58445908
m <<= 1;
@@ -6595,10 +6659,14 @@
65956659
if( iOffset>0 ){
65966660
pCur->ss.iBase += pCur->ss.iStep*iOffset;
65976661
}
65986662
if( iLimit>=0 ){
65996663
sqlite3_int64 iTerm;
6664
+ sqlite3_int64 mxLimit;
6665
+ assert( pCur->ss.iStep>0 );
6666
+ mxLimit = (LARGEST_INT64 - pCur->ss.iBase)/pCur->ss.iStep;
6667
+ if( iLimit>mxLimit ) iLimit = mxLimit;
66006668
iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
66016669
if( pCur->ss.iStep<0 ){
66026670
if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
66036671
}else{
66046672
if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
@@ -10223,10 +10291,11 @@
1022310291
"z HIDDEN" /* 7: Name of zip file */
1022410292
") WITHOUT ROWID;";
1022510293
1022610294
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
1022710295
#define ZIPFILE_BUFFER_SIZE (64*1024)
10296
+#define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */
1022810297
1022910298
1023010299
/*
1023110300
** Magic numbers used to read and write zip files.
1023210301
**
@@ -10779,10 +10848,11 @@
1077910848
pLFH->crc32 = zipfileRead32(aRead);
1078010849
pLFH->szCompressed = zipfileRead32(aRead);
1078110850
pLFH->szUncompressed = zipfileRead32(aRead);
1078210851
pLFH->nFile = zipfileRead16(aRead);
1078310852
pLFH->nExtra = zipfileRead16(aRead);
10853
+ if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR;
1078410854
}
1078510855
return rc;
1078610856
}
1078710857
1078810858
@@ -10992,12 +11062,16 @@
1099211062
if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
1099311063
if( rc==SQLITE_OK ){
1099411064
pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
1099511065
pNew->iDataOff += lfh.nFile + lfh.nExtra;
1099611066
if( aBlob && pNew->cds.szCompressed ){
10997
- pNew->aData = &pNew->aExtra[nExtra];
10998
- memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
11067
+ if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){
11068
+ rc = SQLITE_CORRUPT;
11069
+ }else{
11070
+ pNew->aData = &pNew->aExtra[nExtra];
11071
+ memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
11072
+ }
1099911073
}
1100011074
}else{
1100111075
*pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
1100211076
(int)pNew->cds.iOffset
1100311077
);
@@ -11780,10 +11854,15 @@
1178011854
1178111855
if( rc==SQLITE_OK ){
1178211856
zPath = (const char*)sqlite3_value_text(apVal[2]);
1178311857
if( zPath==0 ) zPath = "";
1178411858
nPath = (int)strlen(zPath);
11859
+ if( nPath>ZIPFILE_MX_NAME ){
11860
+ zipfileTableErr(pTab, "filename too long; max: %d bytes",
11861
+ ZIPFILE_MX_NAME);
11862
+ rc = SQLITE_CONSTRAINT;
11863
+ }
1178511864
mTime = zipfileGetTime(apVal[4]);
1178611865
}
1178711866
1178811867
if( rc==SQLITE_OK && bIsDir ){
1178911868
/* For a directory, check that the last character in the path is a
@@ -12140,10 +12219,17 @@
1214012219
nName = sqlite3_value_bytes(pName);
1214112220
if( zName==0 ){
1214212221
zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
1214312222
rc = SQLITE_ERROR;
1214412223
goto zipfile_step_out;
12224
+ }
12225
+ if( nName>ZIPFILE_MX_NAME ){
12226
+ zErr = sqlite3_mprintf(
12227
+ "filename argument to zipfile() too big; max: %d bytes",
12228
+ ZIPFILE_MX_NAME);
12229
+ rc = SQLITE_ERROR;
12230
+ goto zipfile_step_out;
1214512231
}
1214612232
1214712233
/* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
1214812234
** deflate compression) or NULL (choose automatically). */
1214912235
if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
@@ -22033,11 +22119,11 @@
2203322119
2203422120
/*
2203522121
** Output the given string as a quoted string using SQL quoting conventions:
2203622122
**
2203722123
** (1) Single quotes (') within the string are doubled
22038
-** (2) The whle string is enclosed in '...'
22124
+** (2) The while string is enclosed in '...'
2203922125
** (3) Control characters other than \n, \t, and \r\n are escaped
2204022126
** using \u00XX notation and if such substitutions occur,
2204122127
** the whole string is enclosed in unistr('...') instead of '...'.
2204222128
**
2204322129
** Step (3) is omitted if the control-character escape mode is OFF.
@@ -22279,11 +22365,11 @@
2227922365
**
2228022366
** Escaping is needed if the string contains any control characters
2228122367
** other than \t, \n, and \r\n
2228222368
**
2228322369
** If no escaping is needed (the common case) then set *ppFree to NULL
22284
-** and return the original string. If escapingn is needed, write the
22370
+** and return the original string. If escaping is needed, write the
2228522371
** escaped string into memory obtained from sqlite3_malloc64() or the
2228622372
** equivalent, and return the new string and set *ppFree to the new string
2228722373
** as well.
2228822374
**
2228922375
** The caller is responsible for freeing *ppFree if it is non-NULL in order
@@ -23284,32 +23370,16 @@
2328423370
** Set the destination table field of the ShellState structure to
2328523371
** the name of the table given. Escape any quote characters in the
2328623372
** table name.
2328723373
*/
2328823374
static void set_table_name(ShellState *p, const char *zName){
23289
- int i, n;
23290
- char cQuote;
23291
- char *z;
23292
-
2329323375
if( p->zDestTable ){
23294
- free(p->zDestTable);
23376
+ sqlite3_free(p->zDestTable);
2329523377
p->zDestTable = 0;
2329623378
}
2329723379
if( zName==0 ) return;
23298
- cQuote = quoteChar(zName);
23299
- n = strlen30(zName);
23300
- if( cQuote ) n += n+2;
23301
- z = p->zDestTable = malloc( n+1 );
23302
- shell_check_oom(z);
23303
- n = 0;
23304
- if( cQuote ) z[n++] = cQuote;
23305
- for(i=0; zName[i]; i++){
23306
- z[n++] = zName[i];
23307
- if( zName[i]==cQuote ) z[n++] = cQuote;
23308
- }
23309
- if( cQuote ) z[n++] = cQuote;
23310
- z[n] = 0;
23380
+ p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
2331123381
}
2331223382
2331323383
/*
2331423384
** Maybe construct two lines of text that point out the position of a
2331523385
** syntax error. Return a pointer to the text, in memory obtained from
@@ -26835,14 +26905,17 @@
2683526905
#if SQLITE_SHELL_HAVE_RECOVER
2683626906
/*
2683726907
** Convert a 2-byte or 4-byte big-endian integer into a native integer
2683826908
*/
2683926909
static unsigned int get2byteInt(unsigned char *a){
26840
- return (a[0]<<8) + a[1];
26910
+ return ((unsigned int)a[0]<<8) + (unsigned int)a[1];
2684126911
}
2684226912
static unsigned int get4byteInt(unsigned char *a){
26843
- return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
26913
+ return ((unsigned int)a[0]<<24)
26914
+ + ((unsigned int)a[1]<<16)
26915
+ + ((unsigned int)a[2]<<8)
26916
+ + (unsigned int)a[3];
2684426917
}
2684526918
2684626919
/*
2684726920
** Implementation of the ".dbinfo" command.
2684826921
**
@@ -26975,11 +27048,11 @@
2697527048
if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
2697627049
nPage = sqlite3_column_int64(pStmt, 0);
2697727050
sqlite3_finalize(pStmt);
2697827051
pStmt = 0;
2697927052
if( nPage<1 ) goto dbtotxt_error;
26980
- rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
27053
+ rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2698127054
if( rc ) goto dbtotxt_error;
2698227055
if( sqlite3_step(pStmt)!=SQLITE_ROW ){
2698327056
zTail = "unk.db";
2698427057
}else{
2698527058
const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2);
@@ -26986,10 +27059,11 @@
2698627059
if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
2698727060
zTail = strrchr(zFilename, '/');
2698827061
#if defined(_WIN32)
2698927062
if( zTail==0 ) zTail = strrchr(zFilename, '\\');
2699027063
#endif
27064
+ if( zTail && zTail[1]!=0 ) zTail++;
2699127065
}
2699227066
zName = strdup(zTail);
2699327067
shell_check_oom(zName);
2699427068
sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
2699527069
nPage*pgSz, pgSz, zName);
@@ -29846,16 +29920,10 @@
2984629920
sqlite3_stmt *pStmt;
2984729921
int tnum = 0;
2984829922
int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
2984929923
int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
2985029924
int i;
29851
- if( !ShellHasFlag(p,SHFLG_TestingMode) ){
29852
- sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n",
29853
- "imposter");
29854
- rc = 1;
29855
- goto meta_command_exit;
29856
- }
2985729925
if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
2985829926
eputz("Usage: .imposter INDEX IMPOSTER\n"
2985929927
" .imposter off\n");
2986029928
/* Also allowed, but not documented:
2986129929
**
@@ -29923,22 +29991,19 @@
2992329991
if( lenPK==0 ) lenPK = 100000;
2992429992
zSql = sqlite3_mprintf(
2992529993
"CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
2992629994
azArg[2], zCollist, lenPK, zCollist);
2992729995
sqlite3_free(zCollist);
29928
- rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
29996
+ rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum);
2992929997
if( rc==SQLITE_OK ){
2993029998
rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
2993129999
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
2993230000
if( rc ){
2993330001
sqlite3_fprintf(stderr,
2993430002
"Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
2993530003
}else{
2993630004
sqlite3_fprintf(stdout, "%s;\n", zSql);
29937
- sqlite3_fprintf(stdout,
29938
- "WARNING: writing to an imposter table will corrupt"
29939
- " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index");
2994030005
}
2994130006
}else{
2994230007
sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
2994330008
rc = 1;
2994430009
}
@@ -31824,11 +31889,11 @@
3182431889
{ 0x00000020, 1, "CoverIdxScan" },
3182531890
{ 0x00000040, 1, "OrderByIdxJoin" },
3182631891
{ 0x00000080, 1, "Transitive" },
3182731892
{ 0x00000100, 1, "OmitNoopJoin" },
3182831893
{ 0x00000200, 1, "CountOfView" },
31829
- { 0x00000400, 1, "CurosrHints" },
31894
+ { 0x00000400, 1, "CursorHints" },
3183031895
{ 0x00000800, 1, "Stat4" },
3183131896
{ 0x00001000, 1, "PushDown" },
3183231897
{ 0x00002000, 1, "SimplifyJoin" },
3183331898
{ 0x00004000, 1, "SkipScan" },
3183431899
{ 0x00008000, 1, "PropagateConst" },
@@ -33368,16 +33433,24 @@
3336833433
(void)cmdline_option_value(argc, argv, ++i);
3336933434
#endif
3337033435
}else if( cli_strcmp(z,"-pagecache")==0 ){
3337133436
sqlite3_int64 n, sz;
3337233437
sz = integerValue(cmdline_option_value(argc,argv,++i));
33373
- if( sz>70000 ) sz = 70000;
33438
+ if( sz>65536 ) sz = 65536;
3337433439
if( sz<0 ) sz = 0;
3337533440
n = integerValue(cmdline_option_value(argc,argv,++i));
3337633441
if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
3337733442
n = 0xffffffffffffLL/sz;
3337833443
}
33444
+ if( sz>0 && (sz & (sz-1))==0 ){
33445
+ /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */
33446
+ int szHdr = 0;
33447
+ sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr);
33448
+ sz += szHdr;
33449
+ sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate"
33450
+ " the %d-byte headers\n", (int)sz, szHdr);
33451
+ }
3337933452
verify_uninitialized();
3338033453
sqlite3_config(SQLITE_CONFIG_PAGECACHE,
3338133454
(n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
3338233455
data.shellFlgs |= SHFLG_Pagecache;
3338333456
}else if( cli_strcmp(z,"-lookaside")==0 ){
3338433457
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -653,18 +653,31 @@
653
654 /* Return the current wall-clock time in microseconds since the
655 ** Unix epoch (1970-01-01T00:00:00Z)
656 */
657 static sqlite3_int64 timeOfDay(void){
658 #if defined(_WIN32)
659 sqlite3_uint64 t;
660 FILETIME tm;
661 GetSystemTimePreciseAsFileTime(&tm);
662 t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime;
663 t += 116444736000000000LL;
664 t /= 10;
665 return t;
 
 
 
 
 
 
 
 
 
 
 
 
 
666 #else
667 struct timeval sNow;
668 (void)gettimeofday(&sNow,0);
669 return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec;
670 #endif
@@ -710,11 +723,11 @@
710 static void endTimer(FILE *out){
711 if( enableTimer ){
712 sqlite3_int64 iEnd = timeOfDay();
713 struct rusage sEnd;
714 getrusage(RUSAGE_SELF, &sEnd);
715 sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
716 (iEnd - iBegin)*0.000001,
717 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
718 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
719 }
720 }
@@ -789,14 +802,23 @@
789 static void endTimer(FILE *out){
790 if( enableTimer && getProcessTimesAddr){
791 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
792 sqlite3_int64 ftWallEnd = timeOfDay();
793 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
 
 
794 sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
795 (ftWallEnd - ftWallBegin)*0.000001,
796 timeDiff(&ftUserBegin, &ftUserEnd),
797 timeDiff(&ftKernelBegin, &ftKernelEnd));
 
 
 
 
 
 
 
798 }
799 }
800
801 #define BEGIN_TIMER beginTimer()
802 #define END_TIMER(X) endTimer(X)
@@ -1132,11 +1154,11 @@
1132 }
1133 if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1134 && (z[3] & 0xc0)==0x80
1135 ){
1136 *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1137 | (z[4] & 0x3f);
1138 return 4;
1139 }
1140 *pU = 0;
1141 return 1;
1142 }
@@ -1195,18 +1217,28 @@
1195 ** since with %*.*s the width is measured in bytes, not characters.
1196 **
1197 ** Take into account zero-width and double-width Unicode characters.
1198 ** In other words, a zero-width character does not count toward the
1199 ** the w limit. A double-width character counts as two.
 
 
 
1200 */
1201 static void utf8_width_print(FILE *out, int w, const char *zUtf){
1202 const unsigned char *a = (const unsigned char*)zUtf;
 
1203 unsigned char c;
1204 int i = 0;
1205 int n = 0;
1206 int k;
1207 int aw = w<0 ? -w : w;
 
 
 
 
 
 
1208 if( zUtf==0 ) zUtf = "";
1209 while( (c = a[i])!=0 ){
1210 if( (c&0xc0)==0xc0 ){
1211 int u;
1212 int len = decodeUtf8(a+i, &u);
@@ -1329,11 +1361,11 @@
1329
1330 /*
1331 ** This routine reads a line of text from FILE in, stores
1332 ** the text in memory obtained from malloc() and returns a pointer
1333 ** to the text. NULL is returned at end of file, or if malloc()
1334 ** fails.
1335 **
1336 ** If zLine is not NULL then it is a malloced buffer returned from
1337 ** a previous call to this routine that may be reused.
1338 */
1339 static char *local_getline(char *zLine, FILE *in){
@@ -1340,10 +1372,14 @@
1340 int nLine = zLine==0 ? 0 : 100;
1341 int n = 0;
1342
1343 while( 1 ){
1344 if( n+100>nLine ){
 
 
 
 
1345 nLine = nLine*2 + 100;
1346 zLine = realloc(zLine, nLine);
1347 shell_check_oom(zLine);
1348 }
1349 if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){
@@ -1423,14 +1459,18 @@
1423 return -1;
1424 }
1425
1426 /*
1427 ** Interpret zArg as an integer value, possibly with suffixes.
 
 
 
 
1428 */
1429 static sqlite3_int64 integerValue(const char *zArg){
1430 sqlite3_int64 v = 0;
1431 static const struct { char *zSuffix; int iMult; } aMult[] = {
1432 { "KiB", 1024 },
1433 { "MiB", 1024*1024 },
1434 { "GiB", 1024*1024*1024 },
1435 { "KB", 1000 },
1436 { "MB", 1000000 },
@@ -1449,26 +1489,34 @@
1449 }
1450 if( zArg[0]=='0' && zArg[1]=='x' ){
1451 int x;
1452 zArg += 2;
1453 while( (x = hexDigitValue(zArg[0]))>=0 ){
 
1454 v = (v<<4) + x;
1455 zArg++;
1456 }
1457 }else{
1458 while( IsDigit(zArg[0]) ){
1459 v = v*10 + zArg[0] - '0';
 
 
 
1460 zArg++;
1461 }
1462 }
1463 for(i=0; i<ArraySize(aMult); i++){
1464 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
 
1465 v *= aMult[i].iMult;
1466 break;
1467 }
1468 }
1469 return isNeg? -v : v;
 
 
 
1470 }
1471
1472 /*
1473 ** A variable length string to which one can append text.
1474 */
@@ -3700,10 +3748,14 @@
3700 memset(p->a, 0, iExp);
3701 p->nDigit += iExp;
3702 p->nFrac += iExp;
3703 }
3704 }
 
 
 
 
3705 return p;
3706
3707 new_from_text_failed:
3708 if( p ){
3709 if( p->a ) sqlite3_free(p->a);
@@ -3902,17 +3954,25 @@
3902 ** pA!=0
3903 ** pA->isNull==0
3904 ** pB!=0
3905 ** pB->isNull==0
3906 */
3907 static int decimal_cmp(const Decimal *pA, const Decimal *pB){
3908 int nASig, nBSig, rc, n;
 
 
 
 
 
 
 
 
3909 if( pA->sign!=pB->sign ){
3910 return pA->sign ? -1 : +1;
3911 }
3912 if( pA->sign ){
3913 const Decimal *pTemp = pA;
3914 pA = pB;
3915 pB = pTemp;
3916 }
3917 nASig = pA->nDigit - pA->nFrac;
3918 nBSig = pB->nDigit - pB->nFrac;
@@ -4157,11 +4217,11 @@
4157 r = -r;
4158 }else{
4159 isNeg = 0;
4160 }
4161 memcpy(&a,&r,sizeof(a));
4162 if( a==0 ){
4163 e = 0;
4164 m = 0;
4165 }else{
4166 e = a>>52;
4167 m = a & ((((sqlite3_int64)1)<<52)-1);
@@ -5150,20 +5210,21 @@
5150 return pOut;
5151 }
5152
5153 /* This function does the work for the SQLite base64(x) UDF. */
5154 static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
5155 int nb, nc, nv = sqlite3_value_bytes(av[0]);
 
5156 int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
5157 SQLITE_LIMIT_LENGTH, -1);
5158 char *cBuf;
5159 u8 *bBuf;
5160 assert(na==1);
5161 switch( sqlite3_value_type(av[0]) ){
5162 case SQLITE_BLOB:
5163 nb = nv;
5164 nc = 4*(nv+2/3); /* quads needed */
5165 nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */
5166 if( nvMax < nc ){
5167 sqlite3_result_error(context, "blob expanded to base64 too big", -1);
5168 return;
5169 }
@@ -5835,10 +5896,13 @@
5835 }
5836 memcpy(&a,&r,sizeof(a));
5837 if( a==0 ){
5838 e = 0;
5839 m = 0;
 
 
 
5840 }else{
5841 e = a>>52;
5842 m = a & ((((sqlite3_int64)1)<<52)-1);
5843 if( e==0 ){
5844 m <<= 1;
@@ -6595,10 +6659,14 @@
6595 if( iOffset>0 ){
6596 pCur->ss.iBase += pCur->ss.iStep*iOffset;
6597 }
6598 if( iLimit>=0 ){
6599 sqlite3_int64 iTerm;
 
 
 
 
6600 iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
6601 if( pCur->ss.iStep<0 ){
6602 if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6603 }else{
6604 if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
@@ -10223,10 +10291,11 @@
10223 "z HIDDEN" /* 7: Name of zip file */
10224 ") WITHOUT ROWID;";
10225
10226 #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
10227 #define ZIPFILE_BUFFER_SIZE (64*1024)
 
10228
10229
10230 /*
10231 ** Magic numbers used to read and write zip files.
10232 **
@@ -10779,10 +10848,11 @@
10779 pLFH->crc32 = zipfileRead32(aRead);
10780 pLFH->szCompressed = zipfileRead32(aRead);
10781 pLFH->szUncompressed = zipfileRead32(aRead);
10782 pLFH->nFile = zipfileRead16(aRead);
10783 pLFH->nExtra = zipfileRead16(aRead);
 
10784 }
10785 return rc;
10786 }
10787
10788
@@ -10992,12 +11062,16 @@
10992 if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
10993 if( rc==SQLITE_OK ){
10994 pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
10995 pNew->iDataOff += lfh.nFile + lfh.nExtra;
10996 if( aBlob && pNew->cds.szCompressed ){
10997 pNew->aData = &pNew->aExtra[nExtra];
10998 memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
 
 
 
 
10999 }
11000 }else{
11001 *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
11002 (int)pNew->cds.iOffset
11003 );
@@ -11780,10 +11854,15 @@
11780
11781 if( rc==SQLITE_OK ){
11782 zPath = (const char*)sqlite3_value_text(apVal[2]);
11783 if( zPath==0 ) zPath = "";
11784 nPath = (int)strlen(zPath);
 
 
 
 
 
11785 mTime = zipfileGetTime(apVal[4]);
11786 }
11787
11788 if( rc==SQLITE_OK && bIsDir ){
11789 /* For a directory, check that the last character in the path is a
@@ -12140,10 +12219,17 @@
12140 nName = sqlite3_value_bytes(pName);
12141 if( zName==0 ){
12142 zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
12143 rc = SQLITE_ERROR;
12144 goto zipfile_step_out;
 
 
 
 
 
 
 
12145 }
12146
12147 /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
12148 ** deflate compression) or NULL (choose automatically). */
12149 if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
@@ -22033,11 +22119,11 @@
22033
22034 /*
22035 ** Output the given string as a quoted string using SQL quoting conventions:
22036 **
22037 ** (1) Single quotes (') within the string are doubled
22038 ** (2) The whle string is enclosed in '...'
22039 ** (3) Control characters other than \n, \t, and \r\n are escaped
22040 ** using \u00XX notation and if such substitutions occur,
22041 ** the whole string is enclosed in unistr('...') instead of '...'.
22042 **
22043 ** Step (3) is omitted if the control-character escape mode is OFF.
@@ -22279,11 +22365,11 @@
22279 **
22280 ** Escaping is needed if the string contains any control characters
22281 ** other than \t, \n, and \r\n
22282 **
22283 ** If no escaping is needed (the common case) then set *ppFree to NULL
22284 ** and return the original string. If escapingn is needed, write the
22285 ** escaped string into memory obtained from sqlite3_malloc64() or the
22286 ** equivalent, and return the new string and set *ppFree to the new string
22287 ** as well.
22288 **
22289 ** The caller is responsible for freeing *ppFree if it is non-NULL in order
@@ -23284,32 +23370,16 @@
23284 ** Set the destination table field of the ShellState structure to
23285 ** the name of the table given. Escape any quote characters in the
23286 ** table name.
23287 */
23288 static void set_table_name(ShellState *p, const char *zName){
23289 int i, n;
23290 char cQuote;
23291 char *z;
23292
23293 if( p->zDestTable ){
23294 free(p->zDestTable);
23295 p->zDestTable = 0;
23296 }
23297 if( zName==0 ) return;
23298 cQuote = quoteChar(zName);
23299 n = strlen30(zName);
23300 if( cQuote ) n += n+2;
23301 z = p->zDestTable = malloc( n+1 );
23302 shell_check_oom(z);
23303 n = 0;
23304 if( cQuote ) z[n++] = cQuote;
23305 for(i=0; zName[i]; i++){
23306 z[n++] = zName[i];
23307 if( zName[i]==cQuote ) z[n++] = cQuote;
23308 }
23309 if( cQuote ) z[n++] = cQuote;
23310 z[n] = 0;
23311 }
23312
23313 /*
23314 ** Maybe construct two lines of text that point out the position of a
23315 ** syntax error. Return a pointer to the text, in memory obtained from
@@ -26835,14 +26905,17 @@
26835 #if SQLITE_SHELL_HAVE_RECOVER
26836 /*
26837 ** Convert a 2-byte or 4-byte big-endian integer into a native integer
26838 */
26839 static unsigned int get2byteInt(unsigned char *a){
26840 return (a[0]<<8) + a[1];
26841 }
26842 static unsigned int get4byteInt(unsigned char *a){
26843 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
 
 
 
26844 }
26845
26846 /*
26847 ** Implementation of the ".dbinfo" command.
26848 **
@@ -26975,11 +27048,11 @@
26975 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
26976 nPage = sqlite3_column_int64(pStmt, 0);
26977 sqlite3_finalize(pStmt);
26978 pStmt = 0;
26979 if( nPage<1 ) goto dbtotxt_error;
26980 rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
26981 if( rc ) goto dbtotxt_error;
26982 if( sqlite3_step(pStmt)!=SQLITE_ROW ){
26983 zTail = "unk.db";
26984 }else{
26985 const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2);
@@ -26986,10 +27059,11 @@
26986 if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
26987 zTail = strrchr(zFilename, '/');
26988 #if defined(_WIN32)
26989 if( zTail==0 ) zTail = strrchr(zFilename, '\\');
26990 #endif
 
26991 }
26992 zName = strdup(zTail);
26993 shell_check_oom(zName);
26994 sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
26995 nPage*pgSz, pgSz, zName);
@@ -29846,16 +29920,10 @@
29846 sqlite3_stmt *pStmt;
29847 int tnum = 0;
29848 int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
29849 int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
29850 int i;
29851 if( !ShellHasFlag(p,SHFLG_TestingMode) ){
29852 sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n",
29853 "imposter");
29854 rc = 1;
29855 goto meta_command_exit;
29856 }
29857 if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
29858 eputz("Usage: .imposter INDEX IMPOSTER\n"
29859 " .imposter off\n");
29860 /* Also allowed, but not documented:
29861 **
@@ -29923,22 +29991,19 @@
29923 if( lenPK==0 ) lenPK = 100000;
29924 zSql = sqlite3_mprintf(
29925 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
29926 azArg[2], zCollist, lenPK, zCollist);
29927 sqlite3_free(zCollist);
29928 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
29929 if( rc==SQLITE_OK ){
29930 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
29931 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
29932 if( rc ){
29933 sqlite3_fprintf(stderr,
29934 "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
29935 }else{
29936 sqlite3_fprintf(stdout, "%s;\n", zSql);
29937 sqlite3_fprintf(stdout,
29938 "WARNING: writing to an imposter table will corrupt"
29939 " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index");
29940 }
29941 }else{
29942 sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
29943 rc = 1;
29944 }
@@ -31824,11 +31889,11 @@
31824 { 0x00000020, 1, "CoverIdxScan" },
31825 { 0x00000040, 1, "OrderByIdxJoin" },
31826 { 0x00000080, 1, "Transitive" },
31827 { 0x00000100, 1, "OmitNoopJoin" },
31828 { 0x00000200, 1, "CountOfView" },
31829 { 0x00000400, 1, "CurosrHints" },
31830 { 0x00000800, 1, "Stat4" },
31831 { 0x00001000, 1, "PushDown" },
31832 { 0x00002000, 1, "SimplifyJoin" },
31833 { 0x00004000, 1, "SkipScan" },
31834 { 0x00008000, 1, "PropagateConst" },
@@ -33368,16 +33433,24 @@
33368 (void)cmdline_option_value(argc, argv, ++i);
33369 #endif
33370 }else if( cli_strcmp(z,"-pagecache")==0 ){
33371 sqlite3_int64 n, sz;
33372 sz = integerValue(cmdline_option_value(argc,argv,++i));
33373 if( sz>70000 ) sz = 70000;
33374 if( sz<0 ) sz = 0;
33375 n = integerValue(cmdline_option_value(argc,argv,++i));
33376 if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
33377 n = 0xffffffffffffLL/sz;
33378 }
 
 
 
 
 
 
 
 
33379 verify_uninitialized();
33380 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
33381 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
33382 data.shellFlgs |= SHFLG_Pagecache;
33383 }else if( cli_strcmp(z,"-lookaside")==0 ){
33384
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -653,18 +653,31 @@
653
654 /* Return the current wall-clock time in microseconds since the
655 ** Unix epoch (1970-01-01T00:00:00Z)
656 */
657 static sqlite3_int64 timeOfDay(void){
658 #if defined(_WIN64)
659 sqlite3_uint64 t;
660 FILETIME tm;
661 GetSystemTimePreciseAsFileTime(&tm);
662 t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime;
663 t += 116444736000000000LL;
664 t /= 10;
665 return t;
666 #elif defined(_WIN32)
667 static sqlite3_vfs *clockVfs = 0;
668 sqlite3_int64 t;
669 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
670 if( clockVfs==0 ) return 0; /* Never actually happens */
671 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
672 clockVfs->xCurrentTimeInt64(clockVfs, &t);
673 }else{
674 double r;
675 clockVfs->xCurrentTime(clockVfs, &r);
676 t = (sqlite3_int64)(r*86400000.0);
677 }
678 return t*1000;
679 #else
680 struct timeval sNow;
681 (void)gettimeofday(&sNow,0);
682 return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec;
683 #endif
@@ -710,11 +723,11 @@
723 static void endTimer(FILE *out){
724 if( enableTimer ){
725 sqlite3_int64 iEnd = timeOfDay();
726 struct rusage sEnd;
727 getrusage(RUSAGE_SELF, &sEnd);
728 sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n",
729 (iEnd - iBegin)*0.000001,
730 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
731 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
732 }
733 }
@@ -789,14 +802,23 @@
802 static void endTimer(FILE *out){
803 if( enableTimer && getProcessTimesAddr){
804 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
805 sqlite3_int64 ftWallEnd = timeOfDay();
806 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
807 #ifdef _WIN64
808 /* microsecond precision on 64-bit windows */
809 sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n",
810 (ftWallEnd - ftWallBegin)*0.000001,
811 timeDiff(&ftUserBegin, &ftUserEnd),
812 timeDiff(&ftKernelBegin, &ftKernelEnd));
813 #else
814 /* millisecond precisino on 32-bit windows */
815 sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n",
816 (ftWallEnd - ftWallBegin)*0.000001,
817 timeDiff(&ftUserBegin, &ftUserEnd),
818 timeDiff(&ftKernelBegin, &ftKernelEnd));
819 #endif
820 }
821 }
822
823 #define BEGIN_TIMER beginTimer()
824 #define END_TIMER(X) endTimer(X)
@@ -1132,11 +1154,11 @@
1154 }
1155 if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80
1156 && (z[3] & 0xc0)==0x80
1157 ){
1158 *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6
1159 | (z[3] & 0x3f);
1160 return 4;
1161 }
1162 *pU = 0;
1163 return 1;
1164 }
@@ -1195,18 +1217,28 @@
1217 ** since with %*.*s the width is measured in bytes, not characters.
1218 **
1219 ** Take into account zero-width and double-width Unicode characters.
1220 ** In other words, a zero-width character does not count toward the
1221 ** the w limit. A double-width character counts as two.
1222 **
1223 ** w should normally be a small number. A couple hundred at most. This
1224 ** routine caps w at 100 million to avoid integer overflow issues.
1225 */
1226 static void utf8_width_print(FILE *out, int w, const char *zUtf){
1227 const unsigned char *a = (const unsigned char*)zUtf;
1228 static const int mxW = 10000000;
1229 unsigned char c;
1230 int i = 0;
1231 int n = 0;
1232 int k;
1233 int aw;
1234 if( w<-mxW ){
1235 w = -mxW;
1236 }else if( w>mxW ){
1237 w= mxW;
1238 }
1239 aw = w<0 ? -w : w;
1240 if( zUtf==0 ) zUtf = "";
1241 while( (c = a[i])!=0 ){
1242 if( (c&0xc0)==0xc0 ){
1243 int u;
1244 int len = decodeUtf8(a+i, &u);
@@ -1329,11 +1361,11 @@
1361
1362 /*
1363 ** This routine reads a line of text from FILE in, stores
1364 ** the text in memory obtained from malloc() and returns a pointer
1365 ** to the text. NULL is returned at end of file, or if malloc()
1366 ** fails, or if the length of the line is longer than about a gigabyte.
1367 **
1368 ** If zLine is not NULL then it is a malloced buffer returned from
1369 ** a previous call to this routine that may be reused.
1370 */
1371 static char *local_getline(char *zLine, FILE *in){
@@ -1340,10 +1372,14 @@
1372 int nLine = zLine==0 ? 0 : 100;
1373 int n = 0;
1374
1375 while( 1 ){
1376 if( n+100>nLine ){
1377 if( nLine>=1073741773 ){
1378 free(zLine);
1379 return 0;
1380 }
1381 nLine = nLine*2 + 100;
1382 zLine = realloc(zLine, nLine);
1383 shell_check_oom(zLine);
1384 }
1385 if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){
@@ -1423,14 +1459,18 @@
1459 return -1;
1460 }
1461
1462 /*
1463 ** Interpret zArg as an integer value, possibly with suffixes.
1464 **
1465 ** If the value specified by zArg is outside the range of values that
1466 ** can be represented using a 64-bit twos-complement integer, then return
1467 ** the nearest representable value.
1468 */
1469 static sqlite3_int64 integerValue(const char *zArg){
1470 sqlite3_uint64 v = 0;
1471 static const struct { char *zSuffix; unsigned int iMult; } aMult[] = {
1472 { "KiB", 1024 },
1473 { "MiB", 1024*1024 },
1474 { "GiB", 1024*1024*1024 },
1475 { "KB", 1000 },
1476 { "MB", 1000000 },
@@ -1449,26 +1489,34 @@
1489 }
1490 if( zArg[0]=='0' && zArg[1]=='x' ){
1491 int x;
1492 zArg += 2;
1493 while( (x = hexDigitValue(zArg[0]))>=0 ){
1494 if( v > 0x0fffffffffffffffULL ) goto integer_overflow;
1495 v = (v<<4) + x;
1496 zArg++;
1497 }
1498 }else{
1499 while( IsDigit(zArg[0]) ){
1500 if( v>=922337203685477580 ){
1501 if( v>922337203685477580 || zArg[0]>='8' ) goto integer_overflow;
1502 }
1503 v = v*10 + (zArg[0] - '0');
1504 zArg++;
1505 }
1506 }
1507 for(i=0; i<ArraySize(aMult); i++){
1508 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1509 if( 0x7fffffffffffffffULL/aMult[i].iMult < v ) goto integer_overflow;
1510 v *= aMult[i].iMult;
1511 break;
1512 }
1513 }
1514 if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
1515 return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
1516 integer_overflow:
1517 return isNeg ? 0x8000000000000000LL : 0x7fffffffffffffffLL;
1518 }
1519
1520 /*
1521 ** A variable length string to which one can append text.
1522 */
@@ -3700,10 +3748,14 @@
3748 memset(p->a, 0, iExp);
3749 p->nDigit += iExp;
3750 p->nFrac += iExp;
3751 }
3752 }
3753 if( p->sign ){
3754 for(i=0; i<p->nDigit && p->a[i]==0; i++){}
3755 if( i>=p->nDigit ) p->sign = 0;
3756 }
3757 return p;
3758
3759 new_from_text_failed:
3760 if( p ){
3761 if( p->a ) sqlite3_free(p->a);
@@ -3902,17 +3954,25 @@
3954 ** pA!=0
3955 ** pA->isNull==0
3956 ** pB!=0
3957 ** pB->isNull==0
3958 */
3959 static int decimal_cmp(Decimal *pA, Decimal *pB){
3960 int nASig, nBSig, rc, n;
3961 while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){
3962 pA->nDigit--;
3963 pA->nFrac--;
3964 }
3965 while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){
3966 pB->nDigit--;
3967 pB->nFrac--;
3968 }
3969 if( pA->sign!=pB->sign ){
3970 return pA->sign ? -1 : +1;
3971 }
3972 if( pA->sign ){
3973 Decimal *pTemp = pA;
3974 pA = pB;
3975 pB = pTemp;
3976 }
3977 nASig = pA->nDigit - pA->nFrac;
3978 nBSig = pB->nDigit - pB->nFrac;
@@ -4157,11 +4217,11 @@
4217 r = -r;
4218 }else{
4219 isNeg = 0;
4220 }
4221 memcpy(&a,&r,sizeof(a));
4222 if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){
4223 e = 0;
4224 m = 0;
4225 }else{
4226 e = a>>52;
4227 m = a & ((((sqlite3_int64)1)<<52)-1);
@@ -5150,20 +5210,21 @@
5210 return pOut;
5211 }
5212
5213 /* This function does the work for the SQLite base64(x) UDF. */
5214 static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
5215 int nb, nv = sqlite3_value_bytes(av[0]);
5216 sqlite3_int64 nc;
5217 int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
5218 SQLITE_LIMIT_LENGTH, -1);
5219 char *cBuf;
5220 u8 *bBuf;
5221 assert(na==1);
5222 switch( sqlite3_value_type(av[0]) ){
5223 case SQLITE_BLOB:
5224 nb = nv;
5225 nc = 4*((nv+2)/3); /* quads needed */
5226 nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */
5227 if( nvMax < nc ){
5228 sqlite3_result_error(context, "blob expanded to base64 too big", -1);
5229 return;
5230 }
@@ -5835,10 +5896,13 @@
5896 }
5897 memcpy(&a,&r,sizeof(a));
5898 if( a==0 ){
5899 e = 0;
5900 m = 0;
5901 }else if( a==(sqlite3_int64)0x8000000000000000LL ){
5902 e = -1996;
5903 m = -1;
5904 }else{
5905 e = a>>52;
5906 m = a & ((((sqlite3_int64)1)<<52)-1);
5907 if( e==0 ){
5908 m <<= 1;
@@ -6595,10 +6659,14 @@
6659 if( iOffset>0 ){
6660 pCur->ss.iBase += pCur->ss.iStep*iOffset;
6661 }
6662 if( iLimit>=0 ){
6663 sqlite3_int64 iTerm;
6664 sqlite3_int64 mxLimit;
6665 assert( pCur->ss.iStep>0 );
6666 mxLimit = (LARGEST_INT64 - pCur->ss.iBase)/pCur->ss.iStep;
6667 if( iLimit>mxLimit ) iLimit = mxLimit;
6668 iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
6669 if( pCur->ss.iStep<0 ){
6670 if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6671 }else{
6672 if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
@@ -10223,10 +10291,11 @@
10291 "z HIDDEN" /* 7: Name of zip file */
10292 ") WITHOUT ROWID;";
10293
10294 #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
10295 #define ZIPFILE_BUFFER_SIZE (64*1024)
10296 #define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */
10297
10298
10299 /*
10300 ** Magic numbers used to read and write zip files.
10301 **
@@ -10779,10 +10848,11 @@
10848 pLFH->crc32 = zipfileRead32(aRead);
10849 pLFH->szCompressed = zipfileRead32(aRead);
10850 pLFH->szUncompressed = zipfileRead32(aRead);
10851 pLFH->nFile = zipfileRead16(aRead);
10852 pLFH->nExtra = zipfileRead16(aRead);
10853 if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR;
10854 }
10855 return rc;
10856 }
10857
10858
@@ -10992,12 +11062,16 @@
11062 if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
11063 if( rc==SQLITE_OK ){
11064 pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
11065 pNew->iDataOff += lfh.nFile + lfh.nExtra;
11066 if( aBlob && pNew->cds.szCompressed ){
11067 if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){
11068 rc = SQLITE_CORRUPT;
11069 }else{
11070 pNew->aData = &pNew->aExtra[nExtra];
11071 memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
11072 }
11073 }
11074 }else{
11075 *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
11076 (int)pNew->cds.iOffset
11077 );
@@ -11780,10 +11854,15 @@
11854
11855 if( rc==SQLITE_OK ){
11856 zPath = (const char*)sqlite3_value_text(apVal[2]);
11857 if( zPath==0 ) zPath = "";
11858 nPath = (int)strlen(zPath);
11859 if( nPath>ZIPFILE_MX_NAME ){
11860 zipfileTableErr(pTab, "filename too long; max: %d bytes",
11861 ZIPFILE_MX_NAME);
11862 rc = SQLITE_CONSTRAINT;
11863 }
11864 mTime = zipfileGetTime(apVal[4]);
11865 }
11866
11867 if( rc==SQLITE_OK && bIsDir ){
11868 /* For a directory, check that the last character in the path is a
@@ -12140,10 +12219,17 @@
12219 nName = sqlite3_value_bytes(pName);
12220 if( zName==0 ){
12221 zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
12222 rc = SQLITE_ERROR;
12223 goto zipfile_step_out;
12224 }
12225 if( nName>ZIPFILE_MX_NAME ){
12226 zErr = sqlite3_mprintf(
12227 "filename argument to zipfile() too big; max: %d bytes",
12228 ZIPFILE_MX_NAME);
12229 rc = SQLITE_ERROR;
12230 goto zipfile_step_out;
12231 }
12232
12233 /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
12234 ** deflate compression) or NULL (choose automatically). */
12235 if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
@@ -22033,11 +22119,11 @@
22119
22120 /*
22121 ** Output the given string as a quoted string using SQL quoting conventions:
22122 **
22123 ** (1) Single quotes (') within the string are doubled
22124 ** (2) The while string is enclosed in '...'
22125 ** (3) Control characters other than \n, \t, and \r\n are escaped
22126 ** using \u00XX notation and if such substitutions occur,
22127 ** the whole string is enclosed in unistr('...') instead of '...'.
22128 **
22129 ** Step (3) is omitted if the control-character escape mode is OFF.
@@ -22279,11 +22365,11 @@
22365 **
22366 ** Escaping is needed if the string contains any control characters
22367 ** other than \t, \n, and \r\n
22368 **
22369 ** If no escaping is needed (the common case) then set *ppFree to NULL
22370 ** and return the original string. If escaping is needed, write the
22371 ** escaped string into memory obtained from sqlite3_malloc64() or the
22372 ** equivalent, and return the new string and set *ppFree to the new string
22373 ** as well.
22374 **
22375 ** The caller is responsible for freeing *ppFree if it is non-NULL in order
@@ -23284,32 +23370,16 @@
23370 ** Set the destination table field of the ShellState structure to
23371 ** the name of the table given. Escape any quote characters in the
23372 ** table name.
23373 */
23374 static void set_table_name(ShellState *p, const char *zName){
 
 
 
 
23375 if( p->zDestTable ){
23376 sqlite3_free(p->zDestTable);
23377 p->zDestTable = 0;
23378 }
23379 if( zName==0 ) return;
23380 p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
 
 
 
 
 
 
 
 
 
 
 
 
23381 }
23382
23383 /*
23384 ** Maybe construct two lines of text that point out the position of a
23385 ** syntax error. Return a pointer to the text, in memory obtained from
@@ -26835,14 +26905,17 @@
26905 #if SQLITE_SHELL_HAVE_RECOVER
26906 /*
26907 ** Convert a 2-byte or 4-byte big-endian integer into a native integer
26908 */
26909 static unsigned int get2byteInt(unsigned char *a){
26910 return ((unsigned int)a[0]<<8) + (unsigned int)a[1];
26911 }
26912 static unsigned int get4byteInt(unsigned char *a){
26913 return ((unsigned int)a[0]<<24)
26914 + ((unsigned int)a[1]<<16)
26915 + ((unsigned int)a[2]<<8)
26916 + (unsigned int)a[3];
26917 }
26918
26919 /*
26920 ** Implementation of the ".dbinfo" command.
26921 **
@@ -26975,11 +27048,11 @@
27048 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
27049 nPage = sqlite3_column_int64(pStmt, 0);
27050 sqlite3_finalize(pStmt);
27051 pStmt = 0;
27052 if( nPage<1 ) goto dbtotxt_error;
27053 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
27054 if( rc ) goto dbtotxt_error;
27055 if( sqlite3_step(pStmt)!=SQLITE_ROW ){
27056 zTail = "unk.db";
27057 }else{
27058 const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2);
@@ -26986,10 +27059,11 @@
27059 if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
27060 zTail = strrchr(zFilename, '/');
27061 #if defined(_WIN32)
27062 if( zTail==0 ) zTail = strrchr(zFilename, '\\');
27063 #endif
27064 if( zTail && zTail[1]!=0 ) zTail++;
27065 }
27066 zName = strdup(zTail);
27067 shell_check_oom(zName);
27068 sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
27069 nPage*pgSz, pgSz, zName);
@@ -29846,16 +29920,10 @@
29920 sqlite3_stmt *pStmt;
29921 int tnum = 0;
29922 int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
29923 int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
29924 int i;
 
 
 
 
 
 
29925 if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
29926 eputz("Usage: .imposter INDEX IMPOSTER\n"
29927 " .imposter off\n");
29928 /* Also allowed, but not documented:
29929 **
@@ -29923,22 +29991,19 @@
29991 if( lenPK==0 ) lenPK = 100000;
29992 zSql = sqlite3_mprintf(
29993 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
29994 azArg[2], zCollist, lenPK, zCollist);
29995 sqlite3_free(zCollist);
29996 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum);
29997 if( rc==SQLITE_OK ){
29998 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
29999 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
30000 if( rc ){
30001 sqlite3_fprintf(stderr,
30002 "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
30003 }else{
30004 sqlite3_fprintf(stdout, "%s;\n", zSql);
 
 
 
30005 }
30006 }else{
30007 sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
30008 rc = 1;
30009 }
@@ -31824,11 +31889,11 @@
31889 { 0x00000020, 1, "CoverIdxScan" },
31890 { 0x00000040, 1, "OrderByIdxJoin" },
31891 { 0x00000080, 1, "Transitive" },
31892 { 0x00000100, 1, "OmitNoopJoin" },
31893 { 0x00000200, 1, "CountOfView" },
31894 { 0x00000400, 1, "CursorHints" },
31895 { 0x00000800, 1, "Stat4" },
31896 { 0x00001000, 1, "PushDown" },
31897 { 0x00002000, 1, "SimplifyJoin" },
31898 { 0x00004000, 1, "SkipScan" },
31899 { 0x00008000, 1, "PropagateConst" },
@@ -33368,16 +33433,24 @@
33433 (void)cmdline_option_value(argc, argv, ++i);
33434 #endif
33435 }else if( cli_strcmp(z,"-pagecache")==0 ){
33436 sqlite3_int64 n, sz;
33437 sz = integerValue(cmdline_option_value(argc,argv,++i));
33438 if( sz>65536 ) sz = 65536;
33439 if( sz<0 ) sz = 0;
33440 n = integerValue(cmdline_option_value(argc,argv,++i));
33441 if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
33442 n = 0xffffffffffffLL/sz;
33443 }
33444 if( sz>0 && (sz & (sz-1))==0 ){
33445 /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */
33446 int szHdr = 0;
33447 sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr);
33448 sz += szHdr;
33449 sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate"
33450 " the %d-byte headers\n", (int)sz, szHdr);
33451 }
33452 verify_uninitialized();
33453 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
33454 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
33455 data.shellFlgs |= SHFLG_Pagecache;
33456 }else if( cli_strcmp(z,"-lookaside")==0 ){
33457
+865 -320
--- 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
-** cf7163f82ca380958a79350473b2c5a2cebd with changes in files:
21
+** 821cc0e421bc14a68ebaee507e38a900e0c8 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -168,11 +168,13 @@
168168
#define SQLITE_OMIT_LOAD_EXTENSION 1
169169
#define SQLITE_ENABLE_LOCKING_STYLE 0
170170
#define HAVE_UTIME 1
171171
#else
172172
/* This is not VxWorks. */
173
-#define OS_VXWORKS 0
173
+#ifndef OS_VXWORKS
174
+# define OS_VXWORKS 0
175
+#endif
174176
#define HAVE_FCHOWN 1
175177
#define HAVE_READLINK 1
176178
#define HAVE_LSTAT 1
177179
#endif /* defined(_WRS_KERNEL) */
178180
@@ -465,11 +467,14 @@
465467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
466468
** [sqlite_version()] and [sqlite_source_id()].
467469
*/
468470
#define SQLITE_VERSION "3.51.0"
469471
#define SQLITE_VERSION_NUMBER 3051000
470
-#define SQLITE_SOURCE_ID "2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1"
472
+#define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
473
+#define SQLITE_SCM_BRANCH "trunk"
474
+#define SQLITE_SCM_TAGS ""
475
+#define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
471476
472477
/*
473478
** CAPI3REF: Run-Time Library Version Numbers
474479
** KEYWORDS: sqlite3_version sqlite3_sourceid
475480
**
@@ -2657,21 +2662,24 @@
26572662
** views in the main database schema or in the schemas of ATTACH-ed
26582663
** databases.)^ </dd>
26592664
**
26602665
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
26612666
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2662
-** <dd> ^This option is used to enable or disable the
2663
-** [fts3_tokenizer()] function which is part of the
2664
-** [FTS3] full-text search engine extension.
2665
-** There must be two additional arguments.
2666
-** The first argument is an integer which is 0 to disable fts3_tokenizer() or
2667
-** positive to enable fts3_tokenizer() or negative to leave the setting
2668
-** unchanged.
2669
-** The second parameter is a pointer to an integer into which
2670
-** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2671
-** following this call. The second parameter may be a NULL pointer, in
2672
-** which case the new setting is not reported back. </dd>
2667
+** <dd> ^This option is used to enable or disable using the
2668
+** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine
2669
+** extension - without using bound parameters as the parameters. Doing so
2670
+** is disabled by default. There must be two additional arguments. The first
2671
+** argument is an integer. If it is passed 0, then using fts3_tokenizer()
2672
+** without bound parameters is disabled. If it is passed a positive value,
2673
+** then calling fts3_tokenizer without bound parameters is enabled. If it
2674
+** is passed a negative value, this setting is not modified - this can be
2675
+** used to query for the current setting. The second parameter is a pointer
2676
+** to an integer into which is written 0 or 1 to indicate the current value
2677
+** of this setting (after it is modified, if applicable). The second
2678
+** parameter may be a NULL pointer, in which case the value of the setting
2679
+** is not reported back. Refer to [FTS3] documentation for further details.
2680
+** </dd>
26732681
**
26742682
** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
26752683
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
26762684
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
26772685
** interface independently of the [load_extension()] SQL function.
@@ -4517,10 +4525,38 @@
45174525
SQLITE_API const char *sqlite3_errmsg(sqlite3*);
45184526
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
45194527
SQLITE_API const char *sqlite3_errstr(int);
45204528
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
45214529
4530
+/*
4531
+** CAPI3REF: Set Error Codes And Message
4532
+** METHOD: sqlite3
4533
+**
4534
+** Set the error code of the database handle passed as the first argument
4535
+** to errcode, and the error message to a copy of nul-terminated string
4536
+** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
4537
+** the default message associated with the supplied error code. Subsequent
4538
+** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will
4539
+** return the values set by this routine in place of what was previously
4540
+** set by SQLite itself.
4541
+**
4542
+** This function returns SQLITE_OK if the error code and error message are
4543
+** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if
4544
+** the database handle is NULL or invalid.
4545
+**
4546
+** The error code and message set by this routine remains in effect until
4547
+** they are changed, either by another call to this routine or until they are
4548
+** changed to by SQLite itself to reflect the result of some subsquent
4549
+** API call.
4550
+**
4551
+** This function is intended for use by SQLite extensions or wrappers. The
4552
+** idea is that an extension or wrapper can use this routine to set error
4553
+** messages and error codes and thus behave more like a core SQLite
4554
+** feature from the point of view of an application.
4555
+*/
4556
+SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg);
4557
+
45224558
/*
45234559
** CAPI3REF: Prepared Statement Object
45244560
** KEYWORDS: {prepared statement} {prepared statements}
45254561
**
45264562
** An instance of this object represents a single SQL statement that
@@ -6527,10 +6563,11 @@
65276563
** to be attached to [database connection] D using name N. Subsequent
65286564
** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
65296565
** or a NULL pointer if there were no prior calls to
65306566
** sqlite3_set_clientdata() with the same values of D and N.
65316567
** Names are compared using strcmp() and are thus case sensitive.
6568
+** It returns 0 on success and SQLITE_NOMEM on allocation failure.
65326569
**
65336570
** If P and X are both non-NULL, then the destructor X is invoked with
65346571
** argument P on the first of the following occurrences:
65356572
** <ul>
65366573
** <li> An out-of-memory error occurs during the call to
@@ -10098,25 +10135,38 @@
1009810135
** ^The third parameter is the name of the database that was written to -
1009910136
** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
1010010137
** is the number of pages currently in the write-ahead log file,
1010110138
** including those that were just committed.
1010210139
**
10103
-** The callback function should normally return [SQLITE_OK]. ^If an error
10140
+** ^The callback function should normally return [SQLITE_OK]. ^If an error
1010410141
** code is returned, that error will propagate back up through the
1010510142
** SQLite code base to cause the statement that provoked the callback
1010610143
** to report an error, though the commit will have still occurred. If the
1010710144
** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
1010810145
** that does not correspond to any valid SQLite error code, the results
1010910146
** are undefined.
1011010147
**
10111
-** A single database handle may have at most a single write-ahead log callback
10112
-** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
10113
-** previously registered write-ahead log callback. ^The return value is
10114
-** a copy of the third parameter from the previous call, if any, or 0.
10115
-** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
10116
-** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
10117
-** overwrite any prior [sqlite3_wal_hook()] settings.
10148
+** ^A single database handle may have at most a single write-ahead log
10149
+** callback registered at one time. ^Calling [sqlite3_wal_hook()]
10150
+** replaces the default behavior or previously registered write-ahead
10151
+** log callback.
10152
+**
10153
+** ^The return value is a copy of the third parameter from the
10154
+** previous call, if any, or 0.
10155
+**
10156
+** ^The [sqlite3_wal_autocheckpoint()] interface and the
10157
+** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and
10158
+** will overwrite any prior [sqlite3_wal_hook()] settings.
10159
+**
10160
+** ^If a write-ahead log callback is set using this function then
10161
+** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint]
10162
+** should be invoked periodically to keep the write-ahead log file
10163
+** from growing without bound.
10164
+**
10165
+** ^Passing a NULL pointer for the callback disables automatic
10166
+** checkpointing entirely. To re-enable the default behavior, call
10167
+** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint].
1011810168
*/
1011910169
SQLITE_API void *sqlite3_wal_hook(
1012010170
sqlite3*,
1012110171
int(*)(void *,sqlite3*,const char*,int),
1012210172
void*
@@ -10129,11 +10179,11 @@
1012910179
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
1013010180
** [sqlite3_wal_hook()] that causes any database on [database connection] D
1013110181
** to automatically [checkpoint]
1013210182
** after committing a transaction if there are N or
1013310183
** more frames in the [write-ahead log] file. ^Passing zero or
10134
-** a negative value as the nFrame parameter disables automatic
10184
+** a negative value as the N parameter disables automatic
1013510185
** checkpoints entirely.
1013610186
**
1013710187
** ^The callback registered by this function replaces any existing callback
1013810188
** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
1013910189
** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -10145,13 +10195,14 @@
1014510195
** ^Checkpoints initiated by this mechanism are
1014610196
** [sqlite3_wal_checkpoint_v2|PASSIVE].
1014710197
**
1014810198
** ^Every new [database connection] defaults to having the auto-checkpoint
1014910199
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
10150
-** pages. The use of this interface
10151
-** is only necessary if the default setting is found to be suboptimal
10152
-** for a particular application.
10200
+** pages.
10201
+**
10202
+** ^The use of this interface is only necessary if the default setting
10203
+** is found to be suboptimal for a particular application.
1015310204
*/
1015410205
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
1015510206
1015610207
/*
1015710208
** CAPI3REF: Checkpoint a database
@@ -10212,10 +10263,15 @@
1021210263
**
1021310264
** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
1021410265
** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
1021510266
** addition that it also truncates the log file to zero bytes just prior
1021610267
** to a successful return.
10268
+**
10269
+** <dt>SQLITE_CHECKPOINT_NOOP<dd>
10270
+** ^This mode always checkpoints zero frames. The only reason to invoke
10271
+** a NOOP checkpoint is to access the values returned by
10272
+** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt.
1021710273
** </dl>
1021810274
**
1021910275
** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
1022010276
** the log file or to -1 if the checkpoint could not run because
1022110277
** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -10282,10 +10338,11 @@
1028210338
** These constants define all valid values for the "checkpoint mode" passed
1028310339
** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
1028410340
** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
1028510341
** meaning of each of these checkpoint modes.
1028610342
*/
10343
+#define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */
1028710344
#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
1028810345
#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
1028910346
#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
1029010347
#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
1029110348
@@ -11109,11 +11166,11 @@
1110911166
** to avoid a memory leak.
1111011167
**
1111111168
** The [sqlite3_snapshot_get()] interface is only available when the
1111211169
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1111311170
*/
11114
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
11171
+SQLITE_API int sqlite3_snapshot_get(
1111511172
sqlite3 *db,
1111611173
const char *zSchema,
1111711174
sqlite3_snapshot **ppSnapshot
1111811175
);
1111911176
@@ -11158,11 +11215,11 @@
1115811215
** database connection in order to make it ready to use snapshots.)
1115911216
**
1116011217
** The [sqlite3_snapshot_open()] interface is only available when the
1116111218
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1116211219
*/
11163
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
11220
+SQLITE_API int sqlite3_snapshot_open(
1116411221
sqlite3 *db,
1116511222
const char *zSchema,
1116611223
sqlite3_snapshot *pSnapshot
1116711224
);
1116811225
@@ -11175,11 +11232,11 @@
1117511232
** using this routine to avoid a memory leak.
1117611233
**
1117711234
** The [sqlite3_snapshot_free()] interface is only available when the
1117811235
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1117911236
*/
11180
-SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
11237
+SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*);
1118111238
1118211239
/*
1118311240
** CAPI3REF: Compare the ages of two snapshot handles.
1118411241
** METHOD: sqlite3_snapshot
1118511242
**
@@ -11202,11 +11259,11 @@
1120211259
** snapshot, and a positive value if P1 is a newer snapshot than P2.
1120311260
**
1120411261
** This interface is only available if SQLite is compiled with the
1120511262
** [SQLITE_ENABLE_SNAPSHOT] option.
1120611263
*/
11207
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
11264
+SQLITE_API int sqlite3_snapshot_cmp(
1120811265
sqlite3_snapshot *p1,
1120911266
sqlite3_snapshot *p2
1121011267
);
1121111268
1121211269
/*
@@ -11230,11 +11287,11 @@
1123011287
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
1123111288
**
1123211289
** This interface is only available if SQLite is compiled with the
1123311290
** [SQLITE_ENABLE_SNAPSHOT] option.
1123411291
*/
11235
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
11292
+SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
1123611293
1123711294
/*
1123811295
** CAPI3REF: Serialize a database
1123911296
**
1124011297
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -11304,16 +11361,17 @@
1130411361
/*
1130511362
** CAPI3REF: Deserialize a database
1130611363
**
1130711364
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
1130811365
** [database connection] D to disconnect from database S and then
11309
-** reopen S as an in-memory database based on the serialization contained
11310
-** in P. The serialized database P is N bytes in size. M is the size of
11311
-** the buffer P, which might be larger than N. If M is larger than N, and
11312
-** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
11313
-** permitted to add content to the in-memory database as long as the total
11314
-** size does not exceed M bytes.
11366
+** reopen S as an in-memory database based on the serialization
11367
+** contained in P. If S is a NULL pointer, the main database is
11368
+** used. The serialized database P is N bytes in size. M is the size
11369
+** of the buffer P, which might be larger than N. If M is larger than
11370
+** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
11371
+** SQLite is permitted to add content to the in-memory database as
11372
+** long as the total size does not exceed M bytes.
1131511373
**
1131611374
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
1131711375
** invoke sqlite3_free() on the serialization buffer when the database
1131811376
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
1131911377
** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12634,10 +12692,19 @@
1263412692
** CAPI3REF: Apply A Changeset To A Database
1263512693
**
1263612694
** Apply a changeset or patchset to a database. These functions attempt to
1263712695
** update the "main" database attached to handle db with the changes found in
1263812696
** the changeset passed via the second and third arguments.
12697
+**
12698
+** All changes made by these functions are enclosed in a savepoint transaction.
12699
+** If any other error (aside from a constraint failure when attempting to
12700
+** write to the target database) occurs, then the savepoint transaction is
12701
+** rolled back, restoring the target database to its original state, and an
12702
+** SQLite error code returned. Additionally, starting with version 3.51.0,
12703
+** an error code and error message that may be accessed using the
12704
+** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database
12705
+** handle.
1263912706
**
1264012707
** The fourth argument (xFilter) passed to these functions is the "filter
1264112708
** callback". This may be passed NULL, in which case all changes in the
1264212709
** changeset are applied to the database. For sqlite3changeset_apply() and
1264312710
** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12772,16 +12839,10 @@
1277212839
** It is safe to execute SQL statements, including those that write to the
1277312840
** table that the callback related to, from within the xConflict callback.
1277412841
** This can be used to further customize the application's conflict
1277512842
** resolution strategy.
1277612843
**
12777
-** All changes made by these functions are enclosed in a savepoint transaction.
12778
-** If any other error (aside from a constraint failure when attempting to
12779
-** write to the target database) occurs, then the savepoint transaction is
12780
-** rolled back, restoring the target database to its original state, and an
12781
-** SQLite error code returned.
12782
-**
1278312844
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
1278412845
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
1278512846
** may set (*ppRebase) to point to a "rebase" that may be used with the
1278612847
** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
1278712848
** is set to the size of the buffer in bytes. It is the responsibility of the
@@ -14356,11 +14417,11 @@
1435614417
1435714418
/*
1435814419
** Maximum number of pages in one database file.
1435914420
**
1436014421
** This is really just the default value for the max_page_count pragma.
14361
-** This value can be lowered (or raised) at run-time using that the
14422
+** This value can be lowered (or raised) at run-time using the
1436214423
** max_page_count macro.
1436314424
*/
1436414425
#ifndef SQLITE_MAX_PAGE_COUNT
1436514426
# define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */
1436614427
#endif
@@ -18127,11 +18188,11 @@
1812718188
struct sqlite3InitInfo { /* Information used during initialization */
1812818189
Pgno newTnum; /* Rootpage of table being initialized */
1812918190
u8 iDb; /* Which db file is being initialized */
1813018191
u8 busy; /* TRUE if currently initializing */
1813118192
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
18132
- unsigned imposterTable : 1; /* Building an imposter table */
18193
+ unsigned imposterTable : 2; /* Building an imposter table */
1813318194
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
1813418195
const char **azInit; /* "type", "name", and "tbl_name" columns */
1813518196
} init;
1813618197
int nVdbeActive; /* Number of VDBEs currently running */
1813718198
int nVdbeRead; /* Number of active VDBEs that read or write */
@@ -18920,10 +18981,11 @@
1892018981
#define TF_Shadow 0x00001000 /* True for a shadow table */
1892118982
#define TF_HasStat4 0x00002000 /* STAT4 info available for this table */
1892218983
#define TF_Ephemeral 0x00004000 /* An ephemeral table */
1892318984
#define TF_Eponymous 0x00008000 /* An eponymous virtual table */
1892418985
#define TF_Strict 0x00010000 /* STRICT mode */
18986
+#define TF_Imposter 0x00020000 /* An imposter table */
1892518987
1892618988
/*
1892718989
** Allowed values for Table.eTabType
1892818990
*/
1892918991
#define TABTYP_NORM 0 /* Ordinary table */
@@ -20086,10 +20148,11 @@
2008620148
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
2008720149
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
2008820150
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
2008920151
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
2009020152
#define SF_Correlated 0x20000000 /* True if references the outer context */
20153
+#define SF_OnToWhere 0x40000000 /* One or more ON clauses moved to WHERE */
2009120154
2009220155
/* True if SrcItem X is a subquery that has SF_NestedFrom */
2009320156
#define IsNestedFrom(X) \
2009420157
((X)->fg.isSubquery && \
2009520158
((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
@@ -20839,10 +20902,11 @@
2083920902
struct Table *pTab; /* Table of generated column */
2084020903
struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */
2084120904
SrcItem *pSrcItem; /* A single FROM clause item */
2084220905
DbFixer *pFix; /* See sqlite3FixSelect() */
2084320906
Mem *aMem; /* See sqlite3BtreeCursorHint() */
20907
+ struct CheckOnCtx *pCheckOnCtx; /* See selectCheckOnClauses() */
2084420908
} u;
2084520909
};
2084620910
2084720911
/*
2084820912
** The following structure contains information used by the sqliteFix...
@@ -24209,11 +24273,14 @@
2420924273
Mem oldipk; /* Memory cell holding "old" IPK value */
2421024274
Mem *aNew; /* Array of new.* values */
2421124275
Table *pTab; /* Schema object being updated */
2421224276
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
2421324277
sqlite3_value **apDflt; /* Array of default values, if required */
24214
- u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
24278
+ union {
24279
+ KeyInfo sKey;
24280
+ u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
24281
+ } uKey;
2421524282
};
2421624283
2421724284
/*
2421824285
** An instance of this object is used to pass an vector of values into
2421924286
** OP_VFilter, the xFilter method of a virtual table. The vector is the
@@ -24976,10 +25043,14 @@
2497625043
if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
2497725044
return 1;
2497825045
}
2497925046
zDate += 5;
2498025047
p->tz = sgn*(nMn + nHr*60);
25048
+ if( p->tz==0 ){ /* Forum post 2025-09-17T10:12:14z */
25049
+ p->isLocal = 0;
25050
+ p->isUtc = 1;
25051
+ }
2498125052
zulu_time:
2498225053
while( sqlite3Isspace(*zDate) ){ zDate++; }
2498325054
return *zDate!=0;
2498425055
}
2498525056
@@ -33486,13 +33557,17 @@
3348633557
sqlite3StrAccumFinish(&x);
3348733558
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
3348833559
n = 0;
3348933560
if( pItem->fg.isSubquery ) n++;
3349033561
if( pItem->fg.isTabFunc ) n++;
33491
- if( pItem->fg.isUsing ) n++;
33562
+ if( pItem->fg.isUsing || pItem->u3.pOn!=0 ) n++;
3349233563
if( pItem->fg.isUsing ){
3349333564
sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
33565
+ }else if( pItem->u3.pOn!=0 ){
33566
+ sqlite3TreeViewItem(pView, "ON", (--n)>0);
33567
+ sqlite3TreeViewExpr(pView, pItem->u3.pOn, 0);
33568
+ sqlite3TreeViewPop(&pView);
3349433569
}
3349533570
if( pItem->fg.isSubquery ){
3349633571
assert( n==1 );
3349733572
if( pItem->pSTab ){
3349833573
Table *pTab = pItem->pSTab;
@@ -38131,11 +38206,11 @@
3813138206
static int kvstorageDelete(const char*, const char *zKey);
3813238207
static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf);
3813338208
#define KVSTORAGE_KEY_SZ 32
3813438209
3813538210
/* Expand the key name with an appropriate prefix and put the result
38136
-** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least
38211
+** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least
3813738212
** KVSTORAGE_KEY_SZ bytes.
3813838213
*/
3813938214
static void kvstorageMakeKey(
3814038215
const char *zClass,
3814138216
const char *zKeyIn,
@@ -38190,14 +38265,16 @@
3819038265
** enough to hold it all. The value put into zBuf must always be zero
3819138266
** terminated, even if it gets truncated because nBuf is not large enough.
3819238267
**
3819338268
** Return the total number of bytes in the data, without truncation, and
3819438269
** not counting the final zero terminator. Return -1 if the key does
38195
-** not exist.
38270
+** not exist or its key cannot be read.
3819638271
**
38197
-** If nBuf<=0 then this routine simply returns the size of the data without
38198
-** actually reading it.
38272
+** If nBuf<=0 then this routine simply returns the size of the data
38273
+** without actually reading it. Similarly, if nBuf==1 then it
38274
+** zero-terminates zBuf at zBuf[0] and returns the size of the data
38275
+** without reading it.
3819938276
*/
3820038277
static int kvstorageRead(
3820138278
const char *zClass,
3820238279
const char *zKey,
3820338280
char *zBuf,
@@ -38242,15 +38319,13 @@
3824238319
/*
3824338320
** An internal level of indirection which enables us to replace the
3824438321
** kvvfs i/o methods with JavaScript implementations in WASM builds.
3824538322
** Maintenance reminder: if this struct changes in any way, the JSON
3824638323
** rendering of its structure must be updated in
38247
-** sqlite3_wasm_enum_json(). There are no binary compatibility
38248
-** concerns, so it does not need an iVersion member. This file is
38249
-** necessarily always compiled together with sqlite3_wasm_enum_json(),
38250
-** and JS code dynamically creates the mapping of members based on
38251
-** that JSON description.
38324
+** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary
38325
+** compatibility concerns, so it does not need an iVersion
38326
+** member.
3825238327
*/
3825338328
typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods;
3825438329
struct sqlite3_kvvfs_methods {
3825538330
int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf);
3825638331
int (*xWrite)(const char *zClass, const char *zKey, const char *zData);
@@ -38263,12 +38338,12 @@
3826338338
** for JavaScript-side implementations in WASM builds. In such builds
3826438339
** it cannot be const, but in native builds it should be so that
3826538340
** the compiler can hopefully optimize this level of indirection out.
3826638341
** That said, kvvfs is intended primarily for use in WASM builds.
3826738342
**
38268
-** Note that this is not explicitly flagged as static because the
38269
-** amalgamation build will tag it with SQLITE_PRIVATE.
38343
+** This is not explicitly flagged as static because the amalgamation
38344
+** build will tag it with SQLITE_PRIVATE.
3827038345
*/
3827138346
#ifndef SQLITE_WASM
3827238347
const
3827338348
#endif
3827438349
SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = {
@@ -39437,14 +39512,15 @@
3943739512
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
3943839513
aSyscall[13].pCurrent)
3943939514
3944039515
#if defined(HAVE_FCHMOD)
3944139516
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
39517
+#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
3944239518
#else
3944339519
{ "fchmod", (sqlite3_syscall_ptr)0, 0 },
39520
+#define osFchmod(FID,MODE) 0
3944439521
#endif
39445
-#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
3944639522
3944739523
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
3944839524
{ "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
3944939525
#else
3945039526
{ "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -39698,13 +39774,12 @@
3969839774
return fd;
3969939775
}
3970039776
3970139777
/*
3970239778
** Helper functions to obtain and relinquish the global mutex. The
39703
-** global mutex is used to protect the unixInodeInfo and
39704
-** vxworksFileId objects used by this file, all of which may be
39705
-** shared by multiple threads.
39779
+** global mutex is used to protect the unixInodeInfo objects used by
39780
+** this file, all of which may be shared by multiple threads.
3970639781
**
3970739782
** Function unixMutexHeld() is used to assert() that the global mutex
3970839783
** is held when required. This function is only used as part of assert()
3970939784
** statements. e.g.
3971039785
**
@@ -39902,10 +39977,11 @@
3990239977
/*
3990339978
** All unique filenames are held on a linked list headed by this
3990439979
** variable:
3990539980
*/
3990639981
static struct vxworksFileId *vxworksFileList = 0;
39982
+static sqlite3_mutex *vxworksMutex = 0;
3990739983
3990839984
/*
3990939985
** Simplify a filename into its canonical form
3991039986
** by making the following changes:
3991139987
**
@@ -39967,47 +40043,47 @@
3996740043
3996840044
/* Search for an existing entry that matching the canonical name.
3996940045
** If found, increment the reference count and return a pointer to
3997040046
** the existing file ID.
3997140047
*/
39972
- unixEnterMutex();
40048
+ sqlite3_mutex_enter(vxworksMutex);
3997340049
for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
3997440050
if( pCandidate->nName==n
3997540051
&& memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
3997640052
){
3997740053
sqlite3_free(pNew);
3997840054
pCandidate->nRef++;
39979
- unixLeaveMutex();
40055
+ sqlite3_mutex_leave(vxworksMutex);
3998040056
return pCandidate;
3998140057
}
3998240058
}
3998340059
3998440060
/* No match was found. We will make a new file ID */
3998540061
pNew->nRef = 1;
3998640062
pNew->nName = n;
3998740063
pNew->pNext = vxworksFileList;
3998840064
vxworksFileList = pNew;
39989
- unixLeaveMutex();
40065
+ sqlite3_mutex_leave(vxworksMutex);
3999040066
return pNew;
3999140067
}
3999240068
3999340069
/*
3999440070
** Decrement the reference count on a vxworksFileId object. Free
3999540071
** the object when the reference count reaches zero.
3999640072
*/
3999740073
static void vxworksReleaseFileId(struct vxworksFileId *pId){
39998
- unixEnterMutex();
40074
+ sqlite3_mutex_enter(vxworksMutex);
3999940075
assert( pId->nRef>0 );
4000040076
pId->nRef--;
4000140077
if( pId->nRef==0 ){
4000240078
struct vxworksFileId **pp;
4000340079
for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
4000440080
assert( *pp==pId );
4000540081
*pp = pId->pNext;
4000640082
sqlite3_free(pId);
4000740083
}
40008
- unixLeaveMutex();
40084
+ sqlite3_mutex_leave(vxworksMutex);
4000940085
}
4001040086
#endif /* OS_VXWORKS */
4001140087
/*************** End of Unique File ID Utility Used By VxWorks ****************
4001240088
******************************************************************************/
4001340089
@@ -40391,10 +40467,14 @@
4039140467
do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
4039240468
if( rc!=1 ){
4039340469
storeLastErrno(pFile, errno);
4039440470
return SQLITE_IOERR;
4039540471
}
40472
+ if( fsync(fd) ){
40473
+ storeLastErrno(pFile, errno);
40474
+ return SQLITE_IOERR_FSYNC;
40475
+ }
4039640476
rc = osFstat(fd, &statbuf);
4039740477
if( rc!=0 ){
4039840478
storeLastErrno(pFile, errno);
4039940479
return SQLITE_IOERR;
4040040480
}
@@ -40560,22 +40640,46 @@
4056040640
static int osSetPosixAdvisoryLock(
4056140641
int h, /* The file descriptor on which to take the lock */
4056240642
struct flock *pLock, /* The description of the lock */
4056340643
unixFile *pFile /* Structure holding timeout value */
4056440644
){
40565
- int tm = pFile->iBusyTimeout;
40566
- int rc = osFcntl(h,F_SETLK,pLock);
40567
- while( rc<0 && tm>0 ){
40568
- /* On systems that support some kind of blocking file lock with a timeout,
40569
- ** make appropriate changes here to invoke that blocking file lock. On
40570
- ** generic posix, however, there is no such API. So we simply try the
40571
- ** lock once every millisecond until either the timeout expires, or until
40572
- ** the lock is obtained. */
40573
- unixSleep(0,1000);
40645
+ int rc = 0;
40646
+
40647
+ if( pFile->iBusyTimeout==0 ){
40648
+ /* unixFile->iBusyTimeout is set to 0. In this case, attempt a
40649
+ ** non-blocking lock. */
40650
+ rc = osFcntl(h,F_SETLK,pLock);
40651
+ }else{
40652
+ /* unixFile->iBusyTimeout is set to greater than zero. In this case,
40653
+ ** attempt a blocking-lock with a unixFile->iBusyTimeout ms timeout.
40654
+ **
40655
+ ** On systems that support some kind of blocking file lock operation,
40656
+ ** this block should be replaced by code to attempt a blocking lock
40657
+ ** with a timeout of unixFile->iBusyTimeout ms. The code below is
40658
+ ** placeholder code. If SQLITE_TEST is defined, the placeholder code
40659
+ ** retries the lock once every 1ms until it succeeds or the timeout
40660
+ ** is reached. Or, if SQLITE_TEST is not defined, the placeholder
40661
+ ** code attempts a non-blocking lock and sets unixFile->iBusyTimeout
40662
+ ** to 0. This causes the caller to return SQLITE_BUSY, instead of
40663
+ ** SQLITE_BUSY_TIMEOUT to SQLite - as required by a VFS that does not
40664
+ ** support blocking locks.
40665
+ */
40666
+#ifdef SQLITE_TEST
40667
+ int tm = pFile->iBusyTimeout;
40668
+ while( tm>0 ){
40669
+ rc = osFcntl(h,F_SETLK,pLock);
40670
+ if( rc==0 ) break;
40671
+ unixSleep(0,1000);
40672
+ tm--;
40673
+ }
40674
+#else
4057440675
rc = osFcntl(h,F_SETLK,pLock);
40575
- tm--;
40676
+ pFile->iBusyTimeout = 0;
40677
+#endif
40678
+ /* End of code to replace with real blocking-locks code. */
4057640679
}
40680
+
4057740681
return rc;
4057840682
}
4057940683
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
4058040684
4058140685
@@ -44892,14 +44996,21 @@
4489244996
#endif
4489344997
4489444998
storeLastErrno(pNew, 0);
4489544999
#if OS_VXWORKS
4489645000
if( rc!=SQLITE_OK ){
44897
- if( h>=0 ) robust_close(pNew, h, __LINE__);
44898
- h = -1;
44899
- osUnlink(zFilename);
44900
- pNew->ctrlFlags |= UNIXFILE_DELETE;
45001
+ if( h>=0 ){
45002
+ robust_close(pNew, h, __LINE__);
45003
+ h = -1;
45004
+ }
45005
+ if( pNew->ctrlFlags & UNIXFILE_DELETE ){
45006
+ osUnlink(zFilename);
45007
+ }
45008
+ if( pNew->pId ){
45009
+ vxworksReleaseFileId(pNew->pId);
45010
+ pNew->pId = 0;
45011
+ }
4490145012
}
4490245013
#endif
4490345014
if( rc!=SQLITE_OK ){
4490445015
if( h>=0 ) robust_close(pNew, h, __LINE__);
4490545016
}else{
@@ -44939,10 +45050,13 @@
4493945050
struct stat buf;
4494045051
const char *zDir = sqlite3_temp_directory;
4494145052
4494245053
while(1){
4494345054
if( zDir!=0
45055
+#if OS_VXWORKS
45056
+ && zDir[0]=='/'
45057
+#endif
4494445058
&& osStat(zDir, &buf)==0
4494545059
&& S_ISDIR(buf.st_mode)
4494645060
&& osAccess(zDir, 03)==0
4494745061
){
4494845062
return zDir;
@@ -45252,10 +45366,16 @@
4525245366
assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
4525345367
|| eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
4525445368
|| eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL
4525545369
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
4525645370
);
45371
+
45372
+#if OS_VXWORKS
45373
+ /* The file-ID mechanism used in Vxworks requires that all pathnames
45374
+ ** provided to unixOpen must be absolute pathnames. */
45375
+ if( zPath!=0 && zPath[0]!='/' ){ return SQLITE_CANTOPEN; }
45376
+#endif
4525745377
4525845378
/* Detect a pid change and reset the PRNG. There is a race condition
4525945379
** here such that two or more threads all trying to open databases at
4526045380
** the same instant might all reset the PRNG. But multiple resets
4526145381
** are harmless.
@@ -45453,12 +45573,15 @@
4545345573
goto open_finished;
4545445574
}
4545545575
}
4545645576
#endif
4545745577
45458
- assert( zPath==0 || zPath[0]=='/'
45459
- || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL
45578
+ assert( zPath==0
45579
+ || zPath[0]=='/'
45580
+ || eType==SQLITE_OPEN_SUPER_JOURNAL
45581
+ || eType==SQLITE_OPEN_MAIN_JOURNAL
45582
+ || eType==SQLITE_OPEN_TEMP_JOURNAL
4546045583
);
4546145584
rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
4546245585
4546345586
open_finished:
4546445587
if( rc!=SQLITE_OK ){
@@ -47183,10 +47306,13 @@
4718347306
}
4718447307
#ifdef SQLITE_OS_KV_OPTIONAL
4718547308
sqlite3KvvfsInit();
4718647309
#endif
4718747310
unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
47311
+#if OS_VXWORKS
47312
+ vxworksMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS2);
47313
+#endif
4718847314
4718947315
#ifndef SQLITE_OMIT_WAL
4719047316
/* Validate lock assumptions */
4719147317
assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */
4719247318
assert( UNIX_SHM_BASE==120 ); /* Start of locking area */
@@ -47217,10 +47343,13 @@
4721747343
** to release dynamically allocated objects. But not on unix.
4721847344
** This routine is a no-op for unix.
4721947345
*/
4722047346
SQLITE_API int sqlite3_os_end(void){
4722147347
unixBigLock = 0;
47348
+#if OS_VXWORKS
47349
+ vxworksMutex = 0;
47350
+#endif
4722247351
return SQLITE_OK;
4722347352
}
4722447353
4722547354
#endif /* SQLITE_OS_UNIX */
4722647355
@@ -51349,33 +51478,39 @@
5134951478
** log-summary, each thread has its own winFile object, but they all
5135051479
** point to a single instance of this object. In other words, each
5135151480
** log-summary is opened only once per process.
5135251481
**
5135351482
** winShmMutexHeld() must be true when creating or destroying
51354
-** this object or while reading or writing the following fields:
51483
+** this object, or while editing the global linked list that starts
51484
+** at winShmNodeList.
5135551485
**
51356
-** nRef
51357
-** pNext
51486
+** When reading or writing the linked list starting at winShmNode.pWinShmList,
51487
+** pShmNode->mutex must be held.
5135851488
**
51359
-** The following fields are read-only after the object is created:
51489
+** The following fields are constant after the object is created:
5136051490
**
5136151491
** zFilename
51492
+** hSharedShm
51493
+** mutex
51494
+** bUseSharedLockHandle
5136251495
**
51363
-** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
51496
+** Either winShmNode.mutex must be held or winShmNode.pWinShmList==0 and
5136451497
** winShmMutexHeld() is true when reading or writing any other field
5136551498
** in this structure.
5136651499
**
51367
-** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate
51368
-** the *-shm file if the DMS-locking protocol demands it, and (c) map
51369
-** regions of the *-shm file into memory using MapViewOfFile() or
51370
-** similar. Other locks are taken by individual clients using the
51371
-** winShm.hShm handles.
51500
+** File-handle hSharedShm is always used to (a) take the DMS lock, (b)
51501
+** truncate the *-shm file if the DMS-locking protocol demands it, and
51502
+** (c) map regions of the *-shm file into memory using MapViewOfFile()
51503
+** or similar. If bUseSharedLockHandle is true, then other locks are also
51504
+** taken on hSharedShm. Or, if bUseSharedLockHandle is false, then other
51505
+** locks are taken using each connection's winShm.hShm handles.
5137251506
*/
5137351507
struct winShmNode {
5137451508
sqlite3_mutex *mutex; /* Mutex to access this object */
5137551509
char *zFilename; /* Name of the file */
5137651510
HANDLE hSharedShm; /* File handle open on zFilename */
51511
+ int bUseSharedLockHandle; /* True to use hSharedShm for everything */
5137751512
5137851513
int isUnlocked; /* DMS lock has not yet been obtained */
5137951514
int isReadonly; /* True if read-only */
5138051515
int szRegion; /* Size of shared-memory regions */
5138151516
int nRegion; /* Size of array apRegion */
@@ -51384,11 +51519,12 @@
5138451519
HANDLE hMap; /* File handle from CreateFileMapping */
5138551520
void *pMap;
5138651521
} *aRegion;
5138751522
DWORD lastErrno; /* The Windows errno from the last I/O error */
5138851523
51389
- int nRef; /* Number of winShm objects pointing to this */
51524
+ winShm *pWinShmList; /* List of winShm objects with ptrs to this */
51525
+
5139051526
winShmNode *pNext; /* Next in list of all winShmNode objects */
5139151527
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
5139251528
u8 nextShmId; /* Next available winShm.id value */
5139351529
#endif
5139451530
};
@@ -51412,10 +51548,11 @@
5141251548
HANDLE hShm; /* File-handle on *-shm file. For locking. */
5141351549
int bReadonly; /* True if hShm is opened read-only */
5141451550
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
5141551551
u8 id; /* Id of this connection with its winShmNode */
5141651552
#endif
51553
+ winShm *pWinShmNext; /* Next winShm object on same winShmNode */
5141751554
};
5141851555
5141951556
/*
5142051557
** Constants used for locking
5142151558
*/
@@ -51425,11 +51562,11 @@
5142551562
/* Forward references to VFS methods */
5142651563
static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
5142751564
static int winDelete(sqlite3_vfs *,const char*,int);
5142851565
5142951566
/*
51430
-** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
51567
+** Purge the winShmNodeList list of all entries with winShmNode.pWinShmList==0.
5143151568
**
5143251569
** This is not a VFS shared-memory method; it is a utility function called
5143351570
** by VFS shared-memory methods.
5143451571
*/
5143551572
static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
@@ -51438,11 +51575,11 @@
5143851575
assert( winShmMutexHeld() );
5143951576
OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
5144051577
osGetCurrentProcessId(), deleteFlag));
5144151578
pp = &winShmNodeList;
5144251579
while( (p = *pp)!=0 ){
51443
- if( p->nRef==0 ){
51580
+ if( p->pWinShmList==0 ){
5144451581
int i;
5144551582
if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
5144651583
for(i=0; i<p->nRegion; i++){
5144751584
BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
5144851585
OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
@@ -51602,10 +51739,64 @@
5160251739
*pbReadonly = bReadonly;
5160351740
*ph = h;
5160451741
return rc;
5160551742
}
5160651743
51744
+/*
51745
+** Close pDbFd's connection to shared-memory. Delete the underlying
51746
+** *-shm file if deleteFlag is true.
51747
+*/
51748
+static int winCloseSharedMemory(winFile *pDbFd, int deleteFlag){
51749
+ winShm *p; /* The connection to be closed */
51750
+ winShm **pp; /* Iterator for pShmNode->pWinShmList */
51751
+ winShmNode *pShmNode; /* The underlying shared-memory file */
51752
+
51753
+ p = pDbFd->pShm;
51754
+ if( p==0 ) return SQLITE_OK;
51755
+ if( p->hShm!=INVALID_HANDLE_VALUE ){
51756
+ osCloseHandle(p->hShm);
51757
+ }
51758
+
51759
+ winShmEnterMutex();
51760
+ pShmNode = p->pShmNode;
51761
+
51762
+ /* Remove this connection from the winShmNode.pWinShmList list */
51763
+ sqlite3_mutex_enter(pShmNode->mutex);
51764
+ for(pp=&pShmNode->pWinShmList; *pp!=p; pp=&(*pp)->pWinShmNext){}
51765
+ *pp = p->pWinShmNext;
51766
+ sqlite3_mutex_leave(pShmNode->mutex);
51767
+
51768
+ winShmPurge(pDbFd->pVfs, deleteFlag);
51769
+ winShmLeaveMutex();
51770
+
51771
+ /* Free the connection p */
51772
+ sqlite3_free(p);
51773
+ pDbFd->pShm = 0;
51774
+ return SQLITE_OK;
51775
+}
51776
+
51777
+/*
51778
+** testfixture builds may set this global variable to true via a
51779
+** Tcl interface. This forces the VFS to use the locking normally
51780
+** only used for UNC paths for all files.
51781
+*/
51782
+#ifdef SQLITE_TEST
51783
+SQLITE_API int sqlite3_win_test_unc_locking = 0;
51784
+#else
51785
+# define sqlite3_win_test_unc_locking 0
51786
+#endif
51787
+
51788
+/*
51789
+** Return true if the string passed as the only argument is likely
51790
+** to be a UNC path. In other words, if it starts with "\\".
51791
+*/
51792
+static int winIsUNCPath(const char *zFile){
51793
+ if( zFile[0]=='\\' && zFile[1]=='\\' ){
51794
+ return 1;
51795
+ }
51796
+ return sqlite3_win_test_unc_locking;
51797
+}
5160751798
5160851799
/*
5160951800
** Open the shared-memory area associated with database file pDbFd.
5161051801
*/
5161151802
static int winOpenSharedMemory(winFile *pDbFd){
@@ -51628,19 +51819,14 @@
5162851819
return SQLITE_IOERR_NOMEM_BKPT;
5162951820
}
5163051821
pNew->zFilename = (char*)&pNew[1];
5163151822
pNew->hSharedShm = INVALID_HANDLE_VALUE;
5163251823
pNew->isUnlocked = 1;
51824
+ pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath);
5163351825
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
5163451826
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
5163551827
51636
- /* Open a file-handle on the *-shm file for this connection. This file-handle
51637
- ** is only used for locking. The mapping of the *-shm file is created using
51638
- ** the shared file handle in winShmNode.hSharedShm. */
51639
- p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0);
51640
- rc = winHandleOpen(pNew->zFilename, &p->bReadonly, &p->hShm);
51641
-
5164251828
/* Look to see if there is an existing winShmNode that can be used.
5164351829
** If no matching winShmNode currently exists, then create a new one. */
5164451830
winShmEnterMutex();
5164551831
for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
5164651832
/* TBD need to come up with better match here. Perhaps
@@ -51657,11 +51843,11 @@
5165751843
}
5165851844
5165951845
/* Open a file-handle to use for mappings, and for the DMS lock. */
5166051846
if( rc==SQLITE_OK ){
5166151847
HANDLE h = INVALID_HANDLE_VALUE;
51662
- pShmNode->isReadonly = p->bReadonly;
51848
+ pShmNode->isReadonly = sqlite3_uri_boolean(pDbFd->zPath,"readonly_shm",0);
5166351849
rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h);
5166451850
pShmNode->hSharedShm = h;
5166551851
}
5166651852
5166751853
/* If successful, link the new winShmNode into the global list. If an
@@ -51679,24 +51865,39 @@
5167951865
}
5168051866
5168151867
/* If no error has occurred, link the winShm object to the winShmNode and
5168251868
** the winShm to pDbFd. */
5168351869
if( rc==SQLITE_OK ){
51870
+ sqlite3_mutex_enter(pShmNode->mutex);
5168451871
p->pShmNode = pShmNode;
51685
- pShmNode->nRef++;
51872
+ p->pWinShmNext = pShmNode->pWinShmList;
51873
+ pShmNode->pWinShmList = p;
5168651874
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
5168751875
p->id = pShmNode->nextShmId++;
5168851876
#endif
5168951877
pDbFd->pShm = p;
51878
+ sqlite3_mutex_leave(pShmNode->mutex);
5169051879
}else if( p ){
51691
- winHandleClose(p->hShm);
5169251880
sqlite3_free(p);
5169351881
}
5169451882
5169551883
assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 );
5169651884
winShmLeaveMutex();
5169751885
sqlite3_free(pNew);
51886
+
51887
+ /* Open a file-handle on the *-shm file for this connection. This file-handle
51888
+ ** is only used for locking. The mapping of the *-shm file is created using
51889
+ ** the shared file handle in winShmNode.hSharedShm. */
51890
+ if( rc==SQLITE_OK && pShmNode->bUseSharedLockHandle==0 ){
51891
+ p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0);
51892
+ rc = winHandleOpen(pShmNode->zFilename, &p->bReadonly, &p->hShm);
51893
+ if( rc!=SQLITE_OK ){
51894
+ assert( p->hShm==INVALID_HANDLE_VALUE );
51895
+ winCloseSharedMemory(pDbFd, 0);
51896
+ }
51897
+ }
51898
+
5169851899
return rc;
5169951900
}
5170051901
5170151902
/*
5170251903
** Close a connection to shared-memory. Delete the underlying
@@ -51704,37 +51905,11 @@
5170451905
*/
5170551906
static int winShmUnmap(
5170651907
sqlite3_file *fd, /* Database holding shared memory */
5170751908
int deleteFlag /* Delete after closing if true */
5170851909
){
51709
- winFile *pDbFd; /* Database holding shared-memory */
51710
- winShm *p; /* The connection to be closed */
51711
- winShmNode *pShmNode; /* The underlying shared-memory file */
51712
-
51713
- pDbFd = (winFile*)fd;
51714
- p = pDbFd->pShm;
51715
- if( p==0 ) return SQLITE_OK;
51716
- if( p->hShm!=INVALID_HANDLE_VALUE ){
51717
- osCloseHandle(p->hShm);
51718
- }
51719
-
51720
- pShmNode = p->pShmNode;
51721
- winShmEnterMutex();
51722
-
51723
- /* If pShmNode->nRef has reached 0, then close the underlying
51724
- ** shared-memory file, too. */
51725
- assert( pShmNode->nRef>0 );
51726
- pShmNode->nRef--;
51727
- if( pShmNode->nRef==0 ){
51728
- winShmPurge(pDbFd->pVfs, deleteFlag);
51729
- }
51730
- winShmLeaveMutex();
51731
-
51732
- /* Free the connection p */
51733
- sqlite3_free(p);
51734
- pDbFd->pShm = 0;
51735
- return SQLITE_OK;
51910
+ return winCloseSharedMemory((winFile*)fd, deleteFlag);
5173651911
}
5173751912
5173851913
/*
5173951914
** Change the lock state for a shared-memory segment.
5174051915
*/
@@ -51799,29 +51974,75 @@
5179951974
);
5180051975
if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
5180151976
|| (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
5180251977
|| (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
5180351978
){
51979
+ HANDLE h = p->hShm;
5180451980
5180551981
if( flags & SQLITE_SHM_UNLOCK ){
5180651982
/* Case (a) - unlock. */
5180751983
5180851984
assert( (p->exclMask & p->sharedMask)==0 );
5180951985
assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
5181051986
assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
5181151987
51812
- rc = winHandleUnlock(p->hShm, ofst+WIN_SHM_BASE, n);
51988
+ assert( !(flags & SQLITE_SHM_SHARED) || n==1 );
51989
+ if( pShmNode->bUseSharedLockHandle ){
51990
+ h = pShmNode->hSharedShm;
51991
+ if( flags & SQLITE_SHM_SHARED ){
51992
+ winShm *pShm;
51993
+ sqlite3_mutex_enter(pShmNode->mutex);
51994
+ for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){
51995
+ if( pShm!=p && (pShm->sharedMask & mask) ){
51996
+ /* Another connection within this process is also holding this
51997
+ ** SHARED lock. So do not actually release the OS lock. */
51998
+ h = INVALID_HANDLE_VALUE;
51999
+ break;
52000
+ }
52001
+ }
52002
+ sqlite3_mutex_leave(pShmNode->mutex);
52003
+ }
52004
+ }
52005
+
52006
+ if( h!=INVALID_HANDLE_VALUE ){
52007
+ rc = winHandleUnlock(h, ofst+WIN_SHM_BASE, n);
52008
+ }
5181352009
5181452010
/* If successful, also clear the bits in sharedMask/exclMask */
5181552011
if( rc==SQLITE_OK ){
5181652012
p->exclMask = (p->exclMask & ~mask);
5181752013
p->sharedMask = (p->sharedMask & ~mask);
5181852014
}
5181952015
}else{
5182052016
int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0);
5182152017
DWORD nMs = winFileBusyTimeout(pDbFd);
51822
- rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs);
52018
+
52019
+ if( pShmNode->bUseSharedLockHandle ){
52020
+ winShm *pShm;
52021
+ h = pShmNode->hSharedShm;
52022
+ sqlite3_mutex_enter(pShmNode->mutex);
52023
+ for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){
52024
+ if( bExcl ){
52025
+ if( (pShm->sharedMask|pShm->exclMask) & mask ){
52026
+ rc = SQLITE_BUSY;
52027
+ h = INVALID_HANDLE_VALUE;
52028
+ }
52029
+ }else{
52030
+ if( pShm->sharedMask & mask ){
52031
+ h = INVALID_HANDLE_VALUE;
52032
+ }else if( pShm->exclMask & mask ){
52033
+ rc = SQLITE_BUSY;
52034
+ h = INVALID_HANDLE_VALUE;
52035
+ }
52036
+ }
52037
+ }
52038
+ sqlite3_mutex_leave(pShmNode->mutex);
52039
+ }
52040
+
52041
+ if( h!=INVALID_HANDLE_VALUE ){
52042
+ rc = winHandleLockTimeout(h, ofst+WIN_SHM_BASE, n, bExcl, nMs);
52043
+ }
5182352044
if( rc==SQLITE_OK ){
5182452045
if( bExcl ){
5182552046
p->exclMask = (p->exclMask | mask);
5182652047
}else{
5182752048
p->sharedMask = (p->sharedMask | mask);
@@ -61848,18 +62069,31 @@
6184862069
SQLITE_PRIVATE void sqlite3PagerSetFlags(
6184962070
Pager *pPager, /* The pager to set safety level for */
6185062071
unsigned pgFlags /* Various flags */
6185162072
){
6185262073
unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
61853
- if( pPager->tempFile ){
62074
+ if( pPager->tempFile || level==PAGER_SYNCHRONOUS_OFF ){
6185462075
pPager->noSync = 1;
6185562076
pPager->fullSync = 0;
6185662077
pPager->extraSync = 0;
6185762078
}else{
61858
- pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0;
62079
+ pPager->noSync = 0;
6185962080
pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
61860
- pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
62081
+
62082
+ /* Set Pager.extraSync if "PRAGMA synchronous=EXTRA" is requested, or
62083
+ ** if the file-system supports F2FS style atomic writes. If this flag
62084
+ ** is set, SQLite syncs the directory to disk immediately after deleting
62085
+ ** a journal file in "PRAGMA journal_mode=DELETE" mode. */
62086
+ if( level==PAGER_SYNCHRONOUS_EXTRA
62087
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
62088
+ || (sqlite3OsDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_BATCH_ATOMIC)
62089
+#endif
62090
+ ){
62091
+ pPager->extraSync = 1;
62092
+ }else{
62093
+ pPager->extraSync = 0;
62094
+ }
6186162095
}
6186262096
if( pPager->noSync ){
6186362097
pPager->syncFlags = 0;
6186462098
}else if( pgFlags & PAGER_FULLFSYNC ){
6186562099
pPager->syncFlags = SQLITE_SYNC_FULL;
@@ -65748,11 +65982,11 @@
6574865982
*/
6574965983
sqlite3_exec(db, "PRAGMA table_list",0,0,0);
6575065984
}
6575165985
if( pPager->pWal ){
6575265986
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
65753
- (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
65987
+ (eMode<=SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
6575465988
pPager->pBusyHandlerArg,
6575565989
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
6575665990
pnLog, pnCkpt
6575765991
);
6575865992
}
@@ -70353,11 +70587,12 @@
7035370587
assert( pWal->ckptLock==0 );
7035470588
assert( pWal->writeLock==0 );
7035570589
7035670590
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
7035770591
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
70358
- assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
70592
+ assert( SQLITE_CHECKPOINT_NOOP<SQLITE_CHECKPOINT_PASSIVE );
70593
+ assert( eMode>SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
7035970594
7036070595
if( pWal->readOnly ) return SQLITE_READONLY;
7036170596
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
7036270597
7036370598
/* Enable blocking locks, if possible. */
@@ -70370,35 +70605,39 @@
7037070605
** checkpoint operation at the same time, the lock cannot be obtained and
7037170606
** SQLITE_BUSY is returned.
7037270607
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
7037370608
** it will not be invoked in this case.
7037470609
*/
70375
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
70376
- testcase( rc==SQLITE_BUSY );
70377
- testcase( rc!=SQLITE_OK && xBusy2!=0 );
70378
- if( rc==SQLITE_OK ){
70379
- pWal->ckptLock = 1;
70380
-
70381
- /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
70382
- ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
70383
- ** file.
70384
- **
70385
- ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
70386
- ** immediately, and a busy-handler is configured, it is invoked and the
70387
- ** writer lock retried until either the busy-handler returns 0 or the
70388
- ** lock is successfully obtained.
70389
- */
70390
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
70391
- rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
70392
- if( rc==SQLITE_OK ){
70393
- pWal->writeLock = 1;
70394
- }else if( rc==SQLITE_BUSY ){
70395
- eMode2 = SQLITE_CHECKPOINT_PASSIVE;
70396
- xBusy2 = 0;
70397
- rc = SQLITE_OK;
70398
- }
70399
- }
70610
+ if( eMode!=SQLITE_CHECKPOINT_NOOP ){
70611
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
70612
+ testcase( rc==SQLITE_BUSY );
70613
+ testcase( rc!=SQLITE_OK && xBusy2!=0 );
70614
+ if( rc==SQLITE_OK ){
70615
+ pWal->ckptLock = 1;
70616
+
70617
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART
70618
+ ** and TRUNCATE modes also obtain the exclusive "writer" lock on the
70619
+ ** database file.
70620
+ **
70621
+ ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
70622
+ ** immediately, and a busy-handler is configured, it is invoked and the
70623
+ ** writer lock retried until either the busy-handler returns 0 or the
70624
+ ** lock is successfully obtained.
70625
+ */
70626
+ if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
70627
+ rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
70628
+ if( rc==SQLITE_OK ){
70629
+ pWal->writeLock = 1;
70630
+ }else if( rc==SQLITE_BUSY ){
70631
+ eMode2 = SQLITE_CHECKPOINT_PASSIVE;
70632
+ xBusy2 = 0;
70633
+ rc = SQLITE_OK;
70634
+ }
70635
+ }
70636
+ }
70637
+ }else{
70638
+ rc = SQLITE_OK;
7040070639
}
7040170640
7040270641
7040370642
/* Read the wal-index header. */
7040470643
SEH_TRY {
@@ -70408,21 +70647,21 @@
7040870647
** or invoke the busy handler. The only lock such a checkpoint may
7040970648
** attempt to obtain is a lock on a read-slot, and it should give up
7041070649
** immediately and do a partial checkpoint if it cannot obtain it. */
7041170650
walDisableBlocking(pWal);
7041270651
rc = walIndexReadHdr(pWal, &isChanged);
70413
- if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
70652
+ if( eMode2>SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
7041470653
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
7041570654
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
7041670655
}
7041770656
}
7041870657
7041970658
/* Copy data from the log to the database file. */
7042070659
if( rc==SQLITE_OK ){
7042170660
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
7042270661
rc = SQLITE_CORRUPT_BKPT;
70423
- }else{
70662
+ }else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){
7042470663
rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf);
7042570664
}
7042670665
7042770666
/* If no error occurred, set the output variables. */
7042870667
if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
@@ -91645,11 +91884,11 @@
9164591884
9164691885
preupdate.v = v;
9164791886
preupdate.pCsr = pCsr;
9164891887
preupdate.op = op;
9164991888
preupdate.iNewReg = iReg;
91650
- preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace;
91889
+ preupdate.pKeyinfo = &preupdate.uKey.sKey;
9165191890
preupdate.pKeyinfo->db = db;
9165291891
preupdate.pKeyinfo->enc = ENC(db);
9165391892
preupdate.pKeyinfo->nKeyField = pTab->nCol;
9165491893
preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */
9165591894
preupdate.iKey1 = iKey1;
@@ -102528,10 +102767,11 @@
102528102767
aRes[1] = aRes[2] = -1;
102529102768
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
102530102769
|| pOp->p2==SQLITE_CHECKPOINT_FULL
102531102770
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
102532102771
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
102772
+ || pOp->p2==SQLITE_CHECKPOINT_NOOP
102533102773
);
102534102774
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
102535102775
if( rc ){
102536102776
if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
102537102777
rc = SQLITE_OK;
@@ -110651,18 +110891,21 @@
110651110891
ExprList *pList /* Expression list to resolve. May be NULL. */
110652110892
){
110653110893
SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */
110654110894
NameContext sNC; /* Name context for pParse->pNewTable */
110655110895
int rc;
110656
- u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */
110896
+ union {
110897
+ SrcList sSrc;
110898
+ u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */
110899
+ } uSrc;
110657110900
110658110901
assert( type==0 || pTab!=0 );
110659110902
assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
110660110903
|| type==NC_GenCol || pTab==0 );
110661110904
memset(&sNC, 0, sizeof(sNC));
110662
- pSrc = (SrcList*)srcSpace;
110663
- memset(pSrc, 0, SZ_SRCLIST_1);
110905
+ memset(&uSrc, 0, sizeof(uSrc));
110906
+ pSrc = &uSrc.sSrc;
110664110907
if( pTab ){
110665110908
pSrc->nSrc = 1;
110666110909
pSrc->a[0].zName = pTab->zName;
110667110910
pSrc->a[0].pSTab = pTab;
110668110911
pSrc->a[0].iCursor = -1;
@@ -111921,10 +112164,15 @@
111921112164
if( IsWindowFunc(pExpr) ){
111922112165
sqlite3ExprOrderByAggregateError(pParse, pExpr);
111923112166
sqlite3ExprListDelete(db, pOrderBy);
111924112167
return;
111925112168
}
112169
+ if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
112170
+ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
112171
+ sqlite3ExprListDelete(db, pOrderBy);
112172
+ return;
112173
+ }
111926112174
111927112175
pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0);
111928112176
if( pOB==0 ){
111929112177
sqlite3ExprListDelete(db, pOrderBy);
111930112178
return;
@@ -113117,13 +113365,12 @@
113117113365
}
113118113366
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1);
113119113367
if( addrIsNull==0 ){
113120113368
/*
113121113369
** If the right operand contains a subquery and the left operand does not
113122
- ** and the left operand might be NULL, then check the left operand do
113123
- ** an IsNull check on the left operand before computing the right
113124
- ** operand.
113370
+ ** and the left operand might be NULL, then do an IsNull check
113371
+ ** check on the left operand before computing the right operand.
113125113372
*/
113126113373
if( ExprHasProperty(pExpr->pRight, EP_Subquery)
113127113374
&& sqlite3ExprCanBeNull(pExpr->pLeft)
113128113375
){
113129113376
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1);
@@ -114683,11 +114930,10 @@
114683114930
int destIfNull /* Jump here if the results are unknown due to NULLs */
114684114931
){
114685114932
int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
114686114933
int eType; /* Type of the RHS */
114687114934
int rLhs; /* Register(s) holding the LHS values */
114688
- int rLhsOrig; /* LHS values prior to reordering by aiMap[] */
114689114935
Vdbe *v; /* Statement under construction */
114690114936
int *aiMap = 0; /* Map from vector field to index column */
114691114937
char *zAff = 0; /* Affinity string for comparisons */
114692114938
int nVector; /* Size of vectors for this IN operator */
114693114939
int iDummy; /* Dummy parameter to exprCodeVector() */
@@ -114746,23 +114992,12 @@
114746114992
** Avoid factoring the LHS of the IN(...) expression out of the loop,
114747114993
** even if it is constant, as OP_Affinity may be used on the register
114748114994
** by code generated below. */
114749114995
assert( pParse->okConstFactor==okConstFactor );
114750114996
pParse->okConstFactor = 0;
114751
- rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
114997
+ rLhs = exprCodeVector(pParse, pLeft, &iDummy);
114752114998
pParse->okConstFactor = okConstFactor;
114753
- for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
114754
- if( i==nVector ){
114755
- /* LHS fields are not reordered */
114756
- rLhs = rLhsOrig;
114757
- }else{
114758
- /* Need to reorder the LHS fields according to aiMap */
114759
- rLhs = sqlite3GetTempRange(pParse, nVector);
114760
- for(i=0; i<nVector; i++){
114761
- sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
114762
- }
114763
- }
114764114999
114765115000
/* If sqlite3FindInIndex() did not find or create an index that is
114766115001
** suitable for evaluating the IN operator, then evaluate using a
114767115002
** sequence of comparisons.
114768115003
**
@@ -114773,10 +115008,11 @@
114773115008
CollSeq *pColl;
114774115009
int labelOk = sqlite3VdbeMakeLabel(pParse);
114775115010
int r2, regToFree;
114776115011
int regCkNull = 0;
114777115012
int ii;
115013
+ assert( nVector==1 );
114778115014
assert( ExprUseXList(pExpr) );
114779115015
pList = pExpr->x.pList;
114780115016
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
114781115017
if( destIfNull!=destIfFalse ){
114782115018
regCkNull = sqlite3GetTempReg(pParse);
@@ -114813,10 +115049,30 @@
114813115049
}
114814115050
sqlite3VdbeResolveLabel(v, labelOk);
114815115051
sqlite3ReleaseTempReg(pParse, regCkNull);
114816115052
goto sqlite3ExprCodeIN_finished;
114817115053
}
115054
+
115055
+ if( eType!=IN_INDEX_ROWID ){
115056
+ /* If this IN operator will use an index, then the order of columns in the
115057
+ ** vector might be different from the order in the index. In that case,
115058
+ ** we need to reorder the LHS values to be in index order. Run Affinity
115059
+ ** before reordering the columns, so that the affinity is correct.
115060
+ */
115061
+ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
115062
+ for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
115063
+ if( i!=nVector ){
115064
+ /* Need to reorder the LHS fields according to aiMap */
115065
+ int rLhsOrig = rLhs;
115066
+ rLhs = sqlite3GetTempRange(pParse, nVector);
115067
+ for(i=0; i<nVector; i++){
115068
+ sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
115069
+ }
115070
+ sqlite3ReleaseTempReg(pParse, rLhsOrig);
115071
+ }
115072
+ }
115073
+
114818115074
114819115075
/* Step 2: Check to see if the LHS contains any NULL columns. If the
114820115076
** LHS does contain NULLs then the result must be either FALSE or NULL.
114821115077
** We will then skip the binary search of the RHS.
114822115078
*/
@@ -114840,15 +115096,15 @@
114840115096
*/
114841115097
if( eType==IN_INDEX_ROWID ){
114842115098
/* In this case, the RHS is the ROWID of table b-tree and so we also
114843115099
** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
114844115100
** into a single opcode. */
115101
+ assert( nVector==1 );
114845115102
sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
114846115103
VdbeCoverage(v);
114847115104
addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
114848115105
}else{
114849
- sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
114850115106
if( destIfFalse==destIfNull ){
114851115107
/* Combine Step 3 and Step 5 into a single opcode */
114852115108
if( ExprHasProperty(pExpr, EP_Subrtn) ){
114853115109
const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
114854115110
assert( pOp->opcode==OP_Once || pParse->nErr );
@@ -114922,11 +115178,10 @@
114922115178
114923115179
/* Jumps here in order to return true. */
114924115180
sqlite3VdbeJumpHere(v, addrTruthOp);
114925115181
114926115182
sqlite3ExprCodeIN_finished:
114927
- if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
114928115183
VdbeComment((v, "end IN expr"));
114929115184
sqlite3ExprCodeIN_oom_error:
114930115185
sqlite3DbFree(pParse->db, aiMap);
114931115186
sqlite3DbFree(pParse->db, zAff);
114932115187
}
@@ -115480,10 +115735,82 @@
115480115735
}
115481115736
}
115482115737
return 0;
115483115738
}
115484115739
115740
+/*
115741
+** Generate code that evaluates an AND or OR operator leaving a
115742
+** boolean result in a register. pExpr is the AND/OR expression.
115743
+** Store the result in the "target" register. Use short-circuit
115744
+** evaluation to avoid computing both operands, if possible.
115745
+**
115746
+** The code generated might require the use of a temporary register.
115747
+** If it does, then write the number of that temporary register
115748
+** into *pTmpReg. If not, leave *pTmpReg unchanged.
115749
+*/
115750
+static SQLITE_NOINLINE int exprCodeTargetAndOr(
115751
+ Parse *pParse, /* Parsing context */
115752
+ Expr *pExpr, /* AND or OR expression to be coded */
115753
+ int target, /* Put result in this register, guaranteed */
115754
+ int *pTmpReg /* Write a temporary register here */
115755
+){
115756
+ int op; /* The opcode. TK_AND or TK_OR */
115757
+ int skipOp; /* Opcode for the branch that skips one operand */
115758
+ int addrSkip; /* Branch instruction that skips one of the operands */
115759
+ int regSS = 0; /* Register holding computed operand when other omitted */
115760
+ int r1, r2; /* Registers for left and right operands, respectively */
115761
+ Expr *pAlt; /* Alternative, simplified expression */
115762
+ Vdbe *v; /* statement being coded */
115763
+
115764
+ assert( pExpr!=0 );
115765
+ op = pExpr->op;
115766
+ assert( op==TK_AND || op==TK_OR );
115767
+ assert( TK_AND==OP_And ); testcase( op==TK_AND );
115768
+ assert( TK_OR==OP_Or ); testcase( op==TK_OR );
115769
+ pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
115770
+ if( pAlt!=pExpr ){
115771
+ return sqlite3ExprCodeTarget(pParse, pAlt, target);
115772
+ }
115773
+ assert( pParse->pVdbe!=0 );
115774
+ v = pParse->pVdbe;
115775
+ skipOp = op==TK_AND ? OP_IfNot : OP_If;
115776
+ if( exprEvalRhsFirst(pExpr) ){
115777
+ /* Compute the right operand first. Skip the computation of the left
115778
+ ** operand if the right operand fully determines the result */
115779
+ r2 = regSS = sqlite3ExprCodeTarget(pParse, pExpr->pRight, target);
115780
+ addrSkip = sqlite3VdbeAddOp1(v, skipOp, r2);
115781
+ VdbeComment((v, "skip left operand"));
115782
+ VdbeCoverage(v);
115783
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pTmpReg);
115784
+ }else{
115785
+ /* Compute the left operand first */
115786
+ r1 = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
115787
+ if( ExprHasProperty(pExpr->pRight, EP_Subquery) ){
115788
+ /* Skip over the computation of the right operand if the right
115789
+ ** operand is a subquery and the left operand completely determines
115790
+ ** the result */
115791
+ regSS = r1;
115792
+ addrSkip = sqlite3VdbeAddOp1(v, skipOp, r1);
115793
+ VdbeComment((v, "skip right operand"));
115794
+ VdbeCoverage(v);
115795
+ }else{
115796
+ addrSkip = regSS = 0;
115797
+ }
115798
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pTmpReg);
115799
+ }
115800
+ sqlite3VdbeAddOp3(v, op, r2, r1, target);
115801
+ testcase( (*pTmpReg)==0 );
115802
+ if( addrSkip ){
115803
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
115804
+ sqlite3VdbeJumpHere(v, addrSkip);
115805
+ sqlite3VdbeAddOp3(v, OP_Or, regSS, regSS, target);
115806
+ VdbeComment((v, "short-circut value"));
115807
+ }
115808
+ return target;
115809
+}
115810
+
115811
+
115485115812
115486115813
/*
115487115814
** Generate code into the current Vdbe to evaluate the given
115488115815
** expression. Attempt to store the results in register "target".
115489115816
** Return the register where results are stored.
@@ -115768,16 +116095,18 @@
115768116095
sqlite3VdbeAddOp2(v, OP_Null, 0, inReg);
115769116096
}
115770116097
}
115771116098
testcase( regFree1==0 );
115772116099
testcase( regFree2==0 );
115773
-
115774116100
}
115775116101
break;
115776116102
}
115777116103
case TK_AND:
115778
- case TK_OR:
116104
+ case TK_OR: {
116105
+ inReg = exprCodeTargetAndOr(pParse, pExpr, target, &regFree1);
116106
+ break;
116107
+ }
115779116108
case TK_PLUS:
115780116109
case TK_STAR:
115781116110
case TK_MINUS:
115782116111
case TK_REM:
115783116112
case TK_BITAND:
@@ -115785,12 +116114,10 @@
115785116114
case TK_SLASH:
115786116115
case TK_LSHIFT:
115787116116
case TK_RSHIFT:
115788116117
case TK_CONCAT: {
115789116118
int addrIsNull;
115790
- assert( TK_AND==OP_And ); testcase( op==TK_AND );
115791
- assert( TK_OR==OP_Or ); testcase( op==TK_OR );
115792116119
assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
115793116120
assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
115794116121
assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
115795116122
assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
115796116123
assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
@@ -124573,11 +124900,11 @@
124573124900
*/
124574124901
SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
124575124902
int i;
124576124903
i16 iCol16;
124577124904
assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
124578
- assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 );
124905
+ assert( pIdx->nColumn<=SQLITE_MAX_COLUMN*2 );
124579124906
iCol16 = iCol;
124580124907
for(i=0; i<pIdx->nColumn; i++){
124581124908
if( iCol16==pIdx->aiColumn[i] ){
124582124909
return i;
124583124910
}
@@ -124870,10 +125197,13 @@
124870125197
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
124871125198
sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
124872125199
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
124873125200
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
124874125201
sqlite3VdbeAddOp0(v, OP_Close);
125202
+ }else if( db->init.imposterTable ){
125203
+ pTable->tabFlags |= TF_Imposter;
125204
+ if( db->init.imposterTable>=2 ) pTable->tabFlags |= TF_Readonly;
124875125205
}
124876125206
124877125207
/* Normal (non-error) return. */
124878125208
return;
124879125209
@@ -129165,18 +129495,23 @@
129165129495
pKey->aSortFlags[i] = pIdx->aSortOrder[i];
129166129496
assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
129167129497
}
129168129498
if( pParse->nErr ){
129169129499
assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
129170
- if( pIdx->bNoQuery==0 ){
129500
+ if( pIdx->bNoQuery==0
129501
+ && sqlite3HashFind(&pIdx->pSchema->idxHash, pIdx->zName)
129502
+ ){
129171129503
/* Deactivate the index because it contains an unknown collating
129172129504
** sequence. The only way to reactive the index is to reload the
129173129505
** schema. Adding the missing collating sequence later does not
129174129506
** reactive the index. The application had the chance to register
129175129507
** the missing index using the collation-needed callback. For
129176129508
** simplicity, SQLite will not give the application a second chance.
129177
- */
129509
+ **
129510
+ ** Except, do not do this if the index is not in the schema hash
129511
+ ** table. In this case the index is currently being constructed
129512
+ ** by a CREATE INDEX statement, and retrying will not help. */
129178129513
pIdx->bNoQuery = 1;
129179129514
pParse->rc = SQLITE_ERROR_RETRY;
129180129515
}
129181129516
sqlite3KeyInfoUnref(pKey);
129182129517
pKey = 0;
@@ -139247,10 +139582,12 @@
139247139582
/* Version 3.44.0 and later */
139248139583
void *(*get_clientdata)(sqlite3*,const char*);
139249139584
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
139250139585
/* Version 3.50.0 and later */
139251139586
int (*setlk_timeout)(sqlite3*,int,int);
139587
+ /* Version 3.51.0 and later */
139588
+ int (*set_errmsg)(sqlite3*,int,const char*);
139252139589
};
139253139590
139254139591
/*
139255139592
** This is the function signature used for all extension entry points. It
139256139593
** is also defined in the file "loadext.c".
@@ -139582,10 +139919,12 @@
139582139919
/* Version 3.44.0 and later */
139583139920
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
139584139921
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
139585139922
/* Version 3.50.0 and later */
139586139923
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
139924
+/* Version 3.51.0 and later */
139925
+#define sqlite3_set_errmsg sqlite3_api->set_errmsg
139587139926
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
139588139927
139589139928
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
139590139929
/* This case when the file really is being compiled as a loadable
139591139930
** extension */
@@ -140105,11 +140444,13 @@
140105140444
sqlite3_stmt_explain,
140106140445
/* Version 3.44.0 and later */
140107140446
sqlite3_get_clientdata,
140108140447
sqlite3_set_clientdata,
140109140448
/* Version 3.50.0 and later */
140110
- sqlite3_setlk_timeout
140449
+ sqlite3_setlk_timeout,
140450
+ /* Version 3.51.0 and later */
140451
+ sqlite3_set_errmsg
140111140452
};
140112140453
140113140454
/* True if x is the directory separator character
140114140455
*/
140115140456
#if SQLITE_OS_WIN
@@ -141566,10 +141907,26 @@
141566141907
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
141567141908
VdbeCoverage(v);
141568141909
sqlite3VdbeAddOp0(v, OP_Halt);
141569141910
return addr;
141570141911
}
141912
+
141913
+/*
141914
+** Should table pTab be skipped when doing an integrity_check?
141915
+** Return true or false.
141916
+**
141917
+** If pObjTab is not null, the return true if pTab matches pObjTab.
141918
+**
141919
+** If pObjTab is null, then return true only if pTab is an imposter table.
141920
+*/
141921
+static int tableSkipIntegrityCheck(const Table *pTab, const Table *pObjTab){
141922
+ if( pObjTab ){
141923
+ return pTab!=pObjTab;
141924
+ }else{
141925
+ return (pTab->tabFlags & TF_Imposter)!=0;
141926
+ }
141927
+}
141571141928
141572141929
/*
141573141930
** Process a pragma statement.
141574141931
**
141575141932
** Pragmas are of this form:
@@ -142912,11 +143269,11 @@
142912143269
pTbls = &db->aDb[i].pSchema->tblHash;
142913143270
for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142914143271
Table *pTab = sqliteHashData(x); /* Current table */
142915143272
Index *pIdx; /* An index on pTab */
142916143273
int nIdx; /* Number of indexes on pTab */
142917
- if( pObjTab && pObjTab!=pTab ) continue;
143274
+ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
142918143275
if( HasRowid(pTab) ) cnt++;
142919143276
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
142920143277
}
142921143278
if( cnt==0 ) continue;
142922143279
if( pObjTab ) cnt++;
@@ -142925,11 +143282,11 @@
142925143282
cnt = 0;
142926143283
if( pObjTab ) aRoot[++cnt] = 0;
142927143284
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142928143285
Table *pTab = sqliteHashData(x);
142929143286
Index *pIdx;
142930
- if( pObjTab && pObjTab!=pTab ) continue;
143287
+ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
142931143288
if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
142932143289
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
142933143290
aRoot[++cnt] = pIdx->tnum;
142934143291
}
142935143292
}
@@ -142956,11 +143313,11 @@
142956143313
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
142957143314
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142958143315
int iTab = 0;
142959143316
Table *pTab = sqliteHashData(x);
142960143317
Index *pIdx;
142961
- if( pObjTab && pObjTab!=pTab ) continue;
143318
+ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
142962143319
if( HasRowid(pTab) ){
142963143320
iTab = cnt++;
142964143321
}else{
142965143322
iTab = cnt;
142966143323
for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){
@@ -142992,11 +143349,11 @@
142992143349
int r1 = -1;
142993143350
int bStrict; /* True for a STRICT table */
142994143351
int r2; /* Previous key for WITHOUT ROWID tables */
142995143352
int mxCol; /* Maximum non-virtual column number */
142996143353
142997
- if( pObjTab && pObjTab!=pTab ) continue;
143354
+ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
142998143355
if( !IsOrdinaryTable(pTab) ) continue;
142999143356
if( isQuick || HasRowid(pTab) ){
143000143357
pPk = 0;
143001143358
r2 = 0;
143002143359
}else{
@@ -143316,11 +143673,11 @@
143316143673
*/
143317143674
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143318143675
Table *pTab = sqliteHashData(x);
143319143676
sqlite3_vtab *pVTab;
143320143677
int a1;
143321
- if( pObjTab && pObjTab!=pTab ) continue;
143678
+ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143322143679
if( IsOrdinaryTable(pTab) ) continue;
143323143680
if( !IsVirtual(pTab) ) continue;
143324143681
if( pTab->nCol<=0 ){
143325143682
const char *zMod = pTab->u.vtab.azArg[0];
143326143683
if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
@@ -143548,10 +143905,12 @@
143548143905
eMode = SQLITE_CHECKPOINT_FULL;
143549143906
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
143550143907
eMode = SQLITE_CHECKPOINT_RESTART;
143551143908
}else if( sqlite3StrICmp(zRight, "truncate")==0 ){
143552143909
eMode = SQLITE_CHECKPOINT_TRUNCATE;
143910
+ }else if( sqlite3StrICmp(zRight, "noop")==0 ){
143911
+ eMode = SQLITE_CHECKPOINT_NOOP;
143553143912
}
143554143913
}
143555143914
pParse->nMem = 3;
143556143915
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
143557143916
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
@@ -145114,13 +145473,15 @@
145114145473
** or encounters a permanent error. A schema problem after one schema
145115145474
** reset is considered a permanent error. */
145116145475
rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
145117145476
assert( rc==SQLITE_OK || *ppStmt==0 );
145118145477
if( rc==SQLITE_OK || db->mallocFailed ) break;
145119
- }while( (rc==SQLITE_ERROR_RETRY && (cnt++)<SQLITE_MAX_PREPARE_RETRY)
145120
- || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
145478
+ cnt++;
145479
+ }while( (rc==SQLITE_ERROR_RETRY && ALWAYS(cnt<=SQLITE_MAX_PREPARE_RETRY))
145480
+ || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt)==1) );
145121145481
sqlite3BtreeLeaveAll(db);
145482
+ assert( rc!=SQLITE_ERROR_RETRY );
145122145483
rc = sqlite3ApiExit(db, rc);
145123145484
assert( (rc&db->errMask)==rc );
145124145485
db->busyHandler.nBusy = 0;
145125145486
sqlite3_mutex_leave(db->mutex);
145126145487
assert( rc==SQLITE_OK || (*ppStmt)==0 );
@@ -145790,12 +146151,11 @@
145790146151
while( p ){
145791146152
ExprSetProperty(p, joinFlag);
145792146153
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
145793146154
ExprSetVVAProperty(p, EP_NoReduce);
145794146155
p->w.iJoin = iTable;
145795
- if( p->op==TK_FUNCTION ){
145796
- assert( ExprUseXList(p) );
146156
+ if( ExprUseXList(p) ){
145797146157
if( p->x.pList ){
145798146158
int i;
145799146159
for(i=0; i<p->x.pList->nExpr; i++){
145800146160
sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
145801146161
}
@@ -146007,10 +146367,11 @@
146007146367
else if( pRight->u3.pOn ){
146008146368
sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
146009146369
p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
146010146370
pRight->u3.pOn = 0;
146011146371
pRight->fg.isOn = 1;
146372
+ p->selFlags |= SF_OnToWhere;
146012146373
}
146013146374
}
146014146375
return 0;
146015146376
}
146016146377
@@ -146893,11 +147254,14 @@
146893147254
** Allocate a KeyInfo object sufficient for an index of N key columns and
146894147255
** X extra columns.
146895147256
*/
146896147257
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
146897147258
int nExtra = (N+X)*(sizeof(CollSeq*)+1);
146898
- KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra);
147259
+ KeyInfo *p;
147260
+ assert( X>=0 );
147261
+ if( NEVER(N+X>0xffff) ) return (KeyInfo*)sqlite3OomFault(db);
147262
+ p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra);
146899147263
if( p ){
146900147264
p->aSortFlags = (u8*)&p->aColl[N+X];
146901147265
p->nKeyField = (u16)N;
146902147266
p->nAllField = (u16)(N+X);
146903147267
p->enc = ENC(db);
@@ -149212,11 +149576,11 @@
149212149576
** expressions in pEList.
149213149577
**
149214149578
** ## About "isOuterJoin":
149215149579
**
149216149580
** The isOuterJoin column indicates that the replacement will occur into a
149217
-** position in the parent that NULL-able due to an OUTER JOIN. Either the
149581
+** position in the parent that is NULL-able due to an OUTER JOIN. Either the
149218149582
** target slot in the parent is the right operand of a LEFT JOIN, or one of
149219149583
** the left operands of a RIGHT JOIN. In either case, we need to potentially
149220149584
** bypass the substituted expression with OP_IfNullRow.
149221149585
**
149222149586
** Suppose the original expression is an integer constant. Even though the table
@@ -150050,21 +150414,16 @@
150050150414
** elements we are now copying in.
150051150415
*/
150052150416
pSub = pSub1;
150053150417
for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
150054150418
int nSubSrc;
150055
- u8 jointype = 0;
150056
- u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ;
150419
+ u8 jointype = pSubitem->fg.jointype;
150057150420
assert( pSub!=0 );
150058150421
pSubSrc = pSub->pSrc; /* FROM clause of subquery */
150059150422
nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
150060150423
pSrc = pParent->pSrc; /* FROM clause of the outer query */
150061150424
150062
- if( pParent==p ){
150063
- jointype = pSubitem->fg.jointype; /* First time through the loop */
150064
- }
150065
-
150066150425
/* The subquery uses a single slot of the FROM clause of the outer
150067150426
** query. If the subquery has more than one element in its FROM clause,
150068150427
** then expand the outer query to make space for it to hold all elements
150069150428
** of the subquery.
150070150429
**
@@ -150080,10 +150439,11 @@
150080150439
*/
150081150440
if( nSubSrc>1 ){
150082150441
pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
150083150442
if( pSrc==0 ) break;
150084150443
pParent->pSrc = pSrc;
150444
+ pSubitem = &pSrc->a[iFrom];
150085150445
}
150086150446
150087150447
/* Transfer the FROM clause terms from the subquery into the
150088150448
** outer query.
150089150449
*/
@@ -150094,15 +150454,14 @@
150094150454
assert( pItem->fg.isSubquery
150095150455
|| pItem->fg.fixedSchema
150096150456
|| pItem->u4.zDatabase==0 );
150097150457
if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
150098150458
*pItem = pSubSrc->a[i];
150099
- pItem->fg.jointype |= ltorj;
150459
+ pItem->fg.jointype |= (jointype & JT_LTORJ);
150100150460
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
150101150461
}
150102
- pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
150103
- pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
150462
+ pSubitem->fg.jointype |= jointype;
150104150463
150105150464
/* Now begin substituting subquery result set expressions for
150106150465
** references to the iParent in the outer query.
150107150466
**
150108150467
** Example:
@@ -152838,10 +153197,119 @@
152838153197
existsToJoin(pParse, p, pSubWhere);
152839153198
}
152840153199
}
152841153200
}
152842153201
}
153202
+
153203
+/*
153204
+** Type used for Walker callbacks by selectCheckOnClauses().
153205
+*/
153206
+typedef struct CheckOnCtx CheckOnCtx;
153207
+struct CheckOnCtx {
153208
+ SrcList *pSrc; /* SrcList for this context */
153209
+ int iJoin; /* Cursor numbers must be =< than this */
153210
+ CheckOnCtx *pParent; /* Parent context */
153211
+};
153212
+
153213
+/*
153214
+** True if the SrcList passed as the only argument contains at least
153215
+** one RIGHT or FULL JOIN. False otherwise.
153216
+*/
153217
+#define hasRightJoin(pSrc) (((pSrc)->a[0].fg.jointype & JT_LTORJ)!=0)
153218
+
153219
+/*
153220
+** The xExpr callback for the search of invalid ON clause terms.
153221
+*/
153222
+static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){
153223
+ CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx;
153224
+
153225
+ /* Check if pExpr is root or near-root of an ON clause constraint that needs
153226
+ ** to be checked to ensure that it does not refer to tables in its FROM
153227
+ ** clause to the right of itself. i.e. it is either:
153228
+ **
153229
+ ** + an ON clause on an OUTER join, or
153230
+ ** + an ON clause on an INNER join within a FROM that features at
153231
+ ** least one RIGHT or FULL join.
153232
+ */
153233
+ if( (ExprHasProperty(pExpr, EP_OuterON))
153234
+ || (ExprHasProperty(pExpr, EP_InnerON) && hasRightJoin(pCtx->pSrc))
153235
+ ){
153236
+ /* If CheckOnCtx.iJoin is already set, then fall through and process
153237
+ ** this expression node as normal. Or, if CheckOnCtx.iJoin is still 0,
153238
+ ** set it to the cursor number of the RHS of the join to which this
153239
+ ** ON expression was attached and then iterate through the entire
153240
+ ** expression. */
153241
+ assert( pCtx->iJoin==0 || pCtx->iJoin==pExpr->w.iJoin );
153242
+ if( pCtx->iJoin==0 ){
153243
+ pCtx->iJoin = pExpr->w.iJoin;
153244
+ sqlite3WalkExprNN(pWalker, pExpr);
153245
+ pCtx->iJoin = 0;
153246
+ return WRC_Prune;
153247
+ }
153248
+ }
153249
+
153250
+ if( pExpr->op==TK_COLUMN ){
153251
+ /* A column expression. Find the SrcList (if any) to which it refers.
153252
+ ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
153253
+ ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
153254
+ ** does not refer to a table to the right of CheckOnCtx.iJoin. */
153255
+ do {
153256
+ SrcList *pSrc = pCtx->pSrc;
153257
+ int iTab = pExpr->iTable;
153258
+ if( iTab>=pSrc->a[0].iCursor && iTab<=pSrc->a[pSrc->nSrc-1].iCursor ){
153259
+ if( pCtx->iJoin && iTab>pCtx->iJoin ){
153260
+ sqlite3ErrorMsg(pWalker->pParse,
153261
+ "ON clause references tables to its right");
153262
+ return WRC_Abort;
153263
+ }
153264
+ break;
153265
+ }
153266
+ pCtx = pCtx->pParent;
153267
+ }while( pCtx );
153268
+ }
153269
+ return WRC_Continue;
153270
+}
153271
+
153272
+/*
153273
+** The xSelect callback for the search of invalid ON clause terms.
153274
+*/
153275
+static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){
153276
+ CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx;
153277
+ if( pSelect->pSrc==pCtx->pSrc || pSelect->pSrc->nSrc==0 ){
153278
+ return WRC_Continue;
153279
+ }else{
153280
+ CheckOnCtx sCtx;
153281
+ memset(&sCtx, 0, sizeof(sCtx));
153282
+ sCtx.pSrc = pSelect->pSrc;
153283
+ sCtx.pParent = pCtx;
153284
+ pWalker->u.pCheckOnCtx = &sCtx;
153285
+ sqlite3WalkSelect(pWalker, pSelect);
153286
+ pWalker->u.pCheckOnCtx = pCtx;
153287
+ pSelect->selFlags &= ~SF_OnToWhere;
153288
+ return WRC_Prune;
153289
+ }
153290
+}
153291
+
153292
+/*
153293
+** Check all ON clauses in pSelect to verify that they do not reference
153294
+** columns to the right.
153295
+*/
153296
+static void selectCheckOnClauses(Parse *pParse, Select *pSelect){
153297
+ Walker w;
153298
+ CheckOnCtx sCtx;
153299
+ assert( pSelect->selFlags & SF_OnToWhere );
153300
+ assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 );
153301
+ memset(&w, 0, sizeof(w));
153302
+ w.pParse = pParse;
153303
+ w.xExprCallback = selectCheckOnClausesExpr;
153304
+ w.xSelectCallback = selectCheckOnClausesSelect;
153305
+ w.u.pCheckOnCtx = &sCtx;
153306
+ memset(&sCtx, 0, sizeof(sCtx));
153307
+ sCtx.pSrc = pSelect->pSrc;
153308
+ sqlite3WalkExprNN(&w, pSelect->pWhere);
153309
+ pSelect->selFlags &= ~SF_OnToWhere;
153310
+}
152843153311
152844153312
/*
152845153313
** Generate byte-code for the SELECT statement given in the p argument.
152846153314
**
152847153315
** The results are returned according to the SelectDest structure.
@@ -152965,10 +153433,22 @@
152965153433
if( sqlite3TreeTrace & 0x10 ){
152966153434
TREETRACE(0x10,pParse,p, ("after name resolution:\n"));
152967153435
sqlite3TreeViewSelect(0, p, 0);
152968153436
}
152969153437
#endif
153438
+
153439
+ /* If the SELECT statement contains ON clauses that were moved into
153440
+ ** the WHERE clause, go through and verify that none of the terms
153441
+ ** in the ON clauses reference tables to the right of the ON clause.
153442
+ ** Do this now, after name resolution, but before query flattening
153443
+ */
153444
+ if( p->selFlags & SF_OnToWhere ){
153445
+ selectCheckOnClauses(pParse, p);
153446
+ if( pParse->nErr ){
153447
+ goto select_end;
153448
+ }
153449
+ }
152970153450
152971153451
/* If the SF_UFSrcCheck flag is set, then this function is being called
152972153452
** as part of populating the temp table for an UPDATE...FROM statement.
152973153453
** In this case, it is an error if the target object (pSrc->a[0]) name
152974153454
** or alias is duplicated within FROM clause (pSrc->a[1..n]).
@@ -155531,11 +156011,14 @@
155531156011
sqlite3 *db = pParse->db;
155532156012
ExprList *pNew;
155533156013
Returning *pReturning;
155534156014
Select sSelect;
155535156015
SrcList *pFrom;
155536
- u8 fromSpace[SZ_SRCLIST_1];
156016
+ union {
156017
+ SrcList sSrc;
156018
+ u8 fromSpace[SZ_SRCLIST_1];
156019
+ } uSrc;
155537156020
155538156021
assert( v!=0 );
155539156022
if( !pParse->bReturning ){
155540156023
/* This RETURNING trigger must be for a different statement as
155541156024
** this statement lacks a RETURNING clause. */
@@ -155547,12 +156030,12 @@
155547156030
if( pTrigger != &(pReturning->retTrig) ){
155548156031
/* This RETURNING trigger is for a different statement */
155549156032
return;
155550156033
}
155551156034
memset(&sSelect, 0, sizeof(sSelect));
155552
- pFrom = (SrcList*)fromSpace;
155553
- memset(pFrom, 0, SZ_SRCLIST_1);
156035
+ memset(&uSrc, 0, sizeof(uSrc));
156036
+ pFrom = &uSrc.sSrc;
155554156037
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
155555156038
sSelect.pSrc = pFrom;
155556156039
pFrom->nSrc = 1;
155557156040
pFrom->a[0].pSTab = pTab;
155558156041
pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */
@@ -163079,11 +163562,14 @@
163079163562
WhereClause *pWC = &pWInfo->sWC;
163080163563
WhereInfo *pSubWInfo;
163081163564
WhereLoop *pLoop = pLevel->pWLoop;
163082163565
SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
163083163566
SrcList *pFrom;
163084
- u8 fromSpace[SZ_SRCLIST_1];
163567
+ union {
163568
+ SrcList sSrc;
163569
+ u8 fromSpace[SZ_SRCLIST_1];
163570
+ } uSrc;
163085163571
Bitmask mAll = 0;
163086163572
int k;
163087163573
163088163574
ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
163089163575
sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
@@ -163123,11 +163609,11 @@
163123163609
if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
163124163610
pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
163125163611
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
163126163612
}
163127163613
}
163128
- pFrom = (SrcList*)fromSpace;
163614
+ pFrom = &uSrc.sSrc;
163129163615
pFrom->nSrc = 1;
163130163616
pFrom->nAlloc = 1;
163131163617
memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem));
163132163618
pFrom->a[0].fg.jointype = 0;
163133163619
assert( pParse->withinRJSubrtn < 100 );
@@ -164340,25 +164826,11 @@
164340164826
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
164341164827
if( ExprHasProperty(pExpr, EP_OuterON) ){
164342164828
prereqAll |= x;
164343164829
extraRight = x-1; /* ON clause terms may not be used with an index
164344164830
** on left table of a LEFT JOIN. Ticket #3015 */
164345
- if( (prereqAll>>1)>=x ){
164346
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
164347
- return;
164348
- }
164349164831
}else if( (prereqAll>>1)>=x ){
164350
- /* The ON clause of an INNER JOIN references a table to its right.
164351
- ** Most other SQL database engines raise an error. But SQLite versions
164352
- ** 3.0 through 3.38 just put the ON clause constraint into the WHERE
164353
- ** clause and carried on. Beginning with 3.39, raise an error only
164354
- ** if there is a RIGHT or FULL JOIN in the query. This makes SQLite
164355
- ** more like other systems, and also preserves legacy. */
164356
- if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
164357
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
164358
- return;
164359
- }
164360164832
ExprClearProperty(pExpr, EP_InnerON);
164361164833
}
164362164834
}
164363164835
pTerm->prereqAll = prereqAll;
164364164836
pTerm->leftCursor = -1;
@@ -170216,10 +170688,14 @@
170216170688
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
170217170689
if( pLoop->u.vtab.isOrdered
170218170690
&& ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
170219170691
){
170220170692
obSat = obDone;
170693
+ }else{
170694
+ /* No further ORDER BY terms may be matched. So this call should
170695
+ ** return >=0, not -1. Clear isOrderDistinct to ensure it does so. */
170696
+ isOrderDistinct = 0;
170221170697
}
170222170698
break;
170223170699
}
170224170700
iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
170225170701
@@ -171119,22 +171595,18 @@
171119171595
pFrom = aTo;
171120171596
aTo = aFrom;
171121171597
aFrom = pFrom;
171122171598
nFrom = nTo;
171123171599
}
171600
+ assert( nFrom==0 || nFrom==1 );
171124171601
171125171602
if( nFrom==0 ){
171126171603
sqlite3ErrorMsg(pParse, "no query solution");
171127171604
sqlite3StackFreeNN(pParse->db, pSpace);
171128171605
return SQLITE_ERROR;
171129171606
}
171130
-
171131
- /* Find the lowest cost path. pFrom will be left pointing to that path */
171132171607
pFrom = aFrom;
171133
- for(ii=1; ii<nFrom; ii++){
171134
- if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
171135
- }
171136171608
assert( pWInfo->nLevel==nLoop );
171137171609
/* Load the lowest cost path into pWInfo */
171138171610
for(iLoop=0; iLoop<nLoop; iLoop++){
171139171611
WhereLevel *pLevel = pWInfo->a + iLoop;
171140171612
pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -171263,11 +171735,14 @@
171263171735
int once = 0;
171264171736
#endif
171265171737
for(i=0; i<pWInfo->nLevel; i++){
171266171738
WhereLoop *p = pWInfo->a[i].pWLoop;
171267171739
if( p==0 ) break;
171268
- if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue;
171740
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
171741
+ /* Treat a vtab scan as similar to a full-table scan */
171742
+ break;
171743
+ }
171269171744
if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
171270171745
u8 iTab = p->iTab;
171271171746
WhereLoop *pLoop;
171272171747
for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
171273171748
if( pLoop->iTab!=iTab ) continue;
@@ -175376,11 +175851,11 @@
175376175851
** RETURN_ROW
175377175852
**
175378175853
**
175379175854
** ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
175380175855
**
175381
-** ... loop started by sqlite3WhereBegin() ...
175856
+** ... loop started by sqlite3WhereBegin() ...
175382175857
** if( new partition ){
175383175858
** Gosub flush
175384175859
** }
175385175860
** Insert new row into eph table.
175386175861
** if( first row of partition ){
@@ -175894,10 +176369,16 @@
175894176369
addrStart = sqlite3VdbeCurrentAddr(v);
175895176370
addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
175896176371
addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
175897176372
}else{
175898176373
assert( pMWin->eEnd==TK_FOLLOWING );
176374
+ /* assert( regStart>=0 );
176375
+ ** regEnd = regEnd - regStart;
176376
+ ** regStart = 0; */
176377
+ sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
176378
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regStart);
176379
+
175899176380
addrStart = sqlite3VdbeCurrentAddr(v);
175900176381
addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
175901176382
addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
175902176383
}
175903176384
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
@@ -184839,10 +185320,13 @@
184839185320
for(i=0; i<2 && zName==0; i++, rc &= 0xff){
184840185321
switch( rc ){
184841185322
case SQLITE_OK: zName = "SQLITE_OK"; break;
184842185323
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
184843185324
case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break;
185325
+ case SQLITE_ERROR_RETRY: zName = "SQLITE_ERROR_RETRY"; break;
185326
+ case SQLITE_ERROR_MISSING_COLLSEQ:
185327
+ zName = "SQLITE_ERROR_MISSING_COLLSEQ"; break;
184844185328
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
184845185329
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
184846185330
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
184847185331
case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
184848185332
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
@@ -186019,10 +186503,33 @@
186019186503
}
186020186504
}
186021186505
sqlite3_mutex_leave(db->mutex);
186022186506
return z;
186023186507
}
186508
+
186509
+/*
186510
+** Set the error code and error message associated with the database handle.
186511
+**
186512
+** This routine is intended to be called by outside extensions (ex: the
186513
+** Session extension). Internal logic should invoke sqlite3Error() or
186514
+** sqlite3ErrorWithMsg() directly.
186515
+*/
186516
+SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
186517
+ int rc = SQLITE_OK;
186518
+ if( !sqlite3SafetyCheckSickOrOk(db) ){
186519
+ return SQLITE_MISUSE_BKPT;
186520
+ }
186521
+ sqlite3_mutex_enter(db->mutex);
186522
+ if( zMsg ){
186523
+ sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
186524
+ }else{
186525
+ sqlite3Error(db, errcode);
186526
+ }
186527
+ rc = sqlite3ApiExit(db, rc);
186528
+ sqlite3_mutex_leave(db->mutex);
186529
+ return rc;
186530
+}
186024186531
186025186532
/*
186026186533
** Return the byte offset of the most recent error
186027186534
*/
186028186535
SQLITE_API int sqlite3_error_offset(sqlite3 *db){
@@ -187844,17 +188351,19 @@
187844188351
case SQLITE_TESTCTRL_ISINIT: {
187845188352
if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
187846188353
break;
187847188354
}
187848188355
187849
- /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
188356
+ /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, mode, tnum);
187850188357
**
187851188358
** This test control is used to create imposter tables. "db" is a pointer
187852188359
** to the database connection. dbName is the database name (ex: "main" or
187853
- ** "temp") which will receive the imposter. "onOff" turns imposter mode on
187854
- ** or off. "tnum" is the root page of the b-tree to which the imposter
187855
- ** table should connect.
188360
+ ** "temp") which will receive the imposter. "mode" turns imposter mode on
188361
+ ** or off. mode==0 means imposter mode is off. mode==1 means imposter mode
188362
+ ** is on. mode==2 means imposter mode is on but results in an imposter
188363
+ ** table that is read-only unless writable_schema is on. "tnum" is the
188364
+ ** root page of the b-tree to which the imposter table should connect.
187856188365
**
187857188366
** Enable imposter mode only when the schema has already been parsed. Then
187858188367
** run a single CREATE TABLE statement to construct the imposter table in
187859188368
** the parsed schema. Then turn imposter mode back off again.
187860188369
**
@@ -189087,21 +189596,24 @@
189087189596
**
189088189597
*/
189089189598
#ifndef _FTSINT_H
189090189599
#define _FTSINT_H
189091189600
189601
+/*
189602
+** Activate assert() only if SQLITE_TEST is enabled.
189603
+*/
189604
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189605
+# define NDEBUG 1
189606
+#endif
189607
+
189092189608
/* #include <assert.h> */
189093189609
/* #include <stdlib.h> */
189094189610
/* #include <stddef.h> */
189095189611
/* #include <stdio.h> */
189096189612
/* #include <string.h> */
189097189613
/* #include <stdarg.h> */
189098189614
189099
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189100
-# define NDEBUG 1
189101
-#endif
189102
-
189103189615
/* FTS3/FTS4 require virtual tables */
189104189616
#ifdef SQLITE_OMIT_VIRTUALTABLE
189105189617
# undef SQLITE_ENABLE_FTS3
189106189618
# undef SQLITE_ENABLE_FTS4
189107189619
#endif
@@ -189540,17 +190052,10 @@
189540190052
/*
189541190053
** Macro used to suppress compiler warnings for unused parameters.
189542190054
*/
189543190055
#define UNUSED_PARAMETER(x) (void)(x)
189544190056
189545
-/*
189546
-** Activate assert() only if SQLITE_TEST is enabled.
189547
-*/
189548
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189549
-# define NDEBUG 1
189550
-#endif
189551
-
189552190057
/*
189553190058
** The TESTONLY macro is used to enclose variable declarations or
189554190059
** other bits of code that are needed to support the arguments
189555190060
** within testcase() and assert() macros.
189556190061
*/
@@ -203821,12 +204326,12 @@
203821204326
/*
203822204327
** An object of this type contains the state required to create or append
203823204328
** to an appendable b-tree segment.
203824204329
*/
203825204330
struct IncrmergeWriter {
203826
- int nLeafEst; /* Space allocated for leaf blocks */
203827
- int nWork; /* Number of leaf pages flushed */
204331
+ i64 nLeafEst; /* Space allocated for leaf blocks */
204332
+ i64 nWork; /* Number of leaf pages flushed */
203828204333
sqlite3_int64 iAbsLevel; /* Absolute level of input segments */
203829204334
int iIdx; /* Index of *output* segment in iAbsLevel+1 */
203830204335
sqlite3_int64 iStart; /* Block number of first allocated block */
203831204336
sqlite3_int64 iEnd; /* Block number of last allocated block */
203832204337
sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */
@@ -204568,21 +205073,21 @@
204568205073
Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */
204569205074
IncrmergeWriter *pWriter /* Populate this object */
204570205075
){
204571205076
int rc; /* Return Code */
204572205077
int i; /* Iterator variable */
204573
- int nLeafEst = 0; /* Blocks allocated for leaf nodes */
205078
+ i64 nLeafEst = 0; /* Blocks allocated for leaf nodes */
204574205079
sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */
204575205080
sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */
204576205081
204577205082
/* Calculate nLeafEst. */
204578205083
rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0);
204579205084
if( rc==SQLITE_OK ){
204580205085
sqlite3_bind_int64(pLeafEst, 1, iAbsLevel);
204581205086
sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment);
204582205087
if( SQLITE_ROW==sqlite3_step(pLeafEst) ){
204583
- nLeafEst = sqlite3_column_int(pLeafEst, 0);
205088
+ nLeafEst = sqlite3_column_int64(pLeafEst, 0);
204584205089
}
204585205090
rc = sqlite3_reset(pLeafEst);
204586205091
}
204587205092
if( rc!=SQLITE_OK ) return rc;
204588205093
@@ -228353,12 +228858,12 @@
228353228858
typedef struct DbpageTable DbpageTable;
228354228859
typedef struct DbpageCursor DbpageCursor;
228355228860
228356228861
struct DbpageCursor {
228357228862
sqlite3_vtab_cursor base; /* Base class. Must be first */
228358
- int pgno; /* Current page number */
228359
- int mxPgno; /* Last page to visit on this scan */
228863
+ Pgno pgno; /* Current page number */
228864
+ Pgno mxPgno; /* Last page to visit on this scan */
228360228865
Pager *pPager; /* Pager being read/written */
228361228866
DbPage *pPage1; /* Page 1 of the database */
228362228867
int iDb; /* Index of database to analyze */
228363228868
int szPage; /* Size of each page in bytes */
228364228869
};
@@ -228491,11 +228996,11 @@
228491228996
if( pCsr==0 ){
228492228997
return SQLITE_NOMEM_BKPT;
228493228998
}else{
228494228999
memset(pCsr, 0, sizeof(DbpageCursor));
228495229000
pCsr->base.pVtab = pVTab;
228496
- pCsr->pgno = -1;
229001
+ pCsr->pgno = 0;
228497229002
}
228498229003
228499229004
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
228500229005
return SQLITE_OK;
228501229006
}
@@ -228591,16 +229096,16 @@
228591229096
){
228592229097
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
228593229098
int rc = SQLITE_OK;
228594229099
switch( i ){
228595229100
case 0: { /* pgno */
228596
- sqlite3_result_int(ctx, pCsr->pgno);
229101
+ sqlite3_result_int64(ctx, (sqlite3_int64)pCsr->pgno);
228597229102
break;
228598229103
}
228599229104
case 1: { /* data */
228600229105
DbPage *pDbPage = 0;
228601
- if( pCsr->pgno==((PENDING_BYTE/pCsr->szPage)+1) ){
229106
+ if( pCsr->pgno==(Pgno)((PENDING_BYTE/pCsr->szPage)+1) ){
228602229107
/* The pending byte page. Assume it is zeroed out. Attempting to
228603229108
** request this page from the page is an SQLITE_CORRUPT error. */
228604229109
sqlite3_result_zeroblob(ctx, pCsr->szPage);
228605229110
}else{
228606229111
rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
@@ -228670,14 +229175,14 @@
228670229175
if( argc==1 ){
228671229176
zErr = "cannot delete";
228672229177
goto update_fail;
228673229178
}
228674229179
if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
228675
- pgno = (Pgno)sqlite3_value_int(argv[2]);
229180
+ pgno = (Pgno)sqlite3_value_int64(argv[2]);
228676229181
isInsert = 1;
228677229182
}else{
228678
- pgno = sqlite3_value_int(argv[0]);
229183
+ pgno = (Pgno)sqlite3_value_int64(argv[0]);
228679229184
if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
228680229185
zErr = "cannot insert";
228681229186
goto update_fail;
228682229187
}
228683229188
isInsert = 0;
@@ -231625,10 +232130,23 @@
231625232130
assert( (a - p->aRecord)==p->nRecord );
231626232131
}
231627232132
231628232133
return rc;
231629232134
}
232135
+
232136
+static int sessionPrepare(
232137
+ sqlite3 *db,
232138
+ sqlite3_stmt **pp,
232139
+ char **pzErrmsg,
232140
+ const char *zSql
232141
+){
232142
+ int rc = sqlite3_prepare_v2(db, zSql, -1, pp, 0);
232143
+ if( pzErrmsg && rc!=SQLITE_OK ){
232144
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
232145
+ }
232146
+ return rc;
232147
+}
231630232148
231631232149
/*
231632232150
** Formulate and prepare a SELECT statement to retrieve a row from table
231633232151
** zTab in database zDb based on its primary key. i.e.
231634232152
**
@@ -231647,16 +232165,16 @@
231647232165
const char *zTab, /* Table name */
231648232166
int bRowid,
231649232167
int nCol, /* Number of columns in table */
231650232168
const char **azCol, /* Names of table columns */
231651232169
u8 *abPK, /* PRIMARY KEY array */
231652
- sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
232170
+ sqlite3_stmt **ppStmt, /* OUT: Prepared SELECT statement */
232171
+ char **pzErrmsg /* OUT: Error message */
231653232172
){
231654232173
int rc = SQLITE_OK;
231655232174
char *zSql = 0;
231656232175
const char *zSep = "";
231657
- int nSql = -1;
231658232176
int i;
231659232177
231660232178
SessionBuffer cols = {0, 0, 0};
231661232179
SessionBuffer nooptest = {0, 0, 0};
231662232180
SessionBuffer pkfield = {0, 0, 0};
@@ -231732,11 +232250,11 @@
231732232250
nSql = buf.nBuf;
231733232251
}
231734232252
#endif
231735232253
231736232254
if( rc==SQLITE_OK ){
231737
- rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
232255
+ rc = sessionPrepare(db, ppStmt, pzErrmsg, zSql);
231738232256
}
231739232257
sqlite3_free(zSql);
231740232258
sqlite3_free(nooptest.aBuf);
231741232259
sqlite3_free(pkfield.aBuf);
231742232260
sqlite3_free(pkvar.aBuf);
@@ -231896,11 +232414,11 @@
231896232414
sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
231897232415
231898232416
/* Build and compile a statement to execute: */
231899232417
if( rc==SQLITE_OK ){
231900232418
rc = sessionSelectStmt(db, 0, pSession->zDb,
231901
- zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel
232419
+ zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel, 0
231902232420
);
231903232421
}
231904232422
231905232423
nNoop = buf.nBuf;
231906232424
for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
@@ -233105,10 +233623,11 @@
233105233623
SessionBuffer rebase; /* Rebase information (if any) here */
233106233624
u8 bRebaseStarted; /* If table header is already in rebase */
233107233625
u8 bRebase; /* True to collect rebase information */
233108233626
u8 bIgnoreNoop; /* True to ignore no-op conflicts */
233109233627
int bRowid;
233628
+ char *zErr; /* Error message, if any */
233110233629
};
233111233630
233112233631
/* Number of prepared UPDATE statements to cache. */
233113233632
#define SESSION_UPDATE_CACHE_SZ 12
233114233633
@@ -233330,11 +233849,11 @@
233330233849
}
233331233850
sessionAppendStr(&buf, ")", &rc);
233332233851
}
233333233852
233334233853
if( rc==SQLITE_OK ){
233335
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
233854
+ rc = sessionPrepare(db, &p->pDelete, &p->zErr, (char*)buf.aBuf);
233336233855
}
233337233856
sqlite3_free(buf.aBuf);
233338233857
233339233858
return rc;
233340233859
}
@@ -233357,11 +233876,11 @@
233357233876
const char *zTab, /* Table name */
233358233877
SessionApplyCtx *p /* Session changeset-apply context */
233359233878
){
233360233879
/* TODO */
233361233880
return sessionSelectStmt(db, p->bIgnoreNoop,
233362
- "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect
233881
+ "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect, &p->zErr
233363233882
);
233364233883
}
233365233884
233366233885
/*
233367233886
** Formulate and prepare an INSERT statement to add a record to table zTab.
@@ -233394,37 +233913,33 @@
233394233913
sessionAppendStr(&buf, ", ?", &rc);
233395233914
}
233396233915
sessionAppendStr(&buf, ")", &rc);
233397233916
233398233917
if( rc==SQLITE_OK ){
233399
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
233918
+ rc = sessionPrepare(db, &p->pInsert, &p->zErr, (char*)buf.aBuf);
233400233919
}
233401233920
sqlite3_free(buf.aBuf);
233402233921
return rc;
233403233922
}
233404233923
233405
-static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
233406
- return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
233407
-}
233408
-
233409233924
/*
233410233925
** Prepare statements for applying changes to the sqlite_stat1 table.
233411233926
** These are similar to those created by sessionSelectRow(),
233412233927
** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
233413233928
** other tables.
233414233929
*/
233415233930
static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
233416233931
int rc = sessionSelectRow(db, "sqlite_stat1", p);
233417233932
if( rc==SQLITE_OK ){
233418
- rc = sessionPrepare(db, &p->pInsert,
233933
+ rc = sessionPrepare(db, &p->pInsert, 0,
233419233934
"INSERT INTO main.sqlite_stat1 VALUES(?1, "
233420233935
"CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
233421233936
"?3)"
233422233937
);
233423233938
}
233424233939
if( rc==SQLITE_OK ){
233425
- rc = sessionPrepare(db, &p->pDelete,
233940
+ rc = sessionPrepare(db, &p->pDelete, 0,
233426233941
"DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
233427233942
"CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
233428233943
"AND (?4 OR stat IS ?3)"
233429233944
);
233430233945
}
@@ -233644,11 +234159,11 @@
233644234159
sqlite3_changeset_iter *pIter, /* Changeset iterator */
233645234160
int(*xConflict)(void *, int, sqlite3_changeset_iter*),
233646234161
void *pCtx, /* First argument for conflict handler */
233647234162
int *pbReplace /* OUT: Set to true if PK row is found */
233648234163
){
233649
- int res = 0; /* Value returned by conflict handler */
234164
+ int res = SQLITE_CHANGESET_OMIT;/* Value returned by conflict handler */
233650234165
int rc;
233651234166
int nCol;
233652234167
int op;
233653234168
const char *zDummy;
233654234169
@@ -233665,15 +234180,13 @@
233665234180
rc = SQLITE_OK;
233666234181
}
233667234182
233668234183
if( rc==SQLITE_ROW ){
233669234184
/* There exists another row with the new.* primary key. */
233670
- if( p->bIgnoreNoop
233671
- && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
234185
+ if( 0==p->bIgnoreNoop
234186
+ || 0==sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
233672234187
){
233673
- res = SQLITE_CHANGESET_OMIT;
233674
- }else{
233675234188
pIter->pConflict = p->pSelect;
233676234189
res = xConflict(pCtx, eType, pIter);
233677234190
pIter->pConflict = 0;
233678234191
}
233679234192
rc = sqlite3_reset(p->pSelect);
@@ -233683,11 +234196,13 @@
233683234196
** to the SessionApplyCtx.constraints buffer. */
233684234197
u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
233685234198
int nBlob = pIter->in.iNext - pIter->in.iCurrent;
233686234199
sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
233687234200
return SQLITE_OK;
233688
- }else{
234201
+ }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE
234202
+ || eType==SQLITE_CHANGESET_CONFLICT
234203
+ ){
233689234204
/* No other row with the new.* primary key. */
233690234205
res = xConflict(pCtx, eType+1, pIter);
233691234206
if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
233692234207
}
233693234208
}
@@ -233781,11 +234296,11 @@
233781234296
}
233782234297
if( rc!=SQLITE_OK ) return rc;
233783234298
233784234299
sqlite3_step(p->pDelete);
233785234300
rc = sqlite3_reset(p->pDelete);
233786
- if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){
234301
+ if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
233787234302
rc = sessionConflictHandler(
233788234303
SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
233789234304
);
233790234305
}else if( (rc&0xff)==SQLITE_CONSTRAINT ){
233791234306
rc = sessionConflictHandler(
@@ -234203,10 +234718,15 @@
234203234718
if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
234204234719
assert( db->flags & SQLITE_FkNoAction );
234205234720
db->flags &= ~((u64)SQLITE_FkNoAction);
234206234721
db->aDb[0].pSchema->schema_cookie -= 32;
234207234722
}
234723
+
234724
+ assert( rc!=SQLITE_OK || sApply.zErr==0 );
234725
+ sqlite3_set_errmsg(db, rc, sApply.zErr);
234726
+ sqlite3_free(sApply.zErr);
234727
+
234208234728
sqlite3_mutex_leave(sqlite3_db_mutex(db));
234209234729
return rc;
234210234730
}
234211234731
234212234732
/*
@@ -236412,25 +236932,18 @@
236412236932
** Constants for the largest and smallest possible 64-bit signed integers.
236413236933
*/
236414236934
# define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
236415236935
# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
236416236936
236417
-/* The uptr type is an unsigned integer large enough to hold a pointer
236937
+/*
236938
+** This macro is used in a single assert() within fts5 to check that an
236939
+** allocation is aligned to an 8-byte boundary. But it is a complicated
236940
+** macro to get right for multiple platforms without generating warnings.
236941
+** So instead of reproducing the entire definition from sqliteInt.h, we
236942
+** just do without this assert() for the rare non-amalgamation builds.
236418236943
*/
236419
-#if defined(HAVE_STDINT_H)
236420
- typedef uintptr_t uptr;
236421
-#elif SQLITE_PTRSIZE==4
236422
- typedef u32 uptr;
236423
-#else
236424
- typedef u64 uptr;
236425
-#endif
236426
-
236427
-#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
236428
-# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0)
236429
-#else
236430
-# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
236431
-#endif
236944
+#define EIGHT_BYTE_ALIGNMENT(x) 1
236432236945
236433236946
/*
236434236947
** Macros needed to provide flexible arrays in a portable way
236435236948
*/
236436236949
#ifndef offsetof
@@ -237174,11 +237687,11 @@
237174237687
** ){
237175237688
** // The document with rowid iRowid matches the expression!
237176237689
** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
237177237690
** }
237178237691
*/
237179
-static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
237692
+static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, i64, int bDesc);
237180237693
static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
237181237694
static int sqlite3Fts5ExprEof(Fts5Expr*);
237182237695
static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
237183237696
237184237697
static void sqlite3Fts5ExprFree(Fts5Expr*);
@@ -242743,11 +243256,17 @@
242743243256
** equal to iFirst.
242744243257
**
242745243258
** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
242746243259
** is not considered an error if the query does not match any documents.
242747243260
*/
242748
-static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
243261
+static int sqlite3Fts5ExprFirst(
243262
+ Fts5Expr *p,
243263
+ Fts5Index *pIdx,
243264
+ i64 iFirst,
243265
+ i64 iLast,
243266
+ int bDesc
243267
+){
242749243268
Fts5ExprNode *pRoot = p->pRoot;
242750243269
int rc; /* Return code */
242751243270
242752243271
p->pIndex = pIdx;
242753243272
p->bDesc = bDesc;
@@ -242764,10 +243283,13 @@
242764243283
242765243284
/* If the iterator is not at a real match, skip forward until it is. */
242766243285
while( pRoot->bNomatch && rc==SQLITE_OK ){
242767243286
assert( pRoot->bEof==0 );
242768243287
rc = fts5ExprNodeNext(p, pRoot, 0, 0);
243288
+ }
243289
+ if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
243290
+ pRoot->bEof = 1;
242769243291
}
242770243292
return rc;
242771243293
}
242772243294
242773243295
/*
@@ -251885,14 +252407,17 @@
251885252407
** function populates it with the initial structure objects for each index,
251886252408
** and the initial version of the "averages" record (a zero-byte blob).
251887252409
*/
251888252410
static int sqlite3Fts5IndexReinit(Fts5Index *p){
251889252411
Fts5Structure *pTmp;
251890
- u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252412
+ union {
252413
+ Fts5Structure sFts;
252414
+ u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252415
+ } uFts;
251891252416
fts5StructureInvalidate(p);
251892252417
fts5IndexDiscardData(p);
251893
- pTmp = (Fts5Structure*)tmpSpace;
252418
+ pTmp = &uFts.sFts;
251894252419
memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
251895252420
if( p->pConfig->bContentlessDelete ){
251896252421
pTmp->nOriginCntr = 1;
251897252422
}
251898252423
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
@@ -255109,10 +255634,21 @@
255109255634
{
255110255635
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
255111255636
}
255112255637
#endif
255113255638
}
255639
+
255640
+static void fts5SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
255641
+#if SQLITE_VERSION_NUMBER>=3008002
255642
+#ifndef SQLITE_CORE
255643
+ if( sqlite3_libversion_number()>=3008002 )
255644
+#endif
255645
+ {
255646
+ pIdxInfo->estimatedRows = nRow;
255647
+ }
255648
+#endif
255649
+}
255114255650
255115255651
static int fts5UsePatternMatch(
255116255652
Fts5Config *pConfig,
255117255653
struct sqlite3_index_constraint *p
255118255654
){
@@ -255245,11 +255781,11 @@
255245255781
bSeenRank = 1;
255246255782
}else{
255247255783
nSeenMatch++;
255248255784
idxStr[iIdxStr++] = 'M';
255249255785
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
255250
- idxStr += strlen(&idxStr[iIdxStr]);
255786
+ iIdxStr += (int)strlen(&idxStr[iIdxStr]);
255251255787
assert( idxStr[iIdxStr]=='\0' );
255252255788
}
255253255789
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
255254255790
pInfo->aConstraintUsage[i].omit = 1;
255255255791
}
@@ -255264,10 +255800,11 @@
255264255800
nSeenMatch++;
255265255801
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
255266255802
idxStr[iIdxStr++] = '=';
255267255803
bSeenEq = 1;
255268255804
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
255805
+ pInfo->aConstraintUsage[i].omit = 1;
255269255806
}
255270255807
}
255271255808
}
255272255809
255273255810
if( bSeenEq==0 ){
@@ -255311,21 +255848,25 @@
255311255848
}
255312255849
}
255313255850
255314255851
/* Calculate the estimated cost based on the flags set in idxFlags. */
255315255852
if( bSeenEq ){
255316
- pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0;
255317
- if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
255318
- }else if( bSeenLt && bSeenGt ){
255319
- pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0;
255320
- }else if( bSeenLt || bSeenGt ){
255321
- pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0;
255853
+ pInfo->estimatedCost = nSeenMatch ? 1000.0 : 25.0;
255854
+ fts5SetUniqueFlag(pInfo);
255855
+ fts5SetEstimatedRows(pInfo, 1);
255322255856
}else{
255323
- pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0;
255324
- }
255325
- for(i=1; i<nSeenMatch; i++){
255326
- pInfo->estimatedCost *= 0.4;
255857
+ if( bSeenLt && bSeenGt ){
255858
+ pInfo->estimatedCost = nSeenMatch ? 5000.0 : 750000.0;
255859
+ }else if( bSeenLt || bSeenGt ){
255860
+ pInfo->estimatedCost = nSeenMatch ? 7500.0 : 2250000.0;
255861
+ }else{
255862
+ pInfo->estimatedCost = nSeenMatch ? 10000.0 : 3000000.0;
255863
+ }
255864
+ for(i=1; i<nSeenMatch; i++){
255865
+ pInfo->estimatedCost *= 0.4;
255866
+ }
255867
+ fts5SetEstimatedRows(pInfo, (i64)(pInfo->estimatedCost / 4.0));
255327255868
}
255328255869
255329255870
pInfo->idxNum = idxFlags;
255330255871
return SQLITE_OK;
255331255872
}
@@ -255520,11 +256061,13 @@
255520256061
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
255521256062
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
255522256063
int bDesc = pCsr->bDesc;
255523256064
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
255524256065
255525
- rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
256066
+ rc = sqlite3Fts5ExprFirst(
256067
+ pCsr->pExpr, pTab->p.pIndex, iRowid, pCsr->iLastRowid, bDesc
256068
+ );
255526256069
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
255527256070
*pbSkip = 1;
255528256071
}
255529256072
255530256073
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
@@ -255692,11 +256235,13 @@
255692256235
}
255693256236
255694256237
static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
255695256238
int rc;
255696256239
Fts5Expr *pExpr = pCsr->pExpr;
255697
- rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
256240
+ rc = sqlite3Fts5ExprFirst(
256241
+ pExpr, pTab->p.pIndex, pCsr->iFirstRowid, pCsr->iLastRowid, bDesc
256242
+ );
255698256243
if( sqlite3Fts5ExprEof(pExpr) ){
255699256244
CsrFlagSet(pCsr, FTS5CSR_EOF);
255700256245
}
255701256246
fts5CsrNewrow(pCsr);
255702256247
return rc;
@@ -258177,11 +258722,11 @@
258177258722
int nArg, /* Number of args */
258178258723
sqlite3_value **apUnused /* Function arguments */
258179258724
){
258180258725
assert( nArg==0 );
258181258726
UNUSED_PARAM2(nArg, apUnused);
258182
- sqlite3_result_text(pCtx, "fts5: 2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1", -1, SQLITE_TRANSIENT);
258727
+ sqlite3_result_text(pCtx, "fts5: 2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232", -1, SQLITE_TRANSIENT);
258183258728
}
258184258729
258185258730
/*
258186258731
** Implementation of fts5_locale(LOCALE, TEXT) function.
258187258732
**
258188258733
--- 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 ** cf7163f82ca380958a79350473b2c5a2cebd with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -168,11 +168,13 @@
168 #define SQLITE_OMIT_LOAD_EXTENSION 1
169 #define SQLITE_ENABLE_LOCKING_STYLE 0
170 #define HAVE_UTIME 1
171 #else
172 /* This is not VxWorks. */
173 #define OS_VXWORKS 0
 
 
174 #define HAVE_FCHOWN 1
175 #define HAVE_READLINK 1
176 #define HAVE_LSTAT 1
177 #endif /* defined(_WRS_KERNEL) */
178
@@ -465,11 +467,14 @@
465 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
466 ** [sqlite_version()] and [sqlite_source_id()].
467 */
468 #define SQLITE_VERSION "3.51.0"
469 #define SQLITE_VERSION_NUMBER 3051000
470 #define SQLITE_SOURCE_ID "2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1"
 
 
 
471
472 /*
473 ** CAPI3REF: Run-Time Library Version Numbers
474 ** KEYWORDS: sqlite3_version sqlite3_sourceid
475 **
@@ -2657,21 +2662,24 @@
2657 ** views in the main database schema or in the schemas of ATTACH-ed
2658 ** databases.)^ </dd>
2659 **
2660 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
2661 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2662 ** <dd> ^This option is used to enable or disable the
2663 ** [fts3_tokenizer()] function which is part of the
2664 ** [FTS3] full-text search engine extension.
2665 ** There must be two additional arguments.
2666 ** The first argument is an integer which is 0 to disable fts3_tokenizer() or
2667 ** positive to enable fts3_tokenizer() or negative to leave the setting
2668 ** unchanged.
2669 ** The second parameter is a pointer to an integer into which
2670 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2671 ** following this call. The second parameter may be a NULL pointer, in
2672 ** which case the new setting is not reported back. </dd>
 
 
 
2673 **
2674 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
2675 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2676 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2677 ** interface independently of the [load_extension()] SQL function.
@@ -4517,10 +4525,38 @@
4517 SQLITE_API const char *sqlite3_errmsg(sqlite3*);
4518 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4519 SQLITE_API const char *sqlite3_errstr(int);
4520 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4521
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4522 /*
4523 ** CAPI3REF: Prepared Statement Object
4524 ** KEYWORDS: {prepared statement} {prepared statements}
4525 **
4526 ** An instance of this object represents a single SQL statement that
@@ -6527,10 +6563,11 @@
6527 ** to be attached to [database connection] D using name N. Subsequent
6528 ** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
6529 ** or a NULL pointer if there were no prior calls to
6530 ** sqlite3_set_clientdata() with the same values of D and N.
6531 ** Names are compared using strcmp() and are thus case sensitive.
 
6532 **
6533 ** If P and X are both non-NULL, then the destructor X is invoked with
6534 ** argument P on the first of the following occurrences:
6535 ** <ul>
6536 ** <li> An out-of-memory error occurs during the call to
@@ -10098,25 +10135,38 @@
10098 ** ^The third parameter is the name of the database that was written to -
10099 ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
10100 ** is the number of pages currently in the write-ahead log file,
10101 ** including those that were just committed.
10102 **
10103 ** The callback function should normally return [SQLITE_OK]. ^If an error
10104 ** code is returned, that error will propagate back up through the
10105 ** SQLite code base to cause the statement that provoked the callback
10106 ** to report an error, though the commit will have still occurred. If the
10107 ** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
10108 ** that does not correspond to any valid SQLite error code, the results
10109 ** are undefined.
10110 **
10111 ** A single database handle may have at most a single write-ahead log callback
10112 ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
10113 ** previously registered write-ahead log callback. ^The return value is
10114 ** a copy of the third parameter from the previous call, if any, or 0.
10115 ** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
10116 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
10117 ** overwrite any prior [sqlite3_wal_hook()] settings.
 
 
 
 
 
 
 
 
 
 
 
 
 
10118 */
10119 SQLITE_API void *sqlite3_wal_hook(
10120 sqlite3*,
10121 int(*)(void *,sqlite3*,const char*,int),
10122 void*
@@ -10129,11 +10179,11 @@
10129 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
10130 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
10131 ** to automatically [checkpoint]
10132 ** after committing a transaction if there are N or
10133 ** more frames in the [write-ahead log] file. ^Passing zero or
10134 ** a negative value as the nFrame parameter disables automatic
10135 ** checkpoints entirely.
10136 **
10137 ** ^The callback registered by this function replaces any existing callback
10138 ** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
10139 ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -10145,13 +10195,14 @@
10145 ** ^Checkpoints initiated by this mechanism are
10146 ** [sqlite3_wal_checkpoint_v2|PASSIVE].
10147 **
10148 ** ^Every new [database connection] defaults to having the auto-checkpoint
10149 ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
10150 ** pages. The use of this interface
10151 ** is only necessary if the default setting is found to be suboptimal
10152 ** for a particular application.
 
10153 */
10154 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
10155
10156 /*
10157 ** CAPI3REF: Checkpoint a database
@@ -10212,10 +10263,15 @@
10212 **
10213 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
10214 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
10215 ** addition that it also truncates the log file to zero bytes just prior
10216 ** to a successful return.
 
 
 
 
 
10217 ** </dl>
10218 **
10219 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
10220 ** the log file or to -1 if the checkpoint could not run because
10221 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -10282,10 +10338,11 @@
10282 ** These constants define all valid values for the "checkpoint mode" passed
10283 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
10284 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
10285 ** meaning of each of these checkpoint modes.
10286 */
 
10287 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
10288 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
10289 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
10290 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
10291
@@ -11109,11 +11166,11 @@
11109 ** to avoid a memory leak.
11110 **
11111 ** The [sqlite3_snapshot_get()] interface is only available when the
11112 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11113 */
11114 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
11115 sqlite3 *db,
11116 const char *zSchema,
11117 sqlite3_snapshot **ppSnapshot
11118 );
11119
@@ -11158,11 +11215,11 @@
11158 ** database connection in order to make it ready to use snapshots.)
11159 **
11160 ** The [sqlite3_snapshot_open()] interface is only available when the
11161 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11162 */
11163 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
11164 sqlite3 *db,
11165 const char *zSchema,
11166 sqlite3_snapshot *pSnapshot
11167 );
11168
@@ -11175,11 +11232,11 @@
11175 ** using this routine to avoid a memory leak.
11176 **
11177 ** The [sqlite3_snapshot_free()] interface is only available when the
11178 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11179 */
11180 SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
11181
11182 /*
11183 ** CAPI3REF: Compare the ages of two snapshot handles.
11184 ** METHOD: sqlite3_snapshot
11185 **
@@ -11202,11 +11259,11 @@
11202 ** snapshot, and a positive value if P1 is a newer snapshot than P2.
11203 **
11204 ** This interface is only available if SQLite is compiled with the
11205 ** [SQLITE_ENABLE_SNAPSHOT] option.
11206 */
11207 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
11208 sqlite3_snapshot *p1,
11209 sqlite3_snapshot *p2
11210 );
11211
11212 /*
@@ -11230,11 +11287,11 @@
11230 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
11231 **
11232 ** This interface is only available if SQLite is compiled with the
11233 ** [SQLITE_ENABLE_SNAPSHOT] option.
11234 */
11235 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
11236
11237 /*
11238 ** CAPI3REF: Serialize a database
11239 **
11240 ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -11304,16 +11361,17 @@
11304 /*
11305 ** CAPI3REF: Deserialize a database
11306 **
11307 ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
11308 ** [database connection] D to disconnect from database S and then
11309 ** reopen S as an in-memory database based on the serialization contained
11310 ** in P. The serialized database P is N bytes in size. M is the size of
11311 ** the buffer P, which might be larger than N. If M is larger than N, and
11312 ** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
11313 ** permitted to add content to the in-memory database as long as the total
11314 ** size does not exceed M bytes.
 
11315 **
11316 ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
11317 ** invoke sqlite3_free() on the serialization buffer when the database
11318 ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
11319 ** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12634,10 +12692,19 @@
12634 ** CAPI3REF: Apply A Changeset To A Database
12635 **
12636 ** Apply a changeset or patchset to a database. These functions attempt to
12637 ** update the "main" database attached to handle db with the changes found in
12638 ** the changeset passed via the second and third arguments.
 
 
 
 
 
 
 
 
 
12639 **
12640 ** The fourth argument (xFilter) passed to these functions is the "filter
12641 ** callback". This may be passed NULL, in which case all changes in the
12642 ** changeset are applied to the database. For sqlite3changeset_apply() and
12643 ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12772,16 +12839,10 @@
12772 ** It is safe to execute SQL statements, including those that write to the
12773 ** table that the callback related to, from within the xConflict callback.
12774 ** This can be used to further customize the application's conflict
12775 ** resolution strategy.
12776 **
12777 ** All changes made by these functions are enclosed in a savepoint transaction.
12778 ** If any other error (aside from a constraint failure when attempting to
12779 ** write to the target database) occurs, then the savepoint transaction is
12780 ** rolled back, restoring the target database to its original state, and an
12781 ** SQLite error code returned.
12782 **
12783 ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
12784 ** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
12785 ** may set (*ppRebase) to point to a "rebase" that may be used with the
12786 ** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
12787 ** is set to the size of the buffer in bytes. It is the responsibility of the
@@ -14356,11 +14417,11 @@
14356
14357 /*
14358 ** Maximum number of pages in one database file.
14359 **
14360 ** This is really just the default value for the max_page_count pragma.
14361 ** This value can be lowered (or raised) at run-time using that the
14362 ** max_page_count macro.
14363 */
14364 #ifndef SQLITE_MAX_PAGE_COUNT
14365 # define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */
14366 #endif
@@ -18127,11 +18188,11 @@
18127 struct sqlite3InitInfo { /* Information used during initialization */
18128 Pgno newTnum; /* Rootpage of table being initialized */
18129 u8 iDb; /* Which db file is being initialized */
18130 u8 busy; /* TRUE if currently initializing */
18131 unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
18132 unsigned imposterTable : 1; /* Building an imposter table */
18133 unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
18134 const char **azInit; /* "type", "name", and "tbl_name" columns */
18135 } init;
18136 int nVdbeActive; /* Number of VDBEs currently running */
18137 int nVdbeRead; /* Number of active VDBEs that read or write */
@@ -18920,10 +18981,11 @@
18920 #define TF_Shadow 0x00001000 /* True for a shadow table */
18921 #define TF_HasStat4 0x00002000 /* STAT4 info available for this table */
18922 #define TF_Ephemeral 0x00004000 /* An ephemeral table */
18923 #define TF_Eponymous 0x00008000 /* An eponymous virtual table */
18924 #define TF_Strict 0x00010000 /* STRICT mode */
 
18925
18926 /*
18927 ** Allowed values for Table.eTabType
18928 */
18929 #define TABTYP_NORM 0 /* Ordinary table */
@@ -20086,10 +20148,11 @@
20086 #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
20087 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
20088 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
20089 #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
20090 #define SF_Correlated 0x20000000 /* True if references the outer context */
 
20091
20092 /* True if SrcItem X is a subquery that has SF_NestedFrom */
20093 #define IsNestedFrom(X) \
20094 ((X)->fg.isSubquery && \
20095 ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
@@ -20839,10 +20902,11 @@
20839 struct Table *pTab; /* Table of generated column */
20840 struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */
20841 SrcItem *pSrcItem; /* A single FROM clause item */
20842 DbFixer *pFix; /* See sqlite3FixSelect() */
20843 Mem *aMem; /* See sqlite3BtreeCursorHint() */
 
20844 } u;
20845 };
20846
20847 /*
20848 ** The following structure contains information used by the sqliteFix...
@@ -24209,11 +24273,14 @@
24209 Mem oldipk; /* Memory cell holding "old" IPK value */
24210 Mem *aNew; /* Array of new.* values */
24211 Table *pTab; /* Schema object being updated */
24212 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
24213 sqlite3_value **apDflt; /* Array of default values, if required */
24214 u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
 
 
 
24215 };
24216
24217 /*
24218 ** An instance of this object is used to pass an vector of values into
24219 ** OP_VFilter, the xFilter method of a virtual table. The vector is the
@@ -24976,10 +25043,14 @@
24976 if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
24977 return 1;
24978 }
24979 zDate += 5;
24980 p->tz = sgn*(nMn + nHr*60);
 
 
 
 
24981 zulu_time:
24982 while( sqlite3Isspace(*zDate) ){ zDate++; }
24983 return *zDate!=0;
24984 }
24985
@@ -33486,13 +33557,17 @@
33486 sqlite3StrAccumFinish(&x);
33487 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
33488 n = 0;
33489 if( pItem->fg.isSubquery ) n++;
33490 if( pItem->fg.isTabFunc ) n++;
33491 if( pItem->fg.isUsing ) n++;
33492 if( pItem->fg.isUsing ){
33493 sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
 
 
 
 
33494 }
33495 if( pItem->fg.isSubquery ){
33496 assert( n==1 );
33497 if( pItem->pSTab ){
33498 Table *pTab = pItem->pSTab;
@@ -38131,11 +38206,11 @@
38131 static int kvstorageDelete(const char*, const char *zKey);
38132 static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf);
38133 #define KVSTORAGE_KEY_SZ 32
38134
38135 /* Expand the key name with an appropriate prefix and put the result
38136 ** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least
38137 ** KVSTORAGE_KEY_SZ bytes.
38138 */
38139 static void kvstorageMakeKey(
38140 const char *zClass,
38141 const char *zKeyIn,
@@ -38190,14 +38265,16 @@
38190 ** enough to hold it all. The value put into zBuf must always be zero
38191 ** terminated, even if it gets truncated because nBuf is not large enough.
38192 **
38193 ** Return the total number of bytes in the data, without truncation, and
38194 ** not counting the final zero terminator. Return -1 if the key does
38195 ** not exist.
38196 **
38197 ** If nBuf<=0 then this routine simply returns the size of the data without
38198 ** actually reading it.
 
 
38199 */
38200 static int kvstorageRead(
38201 const char *zClass,
38202 const char *zKey,
38203 char *zBuf,
@@ -38242,15 +38319,13 @@
38242 /*
38243 ** An internal level of indirection which enables us to replace the
38244 ** kvvfs i/o methods with JavaScript implementations in WASM builds.
38245 ** Maintenance reminder: if this struct changes in any way, the JSON
38246 ** rendering of its structure must be updated in
38247 ** sqlite3_wasm_enum_json(). There are no binary compatibility
38248 ** concerns, so it does not need an iVersion member. This file is
38249 ** necessarily always compiled together with sqlite3_wasm_enum_json(),
38250 ** and JS code dynamically creates the mapping of members based on
38251 ** that JSON description.
38252 */
38253 typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods;
38254 struct sqlite3_kvvfs_methods {
38255 int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf);
38256 int (*xWrite)(const char *zClass, const char *zKey, const char *zData);
@@ -38263,12 +38338,12 @@
38263 ** for JavaScript-side implementations in WASM builds. In such builds
38264 ** it cannot be const, but in native builds it should be so that
38265 ** the compiler can hopefully optimize this level of indirection out.
38266 ** That said, kvvfs is intended primarily for use in WASM builds.
38267 **
38268 ** Note that this is not explicitly flagged as static because the
38269 ** amalgamation build will tag it with SQLITE_PRIVATE.
38270 */
38271 #ifndef SQLITE_WASM
38272 const
38273 #endif
38274 SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = {
@@ -39437,14 +39512,15 @@
39437 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
39438 aSyscall[13].pCurrent)
39439
39440 #if defined(HAVE_FCHMOD)
39441 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
 
39442 #else
39443 { "fchmod", (sqlite3_syscall_ptr)0, 0 },
 
39444 #endif
39445 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
39446
39447 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
39448 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
39449 #else
39450 { "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -39698,13 +39774,12 @@
39698 return fd;
39699 }
39700
39701 /*
39702 ** Helper functions to obtain and relinquish the global mutex. The
39703 ** global mutex is used to protect the unixInodeInfo and
39704 ** vxworksFileId objects used by this file, all of which may be
39705 ** shared by multiple threads.
39706 **
39707 ** Function unixMutexHeld() is used to assert() that the global mutex
39708 ** is held when required. This function is only used as part of assert()
39709 ** statements. e.g.
39710 **
@@ -39902,10 +39977,11 @@
39902 /*
39903 ** All unique filenames are held on a linked list headed by this
39904 ** variable:
39905 */
39906 static struct vxworksFileId *vxworksFileList = 0;
 
39907
39908 /*
39909 ** Simplify a filename into its canonical form
39910 ** by making the following changes:
39911 **
@@ -39967,47 +40043,47 @@
39967
39968 /* Search for an existing entry that matching the canonical name.
39969 ** If found, increment the reference count and return a pointer to
39970 ** the existing file ID.
39971 */
39972 unixEnterMutex();
39973 for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
39974 if( pCandidate->nName==n
39975 && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
39976 ){
39977 sqlite3_free(pNew);
39978 pCandidate->nRef++;
39979 unixLeaveMutex();
39980 return pCandidate;
39981 }
39982 }
39983
39984 /* No match was found. We will make a new file ID */
39985 pNew->nRef = 1;
39986 pNew->nName = n;
39987 pNew->pNext = vxworksFileList;
39988 vxworksFileList = pNew;
39989 unixLeaveMutex();
39990 return pNew;
39991 }
39992
39993 /*
39994 ** Decrement the reference count on a vxworksFileId object. Free
39995 ** the object when the reference count reaches zero.
39996 */
39997 static void vxworksReleaseFileId(struct vxworksFileId *pId){
39998 unixEnterMutex();
39999 assert( pId->nRef>0 );
40000 pId->nRef--;
40001 if( pId->nRef==0 ){
40002 struct vxworksFileId **pp;
40003 for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
40004 assert( *pp==pId );
40005 *pp = pId->pNext;
40006 sqlite3_free(pId);
40007 }
40008 unixLeaveMutex();
40009 }
40010 #endif /* OS_VXWORKS */
40011 /*************** End of Unique File ID Utility Used By VxWorks ****************
40012 ******************************************************************************/
40013
@@ -40391,10 +40467,14 @@
40391 do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
40392 if( rc!=1 ){
40393 storeLastErrno(pFile, errno);
40394 return SQLITE_IOERR;
40395 }
 
 
 
 
40396 rc = osFstat(fd, &statbuf);
40397 if( rc!=0 ){
40398 storeLastErrno(pFile, errno);
40399 return SQLITE_IOERR;
40400 }
@@ -40560,22 +40640,46 @@
40560 static int osSetPosixAdvisoryLock(
40561 int h, /* The file descriptor on which to take the lock */
40562 struct flock *pLock, /* The description of the lock */
40563 unixFile *pFile /* Structure holding timeout value */
40564 ){
40565 int tm = pFile->iBusyTimeout;
40566 int rc = osFcntl(h,F_SETLK,pLock);
40567 while( rc<0 && tm>0 ){
40568 /* On systems that support some kind of blocking file lock with a timeout,
40569 ** make appropriate changes here to invoke that blocking file lock. On
40570 ** generic posix, however, there is no such API. So we simply try the
40571 ** lock once every millisecond until either the timeout expires, or until
40572 ** the lock is obtained. */
40573 unixSleep(0,1000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40574 rc = osFcntl(h,F_SETLK,pLock);
40575 tm--;
 
 
40576 }
 
40577 return rc;
40578 }
40579 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
40580
40581
@@ -44892,14 +44996,21 @@
44892 #endif
44893
44894 storeLastErrno(pNew, 0);
44895 #if OS_VXWORKS
44896 if( rc!=SQLITE_OK ){
44897 if( h>=0 ) robust_close(pNew, h, __LINE__);
44898 h = -1;
44899 osUnlink(zFilename);
44900 pNew->ctrlFlags |= UNIXFILE_DELETE;
 
 
 
 
 
 
 
44901 }
44902 #endif
44903 if( rc!=SQLITE_OK ){
44904 if( h>=0 ) robust_close(pNew, h, __LINE__);
44905 }else{
@@ -44939,10 +45050,13 @@
44939 struct stat buf;
44940 const char *zDir = sqlite3_temp_directory;
44941
44942 while(1){
44943 if( zDir!=0
 
 
 
44944 && osStat(zDir, &buf)==0
44945 && S_ISDIR(buf.st_mode)
44946 && osAccess(zDir, 03)==0
44947 ){
44948 return zDir;
@@ -45252,10 +45366,16 @@
45252 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
45253 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
45254 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL
45255 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
45256 );
 
 
 
 
 
 
45257
45258 /* Detect a pid change and reset the PRNG. There is a race condition
45259 ** here such that two or more threads all trying to open databases at
45260 ** the same instant might all reset the PRNG. But multiple resets
45261 ** are harmless.
@@ -45453,12 +45573,15 @@
45453 goto open_finished;
45454 }
45455 }
45456 #endif
45457
45458 assert( zPath==0 || zPath[0]=='/'
45459 || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL
 
 
 
45460 );
45461 rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
45462
45463 open_finished:
45464 if( rc!=SQLITE_OK ){
@@ -47183,10 +47306,13 @@
47183 }
47184 #ifdef SQLITE_OS_KV_OPTIONAL
47185 sqlite3KvvfsInit();
47186 #endif
47187 unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
 
 
 
47188
47189 #ifndef SQLITE_OMIT_WAL
47190 /* Validate lock assumptions */
47191 assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */
47192 assert( UNIX_SHM_BASE==120 ); /* Start of locking area */
@@ -47217,10 +47343,13 @@
47217 ** to release dynamically allocated objects. But not on unix.
47218 ** This routine is a no-op for unix.
47219 */
47220 SQLITE_API int sqlite3_os_end(void){
47221 unixBigLock = 0;
 
 
 
47222 return SQLITE_OK;
47223 }
47224
47225 #endif /* SQLITE_OS_UNIX */
47226
@@ -51349,33 +51478,39 @@
51349 ** log-summary, each thread has its own winFile object, but they all
51350 ** point to a single instance of this object. In other words, each
51351 ** log-summary is opened only once per process.
51352 **
51353 ** winShmMutexHeld() must be true when creating or destroying
51354 ** this object or while reading or writing the following fields:
 
51355 **
51356 ** nRef
51357 ** pNext
51358 **
51359 ** The following fields are read-only after the object is created:
51360 **
51361 ** zFilename
 
 
 
51362 **
51363 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
51364 ** winShmMutexHeld() is true when reading or writing any other field
51365 ** in this structure.
51366 **
51367 ** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate
51368 ** the *-shm file if the DMS-locking protocol demands it, and (c) map
51369 ** regions of the *-shm file into memory using MapViewOfFile() or
51370 ** similar. Other locks are taken by individual clients using the
51371 ** winShm.hShm handles.
 
51372 */
51373 struct winShmNode {
51374 sqlite3_mutex *mutex; /* Mutex to access this object */
51375 char *zFilename; /* Name of the file */
51376 HANDLE hSharedShm; /* File handle open on zFilename */
 
51377
51378 int isUnlocked; /* DMS lock has not yet been obtained */
51379 int isReadonly; /* True if read-only */
51380 int szRegion; /* Size of shared-memory regions */
51381 int nRegion; /* Size of array apRegion */
@@ -51384,11 +51519,12 @@
51384 HANDLE hMap; /* File handle from CreateFileMapping */
51385 void *pMap;
51386 } *aRegion;
51387 DWORD lastErrno; /* The Windows errno from the last I/O error */
51388
51389 int nRef; /* Number of winShm objects pointing to this */
 
51390 winShmNode *pNext; /* Next in list of all winShmNode objects */
51391 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51392 u8 nextShmId; /* Next available winShm.id value */
51393 #endif
51394 };
@@ -51412,10 +51548,11 @@
51412 HANDLE hShm; /* File-handle on *-shm file. For locking. */
51413 int bReadonly; /* True if hShm is opened read-only */
51414 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51415 u8 id; /* Id of this connection with its winShmNode */
51416 #endif
 
51417 };
51418
51419 /*
51420 ** Constants used for locking
51421 */
@@ -51425,11 +51562,11 @@
51425 /* Forward references to VFS methods */
51426 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
51427 static int winDelete(sqlite3_vfs *,const char*,int);
51428
51429 /*
51430 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
51431 **
51432 ** This is not a VFS shared-memory method; it is a utility function called
51433 ** by VFS shared-memory methods.
51434 */
51435 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
@@ -51438,11 +51575,11 @@
51438 assert( winShmMutexHeld() );
51439 OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
51440 osGetCurrentProcessId(), deleteFlag));
51441 pp = &winShmNodeList;
51442 while( (p = *pp)!=0 ){
51443 if( p->nRef==0 ){
51444 int i;
51445 if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
51446 for(i=0; i<p->nRegion; i++){
51447 BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
51448 OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
@@ -51602,10 +51739,64 @@
51602 *pbReadonly = bReadonly;
51603 *ph = h;
51604 return rc;
51605 }
51606
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51607
51608 /*
51609 ** Open the shared-memory area associated with database file pDbFd.
51610 */
51611 static int winOpenSharedMemory(winFile *pDbFd){
@@ -51628,19 +51819,14 @@
51628 return SQLITE_IOERR_NOMEM_BKPT;
51629 }
51630 pNew->zFilename = (char*)&pNew[1];
51631 pNew->hSharedShm = INVALID_HANDLE_VALUE;
51632 pNew->isUnlocked = 1;
 
51633 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
51634 sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
51635
51636 /* Open a file-handle on the *-shm file for this connection. This file-handle
51637 ** is only used for locking. The mapping of the *-shm file is created using
51638 ** the shared file handle in winShmNode.hSharedShm. */
51639 p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0);
51640 rc = winHandleOpen(pNew->zFilename, &p->bReadonly, &p->hShm);
51641
51642 /* Look to see if there is an existing winShmNode that can be used.
51643 ** If no matching winShmNode currently exists, then create a new one. */
51644 winShmEnterMutex();
51645 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
51646 /* TBD need to come up with better match here. Perhaps
@@ -51657,11 +51843,11 @@
51657 }
51658
51659 /* Open a file-handle to use for mappings, and for the DMS lock. */
51660 if( rc==SQLITE_OK ){
51661 HANDLE h = INVALID_HANDLE_VALUE;
51662 pShmNode->isReadonly = p->bReadonly;
51663 rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h);
51664 pShmNode->hSharedShm = h;
51665 }
51666
51667 /* If successful, link the new winShmNode into the global list. If an
@@ -51679,24 +51865,39 @@
51679 }
51680
51681 /* If no error has occurred, link the winShm object to the winShmNode and
51682 ** the winShm to pDbFd. */
51683 if( rc==SQLITE_OK ){
 
51684 p->pShmNode = pShmNode;
51685 pShmNode->nRef++;
 
51686 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51687 p->id = pShmNode->nextShmId++;
51688 #endif
51689 pDbFd->pShm = p;
 
51690 }else if( p ){
51691 winHandleClose(p->hShm);
51692 sqlite3_free(p);
51693 }
51694
51695 assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 );
51696 winShmLeaveMutex();
51697 sqlite3_free(pNew);
 
 
 
 
 
 
 
 
 
 
 
 
 
51698 return rc;
51699 }
51700
51701 /*
51702 ** Close a connection to shared-memory. Delete the underlying
@@ -51704,37 +51905,11 @@
51704 */
51705 static int winShmUnmap(
51706 sqlite3_file *fd, /* Database holding shared memory */
51707 int deleteFlag /* Delete after closing if true */
51708 ){
51709 winFile *pDbFd; /* Database holding shared-memory */
51710 winShm *p; /* The connection to be closed */
51711 winShmNode *pShmNode; /* The underlying shared-memory file */
51712
51713 pDbFd = (winFile*)fd;
51714 p = pDbFd->pShm;
51715 if( p==0 ) return SQLITE_OK;
51716 if( p->hShm!=INVALID_HANDLE_VALUE ){
51717 osCloseHandle(p->hShm);
51718 }
51719
51720 pShmNode = p->pShmNode;
51721 winShmEnterMutex();
51722
51723 /* If pShmNode->nRef has reached 0, then close the underlying
51724 ** shared-memory file, too. */
51725 assert( pShmNode->nRef>0 );
51726 pShmNode->nRef--;
51727 if( pShmNode->nRef==0 ){
51728 winShmPurge(pDbFd->pVfs, deleteFlag);
51729 }
51730 winShmLeaveMutex();
51731
51732 /* Free the connection p */
51733 sqlite3_free(p);
51734 pDbFd->pShm = 0;
51735 return SQLITE_OK;
51736 }
51737
51738 /*
51739 ** Change the lock state for a shared-memory segment.
51740 */
@@ -51799,29 +51974,75 @@
51799 );
51800 if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
51801 || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
51802 || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
51803 ){
 
51804
51805 if( flags & SQLITE_SHM_UNLOCK ){
51806 /* Case (a) - unlock. */
51807
51808 assert( (p->exclMask & p->sharedMask)==0 );
51809 assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
51810 assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
51811
51812 rc = winHandleUnlock(p->hShm, ofst+WIN_SHM_BASE, n);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51813
51814 /* If successful, also clear the bits in sharedMask/exclMask */
51815 if( rc==SQLITE_OK ){
51816 p->exclMask = (p->exclMask & ~mask);
51817 p->sharedMask = (p->sharedMask & ~mask);
51818 }
51819 }else{
51820 int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0);
51821 DWORD nMs = winFileBusyTimeout(pDbFd);
51822 rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51823 if( rc==SQLITE_OK ){
51824 if( bExcl ){
51825 p->exclMask = (p->exclMask | mask);
51826 }else{
51827 p->sharedMask = (p->sharedMask | mask);
@@ -61848,18 +62069,31 @@
61848 SQLITE_PRIVATE void sqlite3PagerSetFlags(
61849 Pager *pPager, /* The pager to set safety level for */
61850 unsigned pgFlags /* Various flags */
61851 ){
61852 unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
61853 if( pPager->tempFile ){
61854 pPager->noSync = 1;
61855 pPager->fullSync = 0;
61856 pPager->extraSync = 0;
61857 }else{
61858 pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0;
61859 pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
61860 pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
 
 
 
 
 
 
 
 
 
 
 
 
 
61861 }
61862 if( pPager->noSync ){
61863 pPager->syncFlags = 0;
61864 }else if( pgFlags & PAGER_FULLFSYNC ){
61865 pPager->syncFlags = SQLITE_SYNC_FULL;
@@ -65748,11 +65982,11 @@
65748 */
65749 sqlite3_exec(db, "PRAGMA table_list",0,0,0);
65750 }
65751 if( pPager->pWal ){
65752 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
65753 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
65754 pPager->pBusyHandlerArg,
65755 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
65756 pnLog, pnCkpt
65757 );
65758 }
@@ -70353,11 +70587,12 @@
70353 assert( pWal->ckptLock==0 );
70354 assert( pWal->writeLock==0 );
70355
70356 /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
70357 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
70358 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
 
70359
70360 if( pWal->readOnly ) return SQLITE_READONLY;
70361 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
70362
70363 /* Enable blocking locks, if possible. */
@@ -70370,35 +70605,39 @@
70370 ** checkpoint operation at the same time, the lock cannot be obtained and
70371 ** SQLITE_BUSY is returned.
70372 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
70373 ** it will not be invoked in this case.
70374 */
70375 rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
70376 testcase( rc==SQLITE_BUSY );
70377 testcase( rc!=SQLITE_OK && xBusy2!=0 );
70378 if( rc==SQLITE_OK ){
70379 pWal->ckptLock = 1;
70380
70381 /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
70382 ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
70383 ** file.
70384 **
70385 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
70386 ** immediately, and a busy-handler is configured, it is invoked and the
70387 ** writer lock retried until either the busy-handler returns 0 or the
70388 ** lock is successfully obtained.
70389 */
70390 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
70391 rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
70392 if( rc==SQLITE_OK ){
70393 pWal->writeLock = 1;
70394 }else if( rc==SQLITE_BUSY ){
70395 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
70396 xBusy2 = 0;
70397 rc = SQLITE_OK;
70398 }
70399 }
 
 
 
 
70400 }
70401
70402
70403 /* Read the wal-index header. */
70404 SEH_TRY {
@@ -70408,21 +70647,21 @@
70408 ** or invoke the busy handler. The only lock such a checkpoint may
70409 ** attempt to obtain is a lock on a read-slot, and it should give up
70410 ** immediately and do a partial checkpoint if it cannot obtain it. */
70411 walDisableBlocking(pWal);
70412 rc = walIndexReadHdr(pWal, &isChanged);
70413 if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
70414 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
70415 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
70416 }
70417 }
70418
70419 /* Copy data from the log to the database file. */
70420 if( rc==SQLITE_OK ){
70421 if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
70422 rc = SQLITE_CORRUPT_BKPT;
70423 }else{
70424 rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf);
70425 }
70426
70427 /* If no error occurred, set the output variables. */
70428 if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
@@ -91645,11 +91884,11 @@
91645
91646 preupdate.v = v;
91647 preupdate.pCsr = pCsr;
91648 preupdate.op = op;
91649 preupdate.iNewReg = iReg;
91650 preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace;
91651 preupdate.pKeyinfo->db = db;
91652 preupdate.pKeyinfo->enc = ENC(db);
91653 preupdate.pKeyinfo->nKeyField = pTab->nCol;
91654 preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */
91655 preupdate.iKey1 = iKey1;
@@ -102528,10 +102767,11 @@
102528 aRes[1] = aRes[2] = -1;
102529 assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
102530 || pOp->p2==SQLITE_CHECKPOINT_FULL
102531 || pOp->p2==SQLITE_CHECKPOINT_RESTART
102532 || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
 
102533 );
102534 rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
102535 if( rc ){
102536 if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
102537 rc = SQLITE_OK;
@@ -110651,18 +110891,21 @@
110651 ExprList *pList /* Expression list to resolve. May be NULL. */
110652 ){
110653 SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */
110654 NameContext sNC; /* Name context for pParse->pNewTable */
110655 int rc;
110656 u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */
 
 
 
110657
110658 assert( type==0 || pTab!=0 );
110659 assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
110660 || type==NC_GenCol || pTab==0 );
110661 memset(&sNC, 0, sizeof(sNC));
110662 pSrc = (SrcList*)srcSpace;
110663 memset(pSrc, 0, SZ_SRCLIST_1);
110664 if( pTab ){
110665 pSrc->nSrc = 1;
110666 pSrc->a[0].zName = pTab->zName;
110667 pSrc->a[0].pSTab = pTab;
110668 pSrc->a[0].iCursor = -1;
@@ -111921,10 +112164,15 @@
111921 if( IsWindowFunc(pExpr) ){
111922 sqlite3ExprOrderByAggregateError(pParse, pExpr);
111923 sqlite3ExprListDelete(db, pOrderBy);
111924 return;
111925 }
 
 
 
 
 
111926
111927 pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0);
111928 if( pOB==0 ){
111929 sqlite3ExprListDelete(db, pOrderBy);
111930 return;
@@ -113117,13 +113365,12 @@
113117 }
113118 r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1);
113119 if( addrIsNull==0 ){
113120 /*
113121 ** If the right operand contains a subquery and the left operand does not
113122 ** and the left operand might be NULL, then check the left operand do
113123 ** an IsNull check on the left operand before computing the right
113124 ** operand.
113125 */
113126 if( ExprHasProperty(pExpr->pRight, EP_Subquery)
113127 && sqlite3ExprCanBeNull(pExpr->pLeft)
113128 ){
113129 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1);
@@ -114683,11 +114930,10 @@
114683 int destIfNull /* Jump here if the results are unknown due to NULLs */
114684 ){
114685 int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
114686 int eType; /* Type of the RHS */
114687 int rLhs; /* Register(s) holding the LHS values */
114688 int rLhsOrig; /* LHS values prior to reordering by aiMap[] */
114689 Vdbe *v; /* Statement under construction */
114690 int *aiMap = 0; /* Map from vector field to index column */
114691 char *zAff = 0; /* Affinity string for comparisons */
114692 int nVector; /* Size of vectors for this IN operator */
114693 int iDummy; /* Dummy parameter to exprCodeVector() */
@@ -114746,23 +114992,12 @@
114746 ** Avoid factoring the LHS of the IN(...) expression out of the loop,
114747 ** even if it is constant, as OP_Affinity may be used on the register
114748 ** by code generated below. */
114749 assert( pParse->okConstFactor==okConstFactor );
114750 pParse->okConstFactor = 0;
114751 rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
114752 pParse->okConstFactor = okConstFactor;
114753 for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
114754 if( i==nVector ){
114755 /* LHS fields are not reordered */
114756 rLhs = rLhsOrig;
114757 }else{
114758 /* Need to reorder the LHS fields according to aiMap */
114759 rLhs = sqlite3GetTempRange(pParse, nVector);
114760 for(i=0; i<nVector; i++){
114761 sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
114762 }
114763 }
114764
114765 /* If sqlite3FindInIndex() did not find or create an index that is
114766 ** suitable for evaluating the IN operator, then evaluate using a
114767 ** sequence of comparisons.
114768 **
@@ -114773,10 +115008,11 @@
114773 CollSeq *pColl;
114774 int labelOk = sqlite3VdbeMakeLabel(pParse);
114775 int r2, regToFree;
114776 int regCkNull = 0;
114777 int ii;
 
114778 assert( ExprUseXList(pExpr) );
114779 pList = pExpr->x.pList;
114780 pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
114781 if( destIfNull!=destIfFalse ){
114782 regCkNull = sqlite3GetTempReg(pParse);
@@ -114813,10 +115049,30 @@
114813 }
114814 sqlite3VdbeResolveLabel(v, labelOk);
114815 sqlite3ReleaseTempReg(pParse, regCkNull);
114816 goto sqlite3ExprCodeIN_finished;
114817 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114818
114819 /* Step 2: Check to see if the LHS contains any NULL columns. If the
114820 ** LHS does contain NULLs then the result must be either FALSE or NULL.
114821 ** We will then skip the binary search of the RHS.
114822 */
@@ -114840,15 +115096,15 @@
114840 */
114841 if( eType==IN_INDEX_ROWID ){
114842 /* In this case, the RHS is the ROWID of table b-tree and so we also
114843 ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
114844 ** into a single opcode. */
 
114845 sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
114846 VdbeCoverage(v);
114847 addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
114848 }else{
114849 sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
114850 if( destIfFalse==destIfNull ){
114851 /* Combine Step 3 and Step 5 into a single opcode */
114852 if( ExprHasProperty(pExpr, EP_Subrtn) ){
114853 const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
114854 assert( pOp->opcode==OP_Once || pParse->nErr );
@@ -114922,11 +115178,10 @@
114922
114923 /* Jumps here in order to return true. */
114924 sqlite3VdbeJumpHere(v, addrTruthOp);
114925
114926 sqlite3ExprCodeIN_finished:
114927 if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
114928 VdbeComment((v, "end IN expr"));
114929 sqlite3ExprCodeIN_oom_error:
114930 sqlite3DbFree(pParse->db, aiMap);
114931 sqlite3DbFree(pParse->db, zAff);
114932 }
@@ -115480,10 +115735,82 @@
115480 }
115481 }
115482 return 0;
115483 }
115484
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115485
115486 /*
115487 ** Generate code into the current Vdbe to evaluate the given
115488 ** expression. Attempt to store the results in register "target".
115489 ** Return the register where results are stored.
@@ -115768,16 +116095,18 @@
115768 sqlite3VdbeAddOp2(v, OP_Null, 0, inReg);
115769 }
115770 }
115771 testcase( regFree1==0 );
115772 testcase( regFree2==0 );
115773
115774 }
115775 break;
115776 }
115777 case TK_AND:
115778 case TK_OR:
 
 
 
115779 case TK_PLUS:
115780 case TK_STAR:
115781 case TK_MINUS:
115782 case TK_REM:
115783 case TK_BITAND:
@@ -115785,12 +116114,10 @@
115785 case TK_SLASH:
115786 case TK_LSHIFT:
115787 case TK_RSHIFT:
115788 case TK_CONCAT: {
115789 int addrIsNull;
115790 assert( TK_AND==OP_And ); testcase( op==TK_AND );
115791 assert( TK_OR==OP_Or ); testcase( op==TK_OR );
115792 assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
115793 assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
115794 assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
115795 assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
115796 assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
@@ -124573,11 +124900,11 @@
124573 */
124574 SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
124575 int i;
124576 i16 iCol16;
124577 assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
124578 assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 );
124579 iCol16 = iCol;
124580 for(i=0; i<pIdx->nColumn; i++){
124581 if( iCol16==pIdx->aiColumn[i] ){
124582 return i;
124583 }
@@ -124870,10 +125197,13 @@
124870 sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
124871 sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
124872 sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
124873 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
124874 sqlite3VdbeAddOp0(v, OP_Close);
 
 
 
124875 }
124876
124877 /* Normal (non-error) return. */
124878 return;
124879
@@ -129165,18 +129495,23 @@
129165 pKey->aSortFlags[i] = pIdx->aSortOrder[i];
129166 assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
129167 }
129168 if( pParse->nErr ){
129169 assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
129170 if( pIdx->bNoQuery==0 ){
 
 
129171 /* Deactivate the index because it contains an unknown collating
129172 ** sequence. The only way to reactive the index is to reload the
129173 ** schema. Adding the missing collating sequence later does not
129174 ** reactive the index. The application had the chance to register
129175 ** the missing index using the collation-needed callback. For
129176 ** simplicity, SQLite will not give the application a second chance.
129177 */
 
 
 
129178 pIdx->bNoQuery = 1;
129179 pParse->rc = SQLITE_ERROR_RETRY;
129180 }
129181 sqlite3KeyInfoUnref(pKey);
129182 pKey = 0;
@@ -139247,10 +139582,12 @@
139247 /* Version 3.44.0 and later */
139248 void *(*get_clientdata)(sqlite3*,const char*);
139249 int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
139250 /* Version 3.50.0 and later */
139251 int (*setlk_timeout)(sqlite3*,int,int);
 
 
139252 };
139253
139254 /*
139255 ** This is the function signature used for all extension entry points. It
139256 ** is also defined in the file "loadext.c".
@@ -139582,10 +139919,12 @@
139582 /* Version 3.44.0 and later */
139583 #define sqlite3_get_clientdata sqlite3_api->get_clientdata
139584 #define sqlite3_set_clientdata sqlite3_api->set_clientdata
139585 /* Version 3.50.0 and later */
139586 #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
 
 
139587 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
139588
139589 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
139590 /* This case when the file really is being compiled as a loadable
139591 ** extension */
@@ -140105,11 +140444,13 @@
140105 sqlite3_stmt_explain,
140106 /* Version 3.44.0 and later */
140107 sqlite3_get_clientdata,
140108 sqlite3_set_clientdata,
140109 /* Version 3.50.0 and later */
140110 sqlite3_setlk_timeout
 
 
140111 };
140112
140113 /* True if x is the directory separator character
140114 */
140115 #if SQLITE_OS_WIN
@@ -141566,10 +141907,26 @@
141566 addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
141567 VdbeCoverage(v);
141568 sqlite3VdbeAddOp0(v, OP_Halt);
141569 return addr;
141570 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141571
141572 /*
141573 ** Process a pragma statement.
141574 **
141575 ** Pragmas are of this form:
@@ -142912,11 +143269,11 @@
142912 pTbls = &db->aDb[i].pSchema->tblHash;
142913 for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142914 Table *pTab = sqliteHashData(x); /* Current table */
142915 Index *pIdx; /* An index on pTab */
142916 int nIdx; /* Number of indexes on pTab */
142917 if( pObjTab && pObjTab!=pTab ) continue;
142918 if( HasRowid(pTab) ) cnt++;
142919 for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
142920 }
142921 if( cnt==0 ) continue;
142922 if( pObjTab ) cnt++;
@@ -142925,11 +143282,11 @@
142925 cnt = 0;
142926 if( pObjTab ) aRoot[++cnt] = 0;
142927 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142928 Table *pTab = sqliteHashData(x);
142929 Index *pIdx;
142930 if( pObjTab && pObjTab!=pTab ) continue;
142931 if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
142932 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
142933 aRoot[++cnt] = pIdx->tnum;
142934 }
142935 }
@@ -142956,11 +143313,11 @@
142956 sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
142957 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
142958 int iTab = 0;
142959 Table *pTab = sqliteHashData(x);
142960 Index *pIdx;
142961 if( pObjTab && pObjTab!=pTab ) continue;
142962 if( HasRowid(pTab) ){
142963 iTab = cnt++;
142964 }else{
142965 iTab = cnt;
142966 for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){
@@ -142992,11 +143349,11 @@
142992 int r1 = -1;
142993 int bStrict; /* True for a STRICT table */
142994 int r2; /* Previous key for WITHOUT ROWID tables */
142995 int mxCol; /* Maximum non-virtual column number */
142996
142997 if( pObjTab && pObjTab!=pTab ) continue;
142998 if( !IsOrdinaryTable(pTab) ) continue;
142999 if( isQuick || HasRowid(pTab) ){
143000 pPk = 0;
143001 r2 = 0;
143002 }else{
@@ -143316,11 +143673,11 @@
143316 */
143317 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143318 Table *pTab = sqliteHashData(x);
143319 sqlite3_vtab *pVTab;
143320 int a1;
143321 if( pObjTab && pObjTab!=pTab ) continue;
143322 if( IsOrdinaryTable(pTab) ) continue;
143323 if( !IsVirtual(pTab) ) continue;
143324 if( pTab->nCol<=0 ){
143325 const char *zMod = pTab->u.vtab.azArg[0];
143326 if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
@@ -143548,10 +143905,12 @@
143548 eMode = SQLITE_CHECKPOINT_FULL;
143549 }else if( sqlite3StrICmp(zRight, "restart")==0 ){
143550 eMode = SQLITE_CHECKPOINT_RESTART;
143551 }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
143552 eMode = SQLITE_CHECKPOINT_TRUNCATE;
 
 
143553 }
143554 }
143555 pParse->nMem = 3;
143556 sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
143557 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
@@ -145114,13 +145473,15 @@
145114 ** or encounters a permanent error. A schema problem after one schema
145115 ** reset is considered a permanent error. */
145116 rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
145117 assert( rc==SQLITE_OK || *ppStmt==0 );
145118 if( rc==SQLITE_OK || db->mallocFailed ) break;
145119 }while( (rc==SQLITE_ERROR_RETRY && (cnt++)<SQLITE_MAX_PREPARE_RETRY)
145120 || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
 
145121 sqlite3BtreeLeaveAll(db);
 
145122 rc = sqlite3ApiExit(db, rc);
145123 assert( (rc&db->errMask)==rc );
145124 db->busyHandler.nBusy = 0;
145125 sqlite3_mutex_leave(db->mutex);
145126 assert( rc==SQLITE_OK || (*ppStmt)==0 );
@@ -145790,12 +146151,11 @@
145790 while( p ){
145791 ExprSetProperty(p, joinFlag);
145792 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
145793 ExprSetVVAProperty(p, EP_NoReduce);
145794 p->w.iJoin = iTable;
145795 if( p->op==TK_FUNCTION ){
145796 assert( ExprUseXList(p) );
145797 if( p->x.pList ){
145798 int i;
145799 for(i=0; i<p->x.pList->nExpr; i++){
145800 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
145801 }
@@ -146007,10 +146367,11 @@
146007 else if( pRight->u3.pOn ){
146008 sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
146009 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
146010 pRight->u3.pOn = 0;
146011 pRight->fg.isOn = 1;
 
146012 }
146013 }
146014 return 0;
146015 }
146016
@@ -146893,11 +147254,14 @@
146893 ** Allocate a KeyInfo object sufficient for an index of N key columns and
146894 ** X extra columns.
146895 */
146896 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
146897 int nExtra = (N+X)*(sizeof(CollSeq*)+1);
146898 KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra);
 
 
 
146899 if( p ){
146900 p->aSortFlags = (u8*)&p->aColl[N+X];
146901 p->nKeyField = (u16)N;
146902 p->nAllField = (u16)(N+X);
146903 p->enc = ENC(db);
@@ -149212,11 +149576,11 @@
149212 ** expressions in pEList.
149213 **
149214 ** ## About "isOuterJoin":
149215 **
149216 ** The isOuterJoin column indicates that the replacement will occur into a
149217 ** position in the parent that NULL-able due to an OUTER JOIN. Either the
149218 ** target slot in the parent is the right operand of a LEFT JOIN, or one of
149219 ** the left operands of a RIGHT JOIN. In either case, we need to potentially
149220 ** bypass the substituted expression with OP_IfNullRow.
149221 **
149222 ** Suppose the original expression is an integer constant. Even though the table
@@ -150050,21 +150414,16 @@
150050 ** elements we are now copying in.
150051 */
150052 pSub = pSub1;
150053 for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
150054 int nSubSrc;
150055 u8 jointype = 0;
150056 u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ;
150057 assert( pSub!=0 );
150058 pSubSrc = pSub->pSrc; /* FROM clause of subquery */
150059 nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
150060 pSrc = pParent->pSrc; /* FROM clause of the outer query */
150061
150062 if( pParent==p ){
150063 jointype = pSubitem->fg.jointype; /* First time through the loop */
150064 }
150065
150066 /* The subquery uses a single slot of the FROM clause of the outer
150067 ** query. If the subquery has more than one element in its FROM clause,
150068 ** then expand the outer query to make space for it to hold all elements
150069 ** of the subquery.
150070 **
@@ -150080,10 +150439,11 @@
150080 */
150081 if( nSubSrc>1 ){
150082 pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
150083 if( pSrc==0 ) break;
150084 pParent->pSrc = pSrc;
 
150085 }
150086
150087 /* Transfer the FROM clause terms from the subquery into the
150088 ** outer query.
150089 */
@@ -150094,15 +150454,14 @@
150094 assert( pItem->fg.isSubquery
150095 || pItem->fg.fixedSchema
150096 || pItem->u4.zDatabase==0 );
150097 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
150098 *pItem = pSubSrc->a[i];
150099 pItem->fg.jointype |= ltorj;
150100 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
150101 }
150102 pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
150103 pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
150104
150105 /* Now begin substituting subquery result set expressions for
150106 ** references to the iParent in the outer query.
150107 **
150108 ** Example:
@@ -152838,10 +153197,119 @@
152838 existsToJoin(pParse, p, pSubWhere);
152839 }
152840 }
152841 }
152842 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152843
152844 /*
152845 ** Generate byte-code for the SELECT statement given in the p argument.
152846 **
152847 ** The results are returned according to the SelectDest structure.
@@ -152965,10 +153433,22 @@
152965 if( sqlite3TreeTrace & 0x10 ){
152966 TREETRACE(0x10,pParse,p, ("after name resolution:\n"));
152967 sqlite3TreeViewSelect(0, p, 0);
152968 }
152969 #endif
 
 
 
 
 
 
 
 
 
 
 
 
152970
152971 /* If the SF_UFSrcCheck flag is set, then this function is being called
152972 ** as part of populating the temp table for an UPDATE...FROM statement.
152973 ** In this case, it is an error if the target object (pSrc->a[0]) name
152974 ** or alias is duplicated within FROM clause (pSrc->a[1..n]).
@@ -155531,11 +156011,14 @@
155531 sqlite3 *db = pParse->db;
155532 ExprList *pNew;
155533 Returning *pReturning;
155534 Select sSelect;
155535 SrcList *pFrom;
155536 u8 fromSpace[SZ_SRCLIST_1];
 
 
 
155537
155538 assert( v!=0 );
155539 if( !pParse->bReturning ){
155540 /* This RETURNING trigger must be for a different statement as
155541 ** this statement lacks a RETURNING clause. */
@@ -155547,12 +156030,12 @@
155547 if( pTrigger != &(pReturning->retTrig) ){
155548 /* This RETURNING trigger is for a different statement */
155549 return;
155550 }
155551 memset(&sSelect, 0, sizeof(sSelect));
155552 pFrom = (SrcList*)fromSpace;
155553 memset(pFrom, 0, SZ_SRCLIST_1);
155554 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
155555 sSelect.pSrc = pFrom;
155556 pFrom->nSrc = 1;
155557 pFrom->a[0].pSTab = pTab;
155558 pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */
@@ -163079,11 +163562,14 @@
163079 WhereClause *pWC = &pWInfo->sWC;
163080 WhereInfo *pSubWInfo;
163081 WhereLoop *pLoop = pLevel->pWLoop;
163082 SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
163083 SrcList *pFrom;
163084 u8 fromSpace[SZ_SRCLIST_1];
 
 
 
163085 Bitmask mAll = 0;
163086 int k;
163087
163088 ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
163089 sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
@@ -163123,11 +163609,11 @@
163123 if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
163124 pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
163125 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
163126 }
163127 }
163128 pFrom = (SrcList*)fromSpace;
163129 pFrom->nSrc = 1;
163130 pFrom->nAlloc = 1;
163131 memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem));
163132 pFrom->a[0].fg.jointype = 0;
163133 assert( pParse->withinRJSubrtn < 100 );
@@ -164340,25 +164826,11 @@
164340 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
164341 if( ExprHasProperty(pExpr, EP_OuterON) ){
164342 prereqAll |= x;
164343 extraRight = x-1; /* ON clause terms may not be used with an index
164344 ** on left table of a LEFT JOIN. Ticket #3015 */
164345 if( (prereqAll>>1)>=x ){
164346 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
164347 return;
164348 }
164349 }else if( (prereqAll>>1)>=x ){
164350 /* The ON clause of an INNER JOIN references a table to its right.
164351 ** Most other SQL database engines raise an error. But SQLite versions
164352 ** 3.0 through 3.38 just put the ON clause constraint into the WHERE
164353 ** clause and carried on. Beginning with 3.39, raise an error only
164354 ** if there is a RIGHT or FULL JOIN in the query. This makes SQLite
164355 ** more like other systems, and also preserves legacy. */
164356 if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
164357 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
164358 return;
164359 }
164360 ExprClearProperty(pExpr, EP_InnerON);
164361 }
164362 }
164363 pTerm->prereqAll = prereqAll;
164364 pTerm->leftCursor = -1;
@@ -170216,10 +170688,14 @@
170216 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
170217 if( pLoop->u.vtab.isOrdered
170218 && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
170219 ){
170220 obSat = obDone;
 
 
 
 
170221 }
170222 break;
170223 }
170224 iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
170225
@@ -171119,22 +171595,18 @@
171119 pFrom = aTo;
171120 aTo = aFrom;
171121 aFrom = pFrom;
171122 nFrom = nTo;
171123 }
 
171124
171125 if( nFrom==0 ){
171126 sqlite3ErrorMsg(pParse, "no query solution");
171127 sqlite3StackFreeNN(pParse->db, pSpace);
171128 return SQLITE_ERROR;
171129 }
171130
171131 /* Find the lowest cost path. pFrom will be left pointing to that path */
171132 pFrom = aFrom;
171133 for(ii=1; ii<nFrom; ii++){
171134 if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
171135 }
171136 assert( pWInfo->nLevel==nLoop );
171137 /* Load the lowest cost path into pWInfo */
171138 for(iLoop=0; iLoop<nLoop; iLoop++){
171139 WhereLevel *pLevel = pWInfo->a + iLoop;
171140 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -171263,11 +171735,14 @@
171263 int once = 0;
171264 #endif
171265 for(i=0; i<pWInfo->nLevel; i++){
171266 WhereLoop *p = pWInfo->a[i].pWLoop;
171267 if( p==0 ) break;
171268 if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue;
 
 
 
171269 if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
171270 u8 iTab = p->iTab;
171271 WhereLoop *pLoop;
171272 for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
171273 if( pLoop->iTab!=iTab ) continue;
@@ -175376,11 +175851,11 @@
175376 ** RETURN_ROW
175377 **
175378 **
175379 ** ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
175380 **
175381 ** ... loop started by sqlite3WhereBegin() ...
175382 ** if( new partition ){
175383 ** Gosub flush
175384 ** }
175385 ** Insert new row into eph table.
175386 ** if( first row of partition ){
@@ -175894,10 +176369,16 @@
175894 addrStart = sqlite3VdbeCurrentAddr(v);
175895 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
175896 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
175897 }else{
175898 assert( pMWin->eEnd==TK_FOLLOWING );
 
 
 
 
 
 
175899 addrStart = sqlite3VdbeCurrentAddr(v);
175900 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
175901 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
175902 }
175903 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
@@ -184839,10 +185320,13 @@
184839 for(i=0; i<2 && zName==0; i++, rc &= 0xff){
184840 switch( rc ){
184841 case SQLITE_OK: zName = "SQLITE_OK"; break;
184842 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
184843 case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break;
 
 
 
184844 case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
184845 case SQLITE_PERM: zName = "SQLITE_PERM"; break;
184846 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
184847 case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
184848 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
@@ -186019,10 +186503,33 @@
186019 }
186020 }
186021 sqlite3_mutex_leave(db->mutex);
186022 return z;
186023 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186024
186025 /*
186026 ** Return the byte offset of the most recent error
186027 */
186028 SQLITE_API int sqlite3_error_offset(sqlite3 *db){
@@ -187844,17 +188351,19 @@
187844 case SQLITE_TESTCTRL_ISINIT: {
187845 if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
187846 break;
187847 }
187848
187849 /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
187850 **
187851 ** This test control is used to create imposter tables. "db" is a pointer
187852 ** to the database connection. dbName is the database name (ex: "main" or
187853 ** "temp") which will receive the imposter. "onOff" turns imposter mode on
187854 ** or off. "tnum" is the root page of the b-tree to which the imposter
187855 ** table should connect.
 
 
187856 **
187857 ** Enable imposter mode only when the schema has already been parsed. Then
187858 ** run a single CREATE TABLE statement to construct the imposter table in
187859 ** the parsed schema. Then turn imposter mode back off again.
187860 **
@@ -189087,21 +189596,24 @@
189087 **
189088 */
189089 #ifndef _FTSINT_H
189090 #define _FTSINT_H
189091
 
 
 
 
 
 
 
189092 /* #include <assert.h> */
189093 /* #include <stdlib.h> */
189094 /* #include <stddef.h> */
189095 /* #include <stdio.h> */
189096 /* #include <string.h> */
189097 /* #include <stdarg.h> */
189098
189099 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189100 # define NDEBUG 1
189101 #endif
189102
189103 /* FTS3/FTS4 require virtual tables */
189104 #ifdef SQLITE_OMIT_VIRTUALTABLE
189105 # undef SQLITE_ENABLE_FTS3
189106 # undef SQLITE_ENABLE_FTS4
189107 #endif
@@ -189540,17 +190052,10 @@
189540 /*
189541 ** Macro used to suppress compiler warnings for unused parameters.
189542 */
189543 #define UNUSED_PARAMETER(x) (void)(x)
189544
189545 /*
189546 ** Activate assert() only if SQLITE_TEST is enabled.
189547 */
189548 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189549 # define NDEBUG 1
189550 #endif
189551
189552 /*
189553 ** The TESTONLY macro is used to enclose variable declarations or
189554 ** other bits of code that are needed to support the arguments
189555 ** within testcase() and assert() macros.
189556 */
@@ -203821,12 +204326,12 @@
203821 /*
203822 ** An object of this type contains the state required to create or append
203823 ** to an appendable b-tree segment.
203824 */
203825 struct IncrmergeWriter {
203826 int nLeafEst; /* Space allocated for leaf blocks */
203827 int nWork; /* Number of leaf pages flushed */
203828 sqlite3_int64 iAbsLevel; /* Absolute level of input segments */
203829 int iIdx; /* Index of *output* segment in iAbsLevel+1 */
203830 sqlite3_int64 iStart; /* Block number of first allocated block */
203831 sqlite3_int64 iEnd; /* Block number of last allocated block */
203832 sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */
@@ -204568,21 +205073,21 @@
204568 Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */
204569 IncrmergeWriter *pWriter /* Populate this object */
204570 ){
204571 int rc; /* Return Code */
204572 int i; /* Iterator variable */
204573 int nLeafEst = 0; /* Blocks allocated for leaf nodes */
204574 sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */
204575 sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */
204576
204577 /* Calculate nLeafEst. */
204578 rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0);
204579 if( rc==SQLITE_OK ){
204580 sqlite3_bind_int64(pLeafEst, 1, iAbsLevel);
204581 sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment);
204582 if( SQLITE_ROW==sqlite3_step(pLeafEst) ){
204583 nLeafEst = sqlite3_column_int(pLeafEst, 0);
204584 }
204585 rc = sqlite3_reset(pLeafEst);
204586 }
204587 if( rc!=SQLITE_OK ) return rc;
204588
@@ -228353,12 +228858,12 @@
228353 typedef struct DbpageTable DbpageTable;
228354 typedef struct DbpageCursor DbpageCursor;
228355
228356 struct DbpageCursor {
228357 sqlite3_vtab_cursor base; /* Base class. Must be first */
228358 int pgno; /* Current page number */
228359 int mxPgno; /* Last page to visit on this scan */
228360 Pager *pPager; /* Pager being read/written */
228361 DbPage *pPage1; /* Page 1 of the database */
228362 int iDb; /* Index of database to analyze */
228363 int szPage; /* Size of each page in bytes */
228364 };
@@ -228491,11 +228996,11 @@
228491 if( pCsr==0 ){
228492 return SQLITE_NOMEM_BKPT;
228493 }else{
228494 memset(pCsr, 0, sizeof(DbpageCursor));
228495 pCsr->base.pVtab = pVTab;
228496 pCsr->pgno = -1;
228497 }
228498
228499 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
228500 return SQLITE_OK;
228501 }
@@ -228591,16 +229096,16 @@
228591 ){
228592 DbpageCursor *pCsr = (DbpageCursor *)pCursor;
228593 int rc = SQLITE_OK;
228594 switch( i ){
228595 case 0: { /* pgno */
228596 sqlite3_result_int(ctx, pCsr->pgno);
228597 break;
228598 }
228599 case 1: { /* data */
228600 DbPage *pDbPage = 0;
228601 if( pCsr->pgno==((PENDING_BYTE/pCsr->szPage)+1) ){
228602 /* The pending byte page. Assume it is zeroed out. Attempting to
228603 ** request this page from the page is an SQLITE_CORRUPT error. */
228604 sqlite3_result_zeroblob(ctx, pCsr->szPage);
228605 }else{
228606 rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
@@ -228670,14 +229175,14 @@
228670 if( argc==1 ){
228671 zErr = "cannot delete";
228672 goto update_fail;
228673 }
228674 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
228675 pgno = (Pgno)sqlite3_value_int(argv[2]);
228676 isInsert = 1;
228677 }else{
228678 pgno = sqlite3_value_int(argv[0]);
228679 if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
228680 zErr = "cannot insert";
228681 goto update_fail;
228682 }
228683 isInsert = 0;
@@ -231625,10 +232130,23 @@
231625 assert( (a - p->aRecord)==p->nRecord );
231626 }
231627
231628 return rc;
231629 }
 
 
 
 
 
 
 
 
 
 
 
 
 
231630
231631 /*
231632 ** Formulate and prepare a SELECT statement to retrieve a row from table
231633 ** zTab in database zDb based on its primary key. i.e.
231634 **
@@ -231647,16 +232165,16 @@
231647 const char *zTab, /* Table name */
231648 int bRowid,
231649 int nCol, /* Number of columns in table */
231650 const char **azCol, /* Names of table columns */
231651 u8 *abPK, /* PRIMARY KEY array */
231652 sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
 
231653 ){
231654 int rc = SQLITE_OK;
231655 char *zSql = 0;
231656 const char *zSep = "";
231657 int nSql = -1;
231658 int i;
231659
231660 SessionBuffer cols = {0, 0, 0};
231661 SessionBuffer nooptest = {0, 0, 0};
231662 SessionBuffer pkfield = {0, 0, 0};
@@ -231732,11 +232250,11 @@
231732 nSql = buf.nBuf;
231733 }
231734 #endif
231735
231736 if( rc==SQLITE_OK ){
231737 rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
231738 }
231739 sqlite3_free(zSql);
231740 sqlite3_free(nooptest.aBuf);
231741 sqlite3_free(pkfield.aBuf);
231742 sqlite3_free(pkvar.aBuf);
@@ -231896,11 +232414,11 @@
231896 sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
231897
231898 /* Build and compile a statement to execute: */
231899 if( rc==SQLITE_OK ){
231900 rc = sessionSelectStmt(db, 0, pSession->zDb,
231901 zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel
231902 );
231903 }
231904
231905 nNoop = buf.nBuf;
231906 for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
@@ -233105,10 +233623,11 @@
233105 SessionBuffer rebase; /* Rebase information (if any) here */
233106 u8 bRebaseStarted; /* If table header is already in rebase */
233107 u8 bRebase; /* True to collect rebase information */
233108 u8 bIgnoreNoop; /* True to ignore no-op conflicts */
233109 int bRowid;
 
233110 };
233111
233112 /* Number of prepared UPDATE statements to cache. */
233113 #define SESSION_UPDATE_CACHE_SZ 12
233114
@@ -233330,11 +233849,11 @@
233330 }
233331 sessionAppendStr(&buf, ")", &rc);
233332 }
233333
233334 if( rc==SQLITE_OK ){
233335 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
233336 }
233337 sqlite3_free(buf.aBuf);
233338
233339 return rc;
233340 }
@@ -233357,11 +233876,11 @@
233357 const char *zTab, /* Table name */
233358 SessionApplyCtx *p /* Session changeset-apply context */
233359 ){
233360 /* TODO */
233361 return sessionSelectStmt(db, p->bIgnoreNoop,
233362 "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect
233363 );
233364 }
233365
233366 /*
233367 ** Formulate and prepare an INSERT statement to add a record to table zTab.
@@ -233394,37 +233913,33 @@
233394 sessionAppendStr(&buf, ", ?", &rc);
233395 }
233396 sessionAppendStr(&buf, ")", &rc);
233397
233398 if( rc==SQLITE_OK ){
233399 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
233400 }
233401 sqlite3_free(buf.aBuf);
233402 return rc;
233403 }
233404
233405 static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
233406 return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
233407 }
233408
233409 /*
233410 ** Prepare statements for applying changes to the sqlite_stat1 table.
233411 ** These are similar to those created by sessionSelectRow(),
233412 ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
233413 ** other tables.
233414 */
233415 static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
233416 int rc = sessionSelectRow(db, "sqlite_stat1", p);
233417 if( rc==SQLITE_OK ){
233418 rc = sessionPrepare(db, &p->pInsert,
233419 "INSERT INTO main.sqlite_stat1 VALUES(?1, "
233420 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
233421 "?3)"
233422 );
233423 }
233424 if( rc==SQLITE_OK ){
233425 rc = sessionPrepare(db, &p->pDelete,
233426 "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
233427 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
233428 "AND (?4 OR stat IS ?3)"
233429 );
233430 }
@@ -233644,11 +234159,11 @@
233644 sqlite3_changeset_iter *pIter, /* Changeset iterator */
233645 int(*xConflict)(void *, int, sqlite3_changeset_iter*),
233646 void *pCtx, /* First argument for conflict handler */
233647 int *pbReplace /* OUT: Set to true if PK row is found */
233648 ){
233649 int res = 0; /* Value returned by conflict handler */
233650 int rc;
233651 int nCol;
233652 int op;
233653 const char *zDummy;
233654
@@ -233665,15 +234180,13 @@
233665 rc = SQLITE_OK;
233666 }
233667
233668 if( rc==SQLITE_ROW ){
233669 /* There exists another row with the new.* primary key. */
233670 if( p->bIgnoreNoop
233671 && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
233672 ){
233673 res = SQLITE_CHANGESET_OMIT;
233674 }else{
233675 pIter->pConflict = p->pSelect;
233676 res = xConflict(pCtx, eType, pIter);
233677 pIter->pConflict = 0;
233678 }
233679 rc = sqlite3_reset(p->pSelect);
@@ -233683,11 +234196,13 @@
233683 ** to the SessionApplyCtx.constraints buffer. */
233684 u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
233685 int nBlob = pIter->in.iNext - pIter->in.iCurrent;
233686 sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
233687 return SQLITE_OK;
233688 }else{
 
 
233689 /* No other row with the new.* primary key. */
233690 res = xConflict(pCtx, eType+1, pIter);
233691 if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
233692 }
233693 }
@@ -233781,11 +234296,11 @@
233781 }
233782 if( rc!=SQLITE_OK ) return rc;
233783
233784 sqlite3_step(p->pDelete);
233785 rc = sqlite3_reset(p->pDelete);
233786 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){
233787 rc = sessionConflictHandler(
233788 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
233789 );
233790 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
233791 rc = sessionConflictHandler(
@@ -234203,10 +234718,15 @@
234203 if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
234204 assert( db->flags & SQLITE_FkNoAction );
234205 db->flags &= ~((u64)SQLITE_FkNoAction);
234206 db->aDb[0].pSchema->schema_cookie -= 32;
234207 }
 
 
 
 
 
234208 sqlite3_mutex_leave(sqlite3_db_mutex(db));
234209 return rc;
234210 }
234211
234212 /*
@@ -236412,25 +236932,18 @@
236412 ** Constants for the largest and smallest possible 64-bit signed integers.
236413 */
236414 # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
236415 # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
236416
236417 /* The uptr type is an unsigned integer large enough to hold a pointer
 
 
 
 
 
236418 */
236419 #if defined(HAVE_STDINT_H)
236420 typedef uintptr_t uptr;
236421 #elif SQLITE_PTRSIZE==4
236422 typedef u32 uptr;
236423 #else
236424 typedef u64 uptr;
236425 #endif
236426
236427 #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
236428 # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0)
236429 #else
236430 # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
236431 #endif
236432
236433 /*
236434 ** Macros needed to provide flexible arrays in a portable way
236435 */
236436 #ifndef offsetof
@@ -237174,11 +237687,11 @@
237174 ** ){
237175 ** // The document with rowid iRowid matches the expression!
237176 ** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
237177 ** }
237178 */
237179 static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
237180 static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
237181 static int sqlite3Fts5ExprEof(Fts5Expr*);
237182 static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
237183
237184 static void sqlite3Fts5ExprFree(Fts5Expr*);
@@ -242743,11 +243256,17 @@
242743 ** equal to iFirst.
242744 **
242745 ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
242746 ** is not considered an error if the query does not match any documents.
242747 */
242748 static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
 
 
 
 
 
 
242749 Fts5ExprNode *pRoot = p->pRoot;
242750 int rc; /* Return code */
242751
242752 p->pIndex = pIdx;
242753 p->bDesc = bDesc;
@@ -242764,10 +243283,13 @@
242764
242765 /* If the iterator is not at a real match, skip forward until it is. */
242766 while( pRoot->bNomatch && rc==SQLITE_OK ){
242767 assert( pRoot->bEof==0 );
242768 rc = fts5ExprNodeNext(p, pRoot, 0, 0);
 
 
 
242769 }
242770 return rc;
242771 }
242772
242773 /*
@@ -251885,14 +252407,17 @@
251885 ** function populates it with the initial structure objects for each index,
251886 ** and the initial version of the "averages" record (a zero-byte blob).
251887 */
251888 static int sqlite3Fts5IndexReinit(Fts5Index *p){
251889 Fts5Structure *pTmp;
251890 u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
 
 
 
251891 fts5StructureInvalidate(p);
251892 fts5IndexDiscardData(p);
251893 pTmp = (Fts5Structure*)tmpSpace;
251894 memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
251895 if( p->pConfig->bContentlessDelete ){
251896 pTmp->nOriginCntr = 1;
251897 }
251898 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
@@ -255109,10 +255634,21 @@
255109 {
255110 pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
255111 }
255112 #endif
255113 }
 
 
 
 
 
 
 
 
 
 
 
255114
255115 static int fts5UsePatternMatch(
255116 Fts5Config *pConfig,
255117 struct sqlite3_index_constraint *p
255118 ){
@@ -255245,11 +255781,11 @@
255245 bSeenRank = 1;
255246 }else{
255247 nSeenMatch++;
255248 idxStr[iIdxStr++] = 'M';
255249 sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
255250 idxStr += strlen(&idxStr[iIdxStr]);
255251 assert( idxStr[iIdxStr]=='\0' );
255252 }
255253 pInfo->aConstraintUsage[i].argvIndex = ++iCons;
255254 pInfo->aConstraintUsage[i].omit = 1;
255255 }
@@ -255264,10 +255800,11 @@
255264 nSeenMatch++;
255265 }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
255266 idxStr[iIdxStr++] = '=';
255267 bSeenEq = 1;
255268 pInfo->aConstraintUsage[i].argvIndex = ++iCons;
 
255269 }
255270 }
255271 }
255272
255273 if( bSeenEq==0 ){
@@ -255311,21 +255848,25 @@
255311 }
255312 }
255313
255314 /* Calculate the estimated cost based on the flags set in idxFlags. */
255315 if( bSeenEq ){
255316 pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0;
255317 if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
255318 }else if( bSeenLt && bSeenGt ){
255319 pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0;
255320 }else if( bSeenLt || bSeenGt ){
255321 pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0;
255322 }else{
255323 pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0;
255324 }
255325 for(i=1; i<nSeenMatch; i++){
255326 pInfo->estimatedCost *= 0.4;
 
 
 
 
 
 
 
255327 }
255328
255329 pInfo->idxNum = idxFlags;
255330 return SQLITE_OK;
255331 }
@@ -255520,11 +256061,13 @@
255520 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
255521 Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
255522 int bDesc = pCsr->bDesc;
255523 i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
255524
255525 rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
 
 
255526 if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
255527 *pbSkip = 1;
255528 }
255529
255530 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
@@ -255692,11 +256235,13 @@
255692 }
255693
255694 static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
255695 int rc;
255696 Fts5Expr *pExpr = pCsr->pExpr;
255697 rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
 
 
255698 if( sqlite3Fts5ExprEof(pExpr) ){
255699 CsrFlagSet(pCsr, FTS5CSR_EOF);
255700 }
255701 fts5CsrNewrow(pCsr);
255702 return rc;
@@ -258177,11 +258722,11 @@
258177 int nArg, /* Number of args */
258178 sqlite3_value **apUnused /* Function arguments */
258179 ){
258180 assert( nArg==0 );
258181 UNUSED_PARAM2(nArg, apUnused);
258182 sqlite3_result_text(pCtx, "fts5: 2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1", -1, SQLITE_TRANSIENT);
258183 }
258184
258185 /*
258186 ** Implementation of fts5_locale(LOCALE, TEXT) function.
258187 **
258188
--- 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 ** 821cc0e421bc14a68ebaee507e38a900e0c8 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -168,11 +168,13 @@
168 #define SQLITE_OMIT_LOAD_EXTENSION 1
169 #define SQLITE_ENABLE_LOCKING_STYLE 0
170 #define HAVE_UTIME 1
171 #else
172 /* This is not VxWorks. */
173 #ifndef OS_VXWORKS
174 # define OS_VXWORKS 0
175 #endif
176 #define HAVE_FCHOWN 1
177 #define HAVE_READLINK 1
178 #define HAVE_LSTAT 1
179 #endif /* defined(_WRS_KERNEL) */
180
@@ -465,11 +467,14 @@
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -2657,21 +2662,24 @@
2662 ** views in the main database schema or in the schemas of ATTACH-ed
2663 ** databases.)^ </dd>
2664 **
2665 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
2666 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2667 ** <dd> ^This option is used to enable or disable using the
2668 ** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine
2669 ** extension - without using bound parameters as the parameters. Doing so
2670 ** is disabled by default. There must be two additional arguments. The first
2671 ** argument is an integer. If it is passed 0, then using fts3_tokenizer()
2672 ** without bound parameters is disabled. If it is passed a positive value,
2673 ** then calling fts3_tokenizer without bound parameters is enabled. If it
2674 ** is passed a negative value, this setting is not modified - this can be
2675 ** used to query for the current setting. The second parameter is a pointer
2676 ** to an integer into which is written 0 or 1 to indicate the current value
2677 ** of this setting (after it is modified, if applicable). The second
2678 ** parameter may be a NULL pointer, in which case the value of the setting
2679 ** is not reported back. Refer to [FTS3] documentation for further details.
2680 ** </dd>
2681 **
2682 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
2683 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2684 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2685 ** interface independently of the [load_extension()] SQL function.
@@ -4517,10 +4525,38 @@
4525 SQLITE_API const char *sqlite3_errmsg(sqlite3*);
4526 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4527 SQLITE_API const char *sqlite3_errstr(int);
4528 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4529
4530 /*
4531 ** CAPI3REF: Set Error Codes And Message
4532 ** METHOD: sqlite3
4533 **
4534 ** Set the error code of the database handle passed as the first argument
4535 ** to errcode, and the error message to a copy of nul-terminated string
4536 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
4537 ** the default message associated with the supplied error code. Subsequent
4538 ** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will
4539 ** return the values set by this routine in place of what was previously
4540 ** set by SQLite itself.
4541 **
4542 ** This function returns SQLITE_OK if the error code and error message are
4543 ** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if
4544 ** the database handle is NULL or invalid.
4545 **
4546 ** The error code and message set by this routine remains in effect until
4547 ** they are changed, either by another call to this routine or until they are
4548 ** changed to by SQLite itself to reflect the result of some subsquent
4549 ** API call.
4550 **
4551 ** This function is intended for use by SQLite extensions or wrappers. The
4552 ** idea is that an extension or wrapper can use this routine to set error
4553 ** messages and error codes and thus behave more like a core SQLite
4554 ** feature from the point of view of an application.
4555 */
4556 SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg);
4557
4558 /*
4559 ** CAPI3REF: Prepared Statement Object
4560 ** KEYWORDS: {prepared statement} {prepared statements}
4561 **
4562 ** An instance of this object represents a single SQL statement that
@@ -6527,10 +6563,11 @@
6563 ** to be attached to [database connection] D using name N. Subsequent
6564 ** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
6565 ** or a NULL pointer if there were no prior calls to
6566 ** sqlite3_set_clientdata() with the same values of D and N.
6567 ** Names are compared using strcmp() and are thus case sensitive.
6568 ** It returns 0 on success and SQLITE_NOMEM on allocation failure.
6569 **
6570 ** If P and X are both non-NULL, then the destructor X is invoked with
6571 ** argument P on the first of the following occurrences:
6572 ** <ul>
6573 ** <li> An out-of-memory error occurs during the call to
@@ -10098,25 +10135,38 @@
10135 ** ^The third parameter is the name of the database that was written to -
10136 ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
10137 ** is the number of pages currently in the write-ahead log file,
10138 ** including those that were just committed.
10139 **
10140 ** ^The callback function should normally return [SQLITE_OK]. ^If an error
10141 ** code is returned, that error will propagate back up through the
10142 ** SQLite code base to cause the statement that provoked the callback
10143 ** to report an error, though the commit will have still occurred. If the
10144 ** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
10145 ** that does not correspond to any valid SQLite error code, the results
10146 ** are undefined.
10147 **
10148 ** ^A single database handle may have at most a single write-ahead log
10149 ** callback registered at one time. ^Calling [sqlite3_wal_hook()]
10150 ** replaces the default behavior or previously registered write-ahead
10151 ** log callback.
10152 **
10153 ** ^The return value is a copy of the third parameter from the
10154 ** previous call, if any, or 0.
10155 **
10156 ** ^The [sqlite3_wal_autocheckpoint()] interface and the
10157 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and
10158 ** will overwrite any prior [sqlite3_wal_hook()] settings.
10159 **
10160 ** ^If a write-ahead log callback is set using this function then
10161 ** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint]
10162 ** should be invoked periodically to keep the write-ahead log file
10163 ** from growing without bound.
10164 **
10165 ** ^Passing a NULL pointer for the callback disables automatic
10166 ** checkpointing entirely. To re-enable the default behavior, call
10167 ** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint].
10168 */
10169 SQLITE_API void *sqlite3_wal_hook(
10170 sqlite3*,
10171 int(*)(void *,sqlite3*,const char*,int),
10172 void*
@@ -10129,11 +10179,11 @@
10179 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
10180 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
10181 ** to automatically [checkpoint]
10182 ** after committing a transaction if there are N or
10183 ** more frames in the [write-ahead log] file. ^Passing zero or
10184 ** a negative value as the N parameter disables automatic
10185 ** checkpoints entirely.
10186 **
10187 ** ^The callback registered by this function replaces any existing callback
10188 ** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
10189 ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -10145,13 +10195,14 @@
10195 ** ^Checkpoints initiated by this mechanism are
10196 ** [sqlite3_wal_checkpoint_v2|PASSIVE].
10197 **
10198 ** ^Every new [database connection] defaults to having the auto-checkpoint
10199 ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
10200 ** pages.
10201 **
10202 ** ^The use of this interface is only necessary if the default setting
10203 ** is found to be suboptimal for a particular application.
10204 */
10205 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
10206
10207 /*
10208 ** CAPI3REF: Checkpoint a database
@@ -10212,10 +10263,15 @@
10263 **
10264 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
10265 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
10266 ** addition that it also truncates the log file to zero bytes just prior
10267 ** to a successful return.
10268 **
10269 ** <dt>SQLITE_CHECKPOINT_NOOP<dd>
10270 ** ^This mode always checkpoints zero frames. The only reason to invoke
10271 ** a NOOP checkpoint is to access the values returned by
10272 ** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt.
10273 ** </dl>
10274 **
10275 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
10276 ** the log file or to -1 if the checkpoint could not run because
10277 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -10282,10 +10338,11 @@
10338 ** These constants define all valid values for the "checkpoint mode" passed
10339 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
10340 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
10341 ** meaning of each of these checkpoint modes.
10342 */
10343 #define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */
10344 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
10345 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
10346 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
10347 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
10348
@@ -11109,11 +11166,11 @@
11166 ** to avoid a memory leak.
11167 **
11168 ** The [sqlite3_snapshot_get()] interface is only available when the
11169 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11170 */
11171 SQLITE_API int sqlite3_snapshot_get(
11172 sqlite3 *db,
11173 const char *zSchema,
11174 sqlite3_snapshot **ppSnapshot
11175 );
11176
@@ -11158,11 +11215,11 @@
11215 ** database connection in order to make it ready to use snapshots.)
11216 **
11217 ** The [sqlite3_snapshot_open()] interface is only available when the
11218 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11219 */
11220 SQLITE_API int sqlite3_snapshot_open(
11221 sqlite3 *db,
11222 const char *zSchema,
11223 sqlite3_snapshot *pSnapshot
11224 );
11225
@@ -11175,11 +11232,11 @@
11232 ** using this routine to avoid a memory leak.
11233 **
11234 ** The [sqlite3_snapshot_free()] interface is only available when the
11235 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
11236 */
11237 SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*);
11238
11239 /*
11240 ** CAPI3REF: Compare the ages of two snapshot handles.
11241 ** METHOD: sqlite3_snapshot
11242 **
@@ -11202,11 +11259,11 @@
11259 ** snapshot, and a positive value if P1 is a newer snapshot than P2.
11260 **
11261 ** This interface is only available if SQLite is compiled with the
11262 ** [SQLITE_ENABLE_SNAPSHOT] option.
11263 */
11264 SQLITE_API int sqlite3_snapshot_cmp(
11265 sqlite3_snapshot *p1,
11266 sqlite3_snapshot *p2
11267 );
11268
11269 /*
@@ -11230,11 +11287,11 @@
11287 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
11288 **
11289 ** This interface is only available if SQLite is compiled with the
11290 ** [SQLITE_ENABLE_SNAPSHOT] option.
11291 */
11292 SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
11293
11294 /*
11295 ** CAPI3REF: Serialize a database
11296 **
11297 ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -11304,16 +11361,17 @@
11361 /*
11362 ** CAPI3REF: Deserialize a database
11363 **
11364 ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
11365 ** [database connection] D to disconnect from database S and then
11366 ** reopen S as an in-memory database based on the serialization
11367 ** contained in P. If S is a NULL pointer, the main database is
11368 ** used. The serialized database P is N bytes in size. M is the size
11369 ** of the buffer P, which might be larger than N. If M is larger than
11370 ** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
11371 ** SQLite is permitted to add content to the in-memory database as
11372 ** long as the total size does not exceed M bytes.
11373 **
11374 ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
11375 ** invoke sqlite3_free() on the serialization buffer when the database
11376 ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
11377 ** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12634,10 +12692,19 @@
12692 ** CAPI3REF: Apply A Changeset To A Database
12693 **
12694 ** Apply a changeset or patchset to a database. These functions attempt to
12695 ** update the "main" database attached to handle db with the changes found in
12696 ** the changeset passed via the second and third arguments.
12697 **
12698 ** All changes made by these functions are enclosed in a savepoint transaction.
12699 ** If any other error (aside from a constraint failure when attempting to
12700 ** write to the target database) occurs, then the savepoint transaction is
12701 ** rolled back, restoring the target database to its original state, and an
12702 ** SQLite error code returned. Additionally, starting with version 3.51.0,
12703 ** an error code and error message that may be accessed using the
12704 ** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database
12705 ** handle.
12706 **
12707 ** The fourth argument (xFilter) passed to these functions is the "filter
12708 ** callback". This may be passed NULL, in which case all changes in the
12709 ** changeset are applied to the database. For sqlite3changeset_apply() and
12710 ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12772,16 +12839,10 @@
12839 ** It is safe to execute SQL statements, including those that write to the
12840 ** table that the callback related to, from within the xConflict callback.
12841 ** This can be used to further customize the application's conflict
12842 ** resolution strategy.
12843 **
 
 
 
 
 
 
12844 ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
12845 ** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
12846 ** may set (*ppRebase) to point to a "rebase" that may be used with the
12847 ** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
12848 ** is set to the size of the buffer in bytes. It is the responsibility of the
@@ -14356,11 +14417,11 @@
14417
14418 /*
14419 ** Maximum number of pages in one database file.
14420 **
14421 ** This is really just the default value for the max_page_count pragma.
14422 ** This value can be lowered (or raised) at run-time using the
14423 ** max_page_count macro.
14424 */
14425 #ifndef SQLITE_MAX_PAGE_COUNT
14426 # define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */
14427 #endif
@@ -18127,11 +18188,11 @@
18188 struct sqlite3InitInfo { /* Information used during initialization */
18189 Pgno newTnum; /* Rootpage of table being initialized */
18190 u8 iDb; /* Which db file is being initialized */
18191 u8 busy; /* TRUE if currently initializing */
18192 unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
18193 unsigned imposterTable : 2; /* Building an imposter table */
18194 unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
18195 const char **azInit; /* "type", "name", and "tbl_name" columns */
18196 } init;
18197 int nVdbeActive; /* Number of VDBEs currently running */
18198 int nVdbeRead; /* Number of active VDBEs that read or write */
@@ -18920,10 +18981,11 @@
18981 #define TF_Shadow 0x00001000 /* True for a shadow table */
18982 #define TF_HasStat4 0x00002000 /* STAT4 info available for this table */
18983 #define TF_Ephemeral 0x00004000 /* An ephemeral table */
18984 #define TF_Eponymous 0x00008000 /* An eponymous virtual table */
18985 #define TF_Strict 0x00010000 /* STRICT mode */
18986 #define TF_Imposter 0x00020000 /* An imposter table */
18987
18988 /*
18989 ** Allowed values for Table.eTabType
18990 */
18991 #define TABTYP_NORM 0 /* Ordinary table */
@@ -20086,10 +20148,11 @@
20148 #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
20149 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
20150 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
20151 #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
20152 #define SF_Correlated 0x20000000 /* True if references the outer context */
20153 #define SF_OnToWhere 0x40000000 /* One or more ON clauses moved to WHERE */
20154
20155 /* True if SrcItem X is a subquery that has SF_NestedFrom */
20156 #define IsNestedFrom(X) \
20157 ((X)->fg.isSubquery && \
20158 ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
@@ -20839,10 +20902,11 @@
20902 struct Table *pTab; /* Table of generated column */
20903 struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */
20904 SrcItem *pSrcItem; /* A single FROM clause item */
20905 DbFixer *pFix; /* See sqlite3FixSelect() */
20906 Mem *aMem; /* See sqlite3BtreeCursorHint() */
20907 struct CheckOnCtx *pCheckOnCtx; /* See selectCheckOnClauses() */
20908 } u;
20909 };
20910
20911 /*
20912 ** The following structure contains information used by the sqliteFix...
@@ -24209,11 +24273,14 @@
24273 Mem oldipk; /* Memory cell holding "old" IPK value */
24274 Mem *aNew; /* Array of new.* values */
24275 Table *pTab; /* Schema object being updated */
24276 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
24277 sqlite3_value **apDflt; /* Array of default values, if required */
24278 union {
24279 KeyInfo sKey;
24280 u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
24281 } uKey;
24282 };
24283
24284 /*
24285 ** An instance of this object is used to pass an vector of values into
24286 ** OP_VFilter, the xFilter method of a virtual table. The vector is the
@@ -24976,10 +25043,14 @@
25043 if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
25044 return 1;
25045 }
25046 zDate += 5;
25047 p->tz = sgn*(nMn + nHr*60);
25048 if( p->tz==0 ){ /* Forum post 2025-09-17T10:12:14z */
25049 p->isLocal = 0;
25050 p->isUtc = 1;
25051 }
25052 zulu_time:
25053 while( sqlite3Isspace(*zDate) ){ zDate++; }
25054 return *zDate!=0;
25055 }
25056
@@ -33486,13 +33557,17 @@
33557 sqlite3StrAccumFinish(&x);
33558 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
33559 n = 0;
33560 if( pItem->fg.isSubquery ) n++;
33561 if( pItem->fg.isTabFunc ) n++;
33562 if( pItem->fg.isUsing || pItem->u3.pOn!=0 ) n++;
33563 if( pItem->fg.isUsing ){
33564 sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
33565 }else if( pItem->u3.pOn!=0 ){
33566 sqlite3TreeViewItem(pView, "ON", (--n)>0);
33567 sqlite3TreeViewExpr(pView, pItem->u3.pOn, 0);
33568 sqlite3TreeViewPop(&pView);
33569 }
33570 if( pItem->fg.isSubquery ){
33571 assert( n==1 );
33572 if( pItem->pSTab ){
33573 Table *pTab = pItem->pSTab;
@@ -38131,11 +38206,11 @@
38206 static int kvstorageDelete(const char*, const char *zKey);
38207 static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf);
38208 #define KVSTORAGE_KEY_SZ 32
38209
38210 /* Expand the key name with an appropriate prefix and put the result
38211 ** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least
38212 ** KVSTORAGE_KEY_SZ bytes.
38213 */
38214 static void kvstorageMakeKey(
38215 const char *zClass,
38216 const char *zKeyIn,
@@ -38190,14 +38265,16 @@
38265 ** enough to hold it all. The value put into zBuf must always be zero
38266 ** terminated, even if it gets truncated because nBuf is not large enough.
38267 **
38268 ** Return the total number of bytes in the data, without truncation, and
38269 ** not counting the final zero terminator. Return -1 if the key does
38270 ** not exist or its key cannot be read.
38271 **
38272 ** If nBuf<=0 then this routine simply returns the size of the data
38273 ** without actually reading it. Similarly, if nBuf==1 then it
38274 ** zero-terminates zBuf at zBuf[0] and returns the size of the data
38275 ** without reading it.
38276 */
38277 static int kvstorageRead(
38278 const char *zClass,
38279 const char *zKey,
38280 char *zBuf,
@@ -38242,15 +38319,13 @@
38319 /*
38320 ** An internal level of indirection which enables us to replace the
38321 ** kvvfs i/o methods with JavaScript implementations in WASM builds.
38322 ** Maintenance reminder: if this struct changes in any way, the JSON
38323 ** rendering of its structure must be updated in
38324 ** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary
38325 ** compatibility concerns, so it does not need an iVersion
38326 ** member.
 
 
38327 */
38328 typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods;
38329 struct sqlite3_kvvfs_methods {
38330 int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf);
38331 int (*xWrite)(const char *zClass, const char *zKey, const char *zData);
@@ -38263,12 +38338,12 @@
38338 ** for JavaScript-side implementations in WASM builds. In such builds
38339 ** it cannot be const, but in native builds it should be so that
38340 ** the compiler can hopefully optimize this level of indirection out.
38341 ** That said, kvvfs is intended primarily for use in WASM builds.
38342 **
38343 ** This is not explicitly flagged as static because the amalgamation
38344 ** build will tag it with SQLITE_PRIVATE.
38345 */
38346 #ifndef SQLITE_WASM
38347 const
38348 #endif
38349 SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = {
@@ -39437,14 +39512,15 @@
39512 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
39513 aSyscall[13].pCurrent)
39514
39515 #if defined(HAVE_FCHMOD)
39516 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
39517 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
39518 #else
39519 { "fchmod", (sqlite3_syscall_ptr)0, 0 },
39520 #define osFchmod(FID,MODE) 0
39521 #endif
 
39522
39523 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
39524 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
39525 #else
39526 { "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -39698,13 +39774,12 @@
39774 return fd;
39775 }
39776
39777 /*
39778 ** Helper functions to obtain and relinquish the global mutex. The
39779 ** global mutex is used to protect the unixInodeInfo objects used by
39780 ** this file, all of which may be shared by multiple threads.
 
39781 **
39782 ** Function unixMutexHeld() is used to assert() that the global mutex
39783 ** is held when required. This function is only used as part of assert()
39784 ** statements. e.g.
39785 **
@@ -39902,10 +39977,11 @@
39977 /*
39978 ** All unique filenames are held on a linked list headed by this
39979 ** variable:
39980 */
39981 static struct vxworksFileId *vxworksFileList = 0;
39982 static sqlite3_mutex *vxworksMutex = 0;
39983
39984 /*
39985 ** Simplify a filename into its canonical form
39986 ** by making the following changes:
39987 **
@@ -39967,47 +40043,47 @@
40043
40044 /* Search for an existing entry that matching the canonical name.
40045 ** If found, increment the reference count and return a pointer to
40046 ** the existing file ID.
40047 */
40048 sqlite3_mutex_enter(vxworksMutex);
40049 for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
40050 if( pCandidate->nName==n
40051 && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
40052 ){
40053 sqlite3_free(pNew);
40054 pCandidate->nRef++;
40055 sqlite3_mutex_leave(vxworksMutex);
40056 return pCandidate;
40057 }
40058 }
40059
40060 /* No match was found. We will make a new file ID */
40061 pNew->nRef = 1;
40062 pNew->nName = n;
40063 pNew->pNext = vxworksFileList;
40064 vxworksFileList = pNew;
40065 sqlite3_mutex_leave(vxworksMutex);
40066 return pNew;
40067 }
40068
40069 /*
40070 ** Decrement the reference count on a vxworksFileId object. Free
40071 ** the object when the reference count reaches zero.
40072 */
40073 static void vxworksReleaseFileId(struct vxworksFileId *pId){
40074 sqlite3_mutex_enter(vxworksMutex);
40075 assert( pId->nRef>0 );
40076 pId->nRef--;
40077 if( pId->nRef==0 ){
40078 struct vxworksFileId **pp;
40079 for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
40080 assert( *pp==pId );
40081 *pp = pId->pNext;
40082 sqlite3_free(pId);
40083 }
40084 sqlite3_mutex_leave(vxworksMutex);
40085 }
40086 #endif /* OS_VXWORKS */
40087 /*************** End of Unique File ID Utility Used By VxWorks ****************
40088 ******************************************************************************/
40089
@@ -40391,10 +40467,14 @@
40467 do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
40468 if( rc!=1 ){
40469 storeLastErrno(pFile, errno);
40470 return SQLITE_IOERR;
40471 }
40472 if( fsync(fd) ){
40473 storeLastErrno(pFile, errno);
40474 return SQLITE_IOERR_FSYNC;
40475 }
40476 rc = osFstat(fd, &statbuf);
40477 if( rc!=0 ){
40478 storeLastErrno(pFile, errno);
40479 return SQLITE_IOERR;
40480 }
@@ -40560,22 +40640,46 @@
40640 static int osSetPosixAdvisoryLock(
40641 int h, /* The file descriptor on which to take the lock */
40642 struct flock *pLock, /* The description of the lock */
40643 unixFile *pFile /* Structure holding timeout value */
40644 ){
40645 int rc = 0;
40646
40647 if( pFile->iBusyTimeout==0 ){
40648 /* unixFile->iBusyTimeout is set to 0. In this case, attempt a
40649 ** non-blocking lock. */
40650 rc = osFcntl(h,F_SETLK,pLock);
40651 }else{
40652 /* unixFile->iBusyTimeout is set to greater than zero. In this case,
40653 ** attempt a blocking-lock with a unixFile->iBusyTimeout ms timeout.
40654 **
40655 ** On systems that support some kind of blocking file lock operation,
40656 ** this block should be replaced by code to attempt a blocking lock
40657 ** with a timeout of unixFile->iBusyTimeout ms. The code below is
40658 ** placeholder code. If SQLITE_TEST is defined, the placeholder code
40659 ** retries the lock once every 1ms until it succeeds or the timeout
40660 ** is reached. Or, if SQLITE_TEST is not defined, the placeholder
40661 ** code attempts a non-blocking lock and sets unixFile->iBusyTimeout
40662 ** to 0. This causes the caller to return SQLITE_BUSY, instead of
40663 ** SQLITE_BUSY_TIMEOUT to SQLite - as required by a VFS that does not
40664 ** support blocking locks.
40665 */
40666 #ifdef SQLITE_TEST
40667 int tm = pFile->iBusyTimeout;
40668 while( tm>0 ){
40669 rc = osFcntl(h,F_SETLK,pLock);
40670 if( rc==0 ) break;
40671 unixSleep(0,1000);
40672 tm--;
40673 }
40674 #else
40675 rc = osFcntl(h,F_SETLK,pLock);
40676 pFile->iBusyTimeout = 0;
40677 #endif
40678 /* End of code to replace with real blocking-locks code. */
40679 }
40680
40681 return rc;
40682 }
40683 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
40684
40685
@@ -44892,14 +44996,21 @@
44996 #endif
44997
44998 storeLastErrno(pNew, 0);
44999 #if OS_VXWORKS
45000 if( rc!=SQLITE_OK ){
45001 if( h>=0 ){
45002 robust_close(pNew, h, __LINE__);
45003 h = -1;
45004 }
45005 if( pNew->ctrlFlags & UNIXFILE_DELETE ){
45006 osUnlink(zFilename);
45007 }
45008 if( pNew->pId ){
45009 vxworksReleaseFileId(pNew->pId);
45010 pNew->pId = 0;
45011 }
45012 }
45013 #endif
45014 if( rc!=SQLITE_OK ){
45015 if( h>=0 ) robust_close(pNew, h, __LINE__);
45016 }else{
@@ -44939,10 +45050,13 @@
45050 struct stat buf;
45051 const char *zDir = sqlite3_temp_directory;
45052
45053 while(1){
45054 if( zDir!=0
45055 #if OS_VXWORKS
45056 && zDir[0]=='/'
45057 #endif
45058 && osStat(zDir, &buf)==0
45059 && S_ISDIR(buf.st_mode)
45060 && osAccess(zDir, 03)==0
45061 ){
45062 return zDir;
@@ -45252,10 +45366,16 @@
45366 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
45367 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
45368 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL
45369 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
45370 );
45371
45372 #if OS_VXWORKS
45373 /* The file-ID mechanism used in Vxworks requires that all pathnames
45374 ** provided to unixOpen must be absolute pathnames. */
45375 if( zPath!=0 && zPath[0]!='/' ){ return SQLITE_CANTOPEN; }
45376 #endif
45377
45378 /* Detect a pid change and reset the PRNG. There is a race condition
45379 ** here such that two or more threads all trying to open databases at
45380 ** the same instant might all reset the PRNG. But multiple resets
45381 ** are harmless.
@@ -45453,12 +45573,15 @@
45573 goto open_finished;
45574 }
45575 }
45576 #endif
45577
45578 assert( zPath==0
45579 || zPath[0]=='/'
45580 || eType==SQLITE_OPEN_SUPER_JOURNAL
45581 || eType==SQLITE_OPEN_MAIN_JOURNAL
45582 || eType==SQLITE_OPEN_TEMP_JOURNAL
45583 );
45584 rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
45585
45586 open_finished:
45587 if( rc!=SQLITE_OK ){
@@ -47183,10 +47306,13 @@
47306 }
47307 #ifdef SQLITE_OS_KV_OPTIONAL
47308 sqlite3KvvfsInit();
47309 #endif
47310 unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
47311 #if OS_VXWORKS
47312 vxworksMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS2);
47313 #endif
47314
47315 #ifndef SQLITE_OMIT_WAL
47316 /* Validate lock assumptions */
47317 assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */
47318 assert( UNIX_SHM_BASE==120 ); /* Start of locking area */
@@ -47217,10 +47343,13 @@
47343 ** to release dynamically allocated objects. But not on unix.
47344 ** This routine is a no-op for unix.
47345 */
47346 SQLITE_API int sqlite3_os_end(void){
47347 unixBigLock = 0;
47348 #if OS_VXWORKS
47349 vxworksMutex = 0;
47350 #endif
47351 return SQLITE_OK;
47352 }
47353
47354 #endif /* SQLITE_OS_UNIX */
47355
@@ -51349,33 +51478,39 @@
51478 ** log-summary, each thread has its own winFile object, but they all
51479 ** point to a single instance of this object. In other words, each
51480 ** log-summary is opened only once per process.
51481 **
51482 ** winShmMutexHeld() must be true when creating or destroying
51483 ** this object, or while editing the global linked list that starts
51484 ** at winShmNodeList.
51485 **
51486 ** When reading or writing the linked list starting at winShmNode.pWinShmList,
51487 ** pShmNode->mutex must be held.
51488 **
51489 ** The following fields are constant after the object is created:
51490 **
51491 ** zFilename
51492 ** hSharedShm
51493 ** mutex
51494 ** bUseSharedLockHandle
51495 **
51496 ** Either winShmNode.mutex must be held or winShmNode.pWinShmList==0 and
51497 ** winShmMutexHeld() is true when reading or writing any other field
51498 ** in this structure.
51499 **
51500 ** File-handle hSharedShm is always used to (a) take the DMS lock, (b)
51501 ** truncate the *-shm file if the DMS-locking protocol demands it, and
51502 ** (c) map regions of the *-shm file into memory using MapViewOfFile()
51503 ** or similar. If bUseSharedLockHandle is true, then other locks are also
51504 ** taken on hSharedShm. Or, if bUseSharedLockHandle is false, then other
51505 ** locks are taken using each connection's winShm.hShm handles.
51506 */
51507 struct winShmNode {
51508 sqlite3_mutex *mutex; /* Mutex to access this object */
51509 char *zFilename; /* Name of the file */
51510 HANDLE hSharedShm; /* File handle open on zFilename */
51511 int bUseSharedLockHandle; /* True to use hSharedShm for everything */
51512
51513 int isUnlocked; /* DMS lock has not yet been obtained */
51514 int isReadonly; /* True if read-only */
51515 int szRegion; /* Size of shared-memory regions */
51516 int nRegion; /* Size of array apRegion */
@@ -51384,11 +51519,12 @@
51519 HANDLE hMap; /* File handle from CreateFileMapping */
51520 void *pMap;
51521 } *aRegion;
51522 DWORD lastErrno; /* The Windows errno from the last I/O error */
51523
51524 winShm *pWinShmList; /* List of winShm objects with ptrs to this */
51525
51526 winShmNode *pNext; /* Next in list of all winShmNode objects */
51527 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51528 u8 nextShmId; /* Next available winShm.id value */
51529 #endif
51530 };
@@ -51412,10 +51548,11 @@
51548 HANDLE hShm; /* File-handle on *-shm file. For locking. */
51549 int bReadonly; /* True if hShm is opened read-only */
51550 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51551 u8 id; /* Id of this connection with its winShmNode */
51552 #endif
51553 winShm *pWinShmNext; /* Next winShm object on same winShmNode */
51554 };
51555
51556 /*
51557 ** Constants used for locking
51558 */
@@ -51425,11 +51562,11 @@
51562 /* Forward references to VFS methods */
51563 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
51564 static int winDelete(sqlite3_vfs *,const char*,int);
51565
51566 /*
51567 ** Purge the winShmNodeList list of all entries with winShmNode.pWinShmList==0.
51568 **
51569 ** This is not a VFS shared-memory method; it is a utility function called
51570 ** by VFS shared-memory methods.
51571 */
51572 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
@@ -51438,11 +51575,11 @@
51575 assert( winShmMutexHeld() );
51576 OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
51577 osGetCurrentProcessId(), deleteFlag));
51578 pp = &winShmNodeList;
51579 while( (p = *pp)!=0 ){
51580 if( p->pWinShmList==0 ){
51581 int i;
51582 if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
51583 for(i=0; i<p->nRegion; i++){
51584 BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
51585 OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
@@ -51602,10 +51739,64 @@
51739 *pbReadonly = bReadonly;
51740 *ph = h;
51741 return rc;
51742 }
51743
51744 /*
51745 ** Close pDbFd's connection to shared-memory. Delete the underlying
51746 ** *-shm file if deleteFlag is true.
51747 */
51748 static int winCloseSharedMemory(winFile *pDbFd, int deleteFlag){
51749 winShm *p; /* The connection to be closed */
51750 winShm **pp; /* Iterator for pShmNode->pWinShmList */
51751 winShmNode *pShmNode; /* The underlying shared-memory file */
51752
51753 p = pDbFd->pShm;
51754 if( p==0 ) return SQLITE_OK;
51755 if( p->hShm!=INVALID_HANDLE_VALUE ){
51756 osCloseHandle(p->hShm);
51757 }
51758
51759 winShmEnterMutex();
51760 pShmNode = p->pShmNode;
51761
51762 /* Remove this connection from the winShmNode.pWinShmList list */
51763 sqlite3_mutex_enter(pShmNode->mutex);
51764 for(pp=&pShmNode->pWinShmList; *pp!=p; pp=&(*pp)->pWinShmNext){}
51765 *pp = p->pWinShmNext;
51766 sqlite3_mutex_leave(pShmNode->mutex);
51767
51768 winShmPurge(pDbFd->pVfs, deleteFlag);
51769 winShmLeaveMutex();
51770
51771 /* Free the connection p */
51772 sqlite3_free(p);
51773 pDbFd->pShm = 0;
51774 return SQLITE_OK;
51775 }
51776
51777 /*
51778 ** testfixture builds may set this global variable to true via a
51779 ** Tcl interface. This forces the VFS to use the locking normally
51780 ** only used for UNC paths for all files.
51781 */
51782 #ifdef SQLITE_TEST
51783 SQLITE_API int sqlite3_win_test_unc_locking = 0;
51784 #else
51785 # define sqlite3_win_test_unc_locking 0
51786 #endif
51787
51788 /*
51789 ** Return true if the string passed as the only argument is likely
51790 ** to be a UNC path. In other words, if it starts with "\\".
51791 */
51792 static int winIsUNCPath(const char *zFile){
51793 if( zFile[0]=='\\' && zFile[1]=='\\' ){
51794 return 1;
51795 }
51796 return sqlite3_win_test_unc_locking;
51797 }
51798
51799 /*
51800 ** Open the shared-memory area associated with database file pDbFd.
51801 */
51802 static int winOpenSharedMemory(winFile *pDbFd){
@@ -51628,19 +51819,14 @@
51819 return SQLITE_IOERR_NOMEM_BKPT;
51820 }
51821 pNew->zFilename = (char*)&pNew[1];
51822 pNew->hSharedShm = INVALID_HANDLE_VALUE;
51823 pNew->isUnlocked = 1;
51824 pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath);
51825 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
51826 sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
51827
 
 
 
 
 
 
51828 /* Look to see if there is an existing winShmNode that can be used.
51829 ** If no matching winShmNode currently exists, then create a new one. */
51830 winShmEnterMutex();
51831 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
51832 /* TBD need to come up with better match here. Perhaps
@@ -51657,11 +51843,11 @@
51843 }
51844
51845 /* Open a file-handle to use for mappings, and for the DMS lock. */
51846 if( rc==SQLITE_OK ){
51847 HANDLE h = INVALID_HANDLE_VALUE;
51848 pShmNode->isReadonly = sqlite3_uri_boolean(pDbFd->zPath,"readonly_shm",0);
51849 rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h);
51850 pShmNode->hSharedShm = h;
51851 }
51852
51853 /* If successful, link the new winShmNode into the global list. If an
@@ -51679,24 +51865,39 @@
51865 }
51866
51867 /* If no error has occurred, link the winShm object to the winShmNode and
51868 ** the winShm to pDbFd. */
51869 if( rc==SQLITE_OK ){
51870 sqlite3_mutex_enter(pShmNode->mutex);
51871 p->pShmNode = pShmNode;
51872 p->pWinShmNext = pShmNode->pWinShmList;
51873 pShmNode->pWinShmList = p;
51874 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
51875 p->id = pShmNode->nextShmId++;
51876 #endif
51877 pDbFd->pShm = p;
51878 sqlite3_mutex_leave(pShmNode->mutex);
51879 }else if( p ){
 
51880 sqlite3_free(p);
51881 }
51882
51883 assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 );
51884 winShmLeaveMutex();
51885 sqlite3_free(pNew);
51886
51887 /* Open a file-handle on the *-shm file for this connection. This file-handle
51888 ** is only used for locking. The mapping of the *-shm file is created using
51889 ** the shared file handle in winShmNode.hSharedShm. */
51890 if( rc==SQLITE_OK && pShmNode->bUseSharedLockHandle==0 ){
51891 p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0);
51892 rc = winHandleOpen(pShmNode->zFilename, &p->bReadonly, &p->hShm);
51893 if( rc!=SQLITE_OK ){
51894 assert( p->hShm==INVALID_HANDLE_VALUE );
51895 winCloseSharedMemory(pDbFd, 0);
51896 }
51897 }
51898
51899 return rc;
51900 }
51901
51902 /*
51903 ** Close a connection to shared-memory. Delete the underlying
@@ -51704,37 +51905,11 @@
51905 */
51906 static int winShmUnmap(
51907 sqlite3_file *fd, /* Database holding shared memory */
51908 int deleteFlag /* Delete after closing if true */
51909 ){
51910 return winCloseSharedMemory((winFile*)fd, deleteFlag);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51911 }
51912
51913 /*
51914 ** Change the lock state for a shared-memory segment.
51915 */
@@ -51799,29 +51974,75 @@
51974 );
51975 if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
51976 || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
51977 || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
51978 ){
51979 HANDLE h = p->hShm;
51980
51981 if( flags & SQLITE_SHM_UNLOCK ){
51982 /* Case (a) - unlock. */
51983
51984 assert( (p->exclMask & p->sharedMask)==0 );
51985 assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
51986 assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
51987
51988 assert( !(flags & SQLITE_SHM_SHARED) || n==1 );
51989 if( pShmNode->bUseSharedLockHandle ){
51990 h = pShmNode->hSharedShm;
51991 if( flags & SQLITE_SHM_SHARED ){
51992 winShm *pShm;
51993 sqlite3_mutex_enter(pShmNode->mutex);
51994 for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){
51995 if( pShm!=p && (pShm->sharedMask & mask) ){
51996 /* Another connection within this process is also holding this
51997 ** SHARED lock. So do not actually release the OS lock. */
51998 h = INVALID_HANDLE_VALUE;
51999 break;
52000 }
52001 }
52002 sqlite3_mutex_leave(pShmNode->mutex);
52003 }
52004 }
52005
52006 if( h!=INVALID_HANDLE_VALUE ){
52007 rc = winHandleUnlock(h, ofst+WIN_SHM_BASE, n);
52008 }
52009
52010 /* If successful, also clear the bits in sharedMask/exclMask */
52011 if( rc==SQLITE_OK ){
52012 p->exclMask = (p->exclMask & ~mask);
52013 p->sharedMask = (p->sharedMask & ~mask);
52014 }
52015 }else{
52016 int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0);
52017 DWORD nMs = winFileBusyTimeout(pDbFd);
52018
52019 if( pShmNode->bUseSharedLockHandle ){
52020 winShm *pShm;
52021 h = pShmNode->hSharedShm;
52022 sqlite3_mutex_enter(pShmNode->mutex);
52023 for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){
52024 if( bExcl ){
52025 if( (pShm->sharedMask|pShm->exclMask) & mask ){
52026 rc = SQLITE_BUSY;
52027 h = INVALID_HANDLE_VALUE;
52028 }
52029 }else{
52030 if( pShm->sharedMask & mask ){
52031 h = INVALID_HANDLE_VALUE;
52032 }else if( pShm->exclMask & mask ){
52033 rc = SQLITE_BUSY;
52034 h = INVALID_HANDLE_VALUE;
52035 }
52036 }
52037 }
52038 sqlite3_mutex_leave(pShmNode->mutex);
52039 }
52040
52041 if( h!=INVALID_HANDLE_VALUE ){
52042 rc = winHandleLockTimeout(h, ofst+WIN_SHM_BASE, n, bExcl, nMs);
52043 }
52044 if( rc==SQLITE_OK ){
52045 if( bExcl ){
52046 p->exclMask = (p->exclMask | mask);
52047 }else{
52048 p->sharedMask = (p->sharedMask | mask);
@@ -61848,18 +62069,31 @@
62069 SQLITE_PRIVATE void sqlite3PagerSetFlags(
62070 Pager *pPager, /* The pager to set safety level for */
62071 unsigned pgFlags /* Various flags */
62072 ){
62073 unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
62074 if( pPager->tempFile || level==PAGER_SYNCHRONOUS_OFF ){
62075 pPager->noSync = 1;
62076 pPager->fullSync = 0;
62077 pPager->extraSync = 0;
62078 }else{
62079 pPager->noSync = 0;
62080 pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
62081
62082 /* Set Pager.extraSync if "PRAGMA synchronous=EXTRA" is requested, or
62083 ** if the file-system supports F2FS style atomic writes. If this flag
62084 ** is set, SQLite syncs the directory to disk immediately after deleting
62085 ** a journal file in "PRAGMA journal_mode=DELETE" mode. */
62086 if( level==PAGER_SYNCHRONOUS_EXTRA
62087 #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
62088 || (sqlite3OsDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_BATCH_ATOMIC)
62089 #endif
62090 ){
62091 pPager->extraSync = 1;
62092 }else{
62093 pPager->extraSync = 0;
62094 }
62095 }
62096 if( pPager->noSync ){
62097 pPager->syncFlags = 0;
62098 }else if( pgFlags & PAGER_FULLFSYNC ){
62099 pPager->syncFlags = SQLITE_SYNC_FULL;
@@ -65748,11 +65982,11 @@
65982 */
65983 sqlite3_exec(db, "PRAGMA table_list",0,0,0);
65984 }
65985 if( pPager->pWal ){
65986 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
65987 (eMode<=SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
65988 pPager->pBusyHandlerArg,
65989 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
65990 pnLog, pnCkpt
65991 );
65992 }
@@ -70353,11 +70587,12 @@
70587 assert( pWal->ckptLock==0 );
70588 assert( pWal->writeLock==0 );
70589
70590 /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
70591 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
70592 assert( SQLITE_CHECKPOINT_NOOP<SQLITE_CHECKPOINT_PASSIVE );
70593 assert( eMode>SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
70594
70595 if( pWal->readOnly ) return SQLITE_READONLY;
70596 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
70597
70598 /* Enable blocking locks, if possible. */
@@ -70370,35 +70605,39 @@
70605 ** checkpoint operation at the same time, the lock cannot be obtained and
70606 ** SQLITE_BUSY is returned.
70607 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
70608 ** it will not be invoked in this case.
70609 */
70610 if( eMode!=SQLITE_CHECKPOINT_NOOP ){
70611 rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
70612 testcase( rc==SQLITE_BUSY );
70613 testcase( rc!=SQLITE_OK && xBusy2!=0 );
70614 if( rc==SQLITE_OK ){
70615 pWal->ckptLock = 1;
70616
70617 /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART
70618 ** and TRUNCATE modes also obtain the exclusive "writer" lock on the
70619 ** database file.
70620 **
70621 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
70622 ** immediately, and a busy-handler is configured, it is invoked and the
70623 ** writer lock retried until either the busy-handler returns 0 or the
70624 ** lock is successfully obtained.
70625 */
70626 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
70627 rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
70628 if( rc==SQLITE_OK ){
70629 pWal->writeLock = 1;
70630 }else if( rc==SQLITE_BUSY ){
70631 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
70632 xBusy2 = 0;
70633 rc = SQLITE_OK;
70634 }
70635 }
70636 }
70637 }else{
70638 rc = SQLITE_OK;
70639 }
70640
70641
70642 /* Read the wal-index header. */
70643 SEH_TRY {
@@ -70408,21 +70647,21 @@
70647 ** or invoke the busy handler. The only lock such a checkpoint may
70648 ** attempt to obtain is a lock on a read-slot, and it should give up
70649 ** immediately and do a partial checkpoint if it cannot obtain it. */
70650 walDisableBlocking(pWal);
70651 rc = walIndexReadHdr(pWal, &isChanged);
70652 if( eMode2>SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
70653 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
70654 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
70655 }
70656 }
70657
70658 /* Copy data from the log to the database file. */
70659 if( rc==SQLITE_OK ){
70660 if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
70661 rc = SQLITE_CORRUPT_BKPT;
70662 }else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){
70663 rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf);
70664 }
70665
70666 /* If no error occurred, set the output variables. */
70667 if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
@@ -91645,11 +91884,11 @@
91884
91885 preupdate.v = v;
91886 preupdate.pCsr = pCsr;
91887 preupdate.op = op;
91888 preupdate.iNewReg = iReg;
91889 preupdate.pKeyinfo = &preupdate.uKey.sKey;
91890 preupdate.pKeyinfo->db = db;
91891 preupdate.pKeyinfo->enc = ENC(db);
91892 preupdate.pKeyinfo->nKeyField = pTab->nCol;
91893 preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */
91894 preupdate.iKey1 = iKey1;
@@ -102528,10 +102767,11 @@
102767 aRes[1] = aRes[2] = -1;
102768 assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
102769 || pOp->p2==SQLITE_CHECKPOINT_FULL
102770 || pOp->p2==SQLITE_CHECKPOINT_RESTART
102771 || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
102772 || pOp->p2==SQLITE_CHECKPOINT_NOOP
102773 );
102774 rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
102775 if( rc ){
102776 if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
102777 rc = SQLITE_OK;
@@ -110651,18 +110891,21 @@
110891 ExprList *pList /* Expression list to resolve. May be NULL. */
110892 ){
110893 SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */
110894 NameContext sNC; /* Name context for pParse->pNewTable */
110895 int rc;
110896 union {
110897 SrcList sSrc;
110898 u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */
110899 } uSrc;
110900
110901 assert( type==0 || pTab!=0 );
110902 assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
110903 || type==NC_GenCol || pTab==0 );
110904 memset(&sNC, 0, sizeof(sNC));
110905 memset(&uSrc, 0, sizeof(uSrc));
110906 pSrc = &uSrc.sSrc;
110907 if( pTab ){
110908 pSrc->nSrc = 1;
110909 pSrc->a[0].zName = pTab->zName;
110910 pSrc->a[0].pSTab = pTab;
110911 pSrc->a[0].iCursor = -1;
@@ -111921,10 +112164,15 @@
112164 if( IsWindowFunc(pExpr) ){
112165 sqlite3ExprOrderByAggregateError(pParse, pExpr);
112166 sqlite3ExprListDelete(db, pOrderBy);
112167 return;
112168 }
112169 if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
112170 sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
112171 sqlite3ExprListDelete(db, pOrderBy);
112172 return;
112173 }
112174
112175 pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0);
112176 if( pOB==0 ){
112177 sqlite3ExprListDelete(db, pOrderBy);
112178 return;
@@ -113117,13 +113365,12 @@
113365 }
113366 r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1);
113367 if( addrIsNull==0 ){
113368 /*
113369 ** If the right operand contains a subquery and the left operand does not
113370 ** and the left operand might be NULL, then do an IsNull check
113371 ** check on the left operand before computing the right operand.
 
113372 */
113373 if( ExprHasProperty(pExpr->pRight, EP_Subquery)
113374 && sqlite3ExprCanBeNull(pExpr->pLeft)
113375 ){
113376 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1);
@@ -114683,11 +114930,10 @@
114930 int destIfNull /* Jump here if the results are unknown due to NULLs */
114931 ){
114932 int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
114933 int eType; /* Type of the RHS */
114934 int rLhs; /* Register(s) holding the LHS values */
 
114935 Vdbe *v; /* Statement under construction */
114936 int *aiMap = 0; /* Map from vector field to index column */
114937 char *zAff = 0; /* Affinity string for comparisons */
114938 int nVector; /* Size of vectors for this IN operator */
114939 int iDummy; /* Dummy parameter to exprCodeVector() */
@@ -114746,23 +114992,12 @@
114992 ** Avoid factoring the LHS of the IN(...) expression out of the loop,
114993 ** even if it is constant, as OP_Affinity may be used on the register
114994 ** by code generated below. */
114995 assert( pParse->okConstFactor==okConstFactor );
114996 pParse->okConstFactor = 0;
114997 rLhs = exprCodeVector(pParse, pLeft, &iDummy);
114998 pParse->okConstFactor = okConstFactor;
 
 
 
 
 
 
 
 
 
 
 
114999
115000 /* If sqlite3FindInIndex() did not find or create an index that is
115001 ** suitable for evaluating the IN operator, then evaluate using a
115002 ** sequence of comparisons.
115003 **
@@ -114773,10 +115008,11 @@
115008 CollSeq *pColl;
115009 int labelOk = sqlite3VdbeMakeLabel(pParse);
115010 int r2, regToFree;
115011 int regCkNull = 0;
115012 int ii;
115013 assert( nVector==1 );
115014 assert( ExprUseXList(pExpr) );
115015 pList = pExpr->x.pList;
115016 pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
115017 if( destIfNull!=destIfFalse ){
115018 regCkNull = sqlite3GetTempReg(pParse);
@@ -114813,10 +115049,30 @@
115049 }
115050 sqlite3VdbeResolveLabel(v, labelOk);
115051 sqlite3ReleaseTempReg(pParse, regCkNull);
115052 goto sqlite3ExprCodeIN_finished;
115053 }
115054
115055 if( eType!=IN_INDEX_ROWID ){
115056 /* If this IN operator will use an index, then the order of columns in the
115057 ** vector might be different from the order in the index. In that case,
115058 ** we need to reorder the LHS values to be in index order. Run Affinity
115059 ** before reordering the columns, so that the affinity is correct.
115060 */
115061 sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
115062 for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
115063 if( i!=nVector ){
115064 /* Need to reorder the LHS fields according to aiMap */
115065 int rLhsOrig = rLhs;
115066 rLhs = sqlite3GetTempRange(pParse, nVector);
115067 for(i=0; i<nVector; i++){
115068 sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
115069 }
115070 sqlite3ReleaseTempReg(pParse, rLhsOrig);
115071 }
115072 }
115073
115074
115075 /* Step 2: Check to see if the LHS contains any NULL columns. If the
115076 ** LHS does contain NULLs then the result must be either FALSE or NULL.
115077 ** We will then skip the binary search of the RHS.
115078 */
@@ -114840,15 +115096,15 @@
115096 */
115097 if( eType==IN_INDEX_ROWID ){
115098 /* In this case, the RHS is the ROWID of table b-tree and so we also
115099 ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
115100 ** into a single opcode. */
115101 assert( nVector==1 );
115102 sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
115103 VdbeCoverage(v);
115104 addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
115105 }else{
 
115106 if( destIfFalse==destIfNull ){
115107 /* Combine Step 3 and Step 5 into a single opcode */
115108 if( ExprHasProperty(pExpr, EP_Subrtn) ){
115109 const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
115110 assert( pOp->opcode==OP_Once || pParse->nErr );
@@ -114922,11 +115178,10 @@
115178
115179 /* Jumps here in order to return true. */
115180 sqlite3VdbeJumpHere(v, addrTruthOp);
115181
115182 sqlite3ExprCodeIN_finished:
 
115183 VdbeComment((v, "end IN expr"));
115184 sqlite3ExprCodeIN_oom_error:
115185 sqlite3DbFree(pParse->db, aiMap);
115186 sqlite3DbFree(pParse->db, zAff);
115187 }
@@ -115480,10 +115735,82 @@
115735 }
115736 }
115737 return 0;
115738 }
115739
115740 /*
115741 ** Generate code that evaluates an AND or OR operator leaving a
115742 ** boolean result in a register. pExpr is the AND/OR expression.
115743 ** Store the result in the "target" register. Use short-circuit
115744 ** evaluation to avoid computing both operands, if possible.
115745 **
115746 ** The code generated might require the use of a temporary register.
115747 ** If it does, then write the number of that temporary register
115748 ** into *pTmpReg. If not, leave *pTmpReg unchanged.
115749 */
115750 static SQLITE_NOINLINE int exprCodeTargetAndOr(
115751 Parse *pParse, /* Parsing context */
115752 Expr *pExpr, /* AND or OR expression to be coded */
115753 int target, /* Put result in this register, guaranteed */
115754 int *pTmpReg /* Write a temporary register here */
115755 ){
115756 int op; /* The opcode. TK_AND or TK_OR */
115757 int skipOp; /* Opcode for the branch that skips one operand */
115758 int addrSkip; /* Branch instruction that skips one of the operands */
115759 int regSS = 0; /* Register holding computed operand when other omitted */
115760 int r1, r2; /* Registers for left and right operands, respectively */
115761 Expr *pAlt; /* Alternative, simplified expression */
115762 Vdbe *v; /* statement being coded */
115763
115764 assert( pExpr!=0 );
115765 op = pExpr->op;
115766 assert( op==TK_AND || op==TK_OR );
115767 assert( TK_AND==OP_And ); testcase( op==TK_AND );
115768 assert( TK_OR==OP_Or ); testcase( op==TK_OR );
115769 pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
115770 if( pAlt!=pExpr ){
115771 return sqlite3ExprCodeTarget(pParse, pAlt, target);
115772 }
115773 assert( pParse->pVdbe!=0 );
115774 v = pParse->pVdbe;
115775 skipOp = op==TK_AND ? OP_IfNot : OP_If;
115776 if( exprEvalRhsFirst(pExpr) ){
115777 /* Compute the right operand first. Skip the computation of the left
115778 ** operand if the right operand fully determines the result */
115779 r2 = regSS = sqlite3ExprCodeTarget(pParse, pExpr->pRight, target);
115780 addrSkip = sqlite3VdbeAddOp1(v, skipOp, r2);
115781 VdbeComment((v, "skip left operand"));
115782 VdbeCoverage(v);
115783 r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pTmpReg);
115784 }else{
115785 /* Compute the left operand first */
115786 r1 = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
115787 if( ExprHasProperty(pExpr->pRight, EP_Subquery) ){
115788 /* Skip over the computation of the right operand if the right
115789 ** operand is a subquery and the left operand completely determines
115790 ** the result */
115791 regSS = r1;
115792 addrSkip = sqlite3VdbeAddOp1(v, skipOp, r1);
115793 VdbeComment((v, "skip right operand"));
115794 VdbeCoverage(v);
115795 }else{
115796 addrSkip = regSS = 0;
115797 }
115798 r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pTmpReg);
115799 }
115800 sqlite3VdbeAddOp3(v, op, r2, r1, target);
115801 testcase( (*pTmpReg)==0 );
115802 if( addrSkip ){
115803 sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
115804 sqlite3VdbeJumpHere(v, addrSkip);
115805 sqlite3VdbeAddOp3(v, OP_Or, regSS, regSS, target);
115806 VdbeComment((v, "short-circut value"));
115807 }
115808 return target;
115809 }
115810
115811
115812
115813 /*
115814 ** Generate code into the current Vdbe to evaluate the given
115815 ** expression. Attempt to store the results in register "target".
115816 ** Return the register where results are stored.
@@ -115768,16 +116095,18 @@
116095 sqlite3VdbeAddOp2(v, OP_Null, 0, inReg);
116096 }
116097 }
116098 testcase( regFree1==0 );
116099 testcase( regFree2==0 );
 
116100 }
116101 break;
116102 }
116103 case TK_AND:
116104 case TK_OR: {
116105 inReg = exprCodeTargetAndOr(pParse, pExpr, target, &regFree1);
116106 break;
116107 }
116108 case TK_PLUS:
116109 case TK_STAR:
116110 case TK_MINUS:
116111 case TK_REM:
116112 case TK_BITAND:
@@ -115785,12 +116114,10 @@
116114 case TK_SLASH:
116115 case TK_LSHIFT:
116116 case TK_RSHIFT:
116117 case TK_CONCAT: {
116118 int addrIsNull;
 
 
116119 assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
116120 assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
116121 assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
116122 assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
116123 assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
@@ -124573,11 +124900,11 @@
124900 */
124901 SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
124902 int i;
124903 i16 iCol16;
124904 assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
124905 assert( pIdx->nColumn<=SQLITE_MAX_COLUMN*2 );
124906 iCol16 = iCol;
124907 for(i=0; i<pIdx->nColumn; i++){
124908 if( iCol16==pIdx->aiColumn[i] ){
124909 return i;
124910 }
@@ -124870,10 +125197,13 @@
125197 sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
125198 sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
125199 sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
125200 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
125201 sqlite3VdbeAddOp0(v, OP_Close);
125202 }else if( db->init.imposterTable ){
125203 pTable->tabFlags |= TF_Imposter;
125204 if( db->init.imposterTable>=2 ) pTable->tabFlags |= TF_Readonly;
125205 }
125206
125207 /* Normal (non-error) return. */
125208 return;
125209
@@ -129165,18 +129495,23 @@
129495 pKey->aSortFlags[i] = pIdx->aSortOrder[i];
129496 assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
129497 }
129498 if( pParse->nErr ){
129499 assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
129500 if( pIdx->bNoQuery==0
129501 && sqlite3HashFind(&pIdx->pSchema->idxHash, pIdx->zName)
129502 ){
129503 /* Deactivate the index because it contains an unknown collating
129504 ** sequence. The only way to reactive the index is to reload the
129505 ** schema. Adding the missing collating sequence later does not
129506 ** reactive the index. The application had the chance to register
129507 ** the missing index using the collation-needed callback. For
129508 ** simplicity, SQLite will not give the application a second chance.
129509 **
129510 ** Except, do not do this if the index is not in the schema hash
129511 ** table. In this case the index is currently being constructed
129512 ** by a CREATE INDEX statement, and retrying will not help. */
129513 pIdx->bNoQuery = 1;
129514 pParse->rc = SQLITE_ERROR_RETRY;
129515 }
129516 sqlite3KeyInfoUnref(pKey);
129517 pKey = 0;
@@ -139247,10 +139582,12 @@
139582 /* Version 3.44.0 and later */
139583 void *(*get_clientdata)(sqlite3*,const char*);
139584 int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
139585 /* Version 3.50.0 and later */
139586 int (*setlk_timeout)(sqlite3*,int,int);
139587 /* Version 3.51.0 and later */
139588 int (*set_errmsg)(sqlite3*,int,const char*);
139589 };
139590
139591 /*
139592 ** This is the function signature used for all extension entry points. It
139593 ** is also defined in the file "loadext.c".
@@ -139582,10 +139919,12 @@
139919 /* Version 3.44.0 and later */
139920 #define sqlite3_get_clientdata sqlite3_api->get_clientdata
139921 #define sqlite3_set_clientdata sqlite3_api->set_clientdata
139922 /* Version 3.50.0 and later */
139923 #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
139924 /* Version 3.51.0 and later */
139925 #define sqlite3_set_errmsg sqlite3_api->set_errmsg
139926 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
139927
139928 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
139929 /* This case when the file really is being compiled as a loadable
139930 ** extension */
@@ -140105,11 +140444,13 @@
140444 sqlite3_stmt_explain,
140445 /* Version 3.44.0 and later */
140446 sqlite3_get_clientdata,
140447 sqlite3_set_clientdata,
140448 /* Version 3.50.0 and later */
140449 sqlite3_setlk_timeout,
140450 /* Version 3.51.0 and later */
140451 sqlite3_set_errmsg
140452 };
140453
140454 /* True if x is the directory separator character
140455 */
140456 #if SQLITE_OS_WIN
@@ -141566,10 +141907,26 @@
141907 addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
141908 VdbeCoverage(v);
141909 sqlite3VdbeAddOp0(v, OP_Halt);
141910 return addr;
141911 }
141912
141913 /*
141914 ** Should table pTab be skipped when doing an integrity_check?
141915 ** Return true or false.
141916 **
141917 ** If pObjTab is not null, the return true if pTab matches pObjTab.
141918 **
141919 ** If pObjTab is null, then return true only if pTab is an imposter table.
141920 */
141921 static int tableSkipIntegrityCheck(const Table *pTab, const Table *pObjTab){
141922 if( pObjTab ){
141923 return pTab!=pObjTab;
141924 }else{
141925 return (pTab->tabFlags & TF_Imposter)!=0;
141926 }
141927 }
141928
141929 /*
141930 ** Process a pragma statement.
141931 **
141932 ** Pragmas are of this form:
@@ -142912,11 +143269,11 @@
143269 pTbls = &db->aDb[i].pSchema->tblHash;
143270 for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143271 Table *pTab = sqliteHashData(x); /* Current table */
143272 Index *pIdx; /* An index on pTab */
143273 int nIdx; /* Number of indexes on pTab */
143274 if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143275 if( HasRowid(pTab) ) cnt++;
143276 for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
143277 }
143278 if( cnt==0 ) continue;
143279 if( pObjTab ) cnt++;
@@ -142925,11 +143282,11 @@
143282 cnt = 0;
143283 if( pObjTab ) aRoot[++cnt] = 0;
143284 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143285 Table *pTab = sqliteHashData(x);
143286 Index *pIdx;
143287 if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143288 if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
143289 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
143290 aRoot[++cnt] = pIdx->tnum;
143291 }
143292 }
@@ -142956,11 +143313,11 @@
143313 sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
143314 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143315 int iTab = 0;
143316 Table *pTab = sqliteHashData(x);
143317 Index *pIdx;
143318 if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143319 if( HasRowid(pTab) ){
143320 iTab = cnt++;
143321 }else{
143322 iTab = cnt;
143323 for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){
@@ -142992,11 +143349,11 @@
143349 int r1 = -1;
143350 int bStrict; /* True for a STRICT table */
143351 int r2; /* Previous key for WITHOUT ROWID tables */
143352 int mxCol; /* Maximum non-virtual column number */
143353
143354 if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143355 if( !IsOrdinaryTable(pTab) ) continue;
143356 if( isQuick || HasRowid(pTab) ){
143357 pPk = 0;
143358 r2 = 0;
143359 }else{
@@ -143316,11 +143673,11 @@
143673 */
143674 for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
143675 Table *pTab = sqliteHashData(x);
143676 sqlite3_vtab *pVTab;
143677 int a1;
143678 if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue;
143679 if( IsOrdinaryTable(pTab) ) continue;
143680 if( !IsVirtual(pTab) ) continue;
143681 if( pTab->nCol<=0 ){
143682 const char *zMod = pTab->u.vtab.azArg[0];
143683 if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
@@ -143548,10 +143905,12 @@
143905 eMode = SQLITE_CHECKPOINT_FULL;
143906 }else if( sqlite3StrICmp(zRight, "restart")==0 ){
143907 eMode = SQLITE_CHECKPOINT_RESTART;
143908 }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
143909 eMode = SQLITE_CHECKPOINT_TRUNCATE;
143910 }else if( sqlite3StrICmp(zRight, "noop")==0 ){
143911 eMode = SQLITE_CHECKPOINT_NOOP;
143912 }
143913 }
143914 pParse->nMem = 3;
143915 sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
143916 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
@@ -145114,13 +145473,15 @@
145473 ** or encounters a permanent error. A schema problem after one schema
145474 ** reset is considered a permanent error. */
145475 rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
145476 assert( rc==SQLITE_OK || *ppStmt==0 );
145477 if( rc==SQLITE_OK || db->mallocFailed ) break;
145478 cnt++;
145479 }while( (rc==SQLITE_ERROR_RETRY && ALWAYS(cnt<=SQLITE_MAX_PREPARE_RETRY))
145480 || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt)==1) );
145481 sqlite3BtreeLeaveAll(db);
145482 assert( rc!=SQLITE_ERROR_RETRY );
145483 rc = sqlite3ApiExit(db, rc);
145484 assert( (rc&db->errMask)==rc );
145485 db->busyHandler.nBusy = 0;
145486 sqlite3_mutex_leave(db->mutex);
145487 assert( rc==SQLITE_OK || (*ppStmt)==0 );
@@ -145790,12 +146151,11 @@
146151 while( p ){
146152 ExprSetProperty(p, joinFlag);
146153 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
146154 ExprSetVVAProperty(p, EP_NoReduce);
146155 p->w.iJoin = iTable;
146156 if( ExprUseXList(p) ){
 
146157 if( p->x.pList ){
146158 int i;
146159 for(i=0; i<p->x.pList->nExpr; i++){
146160 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
146161 }
@@ -146007,10 +146367,11 @@
146367 else if( pRight->u3.pOn ){
146368 sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
146369 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
146370 pRight->u3.pOn = 0;
146371 pRight->fg.isOn = 1;
146372 p->selFlags |= SF_OnToWhere;
146373 }
146374 }
146375 return 0;
146376 }
146377
@@ -146893,11 +147254,14 @@
147254 ** Allocate a KeyInfo object sufficient for an index of N key columns and
147255 ** X extra columns.
147256 */
147257 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
147258 int nExtra = (N+X)*(sizeof(CollSeq*)+1);
147259 KeyInfo *p;
147260 assert( X>=0 );
147261 if( NEVER(N+X>0xffff) ) return (KeyInfo*)sqlite3OomFault(db);
147262 p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra);
147263 if( p ){
147264 p->aSortFlags = (u8*)&p->aColl[N+X];
147265 p->nKeyField = (u16)N;
147266 p->nAllField = (u16)(N+X);
147267 p->enc = ENC(db);
@@ -149212,11 +149576,11 @@
149576 ** expressions in pEList.
149577 **
149578 ** ## About "isOuterJoin":
149579 **
149580 ** The isOuterJoin column indicates that the replacement will occur into a
149581 ** position in the parent that is NULL-able due to an OUTER JOIN. Either the
149582 ** target slot in the parent is the right operand of a LEFT JOIN, or one of
149583 ** the left operands of a RIGHT JOIN. In either case, we need to potentially
149584 ** bypass the substituted expression with OP_IfNullRow.
149585 **
149586 ** Suppose the original expression is an integer constant. Even though the table
@@ -150050,21 +150414,16 @@
150414 ** elements we are now copying in.
150415 */
150416 pSub = pSub1;
150417 for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
150418 int nSubSrc;
150419 u8 jointype = pSubitem->fg.jointype;
 
150420 assert( pSub!=0 );
150421 pSubSrc = pSub->pSrc; /* FROM clause of subquery */
150422 nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
150423 pSrc = pParent->pSrc; /* FROM clause of the outer query */
150424
 
 
 
 
150425 /* The subquery uses a single slot of the FROM clause of the outer
150426 ** query. If the subquery has more than one element in its FROM clause,
150427 ** then expand the outer query to make space for it to hold all elements
150428 ** of the subquery.
150429 **
@@ -150080,10 +150439,11 @@
150439 */
150440 if( nSubSrc>1 ){
150441 pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
150442 if( pSrc==0 ) break;
150443 pParent->pSrc = pSrc;
150444 pSubitem = &pSrc->a[iFrom];
150445 }
150446
150447 /* Transfer the FROM clause terms from the subquery into the
150448 ** outer query.
150449 */
@@ -150094,15 +150454,14 @@
150454 assert( pItem->fg.isSubquery
150455 || pItem->fg.fixedSchema
150456 || pItem->u4.zDatabase==0 );
150457 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
150458 *pItem = pSubSrc->a[i];
150459 pItem->fg.jointype |= (jointype & JT_LTORJ);
150460 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
150461 }
150462 pSubitem->fg.jointype |= jointype;
 
150463
150464 /* Now begin substituting subquery result set expressions for
150465 ** references to the iParent in the outer query.
150466 **
150467 ** Example:
@@ -152838,10 +153197,119 @@
153197 existsToJoin(pParse, p, pSubWhere);
153198 }
153199 }
153200 }
153201 }
153202
153203 /*
153204 ** Type used for Walker callbacks by selectCheckOnClauses().
153205 */
153206 typedef struct CheckOnCtx CheckOnCtx;
153207 struct CheckOnCtx {
153208 SrcList *pSrc; /* SrcList for this context */
153209 int iJoin; /* Cursor numbers must be =< than this */
153210 CheckOnCtx *pParent; /* Parent context */
153211 };
153212
153213 /*
153214 ** True if the SrcList passed as the only argument contains at least
153215 ** one RIGHT or FULL JOIN. False otherwise.
153216 */
153217 #define hasRightJoin(pSrc) (((pSrc)->a[0].fg.jointype & JT_LTORJ)!=0)
153218
153219 /*
153220 ** The xExpr callback for the search of invalid ON clause terms.
153221 */
153222 static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){
153223 CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx;
153224
153225 /* Check if pExpr is root or near-root of an ON clause constraint that needs
153226 ** to be checked to ensure that it does not refer to tables in its FROM
153227 ** clause to the right of itself. i.e. it is either:
153228 **
153229 ** + an ON clause on an OUTER join, or
153230 ** + an ON clause on an INNER join within a FROM that features at
153231 ** least one RIGHT or FULL join.
153232 */
153233 if( (ExprHasProperty(pExpr, EP_OuterON))
153234 || (ExprHasProperty(pExpr, EP_InnerON) && hasRightJoin(pCtx->pSrc))
153235 ){
153236 /* If CheckOnCtx.iJoin is already set, then fall through and process
153237 ** this expression node as normal. Or, if CheckOnCtx.iJoin is still 0,
153238 ** set it to the cursor number of the RHS of the join to which this
153239 ** ON expression was attached and then iterate through the entire
153240 ** expression. */
153241 assert( pCtx->iJoin==0 || pCtx->iJoin==pExpr->w.iJoin );
153242 if( pCtx->iJoin==0 ){
153243 pCtx->iJoin = pExpr->w.iJoin;
153244 sqlite3WalkExprNN(pWalker, pExpr);
153245 pCtx->iJoin = 0;
153246 return WRC_Prune;
153247 }
153248 }
153249
153250 if( pExpr->op==TK_COLUMN ){
153251 /* A column expression. Find the SrcList (if any) to which it refers.
153252 ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
153253 ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
153254 ** does not refer to a table to the right of CheckOnCtx.iJoin. */
153255 do {
153256 SrcList *pSrc = pCtx->pSrc;
153257 int iTab = pExpr->iTable;
153258 if( iTab>=pSrc->a[0].iCursor && iTab<=pSrc->a[pSrc->nSrc-1].iCursor ){
153259 if( pCtx->iJoin && iTab>pCtx->iJoin ){
153260 sqlite3ErrorMsg(pWalker->pParse,
153261 "ON clause references tables to its right");
153262 return WRC_Abort;
153263 }
153264 break;
153265 }
153266 pCtx = pCtx->pParent;
153267 }while( pCtx );
153268 }
153269 return WRC_Continue;
153270 }
153271
153272 /*
153273 ** The xSelect callback for the search of invalid ON clause terms.
153274 */
153275 static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){
153276 CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx;
153277 if( pSelect->pSrc==pCtx->pSrc || pSelect->pSrc->nSrc==0 ){
153278 return WRC_Continue;
153279 }else{
153280 CheckOnCtx sCtx;
153281 memset(&sCtx, 0, sizeof(sCtx));
153282 sCtx.pSrc = pSelect->pSrc;
153283 sCtx.pParent = pCtx;
153284 pWalker->u.pCheckOnCtx = &sCtx;
153285 sqlite3WalkSelect(pWalker, pSelect);
153286 pWalker->u.pCheckOnCtx = pCtx;
153287 pSelect->selFlags &= ~SF_OnToWhere;
153288 return WRC_Prune;
153289 }
153290 }
153291
153292 /*
153293 ** Check all ON clauses in pSelect to verify that they do not reference
153294 ** columns to the right.
153295 */
153296 static void selectCheckOnClauses(Parse *pParse, Select *pSelect){
153297 Walker w;
153298 CheckOnCtx sCtx;
153299 assert( pSelect->selFlags & SF_OnToWhere );
153300 assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 );
153301 memset(&w, 0, sizeof(w));
153302 w.pParse = pParse;
153303 w.xExprCallback = selectCheckOnClausesExpr;
153304 w.xSelectCallback = selectCheckOnClausesSelect;
153305 w.u.pCheckOnCtx = &sCtx;
153306 memset(&sCtx, 0, sizeof(sCtx));
153307 sCtx.pSrc = pSelect->pSrc;
153308 sqlite3WalkExprNN(&w, pSelect->pWhere);
153309 pSelect->selFlags &= ~SF_OnToWhere;
153310 }
153311
153312 /*
153313 ** Generate byte-code for the SELECT statement given in the p argument.
153314 **
153315 ** The results are returned according to the SelectDest structure.
@@ -152965,10 +153433,22 @@
153433 if( sqlite3TreeTrace & 0x10 ){
153434 TREETRACE(0x10,pParse,p, ("after name resolution:\n"));
153435 sqlite3TreeViewSelect(0, p, 0);
153436 }
153437 #endif
153438
153439 /* If the SELECT statement contains ON clauses that were moved into
153440 ** the WHERE clause, go through and verify that none of the terms
153441 ** in the ON clauses reference tables to the right of the ON clause.
153442 ** Do this now, after name resolution, but before query flattening
153443 */
153444 if( p->selFlags & SF_OnToWhere ){
153445 selectCheckOnClauses(pParse, p);
153446 if( pParse->nErr ){
153447 goto select_end;
153448 }
153449 }
153450
153451 /* If the SF_UFSrcCheck flag is set, then this function is being called
153452 ** as part of populating the temp table for an UPDATE...FROM statement.
153453 ** In this case, it is an error if the target object (pSrc->a[0]) name
153454 ** or alias is duplicated within FROM clause (pSrc->a[1..n]).
@@ -155531,11 +156011,14 @@
156011 sqlite3 *db = pParse->db;
156012 ExprList *pNew;
156013 Returning *pReturning;
156014 Select sSelect;
156015 SrcList *pFrom;
156016 union {
156017 SrcList sSrc;
156018 u8 fromSpace[SZ_SRCLIST_1];
156019 } uSrc;
156020
156021 assert( v!=0 );
156022 if( !pParse->bReturning ){
156023 /* This RETURNING trigger must be for a different statement as
156024 ** this statement lacks a RETURNING clause. */
@@ -155547,12 +156030,12 @@
156030 if( pTrigger != &(pReturning->retTrig) ){
156031 /* This RETURNING trigger is for a different statement */
156032 return;
156033 }
156034 memset(&sSelect, 0, sizeof(sSelect));
156035 memset(&uSrc, 0, sizeof(uSrc));
156036 pFrom = &uSrc.sSrc;
156037 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
156038 sSelect.pSrc = pFrom;
156039 pFrom->nSrc = 1;
156040 pFrom->a[0].pSTab = pTab;
156041 pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */
@@ -163079,11 +163562,14 @@
163562 WhereClause *pWC = &pWInfo->sWC;
163563 WhereInfo *pSubWInfo;
163564 WhereLoop *pLoop = pLevel->pWLoop;
163565 SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
163566 SrcList *pFrom;
163567 union {
163568 SrcList sSrc;
163569 u8 fromSpace[SZ_SRCLIST_1];
163570 } uSrc;
163571 Bitmask mAll = 0;
163572 int k;
163573
163574 ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
163575 sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
@@ -163123,11 +163609,11 @@
163609 if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
163610 pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
163611 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
163612 }
163613 }
163614 pFrom = &uSrc.sSrc;
163615 pFrom->nSrc = 1;
163616 pFrom->nAlloc = 1;
163617 memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem));
163618 pFrom->a[0].fg.jointype = 0;
163619 assert( pParse->withinRJSubrtn < 100 );
@@ -164340,25 +164826,11 @@
164826 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
164827 if( ExprHasProperty(pExpr, EP_OuterON) ){
164828 prereqAll |= x;
164829 extraRight = x-1; /* ON clause terms may not be used with an index
164830 ** on left table of a LEFT JOIN. Ticket #3015 */
 
 
 
 
164831 }else if( (prereqAll>>1)>=x ){
 
 
 
 
 
 
 
 
 
 
164832 ExprClearProperty(pExpr, EP_InnerON);
164833 }
164834 }
164835 pTerm->prereqAll = prereqAll;
164836 pTerm->leftCursor = -1;
@@ -170216,10 +170688,14 @@
170688 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
170689 if( pLoop->u.vtab.isOrdered
170690 && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
170691 ){
170692 obSat = obDone;
170693 }else{
170694 /* No further ORDER BY terms may be matched. So this call should
170695 ** return >=0, not -1. Clear isOrderDistinct to ensure it does so. */
170696 isOrderDistinct = 0;
170697 }
170698 break;
170699 }
170700 iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
170701
@@ -171119,22 +171595,18 @@
171595 pFrom = aTo;
171596 aTo = aFrom;
171597 aFrom = pFrom;
171598 nFrom = nTo;
171599 }
171600 assert( nFrom==0 || nFrom==1 );
171601
171602 if( nFrom==0 ){
171603 sqlite3ErrorMsg(pParse, "no query solution");
171604 sqlite3StackFreeNN(pParse->db, pSpace);
171605 return SQLITE_ERROR;
171606 }
 
 
171607 pFrom = aFrom;
 
 
 
171608 assert( pWInfo->nLevel==nLoop );
171609 /* Load the lowest cost path into pWInfo */
171610 for(iLoop=0; iLoop<nLoop; iLoop++){
171611 WhereLevel *pLevel = pWInfo->a + iLoop;
171612 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -171263,11 +171735,14 @@
171735 int once = 0;
171736 #endif
171737 for(i=0; i<pWInfo->nLevel; i++){
171738 WhereLoop *p = pWInfo->a[i].pWLoop;
171739 if( p==0 ) break;
171740 if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
171741 /* Treat a vtab scan as similar to a full-table scan */
171742 break;
171743 }
171744 if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
171745 u8 iTab = p->iTab;
171746 WhereLoop *pLoop;
171747 for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
171748 if( pLoop->iTab!=iTab ) continue;
@@ -175376,11 +175851,11 @@
175851 ** RETURN_ROW
175852 **
175853 **
175854 ** ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
175855 **
175856 ** ... loop started by sqlite3WhereBegin() ...
175857 ** if( new partition ){
175858 ** Gosub flush
175859 ** }
175860 ** Insert new row into eph table.
175861 ** if( first row of partition ){
@@ -175894,10 +176369,16 @@
176369 addrStart = sqlite3VdbeCurrentAddr(v);
176370 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
176371 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
176372 }else{
176373 assert( pMWin->eEnd==TK_FOLLOWING );
176374 /* assert( regStart>=0 );
176375 ** regEnd = regEnd - regStart;
176376 ** regStart = 0; */
176377 sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
176378 sqlite3VdbeAddOp2(v, OP_Integer, 0, regStart);
176379
176380 addrStart = sqlite3VdbeCurrentAddr(v);
176381 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
176382 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
176383 }
176384 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
@@ -184839,10 +185320,13 @@
185320 for(i=0; i<2 && zName==0; i++, rc &= 0xff){
185321 switch( rc ){
185322 case SQLITE_OK: zName = "SQLITE_OK"; break;
185323 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
185324 case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break;
185325 case SQLITE_ERROR_RETRY: zName = "SQLITE_ERROR_RETRY"; break;
185326 case SQLITE_ERROR_MISSING_COLLSEQ:
185327 zName = "SQLITE_ERROR_MISSING_COLLSEQ"; break;
185328 case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
185329 case SQLITE_PERM: zName = "SQLITE_PERM"; break;
185330 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
185331 case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
185332 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
@@ -186019,10 +186503,33 @@
186503 }
186504 }
186505 sqlite3_mutex_leave(db->mutex);
186506 return z;
186507 }
186508
186509 /*
186510 ** Set the error code and error message associated with the database handle.
186511 **
186512 ** This routine is intended to be called by outside extensions (ex: the
186513 ** Session extension). Internal logic should invoke sqlite3Error() or
186514 ** sqlite3ErrorWithMsg() directly.
186515 */
186516 SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
186517 int rc = SQLITE_OK;
186518 if( !sqlite3SafetyCheckSickOrOk(db) ){
186519 return SQLITE_MISUSE_BKPT;
186520 }
186521 sqlite3_mutex_enter(db->mutex);
186522 if( zMsg ){
186523 sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
186524 }else{
186525 sqlite3Error(db, errcode);
186526 }
186527 rc = sqlite3ApiExit(db, rc);
186528 sqlite3_mutex_leave(db->mutex);
186529 return rc;
186530 }
186531
186532 /*
186533 ** Return the byte offset of the most recent error
186534 */
186535 SQLITE_API int sqlite3_error_offset(sqlite3 *db){
@@ -187844,17 +188351,19 @@
188351 case SQLITE_TESTCTRL_ISINIT: {
188352 if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
188353 break;
188354 }
188355
188356 /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, mode, tnum);
188357 **
188358 ** This test control is used to create imposter tables. "db" is a pointer
188359 ** to the database connection. dbName is the database name (ex: "main" or
188360 ** "temp") which will receive the imposter. "mode" turns imposter mode on
188361 ** or off. mode==0 means imposter mode is off. mode==1 means imposter mode
188362 ** is on. mode==2 means imposter mode is on but results in an imposter
188363 ** table that is read-only unless writable_schema is on. "tnum" is the
188364 ** root page of the b-tree to which the imposter table should connect.
188365 **
188366 ** Enable imposter mode only when the schema has already been parsed. Then
188367 ** run a single CREATE TABLE statement to construct the imposter table in
188368 ** the parsed schema. Then turn imposter mode back off again.
188369 **
@@ -189087,21 +189596,24 @@
189596 **
189597 */
189598 #ifndef _FTSINT_H
189599 #define _FTSINT_H
189600
189601 /*
189602 ** Activate assert() only if SQLITE_TEST is enabled.
189603 */
189604 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
189605 # define NDEBUG 1
189606 #endif
189607
189608 /* #include <assert.h> */
189609 /* #include <stdlib.h> */
189610 /* #include <stddef.h> */
189611 /* #include <stdio.h> */
189612 /* #include <string.h> */
189613 /* #include <stdarg.h> */
189614
 
 
 
 
189615 /* FTS3/FTS4 require virtual tables */
189616 #ifdef SQLITE_OMIT_VIRTUALTABLE
189617 # undef SQLITE_ENABLE_FTS3
189618 # undef SQLITE_ENABLE_FTS4
189619 #endif
@@ -189540,17 +190052,10 @@
190052 /*
190053 ** Macro used to suppress compiler warnings for unused parameters.
190054 */
190055 #define UNUSED_PARAMETER(x) (void)(x)
190056
 
 
 
 
 
 
 
190057 /*
190058 ** The TESTONLY macro is used to enclose variable declarations or
190059 ** other bits of code that are needed to support the arguments
190060 ** within testcase() and assert() macros.
190061 */
@@ -203821,12 +204326,12 @@
204326 /*
204327 ** An object of this type contains the state required to create or append
204328 ** to an appendable b-tree segment.
204329 */
204330 struct IncrmergeWriter {
204331 i64 nLeafEst; /* Space allocated for leaf blocks */
204332 i64 nWork; /* Number of leaf pages flushed */
204333 sqlite3_int64 iAbsLevel; /* Absolute level of input segments */
204334 int iIdx; /* Index of *output* segment in iAbsLevel+1 */
204335 sqlite3_int64 iStart; /* Block number of first allocated block */
204336 sqlite3_int64 iEnd; /* Block number of last allocated block */
204337 sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */
@@ -204568,21 +205073,21 @@
205073 Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */
205074 IncrmergeWriter *pWriter /* Populate this object */
205075 ){
205076 int rc; /* Return Code */
205077 int i; /* Iterator variable */
205078 i64 nLeafEst = 0; /* Blocks allocated for leaf nodes */
205079 sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */
205080 sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */
205081
205082 /* Calculate nLeafEst. */
205083 rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0);
205084 if( rc==SQLITE_OK ){
205085 sqlite3_bind_int64(pLeafEst, 1, iAbsLevel);
205086 sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment);
205087 if( SQLITE_ROW==sqlite3_step(pLeafEst) ){
205088 nLeafEst = sqlite3_column_int64(pLeafEst, 0);
205089 }
205090 rc = sqlite3_reset(pLeafEst);
205091 }
205092 if( rc!=SQLITE_OK ) return rc;
205093
@@ -228353,12 +228858,12 @@
228858 typedef struct DbpageTable DbpageTable;
228859 typedef struct DbpageCursor DbpageCursor;
228860
228861 struct DbpageCursor {
228862 sqlite3_vtab_cursor base; /* Base class. Must be first */
228863 Pgno pgno; /* Current page number */
228864 Pgno mxPgno; /* Last page to visit on this scan */
228865 Pager *pPager; /* Pager being read/written */
228866 DbPage *pPage1; /* Page 1 of the database */
228867 int iDb; /* Index of database to analyze */
228868 int szPage; /* Size of each page in bytes */
228869 };
@@ -228491,11 +228996,11 @@
228996 if( pCsr==0 ){
228997 return SQLITE_NOMEM_BKPT;
228998 }else{
228999 memset(pCsr, 0, sizeof(DbpageCursor));
229000 pCsr->base.pVtab = pVTab;
229001 pCsr->pgno = 0;
229002 }
229003
229004 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
229005 return SQLITE_OK;
229006 }
@@ -228591,16 +229096,16 @@
229096 ){
229097 DbpageCursor *pCsr = (DbpageCursor *)pCursor;
229098 int rc = SQLITE_OK;
229099 switch( i ){
229100 case 0: { /* pgno */
229101 sqlite3_result_int64(ctx, (sqlite3_int64)pCsr->pgno);
229102 break;
229103 }
229104 case 1: { /* data */
229105 DbPage *pDbPage = 0;
229106 if( pCsr->pgno==(Pgno)((PENDING_BYTE/pCsr->szPage)+1) ){
229107 /* The pending byte page. Assume it is zeroed out. Attempting to
229108 ** request this page from the page is an SQLITE_CORRUPT error. */
229109 sqlite3_result_zeroblob(ctx, pCsr->szPage);
229110 }else{
229111 rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
@@ -228670,14 +229175,14 @@
229175 if( argc==1 ){
229176 zErr = "cannot delete";
229177 goto update_fail;
229178 }
229179 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
229180 pgno = (Pgno)sqlite3_value_int64(argv[2]);
229181 isInsert = 1;
229182 }else{
229183 pgno = (Pgno)sqlite3_value_int64(argv[0]);
229184 if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
229185 zErr = "cannot insert";
229186 goto update_fail;
229187 }
229188 isInsert = 0;
@@ -231625,10 +232130,23 @@
232130 assert( (a - p->aRecord)==p->nRecord );
232131 }
232132
232133 return rc;
232134 }
232135
232136 static int sessionPrepare(
232137 sqlite3 *db,
232138 sqlite3_stmt **pp,
232139 char **pzErrmsg,
232140 const char *zSql
232141 ){
232142 int rc = sqlite3_prepare_v2(db, zSql, -1, pp, 0);
232143 if( pzErrmsg && rc!=SQLITE_OK ){
232144 *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
232145 }
232146 return rc;
232147 }
232148
232149 /*
232150 ** Formulate and prepare a SELECT statement to retrieve a row from table
232151 ** zTab in database zDb based on its primary key. i.e.
232152 **
@@ -231647,16 +232165,16 @@
232165 const char *zTab, /* Table name */
232166 int bRowid,
232167 int nCol, /* Number of columns in table */
232168 const char **azCol, /* Names of table columns */
232169 u8 *abPK, /* PRIMARY KEY array */
232170 sqlite3_stmt **ppStmt, /* OUT: Prepared SELECT statement */
232171 char **pzErrmsg /* OUT: Error message */
232172 ){
232173 int rc = SQLITE_OK;
232174 char *zSql = 0;
232175 const char *zSep = "";
 
232176 int i;
232177
232178 SessionBuffer cols = {0, 0, 0};
232179 SessionBuffer nooptest = {0, 0, 0};
232180 SessionBuffer pkfield = {0, 0, 0};
@@ -231732,11 +232250,11 @@
232250 nSql = buf.nBuf;
232251 }
232252 #endif
232253
232254 if( rc==SQLITE_OK ){
232255 rc = sessionPrepare(db, ppStmt, pzErrmsg, zSql);
232256 }
232257 sqlite3_free(zSql);
232258 sqlite3_free(nooptest.aBuf);
232259 sqlite3_free(pkfield.aBuf);
232260 sqlite3_free(pkvar.aBuf);
@@ -231896,11 +232414,11 @@
232414 sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
232415
232416 /* Build and compile a statement to execute: */
232417 if( rc==SQLITE_OK ){
232418 rc = sessionSelectStmt(db, 0, pSession->zDb,
232419 zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel, 0
232420 );
232421 }
232422
232423 nNoop = buf.nBuf;
232424 for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
@@ -233105,10 +233623,11 @@
233623 SessionBuffer rebase; /* Rebase information (if any) here */
233624 u8 bRebaseStarted; /* If table header is already in rebase */
233625 u8 bRebase; /* True to collect rebase information */
233626 u8 bIgnoreNoop; /* True to ignore no-op conflicts */
233627 int bRowid;
233628 char *zErr; /* Error message, if any */
233629 };
233630
233631 /* Number of prepared UPDATE statements to cache. */
233632 #define SESSION_UPDATE_CACHE_SZ 12
233633
@@ -233330,11 +233849,11 @@
233849 }
233850 sessionAppendStr(&buf, ")", &rc);
233851 }
233852
233853 if( rc==SQLITE_OK ){
233854 rc = sessionPrepare(db, &p->pDelete, &p->zErr, (char*)buf.aBuf);
233855 }
233856 sqlite3_free(buf.aBuf);
233857
233858 return rc;
233859 }
@@ -233357,11 +233876,11 @@
233876 const char *zTab, /* Table name */
233877 SessionApplyCtx *p /* Session changeset-apply context */
233878 ){
233879 /* TODO */
233880 return sessionSelectStmt(db, p->bIgnoreNoop,
233881 "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect, &p->zErr
233882 );
233883 }
233884
233885 /*
233886 ** Formulate and prepare an INSERT statement to add a record to table zTab.
@@ -233394,37 +233913,33 @@
233913 sessionAppendStr(&buf, ", ?", &rc);
233914 }
233915 sessionAppendStr(&buf, ")", &rc);
233916
233917 if( rc==SQLITE_OK ){
233918 rc = sessionPrepare(db, &p->pInsert, &p->zErr, (char*)buf.aBuf);
233919 }
233920 sqlite3_free(buf.aBuf);
233921 return rc;
233922 }
233923
 
 
 
 
233924 /*
233925 ** Prepare statements for applying changes to the sqlite_stat1 table.
233926 ** These are similar to those created by sessionSelectRow(),
233927 ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
233928 ** other tables.
233929 */
233930 static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
233931 int rc = sessionSelectRow(db, "sqlite_stat1", p);
233932 if( rc==SQLITE_OK ){
233933 rc = sessionPrepare(db, &p->pInsert, 0,
233934 "INSERT INTO main.sqlite_stat1 VALUES(?1, "
233935 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
233936 "?3)"
233937 );
233938 }
233939 if( rc==SQLITE_OK ){
233940 rc = sessionPrepare(db, &p->pDelete, 0,
233941 "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
233942 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
233943 "AND (?4 OR stat IS ?3)"
233944 );
233945 }
@@ -233644,11 +234159,11 @@
234159 sqlite3_changeset_iter *pIter, /* Changeset iterator */
234160 int(*xConflict)(void *, int, sqlite3_changeset_iter*),
234161 void *pCtx, /* First argument for conflict handler */
234162 int *pbReplace /* OUT: Set to true if PK row is found */
234163 ){
234164 int res = SQLITE_CHANGESET_OMIT;/* Value returned by conflict handler */
234165 int rc;
234166 int nCol;
234167 int op;
234168 const char *zDummy;
234169
@@ -233665,15 +234180,13 @@
234180 rc = SQLITE_OK;
234181 }
234182
234183 if( rc==SQLITE_ROW ){
234184 /* There exists another row with the new.* primary key. */
234185 if( 0==p->bIgnoreNoop
234186 || 0==sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
234187 ){
 
 
234188 pIter->pConflict = p->pSelect;
234189 res = xConflict(pCtx, eType, pIter);
234190 pIter->pConflict = 0;
234191 }
234192 rc = sqlite3_reset(p->pSelect);
@@ -233683,11 +234196,13 @@
234196 ** to the SessionApplyCtx.constraints buffer. */
234197 u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
234198 int nBlob = pIter->in.iNext - pIter->in.iCurrent;
234199 sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
234200 return SQLITE_OK;
234201 }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE
234202 || eType==SQLITE_CHANGESET_CONFLICT
234203 ){
234204 /* No other row with the new.* primary key. */
234205 res = xConflict(pCtx, eType+1, pIter);
234206 if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
234207 }
234208 }
@@ -233781,11 +234296,11 @@
234296 }
234297 if( rc!=SQLITE_OK ) return rc;
234298
234299 sqlite3_step(p->pDelete);
234300 rc = sqlite3_reset(p->pDelete);
234301 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
234302 rc = sessionConflictHandler(
234303 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
234304 );
234305 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
234306 rc = sessionConflictHandler(
@@ -234203,10 +234718,15 @@
234718 if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
234719 assert( db->flags & SQLITE_FkNoAction );
234720 db->flags &= ~((u64)SQLITE_FkNoAction);
234721 db->aDb[0].pSchema->schema_cookie -= 32;
234722 }
234723
234724 assert( rc!=SQLITE_OK || sApply.zErr==0 );
234725 sqlite3_set_errmsg(db, rc, sApply.zErr);
234726 sqlite3_free(sApply.zErr);
234727
234728 sqlite3_mutex_leave(sqlite3_db_mutex(db));
234729 return rc;
234730 }
234731
234732 /*
@@ -236412,25 +236932,18 @@
236932 ** Constants for the largest and smallest possible 64-bit signed integers.
236933 */
236934 # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
236935 # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
236936
236937 /*
236938 ** This macro is used in a single assert() within fts5 to check that an
236939 ** allocation is aligned to an 8-byte boundary. But it is a complicated
236940 ** macro to get right for multiple platforms without generating warnings.
236941 ** So instead of reproducing the entire definition from sqliteInt.h, we
236942 ** just do without this assert() for the rare non-amalgamation builds.
236943 */
236944 #define EIGHT_BYTE_ALIGNMENT(x) 1
 
 
 
 
 
 
 
 
 
 
 
 
236945
236946 /*
236947 ** Macros needed to provide flexible arrays in a portable way
236948 */
236949 #ifndef offsetof
@@ -237174,11 +237687,11 @@
237687 ** ){
237688 ** // The document with rowid iRowid matches the expression!
237689 ** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
237690 ** }
237691 */
237692 static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, i64, int bDesc);
237693 static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
237694 static int sqlite3Fts5ExprEof(Fts5Expr*);
237695 static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
237696
237697 static void sqlite3Fts5ExprFree(Fts5Expr*);
@@ -242743,11 +243256,17 @@
243256 ** equal to iFirst.
243257 **
243258 ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
243259 ** is not considered an error if the query does not match any documents.
243260 */
243261 static int sqlite3Fts5ExprFirst(
243262 Fts5Expr *p,
243263 Fts5Index *pIdx,
243264 i64 iFirst,
243265 i64 iLast,
243266 int bDesc
243267 ){
243268 Fts5ExprNode *pRoot = p->pRoot;
243269 int rc; /* Return code */
243270
243271 p->pIndex = pIdx;
243272 p->bDesc = bDesc;
@@ -242764,10 +243283,13 @@
243283
243284 /* If the iterator is not at a real match, skip forward until it is. */
243285 while( pRoot->bNomatch && rc==SQLITE_OK ){
243286 assert( pRoot->bEof==0 );
243287 rc = fts5ExprNodeNext(p, pRoot, 0, 0);
243288 }
243289 if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
243290 pRoot->bEof = 1;
243291 }
243292 return rc;
243293 }
243294
243295 /*
@@ -251885,14 +252407,17 @@
252407 ** function populates it with the initial structure objects for each index,
252408 ** and the initial version of the "averages" record (a zero-byte blob).
252409 */
252410 static int sqlite3Fts5IndexReinit(Fts5Index *p){
252411 Fts5Structure *pTmp;
252412 union {
252413 Fts5Structure sFts;
252414 u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252415 } uFts;
252416 fts5StructureInvalidate(p);
252417 fts5IndexDiscardData(p);
252418 pTmp = &uFts.sFts;
252419 memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
252420 if( p->pConfig->bContentlessDelete ){
252421 pTmp->nOriginCntr = 1;
252422 }
252423 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
@@ -255109,10 +255634,21 @@
255634 {
255635 pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
255636 }
255637 #endif
255638 }
255639
255640 static void fts5SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
255641 #if SQLITE_VERSION_NUMBER>=3008002
255642 #ifndef SQLITE_CORE
255643 if( sqlite3_libversion_number()>=3008002 )
255644 #endif
255645 {
255646 pIdxInfo->estimatedRows = nRow;
255647 }
255648 #endif
255649 }
255650
255651 static int fts5UsePatternMatch(
255652 Fts5Config *pConfig,
255653 struct sqlite3_index_constraint *p
255654 ){
@@ -255245,11 +255781,11 @@
255781 bSeenRank = 1;
255782 }else{
255783 nSeenMatch++;
255784 idxStr[iIdxStr++] = 'M';
255785 sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
255786 iIdxStr += (int)strlen(&idxStr[iIdxStr]);
255787 assert( idxStr[iIdxStr]=='\0' );
255788 }
255789 pInfo->aConstraintUsage[i].argvIndex = ++iCons;
255790 pInfo->aConstraintUsage[i].omit = 1;
255791 }
@@ -255264,10 +255800,11 @@
255800 nSeenMatch++;
255801 }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
255802 idxStr[iIdxStr++] = '=';
255803 bSeenEq = 1;
255804 pInfo->aConstraintUsage[i].argvIndex = ++iCons;
255805 pInfo->aConstraintUsage[i].omit = 1;
255806 }
255807 }
255808 }
255809
255810 if( bSeenEq==0 ){
@@ -255311,21 +255848,25 @@
255848 }
255849 }
255850
255851 /* Calculate the estimated cost based on the flags set in idxFlags. */
255852 if( bSeenEq ){
255853 pInfo->estimatedCost = nSeenMatch ? 1000.0 : 25.0;
255854 fts5SetUniqueFlag(pInfo);
255855 fts5SetEstimatedRows(pInfo, 1);
 
 
 
255856 }else{
255857 if( bSeenLt && bSeenGt ){
255858 pInfo->estimatedCost = nSeenMatch ? 5000.0 : 750000.0;
255859 }else if( bSeenLt || bSeenGt ){
255860 pInfo->estimatedCost = nSeenMatch ? 7500.0 : 2250000.0;
255861 }else{
255862 pInfo->estimatedCost = nSeenMatch ? 10000.0 : 3000000.0;
255863 }
255864 for(i=1; i<nSeenMatch; i++){
255865 pInfo->estimatedCost *= 0.4;
255866 }
255867 fts5SetEstimatedRows(pInfo, (i64)(pInfo->estimatedCost / 4.0));
255868 }
255869
255870 pInfo->idxNum = idxFlags;
255871 return SQLITE_OK;
255872 }
@@ -255520,11 +256061,13 @@
256061 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
256062 Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
256063 int bDesc = pCsr->bDesc;
256064 i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
256065
256066 rc = sqlite3Fts5ExprFirst(
256067 pCsr->pExpr, pTab->p.pIndex, iRowid, pCsr->iLastRowid, bDesc
256068 );
256069 if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
256070 *pbSkip = 1;
256071 }
256072
256073 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
@@ -255692,11 +256235,13 @@
256235 }
256236
256237 static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
256238 int rc;
256239 Fts5Expr *pExpr = pCsr->pExpr;
256240 rc = sqlite3Fts5ExprFirst(
256241 pExpr, pTab->p.pIndex, pCsr->iFirstRowid, pCsr->iLastRowid, bDesc
256242 );
256243 if( sqlite3Fts5ExprEof(pExpr) ){
256244 CsrFlagSet(pCsr, FTS5CSR_EOF);
256245 }
256246 fts5CsrNewrow(pCsr);
256247 return rc;
@@ -258177,11 +258722,11 @@
258722 int nArg, /* Number of args */
258723 sqlite3_value **apUnused /* Function arguments */
258724 ){
258725 assert( nArg==0 );
258726 UNUSED_PARAM2(nArg, apUnused);
258727 sqlite3_result_text(pCtx, "fts5: 2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232", -1, SQLITE_TRANSIENT);
258728 }
258729
258730 /*
258731 ** Implementation of fts5_locale(LOCALE, TEXT) function.
258732 **
258733
+100 -41
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,14 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.51.0"
150150
#define SQLITE_VERSION_NUMBER 3051000
151
-#define SQLITE_SOURCE_ID "2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1"
151
+#define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
152
+#define SQLITE_SCM_BRANCH "trunk"
153
+#define SQLITE_SCM_TAGS ""
154
+#define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
152155
153156
/*
154157
** CAPI3REF: Run-Time Library Version Numbers
155158
** KEYWORDS: sqlite3_version sqlite3_sourceid
156159
**
@@ -2338,21 +2341,24 @@
23382341
** views in the main database schema or in the schemas of ATTACH-ed
23392342
** databases.)^ </dd>
23402343
**
23412344
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
23422345
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2343
-** <dd> ^This option is used to enable or disable the
2344
-** [fts3_tokenizer()] function which is part of the
2345
-** [FTS3] full-text search engine extension.
2346
-** There must be two additional arguments.
2347
-** The first argument is an integer which is 0 to disable fts3_tokenizer() or
2348
-** positive to enable fts3_tokenizer() or negative to leave the setting
2349
-** unchanged.
2350
-** The second parameter is a pointer to an integer into which
2351
-** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2352
-** following this call. The second parameter may be a NULL pointer, in
2353
-** which case the new setting is not reported back. </dd>
2346
+** <dd> ^This option is used to enable or disable using the
2347
+** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine
2348
+** extension - without using bound parameters as the parameters. Doing so
2349
+** is disabled by default. There must be two additional arguments. The first
2350
+** argument is an integer. If it is passed 0, then using fts3_tokenizer()
2351
+** without bound parameters is disabled. If it is passed a positive value,
2352
+** then calling fts3_tokenizer without bound parameters is enabled. If it
2353
+** is passed a negative value, this setting is not modified - this can be
2354
+** used to query for the current setting. The second parameter is a pointer
2355
+** to an integer into which is written 0 or 1 to indicate the current value
2356
+** of this setting (after it is modified, if applicable). The second
2357
+** parameter may be a NULL pointer, in which case the value of the setting
2358
+** is not reported back. Refer to [FTS3] documentation for further details.
2359
+** </dd>
23542360
**
23552361
** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
23562362
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
23572363
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
23582364
** interface independently of the [load_extension()] SQL function.
@@ -4198,10 +4204,38 @@
41984204
SQLITE_API const char *sqlite3_errmsg(sqlite3*);
41994205
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
42004206
SQLITE_API const char *sqlite3_errstr(int);
42014207
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
42024208
4209
+/*
4210
+** CAPI3REF: Set Error Codes And Message
4211
+** METHOD: sqlite3
4212
+**
4213
+** Set the error code of the database handle passed as the first argument
4214
+** to errcode, and the error message to a copy of nul-terminated string
4215
+** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
4216
+** the default message associated with the supplied error code. Subsequent
4217
+** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will
4218
+** return the values set by this routine in place of what was previously
4219
+** set by SQLite itself.
4220
+**
4221
+** This function returns SQLITE_OK if the error code and error message are
4222
+** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if
4223
+** the database handle is NULL or invalid.
4224
+**
4225
+** The error code and message set by this routine remains in effect until
4226
+** they are changed, either by another call to this routine or until they are
4227
+** changed to by SQLite itself to reflect the result of some subsquent
4228
+** API call.
4229
+**
4230
+** This function is intended for use by SQLite extensions or wrappers. The
4231
+** idea is that an extension or wrapper can use this routine to set error
4232
+** messages and error codes and thus behave more like a core SQLite
4233
+** feature from the point of view of an application.
4234
+*/
4235
+SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg);
4236
+
42034237
/*
42044238
** CAPI3REF: Prepared Statement Object
42054239
** KEYWORDS: {prepared statement} {prepared statements}
42064240
**
42074241
** An instance of this object represents a single SQL statement that
@@ -6208,10 +6242,11 @@
62086242
** to be attached to [database connection] D using name N. Subsequent
62096243
** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
62106244
** or a NULL pointer if there were no prior calls to
62116245
** sqlite3_set_clientdata() with the same values of D and N.
62126246
** Names are compared using strcmp() and are thus case sensitive.
6247
+** It returns 0 on success and SQLITE_NOMEM on allocation failure.
62136248
**
62146249
** If P and X are both non-NULL, then the destructor X is invoked with
62156250
** argument P on the first of the following occurrences:
62166251
** <ul>
62176252
** <li> An out-of-memory error occurs during the call to
@@ -9779,25 +9814,38 @@
97799814
** ^The third parameter is the name of the database that was written to -
97809815
** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
97819816
** is the number of pages currently in the write-ahead log file,
97829817
** including those that were just committed.
97839818
**
9784
-** The callback function should normally return [SQLITE_OK]. ^If an error
9819
+** ^The callback function should normally return [SQLITE_OK]. ^If an error
97859820
** code is returned, that error will propagate back up through the
97869821
** SQLite code base to cause the statement that provoked the callback
97879822
** to report an error, though the commit will have still occurred. If the
97889823
** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
97899824
** that does not correspond to any valid SQLite error code, the results
97909825
** are undefined.
97919826
**
9792
-** A single database handle may have at most a single write-ahead log callback
9793
-** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
9794
-** previously registered write-ahead log callback. ^The return value is
9795
-** a copy of the third parameter from the previous call, if any, or 0.
9796
-** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
9797
-** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
9798
-** overwrite any prior [sqlite3_wal_hook()] settings.
9827
+** ^A single database handle may have at most a single write-ahead log
9828
+** callback registered at one time. ^Calling [sqlite3_wal_hook()]
9829
+** replaces the default behavior or previously registered write-ahead
9830
+** log callback.
9831
+**
9832
+** ^The return value is a copy of the third parameter from the
9833
+** previous call, if any, or 0.
9834
+**
9835
+** ^The [sqlite3_wal_autocheckpoint()] interface and the
9836
+** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and
9837
+** will overwrite any prior [sqlite3_wal_hook()] settings.
9838
+**
9839
+** ^If a write-ahead log callback is set using this function then
9840
+** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint]
9841
+** should be invoked periodically to keep the write-ahead log file
9842
+** from growing without bound.
9843
+**
9844
+** ^Passing a NULL pointer for the callback disables automatic
9845
+** checkpointing entirely. To re-enable the default behavior, call
9846
+** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint].
97999847
*/
98009848
SQLITE_API void *sqlite3_wal_hook(
98019849
sqlite3*,
98029850
int(*)(void *,sqlite3*,const char*,int),
98039851
void*
@@ -9810,11 +9858,11 @@
98109858
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
98119859
** [sqlite3_wal_hook()] that causes any database on [database connection] D
98129860
** to automatically [checkpoint]
98139861
** after committing a transaction if there are N or
98149862
** more frames in the [write-ahead log] file. ^Passing zero or
9815
-** a negative value as the nFrame parameter disables automatic
9863
+** a negative value as the N parameter disables automatic
98169864
** checkpoints entirely.
98179865
**
98189866
** ^The callback registered by this function replaces any existing callback
98199867
** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
98209868
** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -9826,13 +9874,14 @@
98269874
** ^Checkpoints initiated by this mechanism are
98279875
** [sqlite3_wal_checkpoint_v2|PASSIVE].
98289876
**
98299877
** ^Every new [database connection] defaults to having the auto-checkpoint
98309878
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
9831
-** pages. The use of this interface
9832
-** is only necessary if the default setting is found to be suboptimal
9833
-** for a particular application.
9879
+** pages.
9880
+**
9881
+** ^The use of this interface is only necessary if the default setting
9882
+** is found to be suboptimal for a particular application.
98349883
*/
98359884
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
98369885
98379886
/*
98389887
** CAPI3REF: Checkpoint a database
@@ -9893,10 +9942,15 @@
98939942
**
98949943
** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
98959944
** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
98969945
** addition that it also truncates the log file to zero bytes just prior
98979946
** to a successful return.
9947
+**
9948
+** <dt>SQLITE_CHECKPOINT_NOOP<dd>
9949
+** ^This mode always checkpoints zero frames. The only reason to invoke
9950
+** a NOOP checkpoint is to access the values returned by
9951
+** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt.
98989952
** </dl>
98999953
**
99009954
** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
99019955
** the log file or to -1 if the checkpoint could not run because
99029956
** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -9963,10 +10017,11 @@
996310017
** These constants define all valid values for the "checkpoint mode" passed
996410018
** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
996510019
** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
996610020
** meaning of each of these checkpoint modes.
996710021
*/
10022
+#define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */
996810023
#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
996910024
#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
997010025
#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
997110026
#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
997210027
@@ -10790,11 +10845,11 @@
1079010845
** to avoid a memory leak.
1079110846
**
1079210847
** The [sqlite3_snapshot_get()] interface is only available when the
1079310848
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1079410849
*/
10795
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
10850
+SQLITE_API int sqlite3_snapshot_get(
1079610851
sqlite3 *db,
1079710852
const char *zSchema,
1079810853
sqlite3_snapshot **ppSnapshot
1079910854
);
1080010855
@@ -10839,11 +10894,11 @@
1083910894
** database connection in order to make it ready to use snapshots.)
1084010895
**
1084110896
** The [sqlite3_snapshot_open()] interface is only available when the
1084210897
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1084310898
*/
10844
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
10899
+SQLITE_API int sqlite3_snapshot_open(
1084510900
sqlite3 *db,
1084610901
const char *zSchema,
1084710902
sqlite3_snapshot *pSnapshot
1084810903
);
1084910904
@@ -10856,11 +10911,11 @@
1085610911
** using this routine to avoid a memory leak.
1085710912
**
1085810913
** The [sqlite3_snapshot_free()] interface is only available when the
1085910914
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
1086010915
*/
10861
-SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
10916
+SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*);
1086210917
1086310918
/*
1086410919
** CAPI3REF: Compare the ages of two snapshot handles.
1086510920
** METHOD: sqlite3_snapshot
1086610921
**
@@ -10883,11 +10938,11 @@
1088310938
** snapshot, and a positive value if P1 is a newer snapshot than P2.
1088410939
**
1088510940
** This interface is only available if SQLite is compiled with the
1088610941
** [SQLITE_ENABLE_SNAPSHOT] option.
1088710942
*/
10888
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
10943
+SQLITE_API int sqlite3_snapshot_cmp(
1088910944
sqlite3_snapshot *p1,
1089010945
sqlite3_snapshot *p2
1089110946
);
1089210947
1089310948
/*
@@ -10911,11 +10966,11 @@
1091110966
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
1091210967
**
1091310968
** This interface is only available if SQLite is compiled with the
1091410969
** [SQLITE_ENABLE_SNAPSHOT] option.
1091510970
*/
10916
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
10971
+SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
1091710972
1091810973
/*
1091910974
** CAPI3REF: Serialize a database
1092010975
**
1092110976
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -10985,16 +11040,17 @@
1098511040
/*
1098611041
** CAPI3REF: Deserialize a database
1098711042
**
1098811043
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
1098911044
** [database connection] D to disconnect from database S and then
10990
-** reopen S as an in-memory database based on the serialization contained
10991
-** in P. The serialized database P is N bytes in size. M is the size of
10992
-** the buffer P, which might be larger than N. If M is larger than N, and
10993
-** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
10994
-** permitted to add content to the in-memory database as long as the total
10995
-** size does not exceed M bytes.
11045
+** reopen S as an in-memory database based on the serialization
11046
+** contained in P. If S is a NULL pointer, the main database is
11047
+** used. The serialized database P is N bytes in size. M is the size
11048
+** of the buffer P, which might be larger than N. If M is larger than
11049
+** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
11050
+** SQLite is permitted to add content to the in-memory database as
11051
+** long as the total size does not exceed M bytes.
1099611052
**
1099711053
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
1099811054
** invoke sqlite3_free() on the serialization buffer when the database
1099911055
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
1100011056
** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12315,10 +12371,19 @@
1231512371
** CAPI3REF: Apply A Changeset To A Database
1231612372
**
1231712373
** Apply a changeset or patchset to a database. These functions attempt to
1231812374
** update the "main" database attached to handle db with the changes found in
1231912375
** the changeset passed via the second and third arguments.
12376
+**
12377
+** All changes made by these functions are enclosed in a savepoint transaction.
12378
+** If any other error (aside from a constraint failure when attempting to
12379
+** write to the target database) occurs, then the savepoint transaction is
12380
+** rolled back, restoring the target database to its original state, and an
12381
+** SQLite error code returned. Additionally, starting with version 3.51.0,
12382
+** an error code and error message that may be accessed using the
12383
+** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database
12384
+** handle.
1232012385
**
1232112386
** The fourth argument (xFilter) passed to these functions is the "filter
1232212387
** callback". This may be passed NULL, in which case all changes in the
1232312388
** changeset are applied to the database. For sqlite3changeset_apply() and
1232412389
** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12453,16 +12518,10 @@
1245312518
** It is safe to execute SQL statements, including those that write to the
1245412519
** table that the callback related to, from within the xConflict callback.
1245512520
** This can be used to further customize the application's conflict
1245612521
** resolution strategy.
1245712522
**
12458
-** All changes made by these functions are enclosed in a savepoint transaction.
12459
-** If any other error (aside from a constraint failure when attempting to
12460
-** write to the target database) occurs, then the savepoint transaction is
12461
-** rolled back, restoring the target database to its original state, and an
12462
-** SQLite error code returned.
12463
-**
1246412523
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
1246512524
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
1246612525
** may set (*ppRebase) to point to a "rebase" that may be used with the
1246712526
** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
1246812527
** is set to the size of the buffer in bytes. It is the responsibility of the
1246912528
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1"
 
 
 
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -2338,21 +2341,24 @@
2338 ** views in the main database schema or in the schemas of ATTACH-ed
2339 ** databases.)^ </dd>
2340 **
2341 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
2342 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2343 ** <dd> ^This option is used to enable or disable the
2344 ** [fts3_tokenizer()] function which is part of the
2345 ** [FTS3] full-text search engine extension.
2346 ** There must be two additional arguments.
2347 ** The first argument is an integer which is 0 to disable fts3_tokenizer() or
2348 ** positive to enable fts3_tokenizer() or negative to leave the setting
2349 ** unchanged.
2350 ** The second parameter is a pointer to an integer into which
2351 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2352 ** following this call. The second parameter may be a NULL pointer, in
2353 ** which case the new setting is not reported back. </dd>
 
 
 
2354 **
2355 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
2356 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2357 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2358 ** interface independently of the [load_extension()] SQL function.
@@ -4198,10 +4204,38 @@
4198 SQLITE_API const char *sqlite3_errmsg(sqlite3*);
4199 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4200 SQLITE_API const char *sqlite3_errstr(int);
4201 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4203 /*
4204 ** CAPI3REF: Prepared Statement Object
4205 ** KEYWORDS: {prepared statement} {prepared statements}
4206 **
4207 ** An instance of this object represents a single SQL statement that
@@ -6208,10 +6242,11 @@
6208 ** to be attached to [database connection] D using name N. Subsequent
6209 ** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
6210 ** or a NULL pointer if there were no prior calls to
6211 ** sqlite3_set_clientdata() with the same values of D and N.
6212 ** Names are compared using strcmp() and are thus case sensitive.
 
6213 **
6214 ** If P and X are both non-NULL, then the destructor X is invoked with
6215 ** argument P on the first of the following occurrences:
6216 ** <ul>
6217 ** <li> An out-of-memory error occurs during the call to
@@ -9779,25 +9814,38 @@
9779 ** ^The third parameter is the name of the database that was written to -
9780 ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
9781 ** is the number of pages currently in the write-ahead log file,
9782 ** including those that were just committed.
9783 **
9784 ** The callback function should normally return [SQLITE_OK]. ^If an error
9785 ** code is returned, that error will propagate back up through the
9786 ** SQLite code base to cause the statement that provoked the callback
9787 ** to report an error, though the commit will have still occurred. If the
9788 ** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
9789 ** that does not correspond to any valid SQLite error code, the results
9790 ** are undefined.
9791 **
9792 ** A single database handle may have at most a single write-ahead log callback
9793 ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
9794 ** previously registered write-ahead log callback. ^The return value is
9795 ** a copy of the third parameter from the previous call, if any, or 0.
9796 ** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
9797 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
9798 ** overwrite any prior [sqlite3_wal_hook()] settings.
 
 
 
 
 
 
 
 
 
 
 
 
 
9799 */
9800 SQLITE_API void *sqlite3_wal_hook(
9801 sqlite3*,
9802 int(*)(void *,sqlite3*,const char*,int),
9803 void*
@@ -9810,11 +9858,11 @@
9810 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
9811 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
9812 ** to automatically [checkpoint]
9813 ** after committing a transaction if there are N or
9814 ** more frames in the [write-ahead log] file. ^Passing zero or
9815 ** a negative value as the nFrame parameter disables automatic
9816 ** checkpoints entirely.
9817 **
9818 ** ^The callback registered by this function replaces any existing callback
9819 ** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
9820 ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -9826,13 +9874,14 @@
9826 ** ^Checkpoints initiated by this mechanism are
9827 ** [sqlite3_wal_checkpoint_v2|PASSIVE].
9828 **
9829 ** ^Every new [database connection] defaults to having the auto-checkpoint
9830 ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
9831 ** pages. The use of this interface
9832 ** is only necessary if the default setting is found to be suboptimal
9833 ** for a particular application.
 
9834 */
9835 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
9836
9837 /*
9838 ** CAPI3REF: Checkpoint a database
@@ -9893,10 +9942,15 @@
9893 **
9894 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
9895 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
9896 ** addition that it also truncates the log file to zero bytes just prior
9897 ** to a successful return.
 
 
 
 
 
9898 ** </dl>
9899 **
9900 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
9901 ** the log file or to -1 if the checkpoint could not run because
9902 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -9963,10 +10017,11 @@
9963 ** These constants define all valid values for the "checkpoint mode" passed
9964 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
9965 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
9966 ** meaning of each of these checkpoint modes.
9967 */
 
9968 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
9969 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
9970 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
9971 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
9972
@@ -10790,11 +10845,11 @@
10790 ** to avoid a memory leak.
10791 **
10792 ** The [sqlite3_snapshot_get()] interface is only available when the
10793 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10794 */
10795 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
10796 sqlite3 *db,
10797 const char *zSchema,
10798 sqlite3_snapshot **ppSnapshot
10799 );
10800
@@ -10839,11 +10894,11 @@
10839 ** database connection in order to make it ready to use snapshots.)
10840 **
10841 ** The [sqlite3_snapshot_open()] interface is only available when the
10842 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10843 */
10844 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
10845 sqlite3 *db,
10846 const char *zSchema,
10847 sqlite3_snapshot *pSnapshot
10848 );
10849
@@ -10856,11 +10911,11 @@
10856 ** using this routine to avoid a memory leak.
10857 **
10858 ** The [sqlite3_snapshot_free()] interface is only available when the
10859 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10860 */
10861 SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
10862
10863 /*
10864 ** CAPI3REF: Compare the ages of two snapshot handles.
10865 ** METHOD: sqlite3_snapshot
10866 **
@@ -10883,11 +10938,11 @@
10883 ** snapshot, and a positive value if P1 is a newer snapshot than P2.
10884 **
10885 ** This interface is only available if SQLite is compiled with the
10886 ** [SQLITE_ENABLE_SNAPSHOT] option.
10887 */
10888 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
10889 sqlite3_snapshot *p1,
10890 sqlite3_snapshot *p2
10891 );
10892
10893 /*
@@ -10911,11 +10966,11 @@
10911 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
10912 **
10913 ** This interface is only available if SQLite is compiled with the
10914 ** [SQLITE_ENABLE_SNAPSHOT] option.
10915 */
10916 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
10917
10918 /*
10919 ** CAPI3REF: Serialize a database
10920 **
10921 ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -10985,16 +11040,17 @@
10985 /*
10986 ** CAPI3REF: Deserialize a database
10987 **
10988 ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
10989 ** [database connection] D to disconnect from database S and then
10990 ** reopen S as an in-memory database based on the serialization contained
10991 ** in P. The serialized database P is N bytes in size. M is the size of
10992 ** the buffer P, which might be larger than N. If M is larger than N, and
10993 ** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
10994 ** permitted to add content to the in-memory database as long as the total
10995 ** size does not exceed M bytes.
 
10996 **
10997 ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
10998 ** invoke sqlite3_free() on the serialization buffer when the database
10999 ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
11000 ** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12315,10 +12371,19 @@
12315 ** CAPI3REF: Apply A Changeset To A Database
12316 **
12317 ** Apply a changeset or patchset to a database. These functions attempt to
12318 ** update the "main" database attached to handle db with the changes found in
12319 ** the changeset passed via the second and third arguments.
 
 
 
 
 
 
 
 
 
12320 **
12321 ** The fourth argument (xFilter) passed to these functions is the "filter
12322 ** callback". This may be passed NULL, in which case all changes in the
12323 ** changeset are applied to the database. For sqlite3changeset_apply() and
12324 ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12453,16 +12518,10 @@
12453 ** It is safe to execute SQL statements, including those that write to the
12454 ** table that the callback related to, from within the xConflict callback.
12455 ** This can be used to further customize the application's conflict
12456 ** resolution strategy.
12457 **
12458 ** All changes made by these functions are enclosed in a savepoint transaction.
12459 ** If any other error (aside from a constraint failure when attempting to
12460 ** write to the target database) occurs, then the savepoint transaction is
12461 ** rolled back, restoring the target database to its original state, and an
12462 ** SQLite error code returned.
12463 **
12464 ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
12465 ** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
12466 ** may set (*ppRebase) to point to a "rebase" that may be used with the
12467 ** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
12468 ** is set to the size of the buffer in bytes. It is the responsibility of the
12469
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
@@ -2338,21 +2341,24 @@
2341 ** views in the main database schema or in the schemas of ATTACH-ed
2342 ** databases.)^ </dd>
2343 **
2344 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
2345 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2346 ** <dd> ^This option is used to enable or disable using the
2347 ** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine
2348 ** extension - without using bound parameters as the parameters. Doing so
2349 ** is disabled by default. There must be two additional arguments. The first
2350 ** argument is an integer. If it is passed 0, then using fts3_tokenizer()
2351 ** without bound parameters is disabled. If it is passed a positive value,
2352 ** then calling fts3_tokenizer without bound parameters is enabled. If it
2353 ** is passed a negative value, this setting is not modified - this can be
2354 ** used to query for the current setting. The second parameter is a pointer
2355 ** to an integer into which is written 0 or 1 to indicate the current value
2356 ** of this setting (after it is modified, if applicable). The second
2357 ** parameter may be a NULL pointer, in which case the value of the setting
2358 ** is not reported back. Refer to [FTS3] documentation for further details.
2359 ** </dd>
2360 **
2361 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
2362 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2363 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2364 ** interface independently of the [load_extension()] SQL function.
@@ -4198,10 +4204,38 @@
4204 SQLITE_API const char *sqlite3_errmsg(sqlite3*);
4205 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
4206 SQLITE_API const char *sqlite3_errstr(int);
4207 SQLITE_API int sqlite3_error_offset(sqlite3 *db);
4208
4209 /*
4210 ** CAPI3REF: Set Error Codes And Message
4211 ** METHOD: sqlite3
4212 **
4213 ** Set the error code of the database handle passed as the first argument
4214 ** to errcode, and the error message to a copy of nul-terminated string
4215 ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to
4216 ** the default message associated with the supplied error code. Subsequent
4217 ** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will
4218 ** return the values set by this routine in place of what was previously
4219 ** set by SQLite itself.
4220 **
4221 ** This function returns SQLITE_OK if the error code and error message are
4222 ** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if
4223 ** the database handle is NULL or invalid.
4224 **
4225 ** The error code and message set by this routine remains in effect until
4226 ** they are changed, either by another call to this routine or until they are
4227 ** changed to by SQLite itself to reflect the result of some subsquent
4228 ** API call.
4229 **
4230 ** This function is intended for use by SQLite extensions or wrappers. The
4231 ** idea is that an extension or wrapper can use this routine to set error
4232 ** messages and error codes and thus behave more like a core SQLite
4233 ** feature from the point of view of an application.
4234 */
4235 SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg);
4236
4237 /*
4238 ** CAPI3REF: Prepared Statement Object
4239 ** KEYWORDS: {prepared statement} {prepared statements}
4240 **
4241 ** An instance of this object represents a single SQL statement that
@@ -6208,10 +6242,11 @@
6242 ** to be attached to [database connection] D using name N. Subsequent
6243 ** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
6244 ** or a NULL pointer if there were no prior calls to
6245 ** sqlite3_set_clientdata() with the same values of D and N.
6246 ** Names are compared using strcmp() and are thus case sensitive.
6247 ** It returns 0 on success and SQLITE_NOMEM on allocation failure.
6248 **
6249 ** If P and X are both non-NULL, then the destructor X is invoked with
6250 ** argument P on the first of the following occurrences:
6251 ** <ul>
6252 ** <li> An out-of-memory error occurs during the call to
@@ -9779,25 +9814,38 @@
9814 ** ^The third parameter is the name of the database that was written to -
9815 ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
9816 ** is the number of pages currently in the write-ahead log file,
9817 ** including those that were just committed.
9818 **
9819 ** ^The callback function should normally return [SQLITE_OK]. ^If an error
9820 ** code is returned, that error will propagate back up through the
9821 ** SQLite code base to cause the statement that provoked the callback
9822 ** to report an error, though the commit will have still occurred. If the
9823 ** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
9824 ** that does not correspond to any valid SQLite error code, the results
9825 ** are undefined.
9826 **
9827 ** ^A single database handle may have at most a single write-ahead log
9828 ** callback registered at one time. ^Calling [sqlite3_wal_hook()]
9829 ** replaces the default behavior or previously registered write-ahead
9830 ** log callback.
9831 **
9832 ** ^The return value is a copy of the third parameter from the
9833 ** previous call, if any, or 0.
9834 **
9835 ** ^The [sqlite3_wal_autocheckpoint()] interface and the
9836 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and
9837 ** will overwrite any prior [sqlite3_wal_hook()] settings.
9838 **
9839 ** ^If a write-ahead log callback is set using this function then
9840 ** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint]
9841 ** should be invoked periodically to keep the write-ahead log file
9842 ** from growing without bound.
9843 **
9844 ** ^Passing a NULL pointer for the callback disables automatic
9845 ** checkpointing entirely. To re-enable the default behavior, call
9846 ** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint].
9847 */
9848 SQLITE_API void *sqlite3_wal_hook(
9849 sqlite3*,
9850 int(*)(void *,sqlite3*,const char*,int),
9851 void*
@@ -9810,11 +9858,11 @@
9858 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
9859 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
9860 ** to automatically [checkpoint]
9861 ** after committing a transaction if there are N or
9862 ** more frames in the [write-ahead log] file. ^Passing zero or
9863 ** a negative value as the N parameter disables automatic
9864 ** checkpoints entirely.
9865 **
9866 ** ^The callback registered by this function replaces any existing callback
9867 ** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
9868 ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
@@ -9826,13 +9874,14 @@
9874 ** ^Checkpoints initiated by this mechanism are
9875 ** [sqlite3_wal_checkpoint_v2|PASSIVE].
9876 **
9877 ** ^Every new [database connection] defaults to having the auto-checkpoint
9878 ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
9879 ** pages.
9880 **
9881 ** ^The use of this interface is only necessary if the default setting
9882 ** is found to be suboptimal for a particular application.
9883 */
9884 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
9885
9886 /*
9887 ** CAPI3REF: Checkpoint a database
@@ -9893,10 +9942,15 @@
9942 **
9943 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
9944 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
9945 ** addition that it also truncates the log file to zero bytes just prior
9946 ** to a successful return.
9947 **
9948 ** <dt>SQLITE_CHECKPOINT_NOOP<dd>
9949 ** ^This mode always checkpoints zero frames. The only reason to invoke
9950 ** a NOOP checkpoint is to access the values returned by
9951 ** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt.
9952 ** </dl>
9953 **
9954 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
9955 ** the log file or to -1 if the checkpoint could not run because
9956 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
@@ -9963,10 +10017,11 @@
10017 ** These constants define all valid values for the "checkpoint mode" passed
10018 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
10019 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
10020 ** meaning of each of these checkpoint modes.
10021 */
10022 #define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */
10023 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
10024 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
10025 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
10026 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
10027
@@ -10790,11 +10845,11 @@
10845 ** to avoid a memory leak.
10846 **
10847 ** The [sqlite3_snapshot_get()] interface is only available when the
10848 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10849 */
10850 SQLITE_API int sqlite3_snapshot_get(
10851 sqlite3 *db,
10852 const char *zSchema,
10853 sqlite3_snapshot **ppSnapshot
10854 );
10855
@@ -10839,11 +10894,11 @@
10894 ** database connection in order to make it ready to use snapshots.)
10895 **
10896 ** The [sqlite3_snapshot_open()] interface is only available when the
10897 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10898 */
10899 SQLITE_API int sqlite3_snapshot_open(
10900 sqlite3 *db,
10901 const char *zSchema,
10902 sqlite3_snapshot *pSnapshot
10903 );
10904
@@ -10856,11 +10911,11 @@
10911 ** using this routine to avoid a memory leak.
10912 **
10913 ** The [sqlite3_snapshot_free()] interface is only available when the
10914 ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
10915 */
10916 SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*);
10917
10918 /*
10919 ** CAPI3REF: Compare the ages of two snapshot handles.
10920 ** METHOD: sqlite3_snapshot
10921 **
@@ -10883,11 +10938,11 @@
10938 ** snapshot, and a positive value if P1 is a newer snapshot than P2.
10939 **
10940 ** This interface is only available if SQLite is compiled with the
10941 ** [SQLITE_ENABLE_SNAPSHOT] option.
10942 */
10943 SQLITE_API int sqlite3_snapshot_cmp(
10944 sqlite3_snapshot *p1,
10945 sqlite3_snapshot *p2
10946 );
10947
10948 /*
@@ -10911,11 +10966,11 @@
10966 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
10967 **
10968 ** This interface is only available if SQLite is compiled with the
10969 ** [SQLITE_ENABLE_SNAPSHOT] option.
10970 */
10971 SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
10972
10973 /*
10974 ** CAPI3REF: Serialize a database
10975 **
10976 ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
@@ -10985,16 +11040,17 @@
11040 /*
11041 ** CAPI3REF: Deserialize a database
11042 **
11043 ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
11044 ** [database connection] D to disconnect from database S and then
11045 ** reopen S as an in-memory database based on the serialization
11046 ** contained in P. If S is a NULL pointer, the main database is
11047 ** used. The serialized database P is N bytes in size. M is the size
11048 ** of the buffer P, which might be larger than N. If M is larger than
11049 ** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
11050 ** SQLite is permitted to add content to the in-memory database as
11051 ** long as the total size does not exceed M bytes.
11052 **
11053 ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
11054 ** invoke sqlite3_free() on the serialization buffer when the database
11055 ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
11056 ** SQLite will try to increase the buffer size using sqlite3_realloc64()
@@ -12315,10 +12371,19 @@
12371 ** CAPI3REF: Apply A Changeset To A Database
12372 **
12373 ** Apply a changeset or patchset to a database. These functions attempt to
12374 ** update the "main" database attached to handle db with the changes found in
12375 ** the changeset passed via the second and third arguments.
12376 **
12377 ** All changes made by these functions are enclosed in a savepoint transaction.
12378 ** If any other error (aside from a constraint failure when attempting to
12379 ** write to the target database) occurs, then the savepoint transaction is
12380 ** rolled back, restoring the target database to its original state, and an
12381 ** SQLite error code returned. Additionally, starting with version 3.51.0,
12382 ** an error code and error message that may be accessed using the
12383 ** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database
12384 ** handle.
12385 **
12386 ** The fourth argument (xFilter) passed to these functions is the "filter
12387 ** callback". This may be passed NULL, in which case all changes in the
12388 ** changeset are applied to the database. For sqlite3changeset_apply() and
12389 ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
@@ -12453,16 +12518,10 @@
12518 ** It is safe to execute SQL statements, including those that write to the
12519 ** table that the callback related to, from within the xConflict callback.
12520 ** This can be used to further customize the application's conflict
12521 ** resolution strategy.
12522 **
 
 
 
 
 
 
12523 ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
12524 ** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
12525 ** may set (*ppRebase) to point to a "rebase" that may be used with the
12526 ** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
12527 ** is set to the size of the buffer in bytes. It is the responsibility of the
12528
+5 -3
--- src/browse.c
+++ src/browse.c
@@ -1038,11 +1038,12 @@
10381038
@ CREATE TABLE IF NOT EXISTS temp.fileage(
10391039
@ fnid INTEGER PRIMARY KEY,
10401040
@ fid INTEGER,
10411041
@ mid INTEGER,
10421042
@ mtime DATETIME,
1043
-@ pathname TEXT
1043
+@ pathname TEXT,
1044
+@ uuid TEXT
10441045
@ );
10451046
@ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
10461047
;
10471048
10481049
static const char zComputeFileAgeRun[] =
@@ -1050,12 +1051,13 @@
10501051
@ ckin(x) AS (VALUES(:ckin)
10511052
@ UNION
10521053
@ SELECT plink.pid
10531054
@ FROM ckin, plink
10541055
@ WHERE plink.cid=ckin.x)
1055
-@ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname)
1056
-@ SELECT filename.fnid, mlink.fid, mlink.mid, event.mtime, filename.name
1056
+@ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname, uuid)
1057
+@ SELECT filename.fnid, mlink.fid, mlink.mid, event.mtime, filename.name,
1058
+@ foci.uuid
10571059
@ FROM foci, filename, blob, mlink, event
10581060
@ WHERE foci.checkinID=:ckin
10591061
@ AND foci.filename GLOB :glob
10601062
@ AND filename.name=foci.filename
10611063
@ AND blob.uuid=foci.uuid
10621064
--- src/browse.c
+++ src/browse.c
@@ -1038,11 +1038,12 @@
1038 @ CREATE TABLE IF NOT EXISTS temp.fileage(
1039 @ fnid INTEGER PRIMARY KEY,
1040 @ fid INTEGER,
1041 @ mid INTEGER,
1042 @ mtime DATETIME,
1043 @ pathname TEXT
 
1044 @ );
1045 @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
1046 ;
1047
1048 static const char zComputeFileAgeRun[] =
@@ -1050,12 +1051,13 @@
1050 @ ckin(x) AS (VALUES(:ckin)
1051 @ UNION
1052 @ SELECT plink.pid
1053 @ FROM ckin, plink
1054 @ WHERE plink.cid=ckin.x)
1055 @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname)
1056 @ SELECT filename.fnid, mlink.fid, mlink.mid, event.mtime, filename.name
 
1057 @ FROM foci, filename, blob, mlink, event
1058 @ WHERE foci.checkinID=:ckin
1059 @ AND foci.filename GLOB :glob
1060 @ AND filename.name=foci.filename
1061 @ AND blob.uuid=foci.uuid
1062
--- src/browse.c
+++ src/browse.c
@@ -1038,11 +1038,12 @@
1038 @ CREATE TABLE IF NOT EXISTS temp.fileage(
1039 @ fnid INTEGER PRIMARY KEY,
1040 @ fid INTEGER,
1041 @ mid INTEGER,
1042 @ mtime DATETIME,
1043 @ pathname TEXT,
1044 @ uuid TEXT
1045 @ );
1046 @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
1047 ;
1048
1049 static const char zComputeFileAgeRun[] =
@@ -1050,12 +1051,13 @@
1051 @ ckin(x) AS (VALUES(:ckin)
1052 @ UNION
1053 @ SELECT plink.pid
1054 @ FROM ckin, plink
1055 @ WHERE plink.cid=ckin.x)
1056 @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname, uuid)
1057 @ SELECT filename.fnid, mlink.fid, mlink.mid, event.mtime, filename.name,
1058 @ foci.uuid
1059 @ FROM foci, filename, blob, mlink, event
1060 @ WHERE foci.checkinID=:ckin
1061 @ AND foci.filename GLOB :glob
1062 @ AND filename.name=foci.filename
1063 @ AND blob.uuid=foci.uuid
1064
+42 -21
--- src/cgi.c
+++ src/cgi.c
@@ -241,11 +241,11 @@
241241
}
242242
243243
/*
244244
** Additional information used to form the HTTP reply
245245
*/
246
-static const char *zContentType = "text/html"; /* Content type of the reply */
246
+static const char *zReplyMimeType = "text/html"; /* Content type of the reply */
247247
static const char *zReplyStatus = "OK"; /* Reply status description */
248248
static int iReplyStatus = 200; /* Reply status code */
249249
static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
250250
static int rangeStart = 0; /* Start of Range: */
251251
static int rangeEnd = 0; /* End of Range: plus 1 */
@@ -256,11 +256,13 @@
256256
** The reply content type defaults to "text/html". It only needs to be
257257
** changed (by calling this routine) in the exceptional case where some
258258
** other content type is being returned.
259259
*/
260260
void cgi_set_content_type(const char *zType){
261
- zContentType = fossil_strdup(zType);
261
+ int i;
262
+ for(i=0; zType[i]>='+' && zType[i]<='z'; i++){}
263
+ zReplyMimeType = fossil_strndup(zType, i);
262264
}
263265
264266
/*
265267
** Erase any existing reply content. Replace is with a pNewContent.
266268
**
@@ -336,14 +338,14 @@
336338
if( g.fNoHttpCompress ) return 0;
337339
if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
338340
/* Maintenance note: this oddball structure is intended to make
339341
** adding new mimetypes to this list less of a performance hit than
340342
** doing a strcmp/glob over a growing set of compressible types. */
341
- switch(zContentType ? *zContentType : 0){
343
+ switch(zReplyMimeType ? *zReplyMimeType : 0){
342344
case (int)'a':
343
- if(0==fossil_strncmp("application/",zContentType,12)){
344
- const char * z = &zContentType[12];
345
+ if(0==fossil_strncmp("application/",zReplyMimeType,12)){
346
+ const char * z = &zReplyMimeType[12];
345347
switch(*z){
346348
case (int)'j':
347349
return fossil_strcmp("javascript", z)==0
348350
|| fossil_strcmp("json", z)==0;
349351
case (int)'w': return fossil_strcmp("wasm", z)==0;
@@ -354,14 +356,14 @@
354356
return sqlite3_strglob("*xml", z)==0;
355357
}
356358
}
357359
break;
358360
case (int)'i':
359
- return fossil_strcmp(zContentType, "image/svg+xml")==0
360
- || fossil_strcmp(zContentType, "image/vnd.microsoft.icon")==0;
361
+ return fossil_strcmp(zReplyMimeType, "image/svg+xml")==0
362
+ || fossil_strcmp(zReplyMimeType, "image/vnd.microsoft.icon")==0;
361363
case (int)'t':
362
- return fossil_strncmp(zContentType, "text/", 5)==0;
364
+ return fossil_strncmp(zReplyMimeType, "text/", 5)==0;
363365
}
364366
return 0;
365367
}
366368
367369
@@ -402,10 +404,12 @@
402404
}
403405
#ifdef FOSSIL_ENABLE_SSL
404406
return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
405407
#else
406408
fossil_fatal("SSL not available");
409
+ /* NOT REACHED */
410
+ return 0;
407411
#endif
408412
}
409413
410414
/* Works like feof():
411415
**
@@ -449,22 +453,22 @@
449453
}
450454
451455
/*
452456
** Given a Content-Type value, returns a string suitable for appending
453457
** to the Content-Type header for adding (or not) the "; charset=..."
454
-** part. It returns an empty string for most types or if zContentType
458
+** part. It returns an empty string for most types or if zReplyMimeType
455459
** is NULL.
456460
**
457461
** See forum post f60dece061c364d1 for the discussions which lead to
458462
** this. Previously we always appended the charset, but WASM loaders
459463
** are pedantic and refuse to load any responses which have a
460464
** charset. Also, adding a charset is not strictly appropriate for
461465
** most types (and not required for many others which may ostensibly
462466
** benefit from one, as detailed in that forum post).
463467
*/
464
-static const char * content_type_charset(const char *zContentType){
465
- if(0==fossil_strncmp(zContentType,"text/",5)){
468
+static const char * content_type_charset(const char *zReplyMimeType){
469
+ if(0==fossil_strncmp(zReplyMimeType,"text/",5)){
466470
return "; charset=utf-8";
467471
}
468472
return "";
469473
}
470474
@@ -500,11 +504,11 @@
500504
assert( rangeEnd==0 );
501505
blob_appendf(&hdr, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
502506
}
503507
if( etag_tag()[0]!=0
504508
&& iReplyStatus==200
505
- && strcmp(zContentType,"text/html")!=0
509
+ && strcmp(zReplyMimeType,"text/html")!=0
506510
){
507511
/* Do not cache HTML replies as those will have been generated and
508512
** will likely, therefore, contains a nonce and we want that nonce to
509513
** be different every time. */
510514
blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag());
@@ -542,13 +546,13 @@
542546
** These headers are probably best added by the web server hosting fossil as
543547
** a CGI script.
544548
*/
545549
546550
if( iReplyStatus!=304 ) {
547
- blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
548
- content_type_charset(zContentType));
549
- if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
551
+ blob_appendf(&hdr, "Content-Type: %s%s\r\n", zReplyMimeType,
552
+ content_type_charset(zReplyMimeType));
553
+ if( fossil_strcmp(zReplyMimeType,"application/x-fossil")==0 ){
550554
cgi_combine_header_and_body();
551555
blob_compress(&cgiContent[0], &cgiContent[0]);
552556
}
553557
554558
if( is_gzippable() && iReplyStatus!=206 ){
@@ -944,10 +948,20 @@
944948
** portion is fixed but a copy is be made of zValue.
945949
*/
946950
void cgi_setenv(const char *zName, const char *zValue){
947951
cgi_set_parameter_nocopy(zName, fossil_strdup(zValue), 0);
948952
}
953
+
954
+/*
955
+** Returns true if NUL-terminated z contains any non-NUL
956
+** control characters (<0x20, 32d).
957
+*/
958
+static int contains_ctrl(const char *z){
959
+ assert(z);
960
+ for( ; *z>=0x20; ++z ){}
961
+ return 0!=*z;
962
+}
949963
950964
/*
951965
** Add a list of query parameters or cookies to the parameter set.
952966
**
953967
** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -974,12 +988,16 @@
974988
** before the NAME is ignored.
975989
**
976990
** The input string "z" is modified but no copies is made. "z"
977991
** should not be deallocated or changed again after this routine
978992
** returns or it will corrupt the parameter table.
993
+**
994
+** If bPermitCtrl is false and the decoded value of any entry in z
995
+** contains control characters (<0x20, 32d) then that key/value pair
996
+** are skipped.
979997
*/
980
-static void add_param_list(char *z, int terminator){
998
+static void add_param_list(char *z, int terminator, int bPermitCtrl){
981999
int isQP = terminator=='&';
9821000
while( *z ){
9831001
char *zName;
9841002
char *zValue;
9851003
while( fossil_isspace(*z) ){ z++; }
@@ -998,11 +1016,14 @@
9981016
}else{
9991017
if( *z ){ *z++ = 0; }
10001018
zValue = "";
10011019
}
10021020
if( zName[0] && fossil_no_strange_characters(zName+1) ){
1003
- if( fossil_islower(zName[0]) ){
1021
+ if( 0==bPermitCtrl && contains_ctrl(zValue) ){
1022
+ continue /* Reject it. An argument could be made
1023
+ ** for break instead of continue. */;
1024
+ }else if( fossil_islower(zName[0]) ){
10041025
cgi_set_parameter_nocopy(zName, zValue, isQP);
10051026
}else if( fossil_isupper(zName[0]) ){
10061027
cgi_set_parameter_nocopy_tolower(zName, zValue, isQP);
10071028
}
10081029
}
@@ -1297,11 +1318,11 @@
12971318
int rc = 0;
12981319
char * z = (char*)P("QUERY_STRING");
12991320
if( z ){
13001321
rc = 0x01;
13011322
z = fossil_strdup(z);
1302
- add_param_list(z, '&');
1323
+ add_param_list(z, '&', 0);
13031324
z = (char*)P("skin");
13041325
if( z ){
13051326
char *zErr = skin_use_alternative(z, 2, SKIN_FROM_QPARAM);
13061327
rc |= 0x02;
13071328
if( !zErr && P("once")==0 ){
@@ -1457,11 +1478,11 @@
14571478
}
14581479
#endif
14591480
z = (char*)P("HTTP_COOKIE");
14601481
if( z ){
14611482
z = fossil_strdup(z);
1462
- add_param_list(z, ';');
1483
+ add_param_list(z, ';', 0);
14631484
z = (char*)cookie_value("skin",0);
14641485
if(z){
14651486
skin_use_alternative(z, 2, SKIN_FROM_COOKIE);
14661487
}
14671488
}
@@ -1520,11 +1541,11 @@
15201541
|| fossil_strncmp(g.zContentType,"multipart/form-data",19)==0
15211542
){
15221543
char *z = blob_str(&g.cgiIn);
15231544
cgi_trace(z);
15241545
if( g.zContentType[0]=='a' ){
1525
- add_param_list(z, '&');
1546
+ add_param_list(z, '&', 1);
15261547
}else{
15271548
process_multipart_form_data(z, len);
15281549
}
15291550
blob_init(&g.cgiIn, 0, 0);
15301551
}
@@ -2021,11 +2042,11 @@
20212042
char *z;
20222043
va_start(ap, zMsg);
20232044
z = vmprintf(zMsg, ap);
20242045
va_end(ap);
20252046
cgi_set_status(400, "Bad Request");
2026
- zContentType = "text/plain";
2047
+ zReplyMimeType = "text/plain";
20272048
if( g.zReqType==0 ) g.zReqType = "WWW";
20282049
if( g.zReqType[0]=='C' && PD("SERVER_SOFTWARE",0)!=0 ){
20292050
const char *zServer = PD("SERVER_SOFTWARE","");
20302051
cgi_printf("Bad CGI Request from \"%s\": %s\n",zServer,z);
20312052
}else{
20322053
--- src/cgi.c
+++ src/cgi.c
@@ -241,11 +241,11 @@
241 }
242
243 /*
244 ** Additional information used to form the HTTP reply
245 */
246 static const char *zContentType = "text/html"; /* Content type of the reply */
247 static const char *zReplyStatus = "OK"; /* Reply status description */
248 static int iReplyStatus = 200; /* Reply status code */
249 static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
250 static int rangeStart = 0; /* Start of Range: */
251 static int rangeEnd = 0; /* End of Range: plus 1 */
@@ -256,11 +256,13 @@
256 ** The reply content type defaults to "text/html". It only needs to be
257 ** changed (by calling this routine) in the exceptional case where some
258 ** other content type is being returned.
259 */
260 void cgi_set_content_type(const char *zType){
261 zContentType = fossil_strdup(zType);
 
 
262 }
263
264 /*
265 ** Erase any existing reply content. Replace is with a pNewContent.
266 **
@@ -336,14 +338,14 @@
336 if( g.fNoHttpCompress ) return 0;
337 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
338 /* Maintenance note: this oddball structure is intended to make
339 ** adding new mimetypes to this list less of a performance hit than
340 ** doing a strcmp/glob over a growing set of compressible types. */
341 switch(zContentType ? *zContentType : 0){
342 case (int)'a':
343 if(0==fossil_strncmp("application/",zContentType,12)){
344 const char * z = &zContentType[12];
345 switch(*z){
346 case (int)'j':
347 return fossil_strcmp("javascript", z)==0
348 || fossil_strcmp("json", z)==0;
349 case (int)'w': return fossil_strcmp("wasm", z)==0;
@@ -354,14 +356,14 @@
354 return sqlite3_strglob("*xml", z)==0;
355 }
356 }
357 break;
358 case (int)'i':
359 return fossil_strcmp(zContentType, "image/svg+xml")==0
360 || fossil_strcmp(zContentType, "image/vnd.microsoft.icon")==0;
361 case (int)'t':
362 return fossil_strncmp(zContentType, "text/", 5)==0;
363 }
364 return 0;
365 }
366
367
@@ -402,10 +404,12 @@
402 }
403 #ifdef FOSSIL_ENABLE_SSL
404 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
405 #else
406 fossil_fatal("SSL not available");
 
 
407 #endif
408 }
409
410 /* Works like feof():
411 **
@@ -449,22 +453,22 @@
449 }
450
451 /*
452 ** Given a Content-Type value, returns a string suitable for appending
453 ** to the Content-Type header for adding (or not) the "; charset=..."
454 ** part. It returns an empty string for most types or if zContentType
455 ** is NULL.
456 **
457 ** See forum post f60dece061c364d1 for the discussions which lead to
458 ** this. Previously we always appended the charset, but WASM loaders
459 ** are pedantic and refuse to load any responses which have a
460 ** charset. Also, adding a charset is not strictly appropriate for
461 ** most types (and not required for many others which may ostensibly
462 ** benefit from one, as detailed in that forum post).
463 */
464 static const char * content_type_charset(const char *zContentType){
465 if(0==fossil_strncmp(zContentType,"text/",5)){
466 return "; charset=utf-8";
467 }
468 return "";
469 }
470
@@ -500,11 +504,11 @@
500 assert( rangeEnd==0 );
501 blob_appendf(&hdr, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
502 }
503 if( etag_tag()[0]!=0
504 && iReplyStatus==200
505 && strcmp(zContentType,"text/html")!=0
506 ){
507 /* Do not cache HTML replies as those will have been generated and
508 ** will likely, therefore, contains a nonce and we want that nonce to
509 ** be different every time. */
510 blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag());
@@ -542,13 +546,13 @@
542 ** These headers are probably best added by the web server hosting fossil as
543 ** a CGI script.
544 */
545
546 if( iReplyStatus!=304 ) {
547 blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
548 content_type_charset(zContentType));
549 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
550 cgi_combine_header_and_body();
551 blob_compress(&cgiContent[0], &cgiContent[0]);
552 }
553
554 if( is_gzippable() && iReplyStatus!=206 ){
@@ -944,10 +948,20 @@
944 ** portion is fixed but a copy is be made of zValue.
945 */
946 void cgi_setenv(const char *zName, const char *zValue){
947 cgi_set_parameter_nocopy(zName, fossil_strdup(zValue), 0);
948 }
 
 
 
 
 
 
 
 
 
 
949
950 /*
951 ** Add a list of query parameters or cookies to the parameter set.
952 **
953 ** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -974,12 +988,16 @@
974 ** before the NAME is ignored.
975 **
976 ** The input string "z" is modified but no copies is made. "z"
977 ** should not be deallocated or changed again after this routine
978 ** returns or it will corrupt the parameter table.
 
 
 
 
979 */
980 static void add_param_list(char *z, int terminator){
981 int isQP = terminator=='&';
982 while( *z ){
983 char *zName;
984 char *zValue;
985 while( fossil_isspace(*z) ){ z++; }
@@ -998,11 +1016,14 @@
998 }else{
999 if( *z ){ *z++ = 0; }
1000 zValue = "";
1001 }
1002 if( zName[0] && fossil_no_strange_characters(zName+1) ){
1003 if( fossil_islower(zName[0]) ){
 
 
 
1004 cgi_set_parameter_nocopy(zName, zValue, isQP);
1005 }else if( fossil_isupper(zName[0]) ){
1006 cgi_set_parameter_nocopy_tolower(zName, zValue, isQP);
1007 }
1008 }
@@ -1297,11 +1318,11 @@
1297 int rc = 0;
1298 char * z = (char*)P("QUERY_STRING");
1299 if( z ){
1300 rc = 0x01;
1301 z = fossil_strdup(z);
1302 add_param_list(z, '&');
1303 z = (char*)P("skin");
1304 if( z ){
1305 char *zErr = skin_use_alternative(z, 2, SKIN_FROM_QPARAM);
1306 rc |= 0x02;
1307 if( !zErr && P("once")==0 ){
@@ -1457,11 +1478,11 @@
1457 }
1458 #endif
1459 z = (char*)P("HTTP_COOKIE");
1460 if( z ){
1461 z = fossil_strdup(z);
1462 add_param_list(z, ';');
1463 z = (char*)cookie_value("skin",0);
1464 if(z){
1465 skin_use_alternative(z, 2, SKIN_FROM_COOKIE);
1466 }
1467 }
@@ -1520,11 +1541,11 @@
1520 || fossil_strncmp(g.zContentType,"multipart/form-data",19)==0
1521 ){
1522 char *z = blob_str(&g.cgiIn);
1523 cgi_trace(z);
1524 if( g.zContentType[0]=='a' ){
1525 add_param_list(z, '&');
1526 }else{
1527 process_multipart_form_data(z, len);
1528 }
1529 blob_init(&g.cgiIn, 0, 0);
1530 }
@@ -2021,11 +2042,11 @@
2021 char *z;
2022 va_start(ap, zMsg);
2023 z = vmprintf(zMsg, ap);
2024 va_end(ap);
2025 cgi_set_status(400, "Bad Request");
2026 zContentType = "text/plain";
2027 if( g.zReqType==0 ) g.zReqType = "WWW";
2028 if( g.zReqType[0]=='C' && PD("SERVER_SOFTWARE",0)!=0 ){
2029 const char *zServer = PD("SERVER_SOFTWARE","");
2030 cgi_printf("Bad CGI Request from \"%s\": %s\n",zServer,z);
2031 }else{
2032
--- src/cgi.c
+++ src/cgi.c
@@ -241,11 +241,11 @@
241 }
242
243 /*
244 ** Additional information used to form the HTTP reply
245 */
246 static const char *zReplyMimeType = "text/html"; /* Content type of the reply */
247 static const char *zReplyStatus = "OK"; /* Reply status description */
248 static int iReplyStatus = 200; /* Reply status code */
249 static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
250 static int rangeStart = 0; /* Start of Range: */
251 static int rangeEnd = 0; /* End of Range: plus 1 */
@@ -256,11 +256,13 @@
256 ** The reply content type defaults to "text/html". It only needs to be
257 ** changed (by calling this routine) in the exceptional case where some
258 ** other content type is being returned.
259 */
260 void cgi_set_content_type(const char *zType){
261 int i;
262 for(i=0; zType[i]>='+' && zType[i]<='z'; i++){}
263 zReplyMimeType = fossil_strndup(zType, i);
264 }
265
266 /*
267 ** Erase any existing reply content. Replace is with a pNewContent.
268 **
@@ -336,14 +338,14 @@
338 if( g.fNoHttpCompress ) return 0;
339 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
340 /* Maintenance note: this oddball structure is intended to make
341 ** adding new mimetypes to this list less of a performance hit than
342 ** doing a strcmp/glob over a growing set of compressible types. */
343 switch(zReplyMimeType ? *zReplyMimeType : 0){
344 case (int)'a':
345 if(0==fossil_strncmp("application/",zReplyMimeType,12)){
346 const char * z = &zReplyMimeType[12];
347 switch(*z){
348 case (int)'j':
349 return fossil_strcmp("javascript", z)==0
350 || fossil_strcmp("json", z)==0;
351 case (int)'w': return fossil_strcmp("wasm", z)==0;
@@ -354,14 +356,14 @@
356 return sqlite3_strglob("*xml", z)==0;
357 }
358 }
359 break;
360 case (int)'i':
361 return fossil_strcmp(zReplyMimeType, "image/svg+xml")==0
362 || fossil_strcmp(zReplyMimeType, "image/vnd.microsoft.icon")==0;
363 case (int)'t':
364 return fossil_strncmp(zReplyMimeType, "text/", 5)==0;
365 }
366 return 0;
367 }
368
369
@@ -402,10 +404,12 @@
404 }
405 #ifdef FOSSIL_ENABLE_SSL
406 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
407 #else
408 fossil_fatal("SSL not available");
409 /* NOT REACHED */
410 return 0;
411 #endif
412 }
413
414 /* Works like feof():
415 **
@@ -449,22 +453,22 @@
453 }
454
455 /*
456 ** Given a Content-Type value, returns a string suitable for appending
457 ** to the Content-Type header for adding (or not) the "; charset=..."
458 ** part. It returns an empty string for most types or if zReplyMimeType
459 ** is NULL.
460 **
461 ** See forum post f60dece061c364d1 for the discussions which lead to
462 ** this. Previously we always appended the charset, but WASM loaders
463 ** are pedantic and refuse to load any responses which have a
464 ** charset. Also, adding a charset is not strictly appropriate for
465 ** most types (and not required for many others which may ostensibly
466 ** benefit from one, as detailed in that forum post).
467 */
468 static const char * content_type_charset(const char *zReplyMimeType){
469 if(0==fossil_strncmp(zReplyMimeType,"text/",5)){
470 return "; charset=utf-8";
471 }
472 return "";
473 }
474
@@ -500,11 +504,11 @@
504 assert( rangeEnd==0 );
505 blob_appendf(&hdr, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
506 }
507 if( etag_tag()[0]!=0
508 && iReplyStatus==200
509 && strcmp(zReplyMimeType,"text/html")!=0
510 ){
511 /* Do not cache HTML replies as those will have been generated and
512 ** will likely, therefore, contains a nonce and we want that nonce to
513 ** be different every time. */
514 blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag());
@@ -542,13 +546,13 @@
546 ** These headers are probably best added by the web server hosting fossil as
547 ** a CGI script.
548 */
549
550 if( iReplyStatus!=304 ) {
551 blob_appendf(&hdr, "Content-Type: %s%s\r\n", zReplyMimeType,
552 content_type_charset(zReplyMimeType));
553 if( fossil_strcmp(zReplyMimeType,"application/x-fossil")==0 ){
554 cgi_combine_header_and_body();
555 blob_compress(&cgiContent[0], &cgiContent[0]);
556 }
557
558 if( is_gzippable() && iReplyStatus!=206 ){
@@ -944,10 +948,20 @@
948 ** portion is fixed but a copy is be made of zValue.
949 */
950 void cgi_setenv(const char *zName, const char *zValue){
951 cgi_set_parameter_nocopy(zName, fossil_strdup(zValue), 0);
952 }
953
954 /*
955 ** Returns true if NUL-terminated z contains any non-NUL
956 ** control characters (<0x20, 32d).
957 */
958 static int contains_ctrl(const char *z){
959 assert(z);
960 for( ; *z>=0x20; ++z ){}
961 return 0!=*z;
962 }
963
964 /*
965 ** Add a list of query parameters or cookies to the parameter set.
966 **
967 ** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -974,12 +988,16 @@
988 ** before the NAME is ignored.
989 **
990 ** The input string "z" is modified but no copies is made. "z"
991 ** should not be deallocated or changed again after this routine
992 ** returns or it will corrupt the parameter table.
993 **
994 ** If bPermitCtrl is false and the decoded value of any entry in z
995 ** contains control characters (<0x20, 32d) then that key/value pair
996 ** are skipped.
997 */
998 static void add_param_list(char *z, int terminator, int bPermitCtrl){
999 int isQP = terminator=='&';
1000 while( *z ){
1001 char *zName;
1002 char *zValue;
1003 while( fossil_isspace(*z) ){ z++; }
@@ -998,11 +1016,14 @@
1016 }else{
1017 if( *z ){ *z++ = 0; }
1018 zValue = "";
1019 }
1020 if( zName[0] && fossil_no_strange_characters(zName+1) ){
1021 if( 0==bPermitCtrl && contains_ctrl(zValue) ){
1022 continue /* Reject it. An argument could be made
1023 ** for break instead of continue. */;
1024 }else if( fossil_islower(zName[0]) ){
1025 cgi_set_parameter_nocopy(zName, zValue, isQP);
1026 }else if( fossil_isupper(zName[0]) ){
1027 cgi_set_parameter_nocopy_tolower(zName, zValue, isQP);
1028 }
1029 }
@@ -1297,11 +1318,11 @@
1318 int rc = 0;
1319 char * z = (char*)P("QUERY_STRING");
1320 if( z ){
1321 rc = 0x01;
1322 z = fossil_strdup(z);
1323 add_param_list(z, '&', 0);
1324 z = (char*)P("skin");
1325 if( z ){
1326 char *zErr = skin_use_alternative(z, 2, SKIN_FROM_QPARAM);
1327 rc |= 0x02;
1328 if( !zErr && P("once")==0 ){
@@ -1457,11 +1478,11 @@
1478 }
1479 #endif
1480 z = (char*)P("HTTP_COOKIE");
1481 if( z ){
1482 z = fossil_strdup(z);
1483 add_param_list(z, ';', 0);
1484 z = (char*)cookie_value("skin",0);
1485 if(z){
1486 skin_use_alternative(z, 2, SKIN_FROM_COOKIE);
1487 }
1488 }
@@ -1520,11 +1541,11 @@
1541 || fossil_strncmp(g.zContentType,"multipart/form-data",19)==0
1542 ){
1543 char *z = blob_str(&g.cgiIn);
1544 cgi_trace(z);
1545 if( g.zContentType[0]=='a' ){
1546 add_param_list(z, '&', 1);
1547 }else{
1548 process_multipart_form_data(z, len);
1549 }
1550 blob_init(&g.cgiIn, 0, 0);
1551 }
@@ -2021,11 +2042,11 @@
2042 char *z;
2043 va_start(ap, zMsg);
2044 z = vmprintf(zMsg, ap);
2045 va_end(ap);
2046 cgi_set_status(400, "Bad Request");
2047 zReplyMimeType = "text/plain";
2048 if( g.zReqType==0 ) g.zReqType = "WWW";
2049 if( g.zReqType[0]=='C' && PD("SERVER_SOFTWARE",0)!=0 ){
2050 const char *zServer = PD("SERVER_SOFTWARE","");
2051 cgi_printf("Bad CGI Request from \"%s\": %s\n",zServer,z);
2052 }else{
2053
+18
--- src/chat.c
+++ src/chat.c
@@ -389,10 +389,25 @@
389389
}else{
390390
CX("}");
391391
}
392392
fossil_free(zTime);
393393
}
394
+
395
+/*
396
+** Like chat_emit_permissions_error() but emits a single
397
+** /chat-message-format JSON object about a CSRF violation.
398
+*/
399
+static void chat_emit_csrf_error(void){
400
+ char * zTime = cgi_iso8601_datestamp();
401
+ cgi_set_content_type("application/json");
402
+ CX("{");
403
+ CX("\"isError\": true, \"xfrom\": null,");
404
+ CX("\"mtime\": %!j, \"lmtime\": %!j,", zTime, zTime);
405
+ CX("\"xmsg\": \"CSRF validation failure.\"");
406
+ CX("}");
407
+ fossil_free(zTime);
408
+}
394409
395410
/*
396411
** WEBPAGE: chat-send hidden loadavg-exempt
397412
**
398413
** This page receives (via XHR) a new chat-message and/or a new file
@@ -421,10 +436,13 @@
421436
const char *zMsg;
422437
const char *zUserName;
423438
login_check_credentials();
424439
if( 0==g.perm.Chat ) {
425440
chat_emit_permissions_error(0);
441
+ return;
442
+ }else if( 0==cgi_csrf_safe(1) ){
443
+ chat_emit_csrf_error();
426444
return;
427445
}
428446
zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
429447
nByte = atoi(PD("file:bytes","0"));
430448
zMsg = PD("msg","");
431449
--- src/chat.c
+++ src/chat.c
@@ -389,10 +389,25 @@
389 }else{
390 CX("}");
391 }
392 fossil_free(zTime);
393 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
395 /*
396 ** WEBPAGE: chat-send hidden loadavg-exempt
397 **
398 ** This page receives (via XHR) a new chat-message and/or a new file
@@ -421,10 +436,13 @@
421 const char *zMsg;
422 const char *zUserName;
423 login_check_credentials();
424 if( 0==g.perm.Chat ) {
425 chat_emit_permissions_error(0);
 
 
 
426 return;
427 }
428 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
429 nByte = atoi(PD("file:bytes","0"));
430 zMsg = PD("msg","");
431
--- src/chat.c
+++ src/chat.c
@@ -389,10 +389,25 @@
389 }else{
390 CX("}");
391 }
392 fossil_free(zTime);
393 }
394
395 /*
396 ** Like chat_emit_permissions_error() but emits a single
397 ** /chat-message-format JSON object about a CSRF violation.
398 */
399 static void chat_emit_csrf_error(void){
400 char * zTime = cgi_iso8601_datestamp();
401 cgi_set_content_type("application/json");
402 CX("{");
403 CX("\"isError\": true, \"xfrom\": null,");
404 CX("\"mtime\": %!j, \"lmtime\": %!j,", zTime, zTime);
405 CX("\"xmsg\": \"CSRF validation failure.\"");
406 CX("}");
407 fossil_free(zTime);
408 }
409
410 /*
411 ** WEBPAGE: chat-send hidden loadavg-exempt
412 **
413 ** This page receives (via XHR) a new chat-message and/or a new file
@@ -421,10 +436,13 @@
436 const char *zMsg;
437 const char *zUserName;
438 login_check_credentials();
439 if( 0==g.perm.Chat ) {
440 chat_emit_permissions_error(0);
441 return;
442 }else if( 0==cgi_csrf_safe(1) ){
443 chat_emit_csrf_error();
444 return;
445 }
446 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
447 nByte = atoi(PD("file:bytes","0"));
448 zMsg = PD("msg","");
449
+11 -5
--- src/checkin.c
+++ src/checkin.c
@@ -718,10 +718,11 @@
718718
*/
719719
static void ls_cmd_rev(
720720
const char *zRev, /* Revision string given */
721721
int verboseFlag, /* Verbose flag given */
722722
int showAge, /* Age flag given */
723
+ int showHash, /* Show hash flag given */
723724
int timeOrder, /* Order by time flag given */
724725
int treeFmt /* Show output in the tree format */
725726
){
726727
Stmt q;
727728
char *zOrderBy = "pathname COLLATE nocase";
@@ -763,11 +764,11 @@
763764
}
764765
765766
compute_fileage(rid,0);
766767
db_prepare(&q,
767768
"SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n"
768
- " blob.size\n"
769
+ " blob.size, fileage.uuid\n"
769770
" FROM fileage, blob\n"
770771
" WHERE blob.rid=fileage.fid %s\n"
771772
" ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
772773
);
773774
blob_reset(&where);
@@ -778,11 +779,12 @@
778779
const char *zFile = db_column_text(&q,1);
779780
int size = db_column_int(&q,2);
780781
if( treeFmt ){
781782
blob_appendf(&out, "%s\n", zFile);
782783
}else if( verboseFlag ){
783
- fossil_print("%s %7d %s\n", zTime, size, zFile);
784
+ const char *zUuid = mprintf("[%S] ", db_column_text(&q,3));
785
+ fossil_print("%s %7d %s%s\n", zTime, size, showHash ? zUuid :"", zFile);
784786
}else if( showAge ){
785787
fossil_print("%s %s\n", zTime, zFile);
786788
}else{
787789
fossil_print("%s\n", zFile);
788790
}
@@ -811,18 +813,20 @@
811813
** The --age option displays file commit times. Like -r, --age has the
812814
** side effect of making -t sort by commit time, not modification time.
813815
**
814816
** The -v option provides extra information about each file. Without -r,
815817
** -v displays the change status, in the manner of the changes command.
816
-** With -r, -v shows the commit time and size of the checked-in files.
818
+** With -r, -v shows the commit time and size of the checked-in files; in
819
+** this combination, it additionally shows file hashes with -h.
817820
**
818821
** The -t option changes the sort order. Without -t, files are sorted by
819822
** path and name (case insensitive sort if -r). If neither --age nor -r
820823
** are used, -t sorts by modification time, otherwise by commit time.
821824
**
822825
** Options:
823826
** --age Show when each file was committed
827
+** -h With -v and -r, show file hashes
824828
** --hash With -v, verify file status using hashing
825829
** rather than relying on file sizes and mtimes
826830
** -r VERSION The specific check-in to list
827831
** -R|--repository REPO Extract info from repository REPO
828832
** -t Sort output in time order
@@ -840,10 +844,11 @@
840844
int timeOrder;
841845
char *zOrderBy = "pathname";
842846
Blob where;
843847
int i;
844848
int useHash = 0;
849
+ int showHash = 0;
845850
const char *zName;
846851
const char *zRev;
847852
848853
verboseFlag = find_option("verbose","v", 0)!=0;
849854
if( !verboseFlag ){
@@ -852,20 +857,21 @@
852857
showAge = find_option("age",0,0)!=0;
853858
zRev = find_option("r","r",1);
854859
timeOrder = find_option("t","t",0)!=0;
855860
if( verboseFlag ){
856861
useHash = find_option("hash",0,0)!=0;
862
+ showHash = find_option("h","h",0)!=0;
857863
}
858864
treeFmt = find_option("tree",0,0)!=0;
859865
if( treeFmt ){
860866
if( zRev==0 ) zRev = "current";
861867
}
862868
863869
if( zRev!=0 ){
864870
db_find_and_open_repository(0, 0);
865871
verify_all_options();
866
- ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder,treeFmt);
872
+ ls_cmd_rev(zRev,verboseFlag,showAge,showHash,timeOrder,treeFmt);
867873
return;
868874
}else if( find_option("R",0,1)!=0 ){
869875
fossil_fatal("the -r is required in addition to -R");
870876
}
871877
@@ -984,11 +990,11 @@
984990
985991
zRev = find_option("r","r",1);
986992
if( zRev==0 ) zRev = "current";
987993
db_find_and_open_repository(0, 0);
988994
verify_all_options();
989
- ls_cmd_rev(zRev,0,0,0,1);
995
+ ls_cmd_rev(zRev,0,0,0,0,1);
990996
}
991997
992998
/*
993999
** COMMAND: extras
9941000
**
9951001
--- src/checkin.c
+++ src/checkin.c
@@ -718,10 +718,11 @@
718 */
719 static void ls_cmd_rev(
720 const char *zRev, /* Revision string given */
721 int verboseFlag, /* Verbose flag given */
722 int showAge, /* Age flag given */
 
723 int timeOrder, /* Order by time flag given */
724 int treeFmt /* Show output in the tree format */
725 ){
726 Stmt q;
727 char *zOrderBy = "pathname COLLATE nocase";
@@ -763,11 +764,11 @@
763 }
764
765 compute_fileage(rid,0);
766 db_prepare(&q,
767 "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n"
768 " blob.size\n"
769 " FROM fileage, blob\n"
770 " WHERE blob.rid=fileage.fid %s\n"
771 " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
772 );
773 blob_reset(&where);
@@ -778,11 +779,12 @@
778 const char *zFile = db_column_text(&q,1);
779 int size = db_column_int(&q,2);
780 if( treeFmt ){
781 blob_appendf(&out, "%s\n", zFile);
782 }else if( verboseFlag ){
783 fossil_print("%s %7d %s\n", zTime, size, zFile);
 
784 }else if( showAge ){
785 fossil_print("%s %s\n", zTime, zFile);
786 }else{
787 fossil_print("%s\n", zFile);
788 }
@@ -811,18 +813,20 @@
811 ** The --age option displays file commit times. Like -r, --age has the
812 ** side effect of making -t sort by commit time, not modification time.
813 **
814 ** The -v option provides extra information about each file. Without -r,
815 ** -v displays the change status, in the manner of the changes command.
816 ** With -r, -v shows the commit time and size of the checked-in files.
 
817 **
818 ** The -t option changes the sort order. Without -t, files are sorted by
819 ** path and name (case insensitive sort if -r). If neither --age nor -r
820 ** are used, -t sorts by modification time, otherwise by commit time.
821 **
822 ** Options:
823 ** --age Show when each file was committed
 
824 ** --hash With -v, verify file status using hashing
825 ** rather than relying on file sizes and mtimes
826 ** -r VERSION The specific check-in to list
827 ** -R|--repository REPO Extract info from repository REPO
828 ** -t Sort output in time order
@@ -840,10 +844,11 @@
840 int timeOrder;
841 char *zOrderBy = "pathname";
842 Blob where;
843 int i;
844 int useHash = 0;
 
845 const char *zName;
846 const char *zRev;
847
848 verboseFlag = find_option("verbose","v", 0)!=0;
849 if( !verboseFlag ){
@@ -852,20 +857,21 @@
852 showAge = find_option("age",0,0)!=0;
853 zRev = find_option("r","r",1);
854 timeOrder = find_option("t","t",0)!=0;
855 if( verboseFlag ){
856 useHash = find_option("hash",0,0)!=0;
 
857 }
858 treeFmt = find_option("tree",0,0)!=0;
859 if( treeFmt ){
860 if( zRev==0 ) zRev = "current";
861 }
862
863 if( zRev!=0 ){
864 db_find_and_open_repository(0, 0);
865 verify_all_options();
866 ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder,treeFmt);
867 return;
868 }else if( find_option("R",0,1)!=0 ){
869 fossil_fatal("the -r is required in addition to -R");
870 }
871
@@ -984,11 +990,11 @@
984
985 zRev = find_option("r","r",1);
986 if( zRev==0 ) zRev = "current";
987 db_find_and_open_repository(0, 0);
988 verify_all_options();
989 ls_cmd_rev(zRev,0,0,0,1);
990 }
991
992 /*
993 ** COMMAND: extras
994 **
995
--- src/checkin.c
+++ src/checkin.c
@@ -718,10 +718,11 @@
718 */
719 static void ls_cmd_rev(
720 const char *zRev, /* Revision string given */
721 int verboseFlag, /* Verbose flag given */
722 int showAge, /* Age flag given */
723 int showHash, /* Show hash flag given */
724 int timeOrder, /* Order by time flag given */
725 int treeFmt /* Show output in the tree format */
726 ){
727 Stmt q;
728 char *zOrderBy = "pathname COLLATE nocase";
@@ -763,11 +764,11 @@
764 }
765
766 compute_fileage(rid,0);
767 db_prepare(&q,
768 "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n"
769 " blob.size, fileage.uuid\n"
770 " FROM fileage, blob\n"
771 " WHERE blob.rid=fileage.fid %s\n"
772 " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
773 );
774 blob_reset(&where);
@@ -778,11 +779,12 @@
779 const char *zFile = db_column_text(&q,1);
780 int size = db_column_int(&q,2);
781 if( treeFmt ){
782 blob_appendf(&out, "%s\n", zFile);
783 }else if( verboseFlag ){
784 const char *zUuid = mprintf("[%S] ", db_column_text(&q,3));
785 fossil_print("%s %7d %s%s\n", zTime, size, showHash ? zUuid :"", zFile);
786 }else if( showAge ){
787 fossil_print("%s %s\n", zTime, zFile);
788 }else{
789 fossil_print("%s\n", zFile);
790 }
@@ -811,18 +813,20 @@
813 ** The --age option displays file commit times. Like -r, --age has the
814 ** side effect of making -t sort by commit time, not modification time.
815 **
816 ** The -v option provides extra information about each file. Without -r,
817 ** -v displays the change status, in the manner of the changes command.
818 ** With -r, -v shows the commit time and size of the checked-in files; in
819 ** this combination, it additionally shows file hashes with -h.
820 **
821 ** The -t option changes the sort order. Without -t, files are sorted by
822 ** path and name (case insensitive sort if -r). If neither --age nor -r
823 ** are used, -t sorts by modification time, otherwise by commit time.
824 **
825 ** Options:
826 ** --age Show when each file was committed
827 ** -h With -v and -r, show file hashes
828 ** --hash With -v, verify file status using hashing
829 ** rather than relying on file sizes and mtimes
830 ** -r VERSION The specific check-in to list
831 ** -R|--repository REPO Extract info from repository REPO
832 ** -t Sort output in time order
@@ -840,10 +844,11 @@
844 int timeOrder;
845 char *zOrderBy = "pathname";
846 Blob where;
847 int i;
848 int useHash = 0;
849 int showHash = 0;
850 const char *zName;
851 const char *zRev;
852
853 verboseFlag = find_option("verbose","v", 0)!=0;
854 if( !verboseFlag ){
@@ -852,20 +857,21 @@
857 showAge = find_option("age",0,0)!=0;
858 zRev = find_option("r","r",1);
859 timeOrder = find_option("t","t",0)!=0;
860 if( verboseFlag ){
861 useHash = find_option("hash",0,0)!=0;
862 showHash = find_option("h","h",0)!=0;
863 }
864 treeFmt = find_option("tree",0,0)!=0;
865 if( treeFmt ){
866 if( zRev==0 ) zRev = "current";
867 }
868
869 if( zRev!=0 ){
870 db_find_and_open_repository(0, 0);
871 verify_all_options();
872 ls_cmd_rev(zRev,verboseFlag,showAge,showHash,timeOrder,treeFmt);
873 return;
874 }else if( find_option("R",0,1)!=0 ){
875 fossil_fatal("the -r is required in addition to -R");
876 }
877
@@ -984,11 +990,11 @@
990
991 zRev = find_option("r","r",1);
992 if( zRev==0 ) zRev = "current";
993 db_find_and_open_repository(0, 0);
994 verify_all_options();
995 ls_cmd_rev(zRev,0,0,0,0,1);
996 }
997
998 /*
999 ** COMMAND: extras
1000 **
1001
+1 -1
--- src/comformat.c
+++ src/comformat.c
@@ -303,11 +303,11 @@
303303
case 4:
304304
*pUtf32 =
305305
( (z[0] & 0x0f)<<18 ) |
306306
( (z[1] & 0x3f)<<12 ) |
307307
( (z[2] & 0x3f)<< 6 ) |
308
- ( (z[4] & 0x3f)<< 0 ) ;
308
+ ( (z[3] & 0x3f)<< 0 ) ;
309309
break;
310310
case 3:
311311
*pUtf32 =
312312
( (z[0] & 0x0f)<<12 ) |
313313
( (z[1] & 0x3f)<< 6 ) |
314314
--- src/comformat.c
+++ src/comformat.c
@@ -303,11 +303,11 @@
303 case 4:
304 *pUtf32 =
305 ( (z[0] & 0x0f)<<18 ) |
306 ( (z[1] & 0x3f)<<12 ) |
307 ( (z[2] & 0x3f)<< 6 ) |
308 ( (z[4] & 0x3f)<< 0 ) ;
309 break;
310 case 3:
311 *pUtf32 =
312 ( (z[0] & 0x0f)<<12 ) |
313 ( (z[1] & 0x3f)<< 6 ) |
314
--- src/comformat.c
+++ src/comformat.c
@@ -303,11 +303,11 @@
303 case 4:
304 *pUtf32 =
305 ( (z[0] & 0x0f)<<18 ) |
306 ( (z[1] & 0x3f)<<12 ) |
307 ( (z[2] & 0x3f)<< 6 ) |
308 ( (z[3] & 0x3f)<< 0 ) ;
309 break;
310 case 3:
311 *pUtf32 =
312 ( (z[0] & 0x0f)<<12 ) |
313 ( (z[1] & 0x3f)<< 6 ) |
314
+3 -1
--- src/cookies.c
+++ src/cookies.c
@@ -256,11 +256,13 @@
256256
if( isQP ) continue;
257257
if( fossil_isupper(zName[0]) ) continue;
258258
if( bFDSonly && strcmp(zName, "fossil_display_settings")!=0 ) continue;
259259
zDel = mprintf("del%s",zName);
260260
if( P(zDel)!=0 ){
261
- cgi_set_cookie(zName, "", 0, -1);
261
+ const char *zPath = fossil_strcmp(ROBOT_COOKIE,zName)==0
262
+ ? "/" : 0;
263
+ cgi_set_cookie(zName, "", zPath, -1);
262264
cgi_redirect(g.zPath);
263265
}
264266
nCookie++;
265267
@ <li><p><b>%h(zName)</b>: %h(zValue)
266268
@ <input type="submit" name="%h(zDel)" value="Delete">
267269
--- src/cookies.c
+++ src/cookies.c
@@ -256,11 +256,13 @@
256 if( isQP ) continue;
257 if( fossil_isupper(zName[0]) ) continue;
258 if( bFDSonly && strcmp(zName, "fossil_display_settings")!=0 ) continue;
259 zDel = mprintf("del%s",zName);
260 if( P(zDel)!=0 ){
261 cgi_set_cookie(zName, "", 0, -1);
 
 
262 cgi_redirect(g.zPath);
263 }
264 nCookie++;
265 @ <li><p><b>%h(zName)</b>: %h(zValue)
266 @ <input type="submit" name="%h(zDel)" value="Delete">
267
--- src/cookies.c
+++ src/cookies.c
@@ -256,11 +256,13 @@
256 if( isQP ) continue;
257 if( fossil_isupper(zName[0]) ) continue;
258 if( bFDSonly && strcmp(zName, "fossil_display_settings")!=0 ) continue;
259 zDel = mprintf("del%s",zName);
260 if( P(zDel)!=0 ){
261 const char *zPath = fossil_strcmp(ROBOT_COOKIE,zName)==0
262 ? "/" : 0;
263 cgi_set_cookie(zName, "", zPath, -1);
264 cgi_redirect(g.zPath);
265 }
266 nCookie++;
267 @ <li><p><b>%h(zName)</b>: %h(zValue)
268 @ <input type="submit" name="%h(zDel)" value="Delete">
269
--- src/default.css
+++ src/default.css
@@ -560,10 +560,11 @@
560560
table.diff {
561561
width: 100%;
562562
border-spacing: 0;
563563
border-radius: 5px;
564564
border: 1px solid black;
565
+ overflow: hidden; /* Prevent background from overlapping rounded borders. */
565566
font-size: 80%;
566567
}
567568
table.diff td.diffln{
568569
padding: 0;
569570
}
570571
--- src/default.css
+++ src/default.css
@@ -560,10 +560,11 @@
560 table.diff {
561 width: 100%;
562 border-spacing: 0;
563 border-radius: 5px;
564 border: 1px solid black;
 
565 font-size: 80%;
566 }
567 table.diff td.diffln{
568 padding: 0;
569 }
570
--- src/default.css
+++ src/default.css
@@ -560,10 +560,11 @@
560 table.diff {
561 width: 100%;
562 border-spacing: 0;
563 border-radius: 5px;
564 border: 1px solid black;
565 overflow: hidden; /* Prevent background from overlapping rounded borders. */
566 font-size: 80%;
567 }
568 table.diff td.diffln{
569 padding: 0;
570 }
571
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -248,11 +248,11 @@
248248
const e = this.create(childType);
249249
if(parent) parent.appendChild(e);
250250
return e;
251251
};
252252
};
253
-
253
+
254254
dom.table = dom.createElemFactory('table');
255255
dom.thead = dom.createElemFactoryWithOptionalParent('thead');
256256
dom.tbody = dom.createElemFactoryWithOptionalParent('tbody');
257257
dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
258258
dom.tr = dom.createElemFactoryWithOptionalParent('tr');
@@ -381,12 +381,12 @@
381381
const domAddRemoveClass = function f(action,e){
382382
if(!f.rxSPlus){
383383
f.rxSPlus = /\s+/;
384384
f.applyAction = function(e,a,v){
385385
if(!e || !v
386
- /*silently skip empty strings/flasy
387
- values, for user convenience*/) return;
386
+ /*silently skip empty strings/falsy
387
+ values, for usage convenience*/) return;
388388
else if(e.forEach){
389389
e.forEach((E)=>E.classList[a](v));
390390
}else{
391391
e.classList[a](v);
392392
}
@@ -584,10 +584,11 @@
584584
}
585585
}
586586
return e;
587587
};
588588
589
+ /* Impl for dom.enable() and dom.disable(). */
589590
const enableDisable = function f(enable){
590591
var i = 1, n = arguments.length;
591592
for( ; i < n; ++i ){
592593
let e = arguments[i];
593594
if(e.forEach){
@@ -843,12 +844,12 @@
843844
/**
844845
Parses a string as HTML.
845846
846847
Usages:
847848
848
- Array (htmlString)
849
- DOMElement (DOMElement target, htmlString)
849
+ Array parseHtml(htmlString)
850
+ DOMElement parseHtml(DOMElement target, htmlString)
850851
851852
The first form parses the string as HTML and returns an Array of
852853
all elements parsed from it. If string is falsy then it returns
853854
an empty array.
854855
855856
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -248,11 +248,11 @@
248 const e = this.create(childType);
249 if(parent) parent.appendChild(e);
250 return e;
251 };
252 };
253
254 dom.table = dom.createElemFactory('table');
255 dom.thead = dom.createElemFactoryWithOptionalParent('thead');
256 dom.tbody = dom.createElemFactoryWithOptionalParent('tbody');
257 dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
258 dom.tr = dom.createElemFactoryWithOptionalParent('tr');
@@ -381,12 +381,12 @@
381 const domAddRemoveClass = function f(action,e){
382 if(!f.rxSPlus){
383 f.rxSPlus = /\s+/;
384 f.applyAction = function(e,a,v){
385 if(!e || !v
386 /*silently skip empty strings/flasy
387 values, for user convenience*/) return;
388 else if(e.forEach){
389 e.forEach((E)=>E.classList[a](v));
390 }else{
391 e.classList[a](v);
392 }
@@ -584,10 +584,11 @@
584 }
585 }
586 return e;
587 };
588
 
589 const enableDisable = function f(enable){
590 var i = 1, n = arguments.length;
591 for( ; i < n; ++i ){
592 let e = arguments[i];
593 if(e.forEach){
@@ -843,12 +844,12 @@
843 /**
844 Parses a string as HTML.
845
846 Usages:
847
848 Array (htmlString)
849 DOMElement (DOMElement target, htmlString)
850
851 The first form parses the string as HTML and returns an Array of
852 all elements parsed from it. If string is falsy then it returns
853 an empty array.
854
855
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -248,11 +248,11 @@
248 const e = this.create(childType);
249 if(parent) parent.appendChild(e);
250 return e;
251 };
252 };
253
254 dom.table = dom.createElemFactory('table');
255 dom.thead = dom.createElemFactoryWithOptionalParent('thead');
256 dom.tbody = dom.createElemFactoryWithOptionalParent('tbody');
257 dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
258 dom.tr = dom.createElemFactoryWithOptionalParent('tr');
@@ -381,12 +381,12 @@
381 const domAddRemoveClass = function f(action,e){
382 if(!f.rxSPlus){
383 f.rxSPlus = /\s+/;
384 f.applyAction = function(e,a,v){
385 if(!e || !v
386 /*silently skip empty strings/falsy
387 values, for usage convenience*/) return;
388 else if(e.forEach){
389 e.forEach((E)=>E.classList[a](v));
390 }else{
391 e.classList[a](v);
392 }
@@ -584,10 +584,11 @@
584 }
585 }
586 return e;
587 };
588
589 /* Impl for dom.enable() and dom.disable(). */
590 const enableDisable = function f(enable){
591 var i = 1, n = arguments.length;
592 for( ; i < n; ++i ){
593 let e = arguments[i];
594 if(e.forEach){
@@ -843,12 +844,12 @@
844 /**
845 Parses a string as HTML.
846
847 Usages:
848
849 Array parseHtml(htmlString)
850 DOMElement parseHtml(DOMElement target, htmlString)
851
852 The first form parses the string as HTML and returns an Array of
853 all elements parsed from it. If string is falsy then it returns
854 an empty array.
855
856
+29 -10
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401401
@ </span></div>
402402
if( pCfg ){
403403
append_diff(zOld, zNew, pCfg);
404404
}
405405
}else{
406
+ const char *zCkin2 =
407
+ mprintf(validate16(zCkin, -1) ? "%!S" : "%T"/*works-like:"%s"*/, zCkin);
406408
if( zOld && zNew ){
407409
if( fossil_strcmp(zOld, zNew)!=0 ){
408410
if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
409411
@ Renamed and modified
410
- @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
412
+ @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
411413
@ %h(zOldName)</a>
412414
@ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
413
- @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
415
+ @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
414416
@ %h(zName)</a>
415417
@ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
416418
}else{
417
- @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
419
+ @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
418420
@ %h(zName)</a>
419421
@ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
420422
@ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
421423
}
422424
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
423425
@ Name change
424
- @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
426
+ @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
425427
@ %h(zOldName)</a>
426
- @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
428
+ @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
427429
@ %h(zName)</a>.
428430
}else{
429
- @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
431
+ @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
430432
@ %h(zName)</a> became
431433
if( mperm==PERM_EXE ){
432434
@ executable with contents
433435
}else if( mperm==PERM_LNK ){
434436
@ a symlink with target
@@ -436,14 +438,14 @@
436438
@ a regular file with contents
437439
}
438440
@ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
439441
}
440442
}else if( zOld ){
441
- @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
443
+ @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zOld,zCkin2))\
442444
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
443445
}else{
444
- @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
446
+ @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
445447
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
446448
}
447449
if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
448450
if( pCfg ){
449451
@ </span></div>
@@ -643,10 +645,12 @@
643645
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
644646
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
645647
}else{
646648
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
647649
}
650
+ @ <div class="section" id="changes_section">Changes</div>
651
+ DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
648652
@ <div class="sectionmenu info-changes-menu">
649653
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
650654
if( diffType!=0 ){
651655
/* Class "smb-hide-diff" required by the fossil.diff.js script. */
652656
const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
727731
blob_reset(&old);
728732
blob_reset(&new);
729733
}
730734
}
731735
db_finalize(&q);
736
+ @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
737
+ @ document.getElementById('changes_section').textContent = 'Changes ' +
738
+ @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
739
+ @ '+%d(g.diffCnt[1]) ' +
740
+ @ '−%d(g.diffCnt[2]))'
741
+ @ </script>
732742
append_diff_javascript(diffType);
733743
}
734744
735745
/*
736746
** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
750760
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
751761
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
752762
}else{
753763
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
754764
}
765
+ @ <div class="section" id="changes_section">Changes</div>
766
+ DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
755767
@ <div class="sectionmenu info-changes-menu">
756768
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
757769
if( diffType!=1 ){
758770
@ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
759771
@ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
812824
}
813825
fossil_free(zLhs);
814826
fossil_free(zRhs);
815827
}
816828
db_finalize(&q);
829
+ @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
830
+ @ document.getElementById('changes_section').textContent = 'Changes ' +
831
+ @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
832
+ @ '+%d(g.diffCnt[1]) ' +
833
+ @ '−%d(g.diffCnt[2]))'
834
+ @ </script>
817835
append_diff_javascript(diffType);
818836
}
819837
820838
/*
821839
** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
19751993
int dflt;
19761994
int res;
19771995
int isBot;
19781996
static char zDflt[2]
19791997
/*static b/c cookie_link_parameter() does not copy it!*/;
1980
- if( client_might_be_a_robot() ){
1998
+ if( client_might_be_a_robot() && robot_restrict_has_tag("diff") ){
19811999
dflt = 0;
19822000
isBot = 1;
19832001
}else{
19842002
dflt = db_get_int("preferred-diff-type",-99);
19852003
if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
29853003
@ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
29863004
}
29873005
db_finalize(&q);
29883006
}
29893007
if( !docOnly ){
2990
- style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
3008
+ style_submenu_element("Download", "%R/raw/%s?at=%T",
3009
+ zUuid, file_tail(blob_str(&downloadName)));
29913010
if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
29923011
style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
29933012
}
29943013
}
29953014
if( zMime ){
29963015
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401 @ </span></div>
402 if( pCfg ){
403 append_diff(zOld, zNew, pCfg);
404 }
405 }else{
 
 
406 if( zOld && zNew ){
407 if( fossil_strcmp(zOld, zNew)!=0 ){
408 if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
409 @ Renamed and modified
410 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
411 @ %h(zOldName)</a>
412 @ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
413 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
414 @ %h(zName)</a>
415 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
416 }else{
417 @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
418 @ %h(zName)</a>
419 @ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
420 @ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
421 }
422 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
423 @ Name change
424 @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
425 @ %h(zOldName)</a>
426 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
427 @ %h(zName)</a>.
428 }else{
429 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
430 @ %h(zName)</a> became
431 if( mperm==PERM_EXE ){
432 @ executable with contents
433 }else if( mperm==PERM_LNK ){
434 @ a symlink with target
@@ -436,14 +438,14 @@
436 @ a regular file with contents
437 }
438 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
439 }
440 }else if( zOld ){
441 @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
442 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
443 }else{
444 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
445 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
446 }
447 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
448 if( pCfg ){
449 @ </span></div>
@@ -643,10 +645,12 @@
643 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
644 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
645 }else{
646 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
647 }
 
 
648 @ <div class="sectionmenu info-changes-menu">
649 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
650 if( diffType!=0 ){
651 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
652 const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
727 blob_reset(&old);
728 blob_reset(&new);
729 }
730 }
731 db_finalize(&q);
 
 
 
 
 
 
732 append_diff_javascript(diffType);
733 }
734
735 /*
736 ** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
750 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
751 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
752 }else{
753 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
754 }
 
 
755 @ <div class="sectionmenu info-changes-menu">
756 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
757 if( diffType!=1 ){
758 @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
759 @ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
812 }
813 fossil_free(zLhs);
814 fossil_free(zRhs);
815 }
816 db_finalize(&q);
 
 
 
 
 
 
817 append_diff_javascript(diffType);
818 }
819
820 /*
821 ** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
1975 int dflt;
1976 int res;
1977 int isBot;
1978 static char zDflt[2]
1979 /*static b/c cookie_link_parameter() does not copy it!*/;
1980 if( client_might_be_a_robot() ){
1981 dflt = 0;
1982 isBot = 1;
1983 }else{
1984 dflt = db_get_int("preferred-diff-type",-99);
1985 if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
2985 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2986 }
2987 db_finalize(&q);
2988 }
2989 if( !docOnly ){
2990 style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
 
2991 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2992 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
2993 }
2994 }
2995 if( zMime ){
2996
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401 @ </span></div>
402 if( pCfg ){
403 append_diff(zOld, zNew, pCfg);
404 }
405 }else{
406 const char *zCkin2 =
407 mprintf(validate16(zCkin, -1) ? "%!S" : "%T"/*works-like:"%s"*/, zCkin);
408 if( zOld && zNew ){
409 if( fossil_strcmp(zOld, zNew)!=0 ){
410 if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
411 @ Renamed and modified
412 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
413 @ %h(zOldName)</a>
414 @ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
415 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
416 @ %h(zName)</a>
417 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
418 }else{
419 @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
420 @ %h(zName)</a>
421 @ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
422 @ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
423 }
424 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
425 @ Name change
426 @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
427 @ %h(zOldName)</a>
428 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
429 @ %h(zName)</a>.
430 }else{
431 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
432 @ %h(zName)</a> became
433 if( mperm==PERM_EXE ){
434 @ executable with contents
435 }else if( mperm==PERM_LNK ){
436 @ a symlink with target
@@ -436,14 +438,14 @@
438 @ a regular file with contents
439 }
440 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
441 }
442 }else if( zOld ){
443 @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zOld,zCkin2))\
444 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
445 }else{
446 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
447 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
448 }
449 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
450 if( pCfg ){
451 @ </span></div>
@@ -643,10 +645,12 @@
645 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
646 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
647 }else{
648 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
649 }
650 @ <div class="section" id="changes_section">Changes</div>
651 DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
652 @ <div class="sectionmenu info-changes-menu">
653 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
654 if( diffType!=0 ){
655 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
656 const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
731 blob_reset(&old);
732 blob_reset(&new);
733 }
734 }
735 db_finalize(&q);
736 @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
737 @ document.getElementById('changes_section').textContent = 'Changes ' +
738 @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
739 @ '+%d(g.diffCnt[1]) ' +
740 @ '−%d(g.diffCnt[2]))'
741 @ </script>
742 append_diff_javascript(diffType);
743 }
744
745 /*
746 ** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
760 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
761 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
762 }else{
763 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
764 }
765 @ <div class="section" id="changes_section">Changes</div>
766 DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
767 @ <div class="sectionmenu info-changes-menu">
768 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
769 if( diffType!=1 ){
770 @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
771 @ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
824 }
825 fossil_free(zLhs);
826 fossil_free(zRhs);
827 }
828 db_finalize(&q);
829 @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
830 @ document.getElementById('changes_section').textContent = 'Changes ' +
831 @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
832 @ '+%d(g.diffCnt[1]) ' +
833 @ '−%d(g.diffCnt[2]))'
834 @ </script>
835 append_diff_javascript(diffType);
836 }
837
838 /*
839 ** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
1993 int dflt;
1994 int res;
1995 int isBot;
1996 static char zDflt[2]
1997 /*static b/c cookie_link_parameter() does not copy it!*/;
1998 if( client_might_be_a_robot() && robot_restrict_has_tag("diff") ){
1999 dflt = 0;
2000 isBot = 1;
2001 }else{
2002 dflt = db_get_int("preferred-diff-type",-99);
2003 if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
3003 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
3004 }
3005 db_finalize(&q);
3006 }
3007 if( !docOnly ){
3008 style_submenu_element("Download", "%R/raw/%s?at=%T",
3009 zUuid, file_tail(blob_str(&downloadName)));
3010 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
3011 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
3012 }
3013 }
3014 if( zMime ){
3015
+29 -10
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401401
@ </span></div>
402402
if( pCfg ){
403403
append_diff(zOld, zNew, pCfg);
404404
}
405405
}else{
406
+ const char *zCkin2 =
407
+ mprintf(validate16(zCkin, -1) ? "%!S" : "%T"/*works-like:"%s"*/, zCkin);
406408
if( zOld && zNew ){
407409
if( fossil_strcmp(zOld, zNew)!=0 ){
408410
if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
409411
@ Renamed and modified
410
- @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
412
+ @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
411413
@ %h(zOldName)</a>
412414
@ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
413
- @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
415
+ @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
414416
@ %h(zName)</a>
415417
@ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
416418
}else{
417
- @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
419
+ @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
418420
@ %h(zName)</a>
419421
@ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
420422
@ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
421423
}
422424
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
423425
@ Name change
424
- @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
426
+ @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
425427
@ %h(zOldName)</a>
426
- @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
428
+ @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
427429
@ %h(zName)</a>.
428430
}else{
429
- @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
431
+ @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
430432
@ %h(zName)</a> became
431433
if( mperm==PERM_EXE ){
432434
@ executable with contents
433435
}else if( mperm==PERM_LNK ){
434436
@ a symlink with target
@@ -436,14 +438,14 @@
436438
@ a regular file with contents
437439
}
438440
@ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
439441
}
440442
}else if( zOld ){
441
- @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
443
+ @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zOld,zCkin2))\
442444
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
443445
}else{
444
- @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
446
+ @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
445447
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
446448
}
447449
if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
448450
if( pCfg ){
449451
@ </span></div>
@@ -643,10 +645,12 @@
643645
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
644646
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
645647
}else{
646648
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
647649
}
650
+ @ <div class="section" id="changes_section">Changes</div>
651
+ DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
648652
@ <div class="sectionmenu info-changes-menu">
649653
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
650654
if( diffType!=0 ){
651655
/* Class "smb-hide-diff" required by the fossil.diff.js script. */
652656
const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
727731
blob_reset(&old);
728732
blob_reset(&new);
729733
}
730734
}
731735
db_finalize(&q);
736
+ @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
737
+ @ document.getElementById('changes_section').textContent = 'Changes ' +
738
+ @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
739
+ @ '+%d(g.diffCnt[1]) ' +
740
+ @ '−%d(g.diffCnt[2]))'
741
+ @ </script>
732742
append_diff_javascript(diffType);
733743
}
734744
735745
/*
736746
** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
750760
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
751761
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
752762
}else{
753763
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
754764
}
765
+ @ <div class="section" id="changes_section">Changes</div>
766
+ DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
755767
@ <div class="sectionmenu info-changes-menu">
756768
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
757769
if( diffType!=1 ){
758770
@ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
759771
@ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
812824
}
813825
fossil_free(zLhs);
814826
fossil_free(zRhs);
815827
}
816828
db_finalize(&q);
829
+ @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
830
+ @ document.getElementById('changes_section').textContent = 'Changes ' +
831
+ @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
832
+ @ '+%d(g.diffCnt[1]) ' +
833
+ @ '−%d(g.diffCnt[2]))'
834
+ @ </script>
817835
append_diff_javascript(diffType);
818836
}
819837
820838
/*
821839
** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
19751993
int dflt;
19761994
int res;
19771995
int isBot;
19781996
static char zDflt[2]
19791997
/*static b/c cookie_link_parameter() does not copy it!*/;
1980
- if( client_might_be_a_robot() ){
1998
+ if( client_might_be_a_robot() && robot_restrict_has_tag("diff") ){
19811999
dflt = 0;
19822000
isBot = 1;
19832001
}else{
19842002
dflt = db_get_int("preferred-diff-type",-99);
19852003
if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
29853003
@ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
29863004
}
29873005
db_finalize(&q);
29883006
}
29893007
if( !docOnly ){
2990
- style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
3008
+ style_submenu_element("Download", "%R/raw/%s?at=%T",
3009
+ zUuid, file_tail(blob_str(&downloadName)));
29913010
if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
29923011
style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
29933012
}
29943013
}
29953014
if( zMime ){
29963015
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401 @ </span></div>
402 if( pCfg ){
403 append_diff(zOld, zNew, pCfg);
404 }
405 }else{
 
 
406 if( zOld && zNew ){
407 if( fossil_strcmp(zOld, zNew)!=0 ){
408 if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
409 @ Renamed and modified
410 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
411 @ %h(zOldName)</a>
412 @ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
413 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
414 @ %h(zName)</a>
415 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
416 }else{
417 @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
418 @ %h(zName)</a>
419 @ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
420 @ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
421 }
422 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
423 @ Name change
424 @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zOldName,zOld,zCkin))\
425 @ %h(zOldName)</a>
426 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
427 @ %h(zName)</a>.
428 }else{
429 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
430 @ %h(zName)</a> became
431 if( mperm==PERM_EXE ){
432 @ executable with contents
433 }else if( mperm==PERM_LNK ){
434 @ a symlink with target
@@ -436,14 +438,14 @@
436 @ a regular file with contents
437 }
438 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
439 }
440 }else if( zOld ){
441 @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
442 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
443 }else{
444 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
445 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
446 }
447 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
448 if( pCfg ){
449 @ </span></div>
@@ -643,10 +645,12 @@
643 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
644 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
645 }else{
646 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
647 }
 
 
648 @ <div class="sectionmenu info-changes-menu">
649 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
650 if( diffType!=0 ){
651 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
652 const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
727 blob_reset(&old);
728 blob_reset(&new);
729 }
730 }
731 db_finalize(&q);
 
 
 
 
 
 
732 append_diff_javascript(diffType);
733 }
734
735 /*
736 ** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
750 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
751 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
752 }else{
753 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
754 }
 
 
755 @ <div class="sectionmenu info-changes-menu">
756 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
757 if( diffType!=1 ){
758 @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
759 @ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
812 }
813 fossil_free(zLhs);
814 fossil_free(zRhs);
815 }
816 db_finalize(&q);
 
 
 
 
 
 
817 append_diff_javascript(diffType);
818 }
819
820 /*
821 ** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
1975 int dflt;
1976 int res;
1977 int isBot;
1978 static char zDflt[2]
1979 /*static b/c cookie_link_parameter() does not copy it!*/;
1980 if( client_might_be_a_robot() ){
1981 dflt = 0;
1982 isBot = 1;
1983 }else{
1984 dflt = db_get_int("preferred-diff-type",-99);
1985 if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
2985 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2986 }
2987 db_finalize(&q);
2988 }
2989 if( !docOnly ){
2990 style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
 
2991 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2992 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
2993 }
2994 }
2995 if( zMime ){
2996
--- src/info.c
+++ src/info.c
@@ -401,34 +401,36 @@
401 @ </span></div>
402 if( pCfg ){
403 append_diff(zOld, zNew, pCfg);
404 }
405 }else{
406 const char *zCkin2 =
407 mprintf(validate16(zCkin, -1) ? "%!S" : "%T"/*works-like:"%s"*/, zCkin);
408 if( zOld && zNew ){
409 if( fossil_strcmp(zOld, zNew)!=0 ){
410 if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
411 @ Renamed and modified
412 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
413 @ %h(zOldName)</a>
414 @ %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
415 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
416 @ %h(zName)</a>
417 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
418 }else{
419 @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
420 @ %h(zName)</a>
421 @ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
422 @ to %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
423 }
424 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
425 @ Name change
426 @ from %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zOldName,zOld,zCkin2))\
427 @ %h(zOldName)</a>
428 @ to %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
429 @ %h(zName)</a>.
430 }else{
431 @ %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
432 @ %h(zName)</a> became
433 if( mperm==PERM_EXE ){
434 @ executable with contents
435 }else if( mperm==PERM_LNK ){
436 @ a symlink with target
@@ -436,14 +438,14 @@
438 @ a regular file with contents
439 }
440 @ %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
441 }
442 }else if( zOld ){
443 @ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zOld,zCkin2))\
444 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
445 }else{
446 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%s",zName,zNew,zCkin2))\
447 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
448 }
449 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
450 if( pCfg ){
451 @ </span></div>
@@ -643,10 +645,12 @@
645 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
646 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
647 }else{
648 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
649 }
650 @ <div class="section" id="changes_section">Changes</div>
651 DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
652 @ <div class="sectionmenu info-changes-menu">
653 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
654 if( diffType!=0 ){
655 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
656 const char *zBtnClass = "button smb-hide-diff";
@@ -727,10 +731,16 @@
731 blob_reset(&old);
732 blob_reset(&new);
733 }
734 }
735 db_finalize(&q);
736 @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
737 @ document.getElementById('changes_section').textContent = 'Changes ' +
738 @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
739 @ '+%d(g.diffCnt[1]) ' +
740 @ '−%d(g.diffCnt[2]))'
741 @ </script>
742 append_diff_javascript(diffType);
743 }
744
745 /*
746 ** Render a web-page diff of the changes in the working check-out to
@@ -750,10 +760,12 @@
760 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
761 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
762 }else{
763 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
764 }
765 @ <div class="section" id="changes_section">Changes</div>
766 DCfg.diffFlags |= DIFF_NUMSTAT; /* Show stats in the 'Changes' section */
767 @ <div class="sectionmenu info-changes-menu">
768 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
769 if( diffType!=1 ){
770 @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
771 @ Unified&nbsp;Diff</a>
@@ -812,10 +824,16 @@
824 }
825 fossil_free(zLhs);
826 fossil_free(zRhs);
827 }
828 db_finalize(&q);
829 @ <script nonce='%h(style_nonce())'>;/* info.c:%d(__LINE__) */
830 @ document.getElementById('changes_section').textContent = 'Changes ' +
831 @ '(%d(g.diffCnt[0]) file' + (%d(g.diffCnt[0])===1 ? '' : 's') + ': ' +
832 @ '+%d(g.diffCnt[1]) ' +
833 @ '−%d(g.diffCnt[2]))'
834 @ </script>
835 append_diff_javascript(diffType);
836 }
837
838 /*
839 ** WEBPAGE: ckout
@@ -1975,11 +1993,11 @@
1993 int dflt;
1994 int res;
1995 int isBot;
1996 static char zDflt[2]
1997 /*static b/c cookie_link_parameter() does not copy it!*/;
1998 if( client_might_be_a_robot() && robot_restrict_has_tag("diff") ){
1999 dflt = 0;
2000 isBot = 1;
2001 }else{
2002 dflt = db_get_int("preferred-diff-type",-99);
2003 if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
@@ -2985,11 +3003,12 @@
3003 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
3004 }
3005 db_finalize(&q);
3006 }
3007 if( !docOnly ){
3008 style_submenu_element("Download", "%R/raw/%s?at=%T",
3009 zUuid, file_tail(blob_str(&downloadName)));
3010 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
3011 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
3012 }
3013 }
3014 if( zMime ){
3015
+1 -1
--- src/manifest.c
+++ src/manifest.c
@@ -2734,11 +2734,11 @@
27342734
}
27352735
zName = p->aTag[i].zName;
27362736
zValue = p->aTag[i].zValue;
27372737
if( strcmp(zName, "*branch")==0 ){
27382738
blob_appendf(&comment,
2739
- " Move to branch [/timeline?r=%h&nd&dp=%!S&unhide | %h].",
2739
+ " Move to branch [/timeline?r=%t&nd&dp=%!S&unhide | %h].",
27402740
zValue, zTagUuid, zValue);
27412741
branchMove = 1;
27422742
continue;
27432743
}else if( strcmp(zName, "*bgcolor")==0 ){
27442744
blob_appendf(&comment,
27452745
--- src/manifest.c
+++ src/manifest.c
@@ -2734,11 +2734,11 @@
2734 }
2735 zName = p->aTag[i].zName;
2736 zValue = p->aTag[i].zValue;
2737 if( strcmp(zName, "*branch")==0 ){
2738 blob_appendf(&comment,
2739 " Move to branch [/timeline?r=%h&nd&dp=%!S&unhide | %h].",
2740 zValue, zTagUuid, zValue);
2741 branchMove = 1;
2742 continue;
2743 }else if( strcmp(zName, "*bgcolor")==0 ){
2744 blob_appendf(&comment,
2745
--- src/manifest.c
+++ src/manifest.c
@@ -2734,11 +2734,11 @@
2734 }
2735 zName = p->aTag[i].zName;
2736 zValue = p->aTag[i].zValue;
2737 if( strcmp(zName, "*branch")==0 ){
2738 blob_appendf(&comment,
2739 " Move to branch [/timeline?r=%t&nd&dp=%!S&unhide | %h].",
2740 zValue, zTagUuid, zValue);
2741 branchMove = 1;
2742 continue;
2743 }else if( strcmp(zName, "*bgcolor")==0 ){
2744 blob_appendf(&comment,
2745
+99 -5
--- src/regexp.c
+++ src/regexp.c
@@ -850,25 +850,38 @@
850850
** Run a regular expression match over the named disk files, or against
851851
** standard input if no disk files are named on the command-line.
852852
**
853853
** Options:
854854
** -i|--ignore-case Ignore case
855
+** --robot-exception Use the robot-exception setting as the REGEXP
855856
*/
856857
void re_test_grep(void){
857858
ReCompiled *pRe;
858859
const char *zErr;
860
+ int iFileList = 3;
859861
int ignoreCase = find_option("ignore-case","i",0)!=0;
860
- if( g.argc<3 ){
861
- usage("REGEXP [FILE...]");
862
+ int bRobot = find_option("robot-exception",0,0)!=0;
863
+ if( bRobot ){
864
+ const char *zRe;
865
+ db_find_and_open_repository(0,0);
866
+ verify_all_options();
867
+ zRe = db_get("robot-exception","^$");
868
+ zErr = re_compile(&pRe, zRe, ignoreCase);
869
+ iFileList = 2;
870
+ }else{
871
+ verify_all_options();
872
+ if( g.argc<3 ){
873
+ usage("REGEXP [FILE...]");
874
+ }
875
+ zErr = re_compile(&pRe, g.argv[2], ignoreCase);
862876
}
863
- zErr = re_compile(&pRe, g.argv[2], ignoreCase);
864877
if( zErr ) fossil_fatal("%s", zErr);
865
- if( g.argc==3 ){
878
+ if( g.argc==iFileList ){
866879
grep_file(pRe, "-", stdin);
867880
}else{
868881
int i;
869
- for(i=3; i<g.argc; i++){
882
+ for(i=iFileList; i<g.argc; i++){
870883
FILE *in = fossil_fopen(g.argv[i], "rb");
871884
if( in==0 ){
872885
fossil_warning("cannot open \"%s\"", g.argv[i]);
873886
}else{
874887
grep_file(pRe, g.argv[i], in);
@@ -1016,5 +1029,86 @@
10161029
}else{
10171030
fossil_print("%d\n", nMatch);
10181031
}
10191032
}
10201033
}
1034
+
1035
+/*
1036
+** WEBPAGE: re_rules
1037
+**
1038
+** Show a summary of the regular expression matching rules for Fossil.
1039
+*/
1040
+void re_rules_page(void){
1041
+ style_set_current_feature("wiki");
1042
+ style_header("Regular Expression Syntax");
1043
+ @ <p>Syntax rules for regular expression matching in Fossil:</p>
1044
+ @
1045
+ @ <table border="0" cellpadding="0" cellspacing="0">
1046
+ @ <tr><th>&emsp;&emsp;&emsp;<th>Pattern
1047
+ @ <th>&emsp;&emsp;&emsp;<th align="left">Match
1048
+ @ <tr><td><td><i>X</i><b>*</b>
1049
+ @ <td><td>Zero or more occurrences of <i>X</i>
1050
+ @ <tr><td><td><i>X</i><b>+</b>
1051
+ @ <td><td>One or more occurrences of <i>X</i>
1052
+ @ <tr><td><td><i>X</i><b>?</b>
1053
+ @ <td><td>Zero or one occurrences of <i>X</i>
1054
+ @ <tr><td><td><i>X</i><b>{</b><i>P</i><b>,</b><i>Q</i><b>}</b>
1055
+ @ <td><td>Between P and Q occurrences of <i>X</i>
1056
+ @ <tr><td><td><b>(</b><i>X</i><b>)</b>
1057
+ @ <td><td><i>X</i>
1058
+ @ <tr><td><td><i>X</i><b>|</b><i>Y</i>
1059
+ @ <td><td><i>X</i> or <i>Y</i>
1060
+ @ <tr><td><td><b>^</b><i>X</i>
1061
+ @ <td><td><i>X</i> at the beginning of the string
1062
+ @ <tr><td><td><i>X</i><b>$</b>
1063
+ @ <td><td><i>X</i> at the end of the string
1064
+ @ <tr><td><td><b>.</b>
1065
+ @ <td><td>Any single character
1066
+ @ <tr><td><td><b>\</b><i>C</i>
1067
+ @ <td><td>Character <i>C</i> if <i>C</i> is one of: <b>\{}()[]|*+?</b>
1068
+ @ <tr><td><td><b>\</b><i>C</i>
1069
+ @ <td><td>C-language escapes if <i>C</i> is one of: <b>afnrtv</b>
1070
+ @ <tr><td><td><b>\u</b><i>HHHH</i>
1071
+ @ <td><td>Unicode character U+HHHH where <i>HHHH</i> is four hex digits
1072
+ @ <tr><td><td><b>\</b><i>HH</i>
1073
+ @ <td><td>Unicode character U+00HH where <i>HH</i> is two hex digits
1074
+ @ <tr><td><td><b>[</b><i>abc</i><b>]</b>
1075
+ @ <td><td>Any single character from <i>abc</i>
1076
+ @ <tr><td><td><b>[^</b><i>abc</i><b>]</b>
1077
+ @ <td><td>Any single character not in <i>abc</i>
1078
+ @ <tr><td><td><b>[</b><i>a-z</i><b>]</b>
1079
+ @ <td><td>Any single character between <i>a</i> and <i>z</i>, inclusive
1080
+ @ <tr><td><td><b>[^</b><i>a-z</i><b>]</b>
1081
+ @ <td><td>Any single character not between <i>a</i> and <i>z</i>
1082
+ @ <tr><td><td><b>\b</b>
1083
+ @ <td><td>Word boundary
1084
+ @ <tr><td><td><b>\w</b>
1085
+ @ <td><td>A word character: a-zA-Z0-9 or _
1086
+ @ <tr><td><td><b>\W</b>
1087
+ @ <td><td>A non-word character
1088
+ @ <tr><td><td><b>\d</b>
1089
+ @ <td><td>A digit. 0-9
1090
+ @ <tr><td><td><b>\D</b>
1091
+ @ <td><td>A non-digit character
1092
+ @ <tr><td><td><b>\s</b>
1093
+ @ <td><td>A whitespace character
1094
+ @ <tr><td><td><b>\S</b>
1095
+ @ <td><td>A non-whitespace character
1096
+ @ </table>
1097
+ @
1098
+ @ <p>In the "Pattern" column of the table above:</p>
1099
+ @ <ul>
1100
+ @ <li> "<i>X</i>" and "<i>Y</i>" mean any subpattern
1101
+ @ <li> "<i>P</i>" and "<i>Q</i>" mean integers
1102
+ @ <li> "<i>C</i>" means a single character
1103
+ @ <li> "<i>H</i>" means a hexadecimal digit
1104
+ @ <li> "<i>abc</i>" means any sequences of one or more characters
1105
+ @ <li> "<i>a-z</i>" means any single character, a single "<b>-</b>"
1106
+ @ character, and then one additional character.
1107
+ @ <li> All other symbols in the patterns are literal text
1108
+ @ </ul>
1109
+ @
1110
+ @ <p>The "<i>X</i><b>|</b><i>Y</i>" pattern has lower precedence
1111
+ @ than the others. Use "<b>(</b>...<b>)</b>" for grouping, as
1112
+ @ necessary.
1113
+ style_finish_page();
1114
+}
10211115
--- src/regexp.c
+++ src/regexp.c
@@ -850,25 +850,38 @@
850 ** Run a regular expression match over the named disk files, or against
851 ** standard input if no disk files are named on the command-line.
852 **
853 ** Options:
854 ** -i|--ignore-case Ignore case
 
855 */
856 void re_test_grep(void){
857 ReCompiled *pRe;
858 const char *zErr;
 
859 int ignoreCase = find_option("ignore-case","i",0)!=0;
860 if( g.argc<3 ){
861 usage("REGEXP [FILE...]");
 
 
 
 
 
 
 
 
 
 
 
 
862 }
863 zErr = re_compile(&pRe, g.argv[2], ignoreCase);
864 if( zErr ) fossil_fatal("%s", zErr);
865 if( g.argc==3 ){
866 grep_file(pRe, "-", stdin);
867 }else{
868 int i;
869 for(i=3; i<g.argc; i++){
870 FILE *in = fossil_fopen(g.argv[i], "rb");
871 if( in==0 ){
872 fossil_warning("cannot open \"%s\"", g.argv[i]);
873 }else{
874 grep_file(pRe, g.argv[i], in);
@@ -1016,5 +1029,86 @@
1016 }else{
1017 fossil_print("%d\n", nMatch);
1018 }
1019 }
1020 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1021
--- src/regexp.c
+++ src/regexp.c
@@ -850,25 +850,38 @@
850 ** Run a regular expression match over the named disk files, or against
851 ** standard input if no disk files are named on the command-line.
852 **
853 ** Options:
854 ** -i|--ignore-case Ignore case
855 ** --robot-exception Use the robot-exception setting as the REGEXP
856 */
857 void re_test_grep(void){
858 ReCompiled *pRe;
859 const char *zErr;
860 int iFileList = 3;
861 int ignoreCase = find_option("ignore-case","i",0)!=0;
862 int bRobot = find_option("robot-exception",0,0)!=0;
863 if( bRobot ){
864 const char *zRe;
865 db_find_and_open_repository(0,0);
866 verify_all_options();
867 zRe = db_get("robot-exception","^$");
868 zErr = re_compile(&pRe, zRe, ignoreCase);
869 iFileList = 2;
870 }else{
871 verify_all_options();
872 if( g.argc<3 ){
873 usage("REGEXP [FILE...]");
874 }
875 zErr = re_compile(&pRe, g.argv[2], ignoreCase);
876 }
 
877 if( zErr ) fossil_fatal("%s", zErr);
878 if( g.argc==iFileList ){
879 grep_file(pRe, "-", stdin);
880 }else{
881 int i;
882 for(i=iFileList; i<g.argc; i++){
883 FILE *in = fossil_fopen(g.argv[i], "rb");
884 if( in==0 ){
885 fossil_warning("cannot open \"%s\"", g.argv[i]);
886 }else{
887 grep_file(pRe, g.argv[i], in);
@@ -1016,5 +1029,86 @@
1029 }else{
1030 fossil_print("%d\n", nMatch);
1031 }
1032 }
1033 }
1034
1035 /*
1036 ** WEBPAGE: re_rules
1037 **
1038 ** Show a summary of the regular expression matching rules for Fossil.
1039 */
1040 void re_rules_page(void){
1041 style_set_current_feature("wiki");
1042 style_header("Regular Expression Syntax");
1043 @ <p>Syntax rules for regular expression matching in Fossil:</p>
1044 @
1045 @ <table border="0" cellpadding="0" cellspacing="0">
1046 @ <tr><th>&emsp;&emsp;&emsp;<th>Pattern
1047 @ <th>&emsp;&emsp;&emsp;<th align="left">Match
1048 @ <tr><td><td><i>X</i><b>*</b>
1049 @ <td><td>Zero or more occurrences of <i>X</i>
1050 @ <tr><td><td><i>X</i><b>+</b>
1051 @ <td><td>One or more occurrences of <i>X</i>
1052 @ <tr><td><td><i>X</i><b>?</b>
1053 @ <td><td>Zero or one occurrences of <i>X</i>
1054 @ <tr><td><td><i>X</i><b>{</b><i>P</i><b>,</b><i>Q</i><b>}</b>
1055 @ <td><td>Between P and Q occurrences of <i>X</i>
1056 @ <tr><td><td><b>(</b><i>X</i><b>)</b>
1057 @ <td><td><i>X</i>
1058 @ <tr><td><td><i>X</i><b>|</b><i>Y</i>
1059 @ <td><td><i>X</i> or <i>Y</i>
1060 @ <tr><td><td><b>^</b><i>X</i>
1061 @ <td><td><i>X</i> at the beginning of the string
1062 @ <tr><td><td><i>X</i><b>$</b>
1063 @ <td><td><i>X</i> at the end of the string
1064 @ <tr><td><td><b>.</b>
1065 @ <td><td>Any single character
1066 @ <tr><td><td><b>\</b><i>C</i>
1067 @ <td><td>Character <i>C</i> if <i>C</i> is one of: <b>\{}()[]|*+?</b>
1068 @ <tr><td><td><b>\</b><i>C</i>
1069 @ <td><td>C-language escapes if <i>C</i> is one of: <b>afnrtv</b>
1070 @ <tr><td><td><b>\u</b><i>HHHH</i>
1071 @ <td><td>Unicode character U+HHHH where <i>HHHH</i> is four hex digits
1072 @ <tr><td><td><b>\</b><i>HH</i>
1073 @ <td><td>Unicode character U+00HH where <i>HH</i> is two hex digits
1074 @ <tr><td><td><b>[</b><i>abc</i><b>]</b>
1075 @ <td><td>Any single character from <i>abc</i>
1076 @ <tr><td><td><b>[^</b><i>abc</i><b>]</b>
1077 @ <td><td>Any single character not in <i>abc</i>
1078 @ <tr><td><td><b>[</b><i>a-z</i><b>]</b>
1079 @ <td><td>Any single character between <i>a</i> and <i>z</i>, inclusive
1080 @ <tr><td><td><b>[^</b><i>a-z</i><b>]</b>
1081 @ <td><td>Any single character not between <i>a</i> and <i>z</i>
1082 @ <tr><td><td><b>\b</b>
1083 @ <td><td>Word boundary
1084 @ <tr><td><td><b>\w</b>
1085 @ <td><td>A word character: a-zA-Z0-9 or _
1086 @ <tr><td><td><b>\W</b>
1087 @ <td><td>A non-word character
1088 @ <tr><td><td><b>\d</b>
1089 @ <td><td>A digit. 0-9
1090 @ <tr><td><td><b>\D</b>
1091 @ <td><td>A non-digit character
1092 @ <tr><td><td><b>\s</b>
1093 @ <td><td>A whitespace character
1094 @ <tr><td><td><b>\S</b>
1095 @ <td><td>A non-whitespace character
1096 @ </table>
1097 @
1098 @ <p>In the "Pattern" column of the table above:</p>
1099 @ <ul>
1100 @ <li> "<i>X</i>" and "<i>Y</i>" mean any subpattern
1101 @ <li> "<i>P</i>" and "<i>Q</i>" mean integers
1102 @ <li> "<i>C</i>" means a single character
1103 @ <li> "<i>H</i>" means a hexadecimal digit
1104 @ <li> "<i>abc</i>" means any sequences of one or more characters
1105 @ <li> "<i>a-z</i>" means any single character, a single "<b>-</b>"
1106 @ character, and then one additional character.
1107 @ <li> All other symbols in the patterns are literal text
1108 @ </ul>
1109 @
1110 @ <p>The "<i>X</i><b>|</b><i>Y</i>" pattern has lower precedence
1111 @ than the others. Use "<b>(</b>...<b>)</b>" for grouping, as
1112 @ necessary.
1113 style_finish_page();
1114 }
1115
+101 -3
--- src/robot.c
+++ src/robot.c
@@ -242,10 +242,15 @@
242242
p4 = (p2/k2)%k3;
243243
p5 = p2/(k2*k3);
244244
@ function ccc(a,b,c){return (a*%u(k3)+b)*%u(k2)+c;}\
245245
@ window.addEventListener('load',function(){\
246246
@ bbb(ccc(%u(p5),%u(p4),%u(p3)),%u(k));},false);
247
+ /* Prevent successfully completed robot checks from reappearing and force
248
+ ** incomplete checks to start over when navigating back and forward. More
249
+ ** information: <https://stackoverflow.com/a/43043658>. */
250
+ @ window.addEventListener('pageshow',function(e){if(e.persisted)\
251
+ @ window.location.reload();});
247252
@ </script>
248253
style_finish_page();
249254
}
250255
251256
/*
@@ -253,11 +258,11 @@
253258
** The VALUE of this setting is a list of GLOB patterns that match
254259
** pages for which complex HTTP requests from unauthenicated clients
255260
** should be disallowed. "Unauthenticated" means the user is "nobody".
256261
** The recommended value for this setting is:
257262
**
258
-** timelineX,diff,annotate,zip,fileage,file,finfo
263
+** timelineX,diff,annotate,zip,fileage,file,finfo,reports
259264
**
260265
** The "diff" tag covers all diffing pages such as /vdiff, /fdiff, and
261266
** /vpatch. The "annotate" tag also covers /blame and /praise. "zip"
262267
** also covers /tarball and /sqlar. If a tag has an "X" character appended,
263268
** then it only applies if query parameters are such that the page is
@@ -264,16 +269,34 @@
264269
** particularly difficult to compute. In all other case, the tag should
265270
** exactly match the page name.
266271
**
267272
** Change this setting "off" to disable all robot restrictions.
268273
*/
274
+/*
275
+** SETTING: robot-exception width=40 block-text
276
+**
277
+** The value of this setting should be a regular expression.
278
+** If it matches the REQUEST_URI without the SCRIPT_NAME prefix
279
+** matches this regular expression, then the request is an exception
280
+** to anti-robot defenses and should be allowed through. For
281
+** example, to allow robots to download tarballs or ZIP archives
282
+** for named versions and releases, you could use an expression like
283
+** this:
284
+**
285
+** ^/(tarball|zip)\\b*\\b(version-|release)\\b
286
+**
287
+** This setting can hold multiple regular expressions, one
288
+** regular expression per line. The input URL is exempted from
289
+** anti-robot defenses if any of the multiple regular expressions
290
+** matches.
291
+*/
269292
270293
/*
271294
** Return the default restriction GLOB
272295
*/
273296
const char *robot_restrict_default(void){
274
- return "timelineX,diff,annotate,zip,fileage,file,finfo";
297
+ return "timelineX,diff,annotate,zip,fileage,file,finfo,reports";
275298
}
276299
277300
/*
278301
** Return true if zTag matches one of the tags in the robot-restrict
279302
** setting.
@@ -287,10 +310,81 @@
287310
if( zGlob[0]==0 || fossil_strcmp(zGlob, "off")==0 ){
288311
return 0;
289312
}
290313
return glob_multi_match(zGlob,zTag);
291314
}
315
+
316
+/*
317
+** Check the request URI to see if it matches one of the URI
318
+** exceptions listed in the robot-exception setting. Return true
319
+** if it does. Return false if it does not.
320
+**
321
+** For the purposes of this routine, the "request URI" means
322
+** the REQUEST_URI value with the SCRIPT_NAME prefix removed and
323
+** with QUERY_STRING appended with a "?" separator if QUERY_STRING
324
+** is not empty.
325
+**
326
+** If the robot-exception setting does not exist or is an empty
327
+** string, then return false.
328
+*/
329
+int robot_exception(void){
330
+ const char *zRE = db_get("robot-exception",0);
331
+ const char *zQS; /* QUERY_STRING */
332
+ const char *zURI; /* REQUEST_URI */
333
+ const char *zSN; /* SCRIPT_NAME */
334
+ const char *zNL; /* Next newline character */
335
+ char *zRequest; /* REQUEST_URL w/o SCRIPT_NAME prefix + QUERY_STRING */
336
+ int nRequest; /* Length of zRequest in bytes */
337
+ size_t nURI, nSN; /* Length of zURI and zSN */
338
+ int bMatch = 0; /* True if there is a match */
339
+
340
+ if( zRE==0 ) return 0;
341
+ if( zRE[0]==0 ) return 0;
342
+ zURI = PD("REQUEST_URI","");
343
+ nURI = strlen(zURI);
344
+ zSN = PD("SCRIPT_NAME","");
345
+ nSN = strlen(zSN);
346
+ if( nSN<=nURI ) zURI += nSN;
347
+ zQS = P("QUERY_STRING");
348
+ if( zQS && zQS[0] ){
349
+ zRequest = mprintf("%s?%s", zURI, zQS);
350
+ }else{
351
+ zRequest = fossil_strdup(zURI);
352
+ }
353
+ nRequest = (int)strlen(zRequest);
354
+ while( zRE[0] && bMatch==0 ){
355
+ char *z;
356
+ const char *zErr;
357
+ size_t n;
358
+ ReCompiled *pRe;
359
+ zNL = strchr(zRE,'\n');
360
+ if( zNL ){
361
+ n = (size_t)(zNL - zRE)+1;
362
+ while( zNL>zRE && fossil_isspace(zNL[0]) ) zNL--;
363
+ if( zNL==zRE ){
364
+ zRE += n;
365
+ continue;
366
+ }
367
+ }else{
368
+ n = strlen(zRE);
369
+ }
370
+ z = mprintf("%.*s", (int)(zNL - zRE)+1, zRE);
371
+ zRE += n;
372
+ zErr = re_compile(&pRe, z, 0);
373
+ if( zErr ){
374
+ fossil_warning("robot-exception error \"%s\" in expression \"%s\"\n",
375
+ zErr, z);
376
+ fossil_free(z);
377
+ continue;
378
+ }
379
+ fossil_free(z);
380
+ bMatch = re_match(pRe, (const unsigned char*)zRequest, nRequest);
381
+ re_free(pRe);
382
+ }
383
+ fossil_free(zRequest);
384
+ return bMatch;
385
+}
292386
293387
/*
294388
** Check to see if the page named in the argument is on the
295389
** robot-restrict list. If it is on the list and if the user
296390
** is "nobody" then bring up a captcha to test to make sure that
@@ -302,12 +396,16 @@
302396
*/
303397
int robot_restrict(const char *zTag){
304398
if( robot.resultCache==KNOWN_NOT_ROBOT ) return 0;
305399
if( !robot_restrict_has_tag(zTag) ) return 0;
306400
if( !client_might_be_a_robot() ) return 0;
401
+ if( robot_exception() ){
402
+ robot.resultCache = KNOWN_NOT_ROBOT;
403
+ return 0;
404
+ }
307405
308
- /* Generate the proof-of-work captcha */
406
+ /* Generate the proof-of-work captcha */
309407
ask_for_proof_that_client_is_not_robot();
310408
return 1;
311409
}
312410
313411
/*
314412
--- src/robot.c
+++ src/robot.c
@@ -242,10 +242,15 @@
242 p4 = (p2/k2)%k3;
243 p5 = p2/(k2*k3);
244 @ function ccc(a,b,c){return (a*%u(k3)+b)*%u(k2)+c;}\
245 @ window.addEventListener('load',function(){\
246 @ bbb(ccc(%u(p5),%u(p4),%u(p3)),%u(k));},false);
 
 
 
 
 
247 @ </script>
248 style_finish_page();
249 }
250
251 /*
@@ -253,11 +258,11 @@
253 ** The VALUE of this setting is a list of GLOB patterns that match
254 ** pages for which complex HTTP requests from unauthenicated clients
255 ** should be disallowed. "Unauthenticated" means the user is "nobody".
256 ** The recommended value for this setting is:
257 **
258 ** timelineX,diff,annotate,zip,fileage,file,finfo
259 **
260 ** The "diff" tag covers all diffing pages such as /vdiff, /fdiff, and
261 ** /vpatch. The "annotate" tag also covers /blame and /praise. "zip"
262 ** also covers /tarball and /sqlar. If a tag has an "X" character appended,
263 ** then it only applies if query parameters are such that the page is
@@ -264,16 +269,34 @@
264 ** particularly difficult to compute. In all other case, the tag should
265 ** exactly match the page name.
266 **
267 ** Change this setting "off" to disable all robot restrictions.
268 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
270 /*
271 ** Return the default restriction GLOB
272 */
273 const char *robot_restrict_default(void){
274 return "timelineX,diff,annotate,zip,fileage,file,finfo";
275 }
276
277 /*
278 ** Return true if zTag matches one of the tags in the robot-restrict
279 ** setting.
@@ -287,10 +310,81 @@
287 if( zGlob[0]==0 || fossil_strcmp(zGlob, "off")==0 ){
288 return 0;
289 }
290 return glob_multi_match(zGlob,zTag);
291 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
293 /*
294 ** Check to see if the page named in the argument is on the
295 ** robot-restrict list. If it is on the list and if the user
296 ** is "nobody" then bring up a captcha to test to make sure that
@@ -302,12 +396,16 @@
302 */
303 int robot_restrict(const char *zTag){
304 if( robot.resultCache==KNOWN_NOT_ROBOT ) return 0;
305 if( !robot_restrict_has_tag(zTag) ) return 0;
306 if( !client_might_be_a_robot() ) return 0;
 
 
 
 
307
308 /* Generate the proof-of-work captcha */
309 ask_for_proof_that_client_is_not_robot();
310 return 1;
311 }
312
313 /*
314
--- src/robot.c
+++ src/robot.c
@@ -242,10 +242,15 @@
242 p4 = (p2/k2)%k3;
243 p5 = p2/(k2*k3);
244 @ function ccc(a,b,c){return (a*%u(k3)+b)*%u(k2)+c;}\
245 @ window.addEventListener('load',function(){\
246 @ bbb(ccc(%u(p5),%u(p4),%u(p3)),%u(k));},false);
247 /* Prevent successfully completed robot checks from reappearing and force
248 ** incomplete checks to start over when navigating back and forward. More
249 ** information: <https://stackoverflow.com/a/43043658>. */
250 @ window.addEventListener('pageshow',function(e){if(e.persisted)\
251 @ window.location.reload();});
252 @ </script>
253 style_finish_page();
254 }
255
256 /*
@@ -253,11 +258,11 @@
258 ** The VALUE of this setting is a list of GLOB patterns that match
259 ** pages for which complex HTTP requests from unauthenicated clients
260 ** should be disallowed. "Unauthenticated" means the user is "nobody".
261 ** The recommended value for this setting is:
262 **
263 ** timelineX,diff,annotate,zip,fileage,file,finfo,reports
264 **
265 ** The "diff" tag covers all diffing pages such as /vdiff, /fdiff, and
266 ** /vpatch. The "annotate" tag also covers /blame and /praise. "zip"
267 ** also covers /tarball and /sqlar. If a tag has an "X" character appended,
268 ** then it only applies if query parameters are such that the page is
@@ -264,16 +269,34 @@
269 ** particularly difficult to compute. In all other case, the tag should
270 ** exactly match the page name.
271 **
272 ** Change this setting "off" to disable all robot restrictions.
273 */
274 /*
275 ** SETTING: robot-exception width=40 block-text
276 **
277 ** The value of this setting should be a regular expression.
278 ** If it matches the REQUEST_URI without the SCRIPT_NAME prefix
279 ** matches this regular expression, then the request is an exception
280 ** to anti-robot defenses and should be allowed through. For
281 ** example, to allow robots to download tarballs or ZIP archives
282 ** for named versions and releases, you could use an expression like
283 ** this:
284 **
285 ** ^/(tarball|zip)\\b*\\b(version-|release)\\b
286 **
287 ** This setting can hold multiple regular expressions, one
288 ** regular expression per line. The input URL is exempted from
289 ** anti-robot defenses if any of the multiple regular expressions
290 ** matches.
291 */
292
293 /*
294 ** Return the default restriction GLOB
295 */
296 const char *robot_restrict_default(void){
297 return "timelineX,diff,annotate,zip,fileage,file,finfo,reports";
298 }
299
300 /*
301 ** Return true if zTag matches one of the tags in the robot-restrict
302 ** setting.
@@ -287,10 +310,81 @@
310 if( zGlob[0]==0 || fossil_strcmp(zGlob, "off")==0 ){
311 return 0;
312 }
313 return glob_multi_match(zGlob,zTag);
314 }
315
316 /*
317 ** Check the request URI to see if it matches one of the URI
318 ** exceptions listed in the robot-exception setting. Return true
319 ** if it does. Return false if it does not.
320 **
321 ** For the purposes of this routine, the "request URI" means
322 ** the REQUEST_URI value with the SCRIPT_NAME prefix removed and
323 ** with QUERY_STRING appended with a "?" separator if QUERY_STRING
324 ** is not empty.
325 **
326 ** If the robot-exception setting does not exist or is an empty
327 ** string, then return false.
328 */
329 int robot_exception(void){
330 const char *zRE = db_get("robot-exception",0);
331 const char *zQS; /* QUERY_STRING */
332 const char *zURI; /* REQUEST_URI */
333 const char *zSN; /* SCRIPT_NAME */
334 const char *zNL; /* Next newline character */
335 char *zRequest; /* REQUEST_URL w/o SCRIPT_NAME prefix + QUERY_STRING */
336 int nRequest; /* Length of zRequest in bytes */
337 size_t nURI, nSN; /* Length of zURI and zSN */
338 int bMatch = 0; /* True if there is a match */
339
340 if( zRE==0 ) return 0;
341 if( zRE[0]==0 ) return 0;
342 zURI = PD("REQUEST_URI","");
343 nURI = strlen(zURI);
344 zSN = PD("SCRIPT_NAME","");
345 nSN = strlen(zSN);
346 if( nSN<=nURI ) zURI += nSN;
347 zQS = P("QUERY_STRING");
348 if( zQS && zQS[0] ){
349 zRequest = mprintf("%s?%s", zURI, zQS);
350 }else{
351 zRequest = fossil_strdup(zURI);
352 }
353 nRequest = (int)strlen(zRequest);
354 while( zRE[0] && bMatch==0 ){
355 char *z;
356 const char *zErr;
357 size_t n;
358 ReCompiled *pRe;
359 zNL = strchr(zRE,'\n');
360 if( zNL ){
361 n = (size_t)(zNL - zRE)+1;
362 while( zNL>zRE && fossil_isspace(zNL[0]) ) zNL--;
363 if( zNL==zRE ){
364 zRE += n;
365 continue;
366 }
367 }else{
368 n = strlen(zRE);
369 }
370 z = mprintf("%.*s", (int)(zNL - zRE)+1, zRE);
371 zRE += n;
372 zErr = re_compile(&pRe, z, 0);
373 if( zErr ){
374 fossil_warning("robot-exception error \"%s\" in expression \"%s\"\n",
375 zErr, z);
376 fossil_free(z);
377 continue;
378 }
379 fossil_free(z);
380 bMatch = re_match(pRe, (const unsigned char*)zRequest, nRequest);
381 re_free(pRe);
382 }
383 fossil_free(zRequest);
384 return bMatch;
385 }
386
387 /*
388 ** Check to see if the page named in the argument is on the
389 ** robot-restrict list. If it is on the list and if the user
390 ** is "nobody" then bring up a captcha to test to make sure that
@@ -302,12 +396,16 @@
396 */
397 int robot_restrict(const char *zTag){
398 if( robot.resultCache==KNOWN_NOT_ROBOT ) return 0;
399 if( !robot_restrict_has_tag(zTag) ) return 0;
400 if( !client_might_be_a_robot() ) return 0;
401 if( robot_exception() ){
402 robot.resultCache = KNOWN_NOT_ROBOT;
403 return 0;
404 }
405
406 /* Generate the proof-of-work captcha */
407 ask_for_proof_that_client_is_not_robot();
408 return 1;
409 }
410
411 /*
412
--- src/security_audit.c
+++ src/security_audit.c
@@ -954,11 +954,13 @@
954954
if( prevWasTime ){
955955
if( strncmp(z,"possible hack attempt - 418 ", 27)==0 ){
956956
bOutput = (eType & 0x01)!=0;
957957
nHack++;
958958
}else
959
- if( (strncmp(z,"panic: ", 7)==0 || strstr(z," assertion fault ")!=0) ){
959
+ if( (strncmp(z,"panic: ", 7)==0 && strncmp(z+7,"Timeout",7)!=0)
960
+ || strstr(z," assertion fault ")!=0
961
+ ){
960962
bOutput = (eType & 0x02)!=0;
961963
nPanic++;
962964
}else
963965
if( strncmp(z,"SMTP:", 5)==0 ){
964966
bOutput = (eType & 0x20)!=0;
965967
--- src/security_audit.c
+++ src/security_audit.c
@@ -954,11 +954,13 @@
954 if( prevWasTime ){
955 if( strncmp(z,"possible hack attempt - 418 ", 27)==0 ){
956 bOutput = (eType & 0x01)!=0;
957 nHack++;
958 }else
959 if( (strncmp(z,"panic: ", 7)==0 || strstr(z," assertion fault ")!=0) ){
 
 
960 bOutput = (eType & 0x02)!=0;
961 nPanic++;
962 }else
963 if( strncmp(z,"SMTP:", 5)==0 ){
964 bOutput = (eType & 0x20)!=0;
965
--- src/security_audit.c
+++ src/security_audit.c
@@ -954,11 +954,13 @@
954 if( prevWasTime ){
955 if( strncmp(z,"possible hack attempt - 418 ", 27)==0 ){
956 bOutput = (eType & 0x01)!=0;
957 nHack++;
958 }else
959 if( (strncmp(z,"panic: ", 7)==0 && strncmp(z+7,"Timeout",7)!=0)
960 || strstr(z," assertion fault ")!=0
961 ){
962 bOutput = (eType & 0x02)!=0;
963 nPanic++;
964 }else
965 if( strncmp(z,"SMTP:", 5)==0 ){
966 bOutput = (eType & 0x20)!=0;
967
+17 -2
--- src/setup.c
+++ src/setup.c
@@ -477,12 +477,12 @@
477477
@
478478
@ <form action="%R/setup_robot" method="post"><div>
479479
login_insert_csrf_secret();
480480
@ <input type="submit" name="submit" value="Apply Changes"></p>
481481
@ <hr>
482
- @ <p><b>Do not allow robots access to these pages.</b>
483
- @ <p> If the page name matches the GLOB pattern of this setting, and the
482
+ @ <p><b>Do not allow robots access to these pages.</b><br>
483
+ @ If the page name matches the GLOB pattern of this setting, and the
484484
@ users is "nobody", and the client has not previously passed a captcha
485485
@ test to show that it is not a robot, then the page is not displayed.
486486
@ A captcha test is is rendered instead.
487487
@ The recommended value for this setting is:
488488
@ <p>
@@ -499,10 +499,25 @@
499499
@ (Property: robot-restrict)
500500
@ <br>
501501
textarea_attribute("", 2, 80,
502502
"robot-restrict", "rbrestrict", robot_restrict_default(), 0);
503503
504
+ @ <hr>
505
+ @ <p><b>Exceptions to anti-robot restrictions</b><br>
506
+ @ The entry below is a list of regular expressions, one per line.
507
+ @ If any of these regular expressions match the input URL, then the
508
+ @ request is exempt from anti-robot defenses. Use this, for example,
509
+ @ to allow scripts to download release tarballs using a pattern
510
+ @ like:</p>
511
+ @ <p>
512
+ @ &emsp;&emsp;<tt>^/tarball\b.*\b(version-|release)\b</tt>
513
+ @ <p>The pattern should match against the REQUEST_URI with the
514
+ @ SCRIPT_NAME prefix removed, and with QUERY_STRING appended following
515
+ @ a "?" if QUERY_STRING exists. (Property: robot-exception)<br>
516
+ textarea_attribute("", 3, 80,
517
+ "robot-exception", "rbexcept", "", 0);
518
+
504519
@ <hr>
505520
addAutoHyperlinkSettings();
506521
507522
@ <hr>
508523
entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan",
509524
--- src/setup.c
+++ src/setup.c
@@ -477,12 +477,12 @@
477 @
478 @ <form action="%R/setup_robot" method="post"><div>
479 login_insert_csrf_secret();
480 @ <input type="submit" name="submit" value="Apply Changes"></p>
481 @ <hr>
482 @ <p><b>Do not allow robots access to these pages.</b>
483 @ <p> If the page name matches the GLOB pattern of this setting, and the
484 @ users is "nobody", and the client has not previously passed a captcha
485 @ test to show that it is not a robot, then the page is not displayed.
486 @ A captcha test is is rendered instead.
487 @ The recommended value for this setting is:
488 @ <p>
@@ -499,10 +499,25 @@
499 @ (Property: robot-restrict)
500 @ <br>
501 textarea_attribute("", 2, 80,
502 "robot-restrict", "rbrestrict", robot_restrict_default(), 0);
503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504 @ <hr>
505 addAutoHyperlinkSettings();
506
507 @ <hr>
508 entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan",
509
--- src/setup.c
+++ src/setup.c
@@ -477,12 +477,12 @@
477 @
478 @ <form action="%R/setup_robot" method="post"><div>
479 login_insert_csrf_secret();
480 @ <input type="submit" name="submit" value="Apply Changes"></p>
481 @ <hr>
482 @ <p><b>Do not allow robots access to these pages.</b><br>
483 @ If the page name matches the GLOB pattern of this setting, and the
484 @ users is "nobody", and the client has not previously passed a captcha
485 @ test to show that it is not a robot, then the page is not displayed.
486 @ A captcha test is is rendered instead.
487 @ The recommended value for this setting is:
488 @ <p>
@@ -499,10 +499,25 @@
499 @ (Property: robot-restrict)
500 @ <br>
501 textarea_attribute("", 2, 80,
502 "robot-restrict", "rbrestrict", robot_restrict_default(), 0);
503
504 @ <hr>
505 @ <p><b>Exceptions to anti-robot restrictions</b><br>
506 @ The entry below is a list of regular expressions, one per line.
507 @ If any of these regular expressions match the input URL, then the
508 @ request is exempt from anti-robot defenses. Use this, for example,
509 @ to allow scripts to download release tarballs using a pattern
510 @ like:</p>
511 @ <p>
512 @ &emsp;&emsp;<tt>^/tarball\b.*\b(version-|release)\b</tt>
513 @ <p>The pattern should match against the REQUEST_URI with the
514 @ SCRIPT_NAME prefix removed, and with QUERY_STRING appended following
515 @ a "?" if QUERY_STRING exists. (Property: robot-exception)<br>
516 textarea_attribute("", 3, 80,
517 "robot-exception", "rbexcept", "", 0);
518
519 @ <hr>
520 addAutoHyperlinkSettings();
521
522 @ <hr>
523 entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan",
524
+2 -2
--- src/timeline.c
+++ src/timeline.c
@@ -1830,11 +1830,11 @@
18301830
|| (bisectLocal && !g.perm.Setup)
18311831
){
18321832
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
18331833
return;
18341834
}
1835
- if( zBefore && robot_restrict("timelineX") ) return;
1835
+ if( (zBefore || zCirca) && robot_restrict("timelineX") ) return;
18361836
if( !bisectLocal ){
18371837
etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA|ETAG_CONFIG, 0);
18381838
}
18391839
cookie_read_parameter("y","y");
18401840
zType = P("y");
@@ -2404,11 +2404,11 @@
24042404
href("%R/info?name=%h",zBaseName), zBaseName,
24052405
href("%R/info?name=%h",zBackTo), zBackTo);
24062406
}else{
24072407
blob_appendf(&desc, " back to %z%h</a>%s",
24082408
href("%R/info?name=%h",zBackTo), zBackTo,
2409
- bBackAdded ? " (not a direct anscestor)" : "");
2409
+ bBackAdded ? " (not a direct ancestor)" : "");
24102410
if( ridFwdTo && zFwdTo ){
24112411
blob_appendf(&desc, " and up to %z%h</a>%s",
24122412
href("%R/info?name=%h",zFwdTo), zFwdTo,
24132413
bFwdAdded ? " (not a direct descendant)" : "");
24142414
}
24152415
--- src/timeline.c
+++ src/timeline.c
@@ -1830,11 +1830,11 @@
1830 || (bisectLocal && !g.perm.Setup)
1831 ){
1832 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1833 return;
1834 }
1835 if( zBefore && robot_restrict("timelineX") ) return;
1836 if( !bisectLocal ){
1837 etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA|ETAG_CONFIG, 0);
1838 }
1839 cookie_read_parameter("y","y");
1840 zType = P("y");
@@ -2404,11 +2404,11 @@
2404 href("%R/info?name=%h",zBaseName), zBaseName,
2405 href("%R/info?name=%h",zBackTo), zBackTo);
2406 }else{
2407 blob_appendf(&desc, " back to %z%h</a>%s",
2408 href("%R/info?name=%h",zBackTo), zBackTo,
2409 bBackAdded ? " (not a direct anscestor)" : "");
2410 if( ridFwdTo && zFwdTo ){
2411 blob_appendf(&desc, " and up to %z%h</a>%s",
2412 href("%R/info?name=%h",zFwdTo), zFwdTo,
2413 bFwdAdded ? " (not a direct descendant)" : "");
2414 }
2415
--- src/timeline.c
+++ src/timeline.c
@@ -1830,11 +1830,11 @@
1830 || (bisectLocal && !g.perm.Setup)
1831 ){
1832 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1833 return;
1834 }
1835 if( (zBefore || zCirca) && robot_restrict("timelineX") ) return;
1836 if( !bisectLocal ){
1837 etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA|ETAG_CONFIG, 0);
1838 }
1839 cookie_read_parameter("y","y");
1840 zType = P("y");
@@ -2404,11 +2404,11 @@
2404 href("%R/info?name=%h",zBaseName), zBaseName,
2405 href("%R/info?name=%h",zBackTo), zBackTo);
2406 }else{
2407 blob_appendf(&desc, " back to %z%h</a>%s",
2408 href("%R/info?name=%h",zBackTo), zBackTo,
2409 bBackAdded ? " (not a direct ancestor)" : "");
2410 if( ridFwdTo && zFwdTo ){
2411 blob_appendf(&desc, " and up to %z%h</a>%s",
2412 href("%R/info?name=%h",zFwdTo), zFwdTo,
2413 bFwdAdded ? " (not a direct descendant)" : "");
2414 }
2415
+18 -5
--- www/changes.wiki
+++ www/changes.wiki
@@ -5,20 +5,33 @@
55
additional defenses built into Fossil, as well as good luck, this injection
66
is not exploitable for either data exfiltration or privilege escalation. The
77
only possible result of invoking the injection is a harmless SQL syntax error.
88
(The [https://en.wikipedia.org/wiki/Swiss_cheese_model|holes in the Swiss cheese]
99
did not line up!)
10
- <li> Enhance the chng= query parameter on the [/help?cmd=/timeline|timeline page]
11
- so that it works with other query parameters like p=, d=, from=, and to=.
12
- <li> Always include nodes identify by sel1= and sel2= in the /timeline display.
10
+ <li> Strengthen robot defenses to help prevent public-facing servers from being
11
+ overwhelmed by the latest generation of AI spiders.
12
+ <ol type="a">
13
+ <li> New javascript captcha used to restrict access by user "nobody" to pages
14
+ listed in the [/help?cmd=robot-restrict|robot-restrict setting].
15
+ <li> The [/help?cmd=robot-exception|robot-exception setting] is available to allow
16
+ access to pages that match a regular expression. Use this, for example, to
17
+ allow curl scripts and similar to download release tarballs.
18
+ <li> Require at least an anonymous login to access the /blame page and similar.
19
+ </ol>
20
+ <li> [/help?cmd=/timeline|Timeline] enhancements:
21
+ <ol type="a">
22
+ <li> The chng= query parameter on the [/help?cmd=/timeline|timeline page]
23
+ so that it works with other query parameters like p=, d=, from=, and to=.
24
+ <li> Always include nodes identify by sel1= and sel2= in the /timeline display.
25
+ <li> Improved title when p= and d= are different.
26
+ </ol>
1327
<li> Enable the --editor option on the [/help?cmd=amend|fossil amend] command.
14
- <li> Require at least an anonymous login to access the /blame page and similar,
15
- to help prevent robots from soaking up excess CPU time on such pages.
1628
<li> When walking the filesystem looking for Fossil repositories, avoid descending
1729
into directories named "/proc".
1830
<li> Reduce memory requirements for sending authenticated sync protocol
1931
messages.
32
+ <li> Show numstat-style change statistics in the /info and /ckout pages.
2033
<li> Add the [/help?cmd=stash | stash rename] subcommand.
2134
</ol>
2235
2336
<h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol>
2437
<li>Enhancements to [/help?cmd=diff|fossil diff] and similar:
2538
--- www/changes.wiki
+++ www/changes.wiki
@@ -5,20 +5,33 @@
5 additional defenses built into Fossil, as well as good luck, this injection
6 is not exploitable for either data exfiltration or privilege escalation. The
7 only possible result of invoking the injection is a harmless SQL syntax error.
8 (The [https://en.wikipedia.org/wiki/Swiss_cheese_model|holes in the Swiss cheese]
9 did not line up!)
10 <li> Enhance the chng= query parameter on the [/help?cmd=/timeline|timeline page]
11 so that it works with other query parameters like p=, d=, from=, and to=.
12 <li> Always include nodes identify by sel1= and sel2= in the /timeline display.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13 <li> Enable the --editor option on the [/help?cmd=amend|fossil amend] command.
14 <li> Require at least an anonymous login to access the /blame page and similar,
15 to help prevent robots from soaking up excess CPU time on such pages.
16 <li> When walking the filesystem looking for Fossil repositories, avoid descending
17 into directories named "/proc".
18 <li> Reduce memory requirements for sending authenticated sync protocol
19 messages.
 
20 <li> Add the [/help?cmd=stash | stash rename] subcommand.
21 </ol>
22
23 <h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol>
24 <li>Enhancements to [/help?cmd=diff|fossil diff] and similar:
25
--- www/changes.wiki
+++ www/changes.wiki
@@ -5,20 +5,33 @@
5 additional defenses built into Fossil, as well as good luck, this injection
6 is not exploitable for either data exfiltration or privilege escalation. The
7 only possible result of invoking the injection is a harmless SQL syntax error.
8 (The [https://en.wikipedia.org/wiki/Swiss_cheese_model|holes in the Swiss cheese]
9 did not line up!)
10 <li> Strengthen robot defenses to help prevent public-facing servers from being
11 overwhelmed by the latest generation of AI spiders.
12 <ol type="a">
13 <li> New javascript captcha used to restrict access by user "nobody" to pages
14 listed in the [/help?cmd=robot-restrict|robot-restrict setting].
15 <li> The [/help?cmd=robot-exception|robot-exception setting] is available to allow
16 access to pages that match a regular expression. Use this, for example, to
17 allow curl scripts and similar to download release tarballs.
18 <li> Require at least an anonymous login to access the /blame page and similar.
19 </ol>
20 <li> [/help?cmd=/timeline|Timeline] enhancements:
21 <ol type="a">
22 <li> The chng= query parameter on the [/help?cmd=/timeline|timeline page]
23 so that it works with other query parameters like p=, d=, from=, and to=.
24 <li> Always include nodes identify by sel1= and sel2= in the /timeline display.
25 <li> Improved title when p= and d= are different.
26 </ol>
27 <li> Enable the --editor option on the [/help?cmd=amend|fossil amend] command.
 
 
28 <li> When walking the filesystem looking for Fossil repositories, avoid descending
29 into directories named "/proc".
30 <li> Reduce memory requirements for sending authenticated sync protocol
31 messages.
32 <li> Show numstat-style change statistics in the /info and /ckout pages.
33 <li> Add the [/help?cmd=stash | stash rename] subcommand.
34 </ol>
35
36 <h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol>
37 <li>Enhancements to [/help?cmd=diff|fossil diff] and similar:
38
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -66,11 +66,11 @@
6666
[corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
6767
[Darcs]: http://darcs.net/
6868
[db2w]: https://youtu.be/2eaQzahCeh4
6969
[emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
7070
[floss26]: https://twit.tv/shows/floss-weekly/episodes/26
71
-[fnc]: https://fnc.bsdbox.org
71
+[fnc]: https://fnc.sh
7272
[fsl]: http://fossil.0branch.com/fsl
7373
[Fuel]: https://fuel-scm.org/fossil/index
7474
[Git]: https://git-scm.com
7575
[GoLand]: https://www.jetbrains.com/go/
7676
[got]: https://gameoftrees.org
7777
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -66,11 +66,11 @@
66 [corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
67 [Darcs]: http://darcs.net/
68 [db2w]: https://youtu.be/2eaQzahCeh4
69 [emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
70 [floss26]: https://twit.tv/shows/floss-weekly/episodes/26
71 [fnc]: https://fnc.bsdbox.org
72 [fsl]: http://fossil.0branch.com/fsl
73 [Fuel]: https://fuel-scm.org/fossil/index
74 [Git]: https://git-scm.com
75 [GoLand]: https://www.jetbrains.com/go/
76 [got]: https://gameoftrees.org
77
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -66,11 +66,11 @@
66 [corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
67 [Darcs]: http://darcs.net/
68 [db2w]: https://youtu.be/2eaQzahCeh4
69 [emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
70 [floss26]: https://twit.tv/shows/floss-weekly/episodes/26
71 [fnc]: https://fnc.sh
72 [fsl]: http://fossil.0branch.com/fsl
73 [Fuel]: https://fuel-scm.org/fossil/index
74 [Git]: https://git-scm.com
75 [GoLand]: https://www.jetbrains.com/go/
76 [got]: https://gameoftrees.org
77

Keyboard Shortcuts

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