Fossil SCM

Merged in trunk.

stephan 2022-03-30 14:15 markdown-tagrefs merge
Commit 28fa0153575c4fbf08d54cfefb0f5173e275ca8ac597c92194280e6539da8e71
80 files changed +1 -1 +1 -1 +1 -1 +701 -134 +2408 -1050 +308 -27 +4 -4 +2 +3 -3 +5 -4 +1 -1 +46 -93 +125 -3 +125 -3 +3 -4 +105 -33 +381 -86 +2 -2 +3 +12 -3 +2 -2 +7 -2 +200 -27 +11 -8 +27 -9 +3 -4 +187 -235 +4 -4 +6 -15 +27 -6 +8 -7 +71 -62 -6 +14 -11 +20 -13 +12 -3 +48 -18 +110 -42 +24 -1 +3 -3 +7 -4 +43 -28 +7 -1 +7 -1 +38 -31 +1 -2 +5 -6 +3 +17 -8 +2 -2 +1 -2 +1 -1 +53 -215 +3 -1 -1 -211 +3 -3 -6 +43 -14 +3 -3 +65 -66 +1 -1 +45 -13 +1 -1 +1 -1 +5 +1 -1 +5 -14 +6 -1 +4 -4 +16 -11 +8 -8 +1 -1 +1 -1 +2 -1 +27 -42 +6 -5 +1 -4 +176
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-2.18
1
+2.19
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.18
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.19
2
+1 -1
--- auto.def
+++ auto.def
@@ -232,11 +232,11 @@
232232
#
233233
define USE_LINENOISE 1
234234
}
235235
236236
if {[string match *-solaris* [get-define host]]} {
237
- define-append EXTRA_CFLAGS {-D_XOPEN_SOURCE=500 -D__EXTENSIONS__}
237
+ define-append EXTRA_CFLAGS {-D__EXTENSIONS__}
238238
}
239239
240240
if {[opt-bool fossil-debug]} {
241241
define CFLAGS {-g -O0 -Wall}
242242
define-append CFLAGS -DFOSSIL_DEBUG
243243
--- auto.def
+++ auto.def
@@ -232,11 +232,11 @@
232 #
233 define USE_LINENOISE 1
234 }
235
236 if {[string match *-solaris* [get-define host]]} {
237 define-append EXTRA_CFLAGS {-D_XOPEN_SOURCE=500 -D__EXTENSIONS__}
238 }
239
240 if {[opt-bool fossil-debug]} {
241 define CFLAGS {-g -O0 -Wall}
242 define-append CFLAGS -DFOSSIL_DEBUG
243
--- auto.def
+++ auto.def
@@ -232,11 +232,11 @@
232 #
233 define USE_LINENOISE 1
234 }
235
236 if {[string match *-solaris* [get-define host]]} {
237 define-append EXTRA_CFLAGS {-D__EXTENSIONS__}
238 }
239
240 if {[opt-bool fossil-debug]} {
241 define CFLAGS {-g -O0 -Wall}
242 define-append CFLAGS -DFOSSIL_DEBUG
243
+1 -1
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -6645,11 +6645,11 @@
66456645
/* Compute one of the built-in functions
66466646
*/
66476647
static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
66486648
PNum v = 0.0;
66496649
switch( pFunc->eCode ){
6650
- case FN_ABS: v = v<0.0 ? -v : v; break;
6650
+ case FN_ABS: v = x<0.0 ? -x : x; break;
66516651
case FN_COS: v = cos(x); break;
66526652
case FN_INT: v = rint(x); break;
66536653
case FN_SIN: v = sin(x); break;
66546654
case FN_SQRT:
66556655
if( x<0.0 ){
66566656
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -6645,11 +6645,11 @@
6645 /* Compute one of the built-in functions
6646 */
6647 static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
6648 PNum v = 0.0;
6649 switch( pFunc->eCode ){
6650 case FN_ABS: v = v<0.0 ? -v : v; break;
6651 case FN_COS: v = cos(x); break;
6652 case FN_INT: v = rint(x); break;
6653 case FN_SIN: v = sin(x); break;
6654 case FN_SQRT:
6655 if( x<0.0 ){
6656
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -6645,11 +6645,11 @@
6645 /* Compute one of the built-in functions
6646 */
6647 static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
6648 PNum v = 0.0;
6649 switch( pFunc->eCode ){
6650 case FN_ABS: v = x<0.0 ? -x : x; break;
6651 case FN_COS: v = cos(x); break;
6652 case FN_INT: v = rint(x); break;
6653 case FN_SIN: v = sin(x); break;
6654 case FN_SQRT:
6655 if( x<0.0 ){
6656
+701 -134
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
3939
** Optionally #include a user-defined header, whereby compilation options
4040
** may be set prior to where they take effect, but after platform setup.
4141
** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
4242
** file. Note that this macro has a like effect on sqlite3.c compilation.
4343
*/
44
+# define SHELL_STRINGIFY_(f) #f
45
+# define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f)
4446
#ifdef SQLITE_CUSTOM_INCLUDE
45
-# define INC_STRINGIFY_(f) #f
46
-# define INC_STRINGIFY(f) INC_STRINGIFY_(f)
47
-# include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
47
+# include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
4848
#endif
4949
5050
/*
5151
** Determine if we are dealing with WinRT, which provides only a subset of
5252
** the full Win32 API.
@@ -1401,11 +1401,11 @@
14011401
** sha3_query(Y,SIZE)
14021402
**
14031403
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
14041404
** X is NULL.
14051405
**
1406
-** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
1406
+** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
14071407
** and returns a hash of their results.
14081408
**
14091409
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
14101410
** is used. If SIZE is included it must be one of the integers 224, 256,
14111411
** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
54495449
unsigned int i;
54505450
int rc = SQLITE_OK;
54515451
SQLITE_EXTENSION_INIT2(pApi);
54525452
(void)pzErrMsg; /* Unused parameter */
54535453
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454
- rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5454
+ rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
54555455
SQLITE_UTF8|SQLITE_INNOCUOUS,
54565456
(void*)&aFunc[i].iAux,
54575457
aFunc[i].xFunc, 0, 0);
54585458
}
54595459
return rc;
@@ -7962,13 +7962,18 @@
79627962
zFile = pTab->zFile;
79637963
}else if( idxNum==0 ){
79647964
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
79657965
return SQLITE_ERROR;
79667966
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
7967
+ static const u8 aEmptyBlob = 0;
79677968
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
79687969
int nBlob = sqlite3_value_bytes(argv[0]);
79697970
assert( pTab->pFirstEntry==0 );
7971
+ if( aBlob==0 ){
7972
+ aBlob = &aEmptyBlob;
7973
+ nBlob = 0;
7974
+ }
79707975
rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
79717976
pCsr->pFreeEntry = pTab->pFirstEntry;
79727977
pTab->pFirstEntry = pTab->pLastEntry = 0;
79737978
if( rc!=SQLITE_OK ) return rc;
79747979
bInMemory = 1;
@@ -8870,10 +8875,14 @@
88708875
0, /* xSync */
88718876
zipfileCommit, /* xCommit */
88728877
zipfileRollback, /* xRollback */
88738878
zipfileFindFunction, /* xFindMethod */
88748879
0, /* xRename */
8880
+ 0, /* xSavepoint */
8881
+ 0, /* xRelease */
8882
+ 0, /* xRollback */
8883
+ 0 /* xShadowName */
88758884
};
88768885
88778886
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
88788887
if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
88798888
if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
1214312152
EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
1214412153
EQPGraphRow *pLast; /* Last element of the pRow list */
1214512154
char zPrefix[100]; /* Graph prefix */
1214612155
};
1214712156
12157
+/* Parameters affecting columnar mode result display (defaulting together) */
12158
+typedef struct ColModeOpts {
12159
+ int iWrap; /* In columnar modes, wrap lines reaching this limit */
12160
+ u8 bQuote; /* Quote results for .mode box and table */
12161
+ u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
12162
+} ColModeOpts;
12163
+#define ColModeOpts_default { 60, 0, 0 }
12164
+#define ColModeOpts_default_qbox { 60, 1, 0 }
12165
+
1214812166
/*
1214912167
** State information about the database connection is contained in an
1215012168
** instance of the following structure.
1215112169
*/
1215212170
typedef struct ShellState ShellState;
@@ -12161,12 +12179,14 @@
1216112179
u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
1216212180
u8 nEqpLevel; /* Depth of the EQP output graph */
1216312181
u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
1216412182
u8 bSafeMode; /* True to prohibit unsafe operations */
1216512183
u8 bSafeModePersist; /* The long-term value of bSafeMode */
12184
+ ColModeOpts cmOpts; /* Option values affecting columnar mode output */
1216612185
unsigned statsOn; /* True to display memory stats before each finalize */
1216712186
unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
12187
+ int inputNesting; /* Track nesting level of .read and other redirects */
1216812188
int outCount; /* Revert to stdout when reaching zero */
1216912189
int cnt; /* Number of records displayed so far */
1217012190
int lineno; /* Line number of last line read from in */
1217112191
int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
1217212192
FILE *in; /* Read commands from this stream */
@@ -12327,10 +12347,16 @@
1232712347
#define SEP_Comma ","
1232812348
#define SEP_CrLf "\r\n"
1232912349
#define SEP_Unit "\x1F"
1233012350
#define SEP_Record "\x1E"
1233112351
12352
+/*
12353
+** Limit input nesting via .read or any other input redirect.
12354
+** It's not too expensive, so a generous allowance can be made.
12355
+*/
12356
+#define MAX_INPUT_NESTING 25
12357
+
1233212358
/*
1233312359
** A callback for the sqlite3_log() interface.
1233412360
*/
1233512361
static void shellLog(void *pArg, int iErrCode, const char *zMsg){
1233612362
ShellState *p = (ShellState*)pArg;
@@ -13371,11 +13397,16 @@
1337113397
if( ur==0x7ff0000000000000LL ){
1337213398
raw_printf(p->out, "1e999");
1337313399
}else if( ur==0xfff0000000000000LL ){
1337413400
raw_printf(p->out, "-1e999");
1337513401
}else{
13376
- sqlite3_snprintf(50,z,"%!.20g", r);
13402
+ sqlite3_int64 ir = (sqlite3_int64)r;
13403
+ if( r==(double)ir ){
13404
+ sqlite3_snprintf(50,z,"%lld.0", ir);
13405
+ }else{
13406
+ sqlite3_snprintf(50,z,"%!.20g", r);
13407
+ }
1337713408
raw_printf(p->out, "%s", z);
1337813409
}
1337913410
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1338013411
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1338113412
int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13697,21 +13728,28 @@
1369713728
/*
1369813729
** Allocate space and save off string indicating current error.
1369913730
*/
1370013731
static char *save_err_msg(
1370113732
sqlite3 *db, /* Database to query */
13702
- const char *zWhen, /* Qualifier (format) wrapper */
13733
+ const char *zPhase, /* When the error occcurs */
1370313734
int rc, /* Error code returned from API */
1370413735
const char *zSql /* SQL string, or NULL */
1370513736
){
1370613737
char *zErr;
1370713738
char *zContext;
13708
- if( zWhen==0 ) zWhen = "%s (%d)%s";
13739
+ sqlite3_str *pStr = sqlite3_str_new(0);
13740
+ sqlite3_str_appendf(pStr, "%s, %s", zPhase, sqlite3_errmsg(db));
13741
+ if( rc>1 ){
13742
+ sqlite3_str_appendf(pStr, " (%d)", rc);
13743
+ }
1370913744
zContext = shell_error_context(zSql, db);
13710
- zErr = sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc, zContext);
13745
+ if( zContext ){
13746
+ sqlite3_str_appendall(pStr, zContext);
13747
+ sqlite3_free(zContext);
13748
+ }
13749
+ zErr = sqlite3_str_finish(pStr);
1371113750
shell_check_oom(zErr);
13712
- sqlite3_free(zContext);
1371313751
return zErr;
1371413752
}
1371513753
1371613754
#ifdef __linux__
1371713755
/*
@@ -14234,11 +14272,138 @@
1423414272
utf8_printf(p->out, "%s", zSep3);
1423514273
}
1423614274
fputs("\n", p->out);
1423714275
}
1423814276
14277
+/*
14278
+** z[] is a line of text that is to be displayed the .mode box or table or
14279
+** similar tabular formats. z[] might contain control characters such
14280
+** as \n, \t, \f, or \r.
14281
+**
14282
+** Compute characters to display on the first line of z[]. Stop at the
14283
+** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
14284
+** from malloc()) of that first line, which caller should free sometime.
14285
+** Write anything to display on the next line into *pzTail. If this is
14286
+** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
14287
+*/
14288
+static char *translateForDisplayAndDup(
14289
+ const unsigned char *z, /* Input text to be transformed */
14290
+ const unsigned char **pzTail, /* OUT: Tail of the input for next line */
14291
+ int mxWidth, /* Max width. 0 means no limit */
14292
+ u8 bWordWrap /* If true, avoid breaking mid-word */
14293
+){
14294
+ int i; /* Input bytes consumed */
14295
+ int j; /* Output bytes generated */
14296
+ int k; /* Input bytes to be displayed */
14297
+ int n; /* Output column number */
14298
+ unsigned char *zOut; /* Output text */
1423914299
14300
+ if( z==0 ){
14301
+ *pzTail = 0;
14302
+ return 0;
14303
+ }
14304
+ if( mxWidth<0 ) mxWidth = -mxWidth;
14305
+ if( mxWidth==0 ) mxWidth = 1000000;
14306
+ i = j = n = 0;
14307
+ while( n<mxWidth ){
14308
+ if( z[i]>=' ' ){
14309
+ n++;
14310
+ do{ i++; j++; }while( (z[i]&0xc0)==0x80 );
14311
+ continue;
14312
+ }
14313
+ if( z[i]=='\t' ){
14314
+ do{
14315
+ n++;
14316
+ j++;
14317
+ }while( (n&7)!=0 && n<mxWidth );
14318
+ i++;
14319
+ continue;
14320
+ }
14321
+ break;
14322
+ }
14323
+ if( n>=mxWidth && bWordWrap ){
14324
+ /* Perhaps try to back up to a better place to break the line */
14325
+ for(k=i; k>i/2; k--){
14326
+ if( isspace(z[k-1]) ) break;
14327
+ }
14328
+ if( k<=i/2 ){
14329
+ for(k=i; k>i/2; k--){
14330
+ if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
14331
+ }
14332
+ }
14333
+ if( k<=i/2 ){
14334
+ k = i;
14335
+ }else{
14336
+ i = k;
14337
+ while( z[i]==' ' ) i++;
14338
+ }
14339
+ }else{
14340
+ k = i;
14341
+ }
14342
+ if( n>=mxWidth && z[i]>=' ' ){
14343
+ *pzTail = &z[i];
14344
+ }else if( z[i]=='\r' && z[i+1]=='\n' ){
14345
+ *pzTail = z[i+2] ? &z[i+2] : 0;
14346
+ }else if( z[i]==0 || z[i+1]==0 ){
14347
+ *pzTail = 0;
14348
+ }else{
14349
+ *pzTail = &z[i+1];
14350
+ }
14351
+ zOut = malloc( j+1 );
14352
+ shell_check_oom(zOut);
14353
+ i = j = n = 0;
14354
+ while( i<k ){
14355
+ if( z[i]>=' ' ){
14356
+ n++;
14357
+ do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 );
14358
+ continue;
14359
+ }
14360
+ if( z[i]=='\t' ){
14361
+ do{
14362
+ n++;
14363
+ zOut[j++] = ' ';
14364
+ }while( (n&7)!=0 && n<mxWidth );
14365
+ i++;
14366
+ continue;
14367
+ }
14368
+ break;
14369
+ }
14370
+ zOut[j] = 0;
14371
+ return (char*)zOut;
14372
+}
14373
+
14374
+/* Extract the value of the i-th current column for pStmt as an SQL literal
14375
+** value. Memory is obtained from sqlite3_malloc64() and must be freed by
14376
+** the caller.
14377
+*/
14378
+static char *quoted_column(sqlite3_stmt *pStmt, int i){
14379
+ switch( sqlite3_column_type(pStmt, i) ){
14380
+ case SQLITE_NULL: {
14381
+ return sqlite3_mprintf("NULL");
14382
+ }
14383
+ case SQLITE_INTEGER:
14384
+ case SQLITE_FLOAT: {
14385
+ return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
14386
+ }
14387
+ case SQLITE_TEXT: {
14388
+ return sqlite3_mprintf("%Q",sqlite3_column_text(pStmt,i));
14389
+ }
14390
+ case SQLITE_BLOB: {
14391
+ int j;
14392
+ sqlite3_str *pStr = sqlite3_str_new(0);
14393
+ const unsigned char *a = sqlite3_column_blob(pStmt,i);
14394
+ int n = sqlite3_column_bytes(pStmt,i);
14395
+ sqlite3_str_append(pStr, "x'", 2);
14396
+ for(j=0; j<n; j++){
14397
+ sqlite3_str_appendf(pStr, "%02x", a[j]);
14398
+ }
14399
+ sqlite3_str_append(pStr, "'", 1);
14400
+ return sqlite3_str_finish(pStr);
14401
+ }
14402
+ }
14403
+ return 0; /* Not reached */
14404
+}
1424014405
1424114406
/*
1424214407
** Run a prepared statement and output the result in one of the
1424314408
** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
1424414409
** or MODE_Box.
@@ -14254,39 +14419,41 @@
1425414419
){
1425514420
sqlite3_int64 nRow = 0;
1425614421
int nColumn = 0;
1425714422
char **azData = 0;
1425814423
sqlite3_int64 nAlloc = 0;
14424
+ char *abRowDiv = 0;
14425
+ const unsigned char *uz;
1425914426
const char *z;
14427
+ char **azQuoted = 0;
1426014428
int rc;
1426114429
sqlite3_int64 i, nData;
1426214430
int j, nTotal, w, n;
1426314431
const char *colSep = 0;
1426414432
const char *rowSep = 0;
14433
+ const unsigned char **azNextLine = 0;
14434
+ int bNextLine = 0;
14435
+ int bMultiLineRowExists = 0;
14436
+ int bw = p->cmOpts.bWordWrap;
1426514437
1426614438
rc = sqlite3_step(pStmt);
1426714439
if( rc!=SQLITE_ROW ) return;
1426814440
nColumn = sqlite3_column_count(pStmt);
1426914441
nAlloc = nColumn*4;
1427014442
if( nAlloc<=0 ) nAlloc = 1;
1427114443
azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
1427214444
shell_check_oom(azData);
14273
- for(i=0; i<nColumn; i++){
14274
- azData[i] = strdup(sqlite3_column_name(pStmt,i));
14275
- }
14276
- do{
14277
- if( (nRow+2)*nColumn >= nAlloc ){
14278
- nAlloc *= 2;
14279
- azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14280
- shell_check_oom(azData);
14281
- }
14282
- nRow++;
14283
- for(i=0; i<nColumn; i++){
14284
- z = (const char*)sqlite3_column_text(pStmt,i);
14285
- azData[nRow*nColumn + i] = z ? strdup(z) : 0;
14286
- }
14287
- }while( sqlite3_step(pStmt)==SQLITE_ROW );
14445
+ azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
14446
+ shell_check_oom((void*)azNextLine);
14447
+ memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
14448
+ if( p->cmOpts.bQuote ){
14449
+ azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
14450
+ shell_check_oom(azQuoted);
14451
+ memset(azQuoted, 0, nColumn*sizeof(char*) );
14452
+ }
14453
+ abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
14454
+ shell_check_oom(abRowDiv);
1428814455
if( nColumn>p->nWidth ){
1428914456
p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
1429014457
shell_check_oom(p->colWidth);
1429114458
for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
1429214459
p->nWidth = nColumn;
@@ -14296,10 +14463,56 @@
1429614463
for(i=0; i<nColumn; i++){
1429714464
w = p->colWidth[i];
1429814465
if( w<0 ) w = -w;
1429914466
p->actualWidth[i] = w;
1430014467
}
14468
+ for(i=0; i<nColumn; i++){
14469
+ const unsigned char *zNotUsed;
14470
+ int wx = p->colWidth[i];
14471
+ if( wx==0 ){
14472
+ wx = p->cmOpts.iWrap;
14473
+ }
14474
+ if( wx<0 ) wx = -wx;
14475
+ uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
14476
+ azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw);
14477
+ }
14478
+ do{
14479
+ int useNextLine = bNextLine;
14480
+ bNextLine = 0;
14481
+ if( (nRow+2)*nColumn >= nAlloc ){
14482
+ nAlloc *= 2;
14483
+ azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14484
+ shell_check_oom(azData);
14485
+ abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
14486
+ shell_check_oom(abRowDiv);
14487
+ }
14488
+ abRowDiv[nRow] = 1;
14489
+ nRow++;
14490
+ for(i=0; i<nColumn; i++){
14491
+ int wx = p->colWidth[i];
14492
+ if( wx==0 ){
14493
+ wx = p->cmOpts.iWrap;
14494
+ }
14495
+ if( wx<0 ) wx = -wx;
14496
+ if( useNextLine ){
14497
+ uz = azNextLine[i];
14498
+ }else if( p->cmOpts.bQuote ){
14499
+ sqlite3_free(azQuoted[i]);
14500
+ azQuoted[i] = quoted_column(pStmt,i);
14501
+ uz = (const unsigned char*)azQuoted[i];
14502
+ }else{
14503
+ uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14504
+ }
14505
+ azData[nRow*nColumn + i]
14506
+ = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14507
+ if( azNextLine[i] ){
14508
+ bNextLine = 1;
14509
+ abRowDiv[nRow-1] = 0;
14510
+ bMultiLineRowExists = 1;
14511
+ }
14512
+ }
14513
+ }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
1430114514
nTotal = nColumn*(nRow+1);
1430214515
for(i=0; i<nTotal; i++){
1430314516
z = azData[i];
1430414517
if( z==0 ) z = p->nullValue;
1430514518
n = strlenChar(z);
@@ -14378,10 +14591,19 @@
1437814591
w = p->actualWidth[j];
1437914592
if( p->colWidth[j]<0 ) w = -w;
1438014593
utf8_width_print(p->out, w, z);
1438114594
if( j==nColumn-1 ){
1438214595
utf8_printf(p->out, "%s", rowSep);
14596
+ if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
14597
+ if( p->cMode==MODE_Table ){
14598
+ print_row_separator(p, nColumn, "+");
14599
+ }else if( p->cMode==MODE_Box ){
14600
+ print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
14601
+ }else if( p->cMode==MODE_Column ){
14602
+ raw_printf(p->out, "\n");
14603
+ }
14604
+ }
1438314605
j = -1;
1438414606
if( seenInterrupt ) goto columnar_end;
1438514607
}else{
1438614608
utf8_printf(p->out, "%s", colSep);
1438714609
}
@@ -14396,10 +14618,16 @@
1439614618
utf8_printf(p->out, "Interrupt\n");
1439714619
}
1439814620
nData = (nRow+1)*nColumn;
1439914621
for(i=0; i<nData; i++) free(azData[i]);
1440014622
sqlite3_free(azData);
14623
+ sqlite3_free((void*)azNextLine);
14624
+ sqlite3_free(abRowDiv);
14625
+ if( azQuoted ){
14626
+ for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
14627
+ sqlite3_free(azQuoted);
14628
+ }
1440114629
}
1440214630
1440314631
/*
1440414632
** Run a prepared statement
1440514633
*/
@@ -14648,11 +14876,11 @@
1464814876
while( zSql[0] && (SQLITE_OK == rc) ){
1464914877
static const char *zStmtSql;
1465014878
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1465114879
if( SQLITE_OK != rc ){
1465214880
if( pzErrMsg ){
14653
- *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)%s", rc, zSql);
14881
+ *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
1465414882
}
1465514883
}else{
1465614884
if( !pStmt ){
1465714885
/* this happens for a comment or white-space */
1465814886
zSql = zLeftover;
@@ -14764,11 +14992,11 @@
1476414992
if( rc!=SQLITE_NOMEM ) rc = rc2;
1476514993
if( rc==SQLITE_OK ){
1476614994
zSql = zLeftover;
1476714995
while( IsSpace(zSql[0]) ) zSql++;
1476814996
}else if( pzErrMsg ){
14769
- *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc, 0);
14997
+ *pzErrMsg = save_err_msg(db, "stepping", rc, 0);
1477014998
}
1477114999
1477215000
/* clear saved stmt handle */
1477315001
if( pArg ){
1477415002
pArg->pStmt = NULL;
@@ -15103,10 +15331,11 @@
1510315331
#endif
1510415332
#ifndef SQLITE_OMIT_AUTHORIZATION
1510515333
".auth ON|OFF Show authorizer callbacks",
1510615334
#endif
1510715335
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15336
+ " Options:",
1510815337
" --append Use the appendvfs",
1510915338
" --async Write to FILE without journal and fsync()",
1511015339
".bail on|off Stop after hitting an error. Default OFF",
1511115340
".binary on|off Turn binary output on or off. Default OFF",
1511215341
".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15147,10 +15376,11 @@
1514715376
".import FILE TABLE Import data from FILE into TABLE",
1514815377
" Options:",
1514915378
" --ascii Use \\037 and \\036 as column and row separators",
1515015379
" --csv Use , and \\n as column and row separators",
1515115380
" --skip N Skip the first N rows of input",
15381
+ " --schema S Target table to be S.TABLE",
1515215382
" -v \"Verbose\" - increase auxiliary output",
1515315383
" Notes:",
1515415384
" * If TABLE does not exist, it is created. The first row of input",
1515515385
" determines the column names.",
1515615386
" * If neither --csv or --ascii are used, the input mode is derived",
@@ -15172,27 +15402,35 @@
1517215402
" fkey-indexes Find missing foreign key indexes",
1517315403
#ifndef SQLITE_OMIT_LOAD_EXTENSION
1517415404
".load FILE ?ENTRY? Load an extension library",
1517515405
#endif
1517615406
".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15177
- ".mode MODE ?TABLE? Set output mode",
15407
+ ".mode MODE ?OPTIONS? Set output mode",
1517815408
" MODE is one of:",
15179
- " ascii Columns/rows delimited by 0x1F and 0x1E",
15180
- " box Tables using unicode box-drawing characters",
15181
- " csv Comma-separated values",
15182
- " column Output in columns. (See .width)",
15183
- " html HTML <table> code",
15184
- " insert SQL insert statements for TABLE",
15185
- " json Results in a JSON array",
15186
- " line One value per line",
15187
- " list Values delimited by \"|\"",
15188
- " markdown Markdown table format",
15189
- " quote Escape answers as for SQL",
15190
- " table ASCII-art table",
15191
- " tabs Tab-separated values",
15192
- " tcl TCL list elements",
15193
- ".nonce STRING Disable safe mode for one command if the nonce matches",
15409
+ " ascii Columns/rows delimited by 0x1F and 0x1E",
15410
+ " box Tables using unicode box-drawing characters",
15411
+ " csv Comma-separated values",
15412
+ " column Output in columns. (See .width)",
15413
+ " html HTML <table> code",
15414
+ " insert SQL insert statements for TABLE",
15415
+ " json Results in a JSON array",
15416
+ " line One value per line",
15417
+ " list Values delimited by \"|\"",
15418
+ " markdown Markdown table format",
15419
+ " qbox Shorthand for \"box --width 60 --quote\"",
15420
+ " quote Escape answers as for SQL",
15421
+ " table ASCII-art table",
15422
+ " tabs Tab-separated values",
15423
+ " tcl TCL list elements",
15424
+ " OPTIONS: (for columnar modes or insert mode):",
15425
+ " --wrap N Wrap output lines to no longer than N characters",
15426
+ " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15427
+ " --ww Shorthand for \"--wordwrap 1\"",
15428
+ " --quote Quote output text as SQL literals",
15429
+ " --noquote Do not quote output text",
15430
+ " TABLE The name of SQL table used for \"insert\" mode",
15431
+ ".nonce STRING Suspend safe mode for one command if nonce matches",
1519415432
".nullvalue STRING Use STRING in place of NULL values",
1519515433
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
1519615434
" If FILE begins with '|' then open as a pipe",
1519715435
" --bom Put a UTF8 byte-order mark at the beginning",
1519815436
" -e Send output to the system text editor",
@@ -15241,11 +15479,11 @@
1524115479
" --lost-and-found TABLE Alternative name for the lost-and-found table",
1524215480
" --no-rowids Do not attempt to recover rowid values",
1524315481
" that are not also INTEGER PRIMARY KEYs",
1524415482
#endif
1524515483
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15246
- ".save FILE Write in-memory database into FILE",
15484
+ ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
1524715485
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
1524815486
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
1524915487
" Options:",
1525015488
" --indent Try to pretty-print the schema",
1525115489
" --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15845,12 +16083,14 @@
1584516083
sqlite3_series_init(p->db, 0, 0);
1584616084
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1584716085
sqlite3_dbdata_init(p->db, 0, 0);
1584816086
#endif
1584916087
#ifdef SQLITE_HAVE_ZLIB
15850
- sqlite3_zipfile_init(p->db, 0, 0);
15851
- sqlite3_sqlar_init(p->db, 0, 0);
16088
+ if( !p->bSafeModePersist ){
16089
+ sqlite3_zipfile_init(p->db, 0, 0);
16090
+ sqlite3_sqlar_init(p->db, 0, 0);
16091
+ }
1585216092
#endif
1585316093
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
1585416094
shellAddSchemaName, 0, 0);
1585516095
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
1585616096
shellModuleSchema, 0, 0);
@@ -16605,14 +16845,14 @@
1660516845
}
1660616846
1660716847
/*
1660816848
** Run an SQL command and return the single integer result.
1660916849
*/
16610
-static int db_int(ShellState *p, const char *zSql){
16850
+static int db_int(sqlite3 *db, const char *zSql){
1661116851
sqlite3_stmt *pStmt;
1661216852
int res = 0;
16613
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
16853
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
1661416854
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
1661516855
res = sqlite3_column_int(pStmt,0);
1661616856
}
1661716857
sqlite3_finalize(pStmt);
1661816858
return res;
@@ -16713,11 +16953,11 @@
1671316953
}else{
1671416954
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
1671516955
}
1671616956
for(i=0; i<ArraySize(aQuery); i++){
1671716957
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16718
- int val = db_int(p, zSql);
16958
+ int val = db_int(p->db, zSql);
1671916959
sqlite3_free(zSql);
1672016960
utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
1672116961
}
1672216962
sqlite3_free(zSchemaTab);
1672316963
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18076,10 +18316,11 @@
1807618316
*pRc = SQLITE_NOMEM;
1807718317
}
1807818318
}
1807918319
return z;
1808018320
}
18321
+
1808118322
1808218323
/*
1808318324
** When running the ".recover" command, each output table, and the special
1808418325
** orphaned row table if it is required, is represented by an instance
1808518326
** of the following struct.
@@ -18673,10 +18914,225 @@
1867318914
sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
1867418915
return rc;
1867518916
}
1867618917
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
1867718918
18919
+
18920
+/*
18921
+ * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18922
+ * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18923
+ * close db and set it to 0, and return the columns spec, to later
18924
+ * be sqlite3_free()'ed by the caller.
18925
+ * The return is 0 when either:
18926
+ * (a) The db was not initialized and zCol==0 (There are no columns.)
18927
+ * (b) zCol!=0 (Column was added, db initialized as needed.)
18928
+ * The 3rd argument, pRenamed, references an out parameter. If the
18929
+ * pointer is non-zero, its referent will be set to a summary of renames
18930
+ * done if renaming was necessary, or set to 0 if none was done. The out
18931
+ * string (if any) must be sqlite3_free()'ed by the caller.
18932
+ */
18933
+#ifdef SHELL_DEBUG
18934
+#define rc_err_oom_die(rc) \
18935
+ if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
18936
+ else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
18937
+ fprintf(stderr,"E:%d\n",rc), assert(0)
18938
+#else
18939
+static void rc_err_oom_die(int rc){
18940
+ if( rc==SQLITE_NOMEM ) shell_check_oom(0);
18941
+ assert(rc==SQLITE_OK||rc==SQLITE_DONE);
18942
+}
18943
+#endif
18944
+
18945
+#ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
18946
+static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB);
18947
+#else /* Otherwise, memory is faster/better for the transient DB. */
18948
+static const char *zCOL_DB = ":memory:";
18949
+#endif
18950
+
18951
+/* Define character (as C string) to separate generated column ordinal
18952
+ * from protected part of incoming column names. This defaults to "_"
18953
+ * so that incoming column identifiers that did not need not be quoted
18954
+ * remain usable without being quoted. It must be one character.
18955
+ */
18956
+#ifndef SHELL_AUTOCOLUMN_SEP
18957
+# define AUTOCOLUMN_SEP "_"
18958
+#else
18959
+# define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
18960
+#endif
18961
+
18962
+static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){
18963
+ /* Queries and D{D,M}L used here */
18964
+ static const char * const zTabMake = "\
18965
+CREATE TABLE ColNames(\
18966
+ cpos INTEGER PRIMARY KEY,\
18967
+ name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\
18968
+CREATE VIEW RepeatedNames AS \
18969
+SELECT DISTINCT t.name FROM ColNames t \
18970
+WHERE t.name COLLATE NOCASE IN (\
18971
+ SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\
18972
+);\
18973
+";
18974
+ static const char * const zTabFill = "\
18975
+INSERT INTO ColNames(name,nlen,chop,reps,suff)\
18976
+ VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
18977
+";
18978
+ static const char * const zHasDupes = "\
18979
+SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
18980
+ <count(name) FROM ColNames\
18981
+";
18982
+#ifdef SHELL_COLUMN_RENAME_CLEAN
18983
+ static const char * const zDedoctor = "\
18984
+UPDATE ColNames SET chop=iif(\
18985
+ (substring(name,nlen,1) BETWEEN '0' AND '9')\
18986
+ AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\
18987
+ nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\
18988
+ 0\
18989
+)\
18990
+";
18991
+#endif
18992
+ static const char * const zSetReps = "\
18993
+UPDATE ColNames AS t SET reps=\
18994
+(SELECT count(*) FROM ColNames d \
18995
+ WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
18996
+ COLLATE NOCASE\
18997
+)\
18998
+";
18999
+#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19000
+ static const char * const zColDigits = "\
19001
+SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19002
+";
19003
+#endif
19004
+ static const char * const zRenameRank =
19005
+#ifdef SHELL_COLUMN_RENAME_CLEAN
19006
+ "UPDATE ColNames AS t SET suff="
19007
+ "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
19008
+#else /* ...RENAME_MINIMAL_ONE_PASS */
19009
+"WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */
19010
+" SELECT 0 AS nlz"
19011
+" UNION"
19012
+" SELECT nlz+1 AS nlz FROM Lzn"
19013
+" WHERE EXISTS("
19014
+" SELECT 1"
19015
+" FROM ColNames t, ColNames o"
19016
+" WHERE"
19017
+" iif(t.name IN (SELECT * FROM RepeatedNames),"
19018
+" printf('%s"AUTOCOLUMN_SEP"%s',"
19019
+" t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2)),"
19020
+" t.name"
19021
+" )"
19022
+" ="
19023
+" iif(o.name IN (SELECT * FROM RepeatedNames),"
19024
+" printf('%s"AUTOCOLUMN_SEP"%s',"
19025
+" o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2)),"
19026
+" o.name"
19027
+" )"
19028
+" COLLATE NOCASE"
19029
+" AND o.cpos<>t.cpos"
19030
+" GROUP BY t.cpos"
19031
+" )"
19032
+") UPDATE Colnames AS t SET"
19033
+" chop = 0," /* No chopping, never touch incoming names. */
19034
+" suff = iif(name IN (SELECT * FROM RepeatedNames),"
19035
+" printf('"AUTOCOLUMN_SEP"%s', substring("
19036
+" printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2)),"
19037
+" ''"
19038
+" )"
19039
+#endif
19040
+ ;
19041
+ static const char * const zCollectVar = "\
19042
+SELECT\
19043
+ '('||x'0a'\
19044
+ || group_concat(\
19045
+ cname||' TEXT',\
19046
+ ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19047
+ ||')' AS ColsSpec \
19048
+FROM (\
19049
+ SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19050
+ FROM ColNames ORDER BY cpos\
19051
+)";
19052
+ static const char * const zRenamesDone =
19053
+ "SELECT group_concat("
19054
+ " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19055
+ " ','||x'0a')"
19056
+ "FROM ColNames WHERE suff<>'' OR chop!=0"
19057
+ ;
19058
+ int rc;
19059
+ sqlite3_stmt *pStmt = 0;
19060
+ assert(pDb!=0);
19061
+ if( zColNew ){
19062
+ /* Add initial or additional column. Init db if necessary. */
19063
+ if( *pDb==0 ){
19064
+ if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
19065
+#ifdef SHELL_COLFIX_DB
19066
+ if(*zCOL_DB!=':')
19067
+ sqlite3_exec(*pDb,"drop table if exists ColNames;"
19068
+ "drop view if exists RepeatedNames;",0,0,0);
19069
+#endif
19070
+ rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
19071
+ rc_err_oom_die(rc);
19072
+ }
19073
+ assert(*pDb!=0);
19074
+ rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
19075
+ rc_err_oom_die(rc);
19076
+ rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
19077
+ rc_err_oom_die(rc);
19078
+ rc = sqlite3_step(pStmt);
19079
+ rc_err_oom_die(rc);
19080
+ sqlite3_finalize(pStmt);
19081
+ return 0;
19082
+ }else if( *pDb==0 ){
19083
+ return 0;
19084
+ }else{
19085
+ /* Formulate the columns spec, close the DB, zero *pDb. */
19086
+ char *zColsSpec = 0;
19087
+ int hasDupes = db_int(*pDb, zHasDupes);
19088
+#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19089
+ int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090
+#else
19091
+# define nDigits 2
19092
+#endif
19093
+ if( hasDupes ){
19094
+#ifdef SHELL_COLUMN_RENAME_CLEAN
19095
+ rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19096
+ rc_err_oom_die(rc);
19097
+#endif
19098
+ rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
19099
+ rc_err_oom_die(rc);
19100
+ rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
19101
+ rc_err_oom_die(rc);
19102
+ sqlite3_bind_int(pStmt, 1, nDigits);
19103
+ rc = sqlite3_step(pStmt);
19104
+ sqlite3_finalize(pStmt);
19105
+ assert(rc==SQLITE_DONE);
19106
+ }
19107
+ assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
19108
+ rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
19109
+ rc_err_oom_die(rc);
19110
+ rc = sqlite3_step(pStmt);
19111
+ if( rc==SQLITE_ROW ){
19112
+ zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19113
+ }else{
19114
+ zColsSpec = 0;
19115
+ }
19116
+ if( pzRenamed!=0 ){
19117
+ if( !hasDupes ) *pzRenamed = 0;
19118
+ else{
19119
+ sqlite3_finalize(pStmt);
19120
+ if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0)
19121
+ && SQLITE_ROW==sqlite3_step(pStmt) ){
19122
+ *pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19123
+ }else
19124
+ *pzRenamed = 0;
19125
+ }
19126
+ }
19127
+ sqlite3_finalize(pStmt);
19128
+ sqlite3_close(*pDb);
19129
+ *pDb = 0;
19130
+ return zColsSpec;
19131
+ }
19132
+}
19133
+
1867819134
/*
1867919135
** If an input line begins with "." then invoke this routine to
1868019136
** process that line.
1868119137
**
1868219138
** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19459,23 +19915,26 @@
1945919915
}
1946019916
}else
1946119917
1946219918
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
1946319919
char *zTable = 0; /* Insert data into this table */
19920
+ char *zSchema = 0; /* within this schema (may default to "main") */
1946419921
char *zFile = 0; /* Name of file to extra content from */
1946519922
sqlite3_stmt *pStmt = NULL; /* A statement */
1946619923
int nCol; /* Number of columns in the table */
1946719924
int nByte; /* Number of bytes in an SQL string */
1946819925
int i, j; /* Loop counters */
1946919926
int needCommit; /* True to COMMIT or ROLLBACK at end */
1947019927
int nSep; /* Number of bytes in p->colSeparator[] */
1947119928
char *zSql; /* An SQL statement */
19929
+ char *zFullTabName; /* Table name with schema if applicable */
1947219930
ImportCtx sCtx; /* Reader context */
1947319931
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
1947419932
int eVerbose = 0; /* Larger for more console output */
1947519933
int nSkip = 0; /* Initial lines to skip */
1947619934
int useOutputMode = 1; /* Use output mode to determine separators */
19935
+ char *zCreate = 0; /* CREATE TABLE statement text */
1947719936
1947819937
failIfSafeMode(p, "cannot run .import in safe mode");
1947919938
memset(&sCtx, 0, sizeof(sCtx));
1948019939
sCtx.z = sqlite3_malloc64(120);
1948119940
if( sCtx.z==0 ){
@@ -19501,10 +19960,12 @@
1950119960
rc = 1;
1950219961
goto meta_command_exit;
1950319962
}
1950419963
}else if( strcmp(z,"-v")==0 ){
1950519964
eVerbose++;
19965
+ }else if( strcmp(z,"-schema")==0 && i<nArg-1 ){
19966
+ zSchema = azArg[++i];
1950619967
}else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
1950719968
nSkip = integerValue(azArg[++i]);
1950819969
}else if( strcmp(z,"-ascii")==0 ){
1950919970
sCtx.cColSep = SEP_Unit[0];
1951019971
sCtx.cRowSep = SEP_Record[0];
@@ -19603,69 +20064,83 @@
1960320064
utf8_printf(p->out, ", row separator ");
1960420065
zSep[0] = sCtx.cRowSep;
1960520066
output_c_string(p->out, zSep);
1960620067
utf8_printf(p->out, "\n");
1960720068
}
20069
+ /* Below, resources must be freed before exit. */
1960820070
while( (nSkip--)>0 ){
1960920071
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
1961020072
}
19611
- zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
19612
- if( zSql==0 ){
20073
+ if( zSchema!=0 ){
20074
+ zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
20075
+ }else{
20076
+ zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
20077
+ }
20078
+ zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
20079
+ if( zSql==0 || zFullTabName==0 ){
1961320080
import_cleanup(&sCtx);
1961420081
shell_out_of_memory();
1961520082
}
1961620083
nByte = strlen30(zSql);
1961720084
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1961820085
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
1961920086
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
19620
- char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
19621
- char cSep = '(';
19622
- while( xRead(&sCtx) ){
19623
- zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
19624
- cSep = ',';
19625
- if( sCtx.cTerm!=sCtx.cColSep ) break;
19626
- }
19627
- if( cSep=='(' ){
19628
- sqlite3_free(zCreate);
19629
- import_cleanup(&sCtx);
19630
- utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
19631
- rc = 1;
19632
- goto meta_command_exit;
19633
- }
19634
- zCreate = sqlite3_mprintf("%z\n)", zCreate);
19635
- if( eVerbose>=1 ){
19636
- utf8_printf(p->out, "%s\n", zCreate);
19637
- }
19638
- rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
19639
- sqlite3_free(zCreate);
19640
- if( rc ){
19641
- utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
19642
- sqlite3_errmsg(p->db));
19643
- import_cleanup(&sCtx);
19644
- rc = 1;
19645
- goto meta_command_exit;
19646
- }
19647
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19648
- }
19649
- sqlite3_free(zSql);
19650
- if( rc ){
19651
- if (pStmt) sqlite3_finalize(pStmt);
19652
- utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
19653
- import_cleanup(&sCtx);
19654
- rc = 1;
19655
- goto meta_command_exit;
19656
- }
20087
+ sqlite3 *dbCols = 0;
20088
+ char *zRenames = 0;
20089
+ char *zColDefs;
20090
+ zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
20091
+ while( xRead(&sCtx) ){
20092
+ zAutoColumn(sCtx.z, &dbCols, 0);
20093
+ if( sCtx.cTerm!=sCtx.cColSep ) break;
20094
+ }
20095
+ zColDefs = zAutoColumn(0, &dbCols, &zRenames);
20096
+ if( zRenames!=0 ){
20097
+ utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
20098
+ "Columns renamed during .import %s due to duplicates:\n"
20099
+ "%s\n", sCtx.zFile, zRenames);
20100
+ sqlite3_free(zRenames);
20101
+ }
20102
+ assert(dbCols==0);
20103
+ if( zColDefs==0 ){
20104
+ utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
20105
+ import_fail:
20106
+ sqlite3_free(zCreate);
20107
+ sqlite3_free(zSql);
20108
+ sqlite3_free(zFullTabName);
20109
+ import_cleanup(&sCtx);
20110
+ rc = 1;
20111
+ goto meta_command_exit;
20112
+ }
20113
+ zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
20114
+ if( eVerbose>=1 ){
20115
+ utf8_printf(p->out, "%s\n", zCreate);
20116
+ }
20117
+ rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
20118
+ if( rc ){
20119
+ utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
20120
+ goto import_fail;
20121
+ }
20122
+ sqlite3_free(zCreate);
20123
+ zCreate = 0;
20124
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
20125
+ }
20126
+ if( rc ){
20127
+ if (pStmt) sqlite3_finalize(pStmt);
20128
+ utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
20129
+ goto import_fail;
20130
+ }
20131
+ sqlite3_free(zSql);
1965720132
nCol = sqlite3_column_count(pStmt);
1965820133
sqlite3_finalize(pStmt);
1965920134
pStmt = 0;
1966020135
if( nCol==0 ) return 0; /* no columns, no error */
1966120136
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
1966220137
if( zSql==0 ){
1966320138
import_cleanup(&sCtx);
1966420139
shell_out_of_memory();
1966520140
}
19666
- sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
20141
+ sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
1966720142
j = strlen30(zSql);
1966820143
for(i=1; i<nCol; i++){
1966920144
zSql[j++] = ',';
1967020145
zSql[j++] = '?';
1967120146
}
@@ -19673,18 +20148,17 @@
1967320148
zSql[j] = 0;
1967420149
if( eVerbose>=2 ){
1967520150
utf8_printf(p->out, "Insert using: %s\n", zSql);
1967620151
}
1967720152
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19678
- sqlite3_free(zSql);
1967920153
if( rc ){
1968020154
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1968120155
if (pStmt) sqlite3_finalize(pStmt);
19682
- import_cleanup(&sCtx);
19683
- rc = 1;
19684
- goto meta_command_exit;
20156
+ goto import_fail;
1968520157
}
20158
+ sqlite3_free(zSql);
20159
+ sqlite3_free(zFullTabName);
1968620160
needCommit = sqlite3_get_autocommit(p->db);
1968720161
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1968820162
do{
1968920163
int startLine = sCtx.nLine;
1969020164
for(i=0; i<nCol; i++){
@@ -19962,68 +20436,127 @@
1996220436
p->pLog = output_file_open(zFile, 0);
1996320437
}
1996420438
}else
1996520439
1996620440
if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
19967
- const char *zMode = nArg>=2 ? azArg[1] : "";
19968
- int n2 = strlen30(zMode);
19969
- int c2 = zMode[0];
19970
- if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
20441
+ const char *zMode = 0;
20442
+ const char *zTabname = 0;
20443
+ int i, n2;
20444
+ ColModeOpts cmOpts = ColModeOpts_default;
20445
+ for(i=1; i<nArg; i++){
20446
+ const char *z = azArg[i];
20447
+ if( optionMatch(z,"wrap") && i+1<nArg ){
20448
+ cmOpts.iWrap = integerValue(azArg[++i]);
20449
+ }else if( optionMatch(z,"ww") ){
20450
+ cmOpts.bWordWrap = 1;
20451
+ }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
20452
+ cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
20453
+ }else if( optionMatch(z,"quote") ){
20454
+ cmOpts.bQuote = 1;
20455
+ }else if( optionMatch(z,"noquote") ){
20456
+ cmOpts.bQuote = 0;
20457
+ }else if( zMode==0 ){
20458
+ zMode = z;
20459
+ /* Apply defaults for qbox pseudo-mods. If that
20460
+ * overwrites already-set values, user was informed of this.
20461
+ */
20462
+ if( strcmp(z, "qbox")==0 ){
20463
+ ColModeOpts cmo = ColModeOpts_default_qbox;
20464
+ zMode = "box";
20465
+ cmOpts = cmo;
20466
+ }
20467
+ }else if( zTabname==0 ){
20468
+ zTabname = z;
20469
+ }else if( z[0]=='-' ){
20470
+ utf8_printf(stderr, "unknown option: %s\n", z);
20471
+ utf8_printf(stderr, "options:\n"
20472
+ " --noquote\n"
20473
+ " --quote\n"
20474
+ " --wordwrap on/off\n"
20475
+ " --wrap N\n"
20476
+ " --ww\n");
20477
+ rc = 1;
20478
+ goto meta_command_exit;
20479
+ }else{
20480
+ utf8_printf(stderr, "extra argument: \"%s\"\n", z);
20481
+ rc = 1;
20482
+ goto meta_command_exit;
20483
+ }
20484
+ }
20485
+ if( zMode==0 ){
20486
+ if( p->mode==MODE_Column
20487
+ || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
20488
+ ){
20489
+ raw_printf
20490
+ (p->out,
20491
+ "current output mode: %s --wrap %d --wordwrap %s --%squote\n",
20492
+ modeDescr[p->mode], p->cmOpts.iWrap,
20493
+ p->cmOpts.bWordWrap ? "on" : "off",
20494
+ p->cmOpts.bQuote ? "" : "no");
20495
+ }else{
20496
+ raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20497
+ }
20498
+ zMode = modeDescr[p->mode];
20499
+ }
20500
+ n2 = strlen30(zMode);
20501
+ if( strncmp(zMode,"lines",n2)==0 ){
1997120502
p->mode = MODE_Line;
1997220503
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19973
- }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
20504
+ }else if( strncmp(zMode,"columns",n2)==0 ){
1997420505
p->mode = MODE_Column;
1997520506
if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
1997620507
p->showHeader = 1;
1997720508
}
1997820509
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19979
- }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
20510
+ p->cmOpts = cmOpts;
20511
+ }else if( strncmp(zMode,"list",n2)==0 ){
1998020512
p->mode = MODE_List;
1998120513
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
1998220514
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19983
- }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
20515
+ }else if( strncmp(zMode,"html",n2)==0 ){
1998420516
p->mode = MODE_Html;
19985
- }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
20517
+ }else if( strncmp(zMode,"tcl",n2)==0 ){
1998620518
p->mode = MODE_Tcl;
1998720519
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
1998820520
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19989
- }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
20521
+ }else if( strncmp(zMode,"csv",n2)==0 ){
1999020522
p->mode = MODE_Csv;
1999120523
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
1999220524
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
19993
- }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
20525
+ }else if( strncmp(zMode,"tabs",n2)==0 ){
1999420526
p->mode = MODE_List;
1999520527
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
19996
- }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
20528
+ }else if( strncmp(zMode,"insert",n2)==0 ){
1999720529
p->mode = MODE_Insert;
19998
- set_table_name(p, nArg>=3 ? azArg[2] : "table");
19999
- }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
20530
+ set_table_name(p, zTabname ? zTabname : "table");
20531
+ }else if( strncmp(zMode,"quote",n2)==0 ){
2000020532
p->mode = MODE_Quote;
2000120533
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
2000220534
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20003
- }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
20535
+ }else if( strncmp(zMode,"ascii",n2)==0 ){
2000420536
p->mode = MODE_Ascii;
2000520537
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
2000620538
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20007
- }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
20539
+ }else if( strncmp(zMode,"markdown",n2)==0 ){
2000820540
p->mode = MODE_Markdown;
20009
- }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
20541
+ p->cmOpts = cmOpts;
20542
+ }else if( strncmp(zMode,"table",n2)==0 ){
2001020543
p->mode = MODE_Table;
20011
- }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
20544
+ p->cmOpts = cmOpts;
20545
+ }else if( strncmp(zMode,"box",n2)==0 ){
2001220546
p->mode = MODE_Box;
20013
- }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
20547
+ p->cmOpts = cmOpts;
20548
+ }else if( strncmp(zMode,"count",n2)==0 ){
2001420549
p->mode = MODE_Count;
20015
- }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
20550
+ }else if( strncmp(zMode,"off",n2)==0 ){
2001620551
p->mode = MODE_Off;
20017
- }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
20552
+ }else if( strncmp(zMode,"json",n2)==0 ){
2001820553
p->mode = MODE_Json;
20019
- }else if( nArg==1 ){
20020
- raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
2002120554
}else{
2002220555
raw_printf(stderr, "Error: mode should be one of: "
2002320556
"ascii box column csv html insert json line list markdown "
20024
- "quote table tabs tcl\n");
20557
+ "qbox quote table tabs tcl\n");
2002520558
rc = 1;
2002620559
}
2002720560
p->cMode = p->mode;
2002820561
}else
2002920562
@@ -20144,13 +20677,14 @@
2014420677
){
2014520678
char *zFile = 0;
2014620679
int bTxtMode = 0;
2014720680
int i;
2014820681
int eMode = 0;
20149
- int bBOM = 0;
20150
- int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20682
+ int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20683
+ unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */
2015120684
20685
+ zBOM[0] = 0;
2015220686
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
2015320687
if( c=='e' ){
2015420688
eMode = 'x';
2015520689
bOnce = 2;
2015620690
}else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20159,11 +20693,14 @@
2015920693
for(i=1; i<nArg; i++){
2016020694
char *z = azArg[i];
2016120695
if( z[0]=='-' ){
2016220696
if( z[1]=='-' ) z++;
2016320697
if( strcmp(z,"-bom")==0 ){
20164
- bBOM = 1;
20698
+ zBOM[0] = 0xef;
20699
+ zBOM[1] = 0xbb;
20700
+ zBOM[2] = 0xbf;
20701
+ zBOM[3] = 0;
2016520702
}else if( c!='e' && strcmp(z,"-x")==0 ){
2016620703
eMode = 'x'; /* spreadsheet */
2016720704
}else if( c!='e' && strcmp(z,"-e")==0 ){
2016820705
eMode = 'e'; /* text editor */
2016920706
}else{
@@ -20228,11 +20765,11 @@
2022820765
if( p->out==0 ){
2022920766
utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
2023020767
p->out = stdout;
2023120768
rc = 1;
2023220769
}else{
20233
- if( bBOM ) fprintf(p->out,"\357\273\277");
20770
+ if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
2023420771
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
2023520772
}
2023620773
#endif
2023720774
}else{
2023820775
p->out = output_file_open(zFile, bTxtMode);
@@ -20241,11 +20778,11 @@
2024120778
utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
2024220779
}
2024320780
p->out = stdout;
2024420781
rc = 1;
2024520782
} else {
20246
- if( bBOM ) fprintf(p->out,"\357\273\277");
20783
+ if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
2024720784
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
2024820785
}
2024920786
}
2025020787
sqlite3_free(zFile);
2025120788
}else
@@ -21167,11 +21704,21 @@
2116721704
azBool[ShellHasFlag(p, SHFLG_Echo)]);
2116821705
utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
2116921706
utf8_printf(p->out, "%12.12s: %s\n","explain",
2117021707
p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
2117121708
utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21172
- utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21709
+ if( p->mode==MODE_Column
21710
+ || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
21711
+ ){
21712
+ utf8_printf
21713
+ (p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
21714
+ modeDescr[p->mode], p->cmOpts.iWrap,
21715
+ p->cmOpts.bWordWrap ? "on" : "off",
21716
+ p->cmOpts.bQuote ? "" : "no");
21717
+ }else{
21718
+ utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21719
+ }
2117321720
utf8_printf(p->out, "%12.12s: ", "nullvalue");
2117421721
output_c_string(p->out, p->nullValue);
2117521722
raw_printf(p->out, "\n");
2117621723
utf8_printf(p->out,"%12.12s: %s\n","output",
2117721724
strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21965,23 +22512,34 @@
2196522512
BEGIN_TIMER;
2196622513
rc = shell_exec(p, zSql, &zErrMsg);
2196722514
END_TIMER;
2196822515
if( rc || zErrMsg ){
2196922516
char zPrefix[100];
22517
+ const char *zErrorTail;
22518
+ const char *zErrorType;
22519
+ if( zErrMsg==0 ){
22520
+ zErrorType = "Error";
22521
+ zErrorTail = sqlite3_errmsg(p->db);
22522
+ }else if( strncmp(zErrMsg, "in prepare, ",12)==0 ){
22523
+ zErrorType = "Parse error";
22524
+ zErrorTail = &zErrMsg[12];
22525
+ }else if( strncmp(zErrMsg, "stepping, ", 10)==0 ){
22526
+ zErrorType = "Runtime error";
22527
+ zErrorTail = &zErrMsg[10];
22528
+ }else{
22529
+ zErrorType = "Error";
22530
+ zErrorTail = zErrMsg;
22531
+ }
2197022532
if( in!=0 || !stdin_is_interactive ){
2197122533
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
21972
- "Error: near line %d:", startline);
21973
- }else{
21974
- sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
21975
- }
21976
- if( zErrMsg!=0 ){
21977
- utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
21978
- sqlite3_free(zErrMsg);
21979
- zErrMsg = 0;
21980
- }else{
21981
- utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
21982
- }
22534
+ "%s near line %d:", zErrorType, startline);
22535
+ }else{
22536
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
22537
+ }
22538
+ utf8_printf(stderr, "%s %s\n", zPrefix, zErrorTail);
22539
+ sqlite3_free(zErrMsg);
22540
+ zErrMsg = 0;
2198322541
return 1;
2198422542
}else if( ShellHasFlag(p, SHFLG_CountChanges) ){
2198522543
char zLineBuf[2000];
2198622544
sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
2198722545
"changes: %lld total_changes: %lld",
@@ -22010,10 +22568,17 @@
2201022568
int rc; /* Error code */
2201122569
int errCnt = 0; /* Number of errors seen */
2201222570
int startline = 0; /* Line number for start of current input */
2201322571
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
2201422572
22573
+ if( p->inputNesting==MAX_INPUT_NESTING ){
22574
+ /* This will be more informative in a later version. */
22575
+ utf8_printf(stderr,"Input nesting limit (%d) reached at line %d."
22576
+ " Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
22577
+ return 1;
22578
+ }
22579
+ ++p->inputNesting;
2201522580
p->lineno = 0;
2201622581
while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
2201722582
fflush(p->out);
2201822583
zLine = one_input_line(p->in, zLine, nSql>0);
2201922584
if( zLine==0 ){
@@ -22087,15 +22652,17 @@
2208722652
if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
2208822653
nSql = 0;
2208922654
qss = QSS_Start;
2209022655
}
2209122656
}
22092
- if( nSql && QSS_PLAINDARK(qss) ){
22657
+ if( nSql ){
22658
+ /* This may be incomplete. Let the SQL parser deal with that. */
2209322659
errCnt += runOneSqlLine(p, zSql, p->in, startline);
2209422660
}
2209522661
free(zSql);
2209622662
free(zLine);
22663
+ --p->inputNesting;
2209722664
return errCnt>0;
2209822665
}
2209922666
2210022667
/*
2210122668
** Return a pathname which is the user's home directory. A
2210222669
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
39 ** Optionally #include a user-defined header, whereby compilation options
40 ** may be set prior to where they take effect, but after platform setup.
41 ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
42 ** file. Note that this macro has a like effect on sqlite3.c compilation.
43 */
 
 
44 #ifdef SQLITE_CUSTOM_INCLUDE
45 # define INC_STRINGIFY_(f) #f
46 # define INC_STRINGIFY(f) INC_STRINGIFY_(f)
47 # include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
48 #endif
49
50 /*
51 ** Determine if we are dealing with WinRT, which provides only a subset of
52 ** the full Win32 API.
@@ -1401,11 +1401,11 @@
1401 ** sha3_query(Y,SIZE)
1402 **
1403 ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
1404 ** X is NULL.
1405 **
1406 ** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
1407 ** and returns a hash of their results.
1408 **
1409 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1410 ** is used. If SIZE is included it must be one of the integers 224, 256,
1411 ** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
5449 unsigned int i;
5450 int rc = SQLITE_OK;
5451 SQLITE_EXTENSION_INIT2(pApi);
5452 (void)pzErrMsg; /* Unused parameter */
5453 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454 rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5455 SQLITE_UTF8|SQLITE_INNOCUOUS,
5456 (void*)&aFunc[i].iAux,
5457 aFunc[i].xFunc, 0, 0);
5458 }
5459 return rc;
@@ -7962,13 +7962,18 @@
7962 zFile = pTab->zFile;
7963 }else if( idxNum==0 ){
7964 zipfileCursorErr(pCsr, "zipfile() function requires an argument");
7965 return SQLITE_ERROR;
7966 }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
 
7967 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
7968 int nBlob = sqlite3_value_bytes(argv[0]);
7969 assert( pTab->pFirstEntry==0 );
 
 
 
 
7970 rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
7971 pCsr->pFreeEntry = pTab->pFirstEntry;
7972 pTab->pFirstEntry = pTab->pLastEntry = 0;
7973 if( rc!=SQLITE_OK ) return rc;
7974 bInMemory = 1;
@@ -8870,10 +8875,14 @@
8870 0, /* xSync */
8871 zipfileCommit, /* xCommit */
8872 zipfileRollback, /* xRollback */
8873 zipfileFindFunction, /* xFindMethod */
8874 0, /* xRename */
 
 
 
 
8875 };
8876
8877 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
8878 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
8879 if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
12143 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
12144 EQPGraphRow *pLast; /* Last element of the pRow list */
12145 char zPrefix[100]; /* Graph prefix */
12146 };
12147
 
 
 
 
 
 
 
 
 
12148 /*
12149 ** State information about the database connection is contained in an
12150 ** instance of the following structure.
12151 */
12152 typedef struct ShellState ShellState;
@@ -12161,12 +12179,14 @@
12161 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
12162 u8 nEqpLevel; /* Depth of the EQP output graph */
12163 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
12164 u8 bSafeMode; /* True to prohibit unsafe operations */
12165 u8 bSafeModePersist; /* The long-term value of bSafeMode */
 
12166 unsigned statsOn; /* True to display memory stats before each finalize */
12167 unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
 
12168 int outCount; /* Revert to stdout when reaching zero */
12169 int cnt; /* Number of records displayed so far */
12170 int lineno; /* Line number of last line read from in */
12171 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
12172 FILE *in; /* Read commands from this stream */
@@ -12327,10 +12347,16 @@
12327 #define SEP_Comma ","
12328 #define SEP_CrLf "\r\n"
12329 #define SEP_Unit "\x1F"
12330 #define SEP_Record "\x1E"
12331
 
 
 
 
 
 
12332 /*
12333 ** A callback for the sqlite3_log() interface.
12334 */
12335 static void shellLog(void *pArg, int iErrCode, const char *zMsg){
12336 ShellState *p = (ShellState*)pArg;
@@ -13371,11 +13397,16 @@
13371 if( ur==0x7ff0000000000000LL ){
13372 raw_printf(p->out, "1e999");
13373 }else if( ur==0xfff0000000000000LL ){
13374 raw_printf(p->out, "-1e999");
13375 }else{
13376 sqlite3_snprintf(50,z,"%!.20g", r);
 
 
 
 
 
13377 raw_printf(p->out, "%s", z);
13378 }
13379 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
13380 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
13381 int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13697,21 +13728,28 @@
13697 /*
13698 ** Allocate space and save off string indicating current error.
13699 */
13700 static char *save_err_msg(
13701 sqlite3 *db, /* Database to query */
13702 const char *zWhen, /* Qualifier (format) wrapper */
13703 int rc, /* Error code returned from API */
13704 const char *zSql /* SQL string, or NULL */
13705 ){
13706 char *zErr;
13707 char *zContext;
13708 if( zWhen==0 ) zWhen = "%s (%d)%s";
 
 
 
 
13709 zContext = shell_error_context(zSql, db);
13710 zErr = sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc, zContext);
 
 
 
 
13711 shell_check_oom(zErr);
13712 sqlite3_free(zContext);
13713 return zErr;
13714 }
13715
13716 #ifdef __linux__
13717 /*
@@ -14234,11 +14272,138 @@
14234 utf8_printf(p->out, "%s", zSep3);
14235 }
14236 fputs("\n", p->out);
14237 }
14238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14240
14241 /*
14242 ** Run a prepared statement and output the result in one of the
14243 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
14244 ** or MODE_Box.
@@ -14254,39 +14419,41 @@
14254 ){
14255 sqlite3_int64 nRow = 0;
14256 int nColumn = 0;
14257 char **azData = 0;
14258 sqlite3_int64 nAlloc = 0;
 
 
14259 const char *z;
 
14260 int rc;
14261 sqlite3_int64 i, nData;
14262 int j, nTotal, w, n;
14263 const char *colSep = 0;
14264 const char *rowSep = 0;
 
 
 
 
14265
14266 rc = sqlite3_step(pStmt);
14267 if( rc!=SQLITE_ROW ) return;
14268 nColumn = sqlite3_column_count(pStmt);
14269 nAlloc = nColumn*4;
14270 if( nAlloc<=0 ) nAlloc = 1;
14271 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
14272 shell_check_oom(azData);
14273 for(i=0; i<nColumn; i++){
14274 azData[i] = strdup(sqlite3_column_name(pStmt,i));
14275 }
14276 do{
14277 if( (nRow+2)*nColumn >= nAlloc ){
14278 nAlloc *= 2;
14279 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14280 shell_check_oom(azData);
14281 }
14282 nRow++;
14283 for(i=0; i<nColumn; i++){
14284 z = (const char*)sqlite3_column_text(pStmt,i);
14285 azData[nRow*nColumn + i] = z ? strdup(z) : 0;
14286 }
14287 }while( sqlite3_step(pStmt)==SQLITE_ROW );
14288 if( nColumn>p->nWidth ){
14289 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
14290 shell_check_oom(p->colWidth);
14291 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
14292 p->nWidth = nColumn;
@@ -14296,10 +14463,56 @@
14296 for(i=0; i<nColumn; i++){
14297 w = p->colWidth[i];
14298 if( w<0 ) w = -w;
14299 p->actualWidth[i] = w;
14300 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14301 nTotal = nColumn*(nRow+1);
14302 for(i=0; i<nTotal; i++){
14303 z = azData[i];
14304 if( z==0 ) z = p->nullValue;
14305 n = strlenChar(z);
@@ -14378,10 +14591,19 @@
14378 w = p->actualWidth[j];
14379 if( p->colWidth[j]<0 ) w = -w;
14380 utf8_width_print(p->out, w, z);
14381 if( j==nColumn-1 ){
14382 utf8_printf(p->out, "%s", rowSep);
 
 
 
 
 
 
 
 
 
14383 j = -1;
14384 if( seenInterrupt ) goto columnar_end;
14385 }else{
14386 utf8_printf(p->out, "%s", colSep);
14387 }
@@ -14396,10 +14618,16 @@
14396 utf8_printf(p->out, "Interrupt\n");
14397 }
14398 nData = (nRow+1)*nColumn;
14399 for(i=0; i<nData; i++) free(azData[i]);
14400 sqlite3_free(azData);
 
 
 
 
 
 
14401 }
14402
14403 /*
14404 ** Run a prepared statement
14405 */
@@ -14648,11 +14876,11 @@
14648 while( zSql[0] && (SQLITE_OK == rc) ){
14649 static const char *zStmtSql;
14650 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14651 if( SQLITE_OK != rc ){
14652 if( pzErrMsg ){
14653 *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)%s", rc, zSql);
14654 }
14655 }else{
14656 if( !pStmt ){
14657 /* this happens for a comment or white-space */
14658 zSql = zLeftover;
@@ -14764,11 +14992,11 @@
14764 if( rc!=SQLITE_NOMEM ) rc = rc2;
14765 if( rc==SQLITE_OK ){
14766 zSql = zLeftover;
14767 while( IsSpace(zSql[0]) ) zSql++;
14768 }else if( pzErrMsg ){
14769 *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc, 0);
14770 }
14771
14772 /* clear saved stmt handle */
14773 if( pArg ){
14774 pArg->pStmt = NULL;
@@ -15103,10 +15331,11 @@
15103 #endif
15104 #ifndef SQLITE_OMIT_AUTHORIZATION
15105 ".auth ON|OFF Show authorizer callbacks",
15106 #endif
15107 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
 
15108 " --append Use the appendvfs",
15109 " --async Write to FILE without journal and fsync()",
15110 ".bail on|off Stop after hitting an error. Default OFF",
15111 ".binary on|off Turn binary output on or off. Default OFF",
15112 ".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15147,10 +15376,11 @@
15147 ".import FILE TABLE Import data from FILE into TABLE",
15148 " Options:",
15149 " --ascii Use \\037 and \\036 as column and row separators",
15150 " --csv Use , and \\n as column and row separators",
15151 " --skip N Skip the first N rows of input",
 
15152 " -v \"Verbose\" - increase auxiliary output",
15153 " Notes:",
15154 " * If TABLE does not exist, it is created. The first row of input",
15155 " determines the column names.",
15156 " * If neither --csv or --ascii are used, the input mode is derived",
@@ -15172,27 +15402,35 @@
15172 " fkey-indexes Find missing foreign key indexes",
15173 #ifndef SQLITE_OMIT_LOAD_EXTENSION
15174 ".load FILE ?ENTRY? Load an extension library",
15175 #endif
15176 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15177 ".mode MODE ?TABLE? Set output mode",
15178 " MODE is one of:",
15179 " ascii Columns/rows delimited by 0x1F and 0x1E",
15180 " box Tables using unicode box-drawing characters",
15181 " csv Comma-separated values",
15182 " column Output in columns. (See .width)",
15183 " html HTML <table> code",
15184 " insert SQL insert statements for TABLE",
15185 " json Results in a JSON array",
15186 " line One value per line",
15187 " list Values delimited by \"|\"",
15188 " markdown Markdown table format",
15189 " quote Escape answers as for SQL",
15190 " table ASCII-art table",
15191 " tabs Tab-separated values",
15192 " tcl TCL list elements",
15193 ".nonce STRING Disable safe mode for one command if the nonce matches",
 
 
 
 
 
 
 
 
15194 ".nullvalue STRING Use STRING in place of NULL values",
15195 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15196 " If FILE begins with '|' then open as a pipe",
15197 " --bom Put a UTF8 byte-order mark at the beginning",
15198 " -e Send output to the system text editor",
@@ -15241,11 +15479,11 @@
15241 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15242 " --no-rowids Do not attempt to recover rowid values",
15243 " that are not also INTEGER PRIMARY KEYs",
15244 #endif
15245 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15246 ".save FILE Write in-memory database into FILE",
15247 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15248 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15249 " Options:",
15250 " --indent Try to pretty-print the schema",
15251 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15845,12 +16083,14 @@
15845 sqlite3_series_init(p->db, 0, 0);
15846 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15847 sqlite3_dbdata_init(p->db, 0, 0);
15848 #endif
15849 #ifdef SQLITE_HAVE_ZLIB
15850 sqlite3_zipfile_init(p->db, 0, 0);
15851 sqlite3_sqlar_init(p->db, 0, 0);
 
 
15852 #endif
15853 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
15854 shellAddSchemaName, 0, 0);
15855 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
15856 shellModuleSchema, 0, 0);
@@ -16605,14 +16845,14 @@
16605 }
16606
16607 /*
16608 ** Run an SQL command and return the single integer result.
16609 */
16610 static int db_int(ShellState *p, const char *zSql){
16611 sqlite3_stmt *pStmt;
16612 int res = 0;
16613 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
16614 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
16615 res = sqlite3_column_int(pStmt,0);
16616 }
16617 sqlite3_finalize(pStmt);
16618 return res;
@@ -16713,11 +16953,11 @@
16713 }else{
16714 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
16715 }
16716 for(i=0; i<ArraySize(aQuery); i++){
16717 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16718 int val = db_int(p, zSql);
16719 sqlite3_free(zSql);
16720 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
16721 }
16722 sqlite3_free(zSchemaTab);
16723 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18076,10 +18316,11 @@
18076 *pRc = SQLITE_NOMEM;
18077 }
18078 }
18079 return z;
18080 }
 
18081
18082 /*
18083 ** When running the ".recover" command, each output table, and the special
18084 ** orphaned row table if it is required, is represented by an instance
18085 ** of the following struct.
@@ -18673,10 +18914,225 @@
18673 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
18674 return rc;
18675 }
18676 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18677
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18678 /*
18679 ** If an input line begins with "." then invoke this routine to
18680 ** process that line.
18681 **
18682 ** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19459,23 +19915,26 @@
19459 }
19460 }else
19461
19462 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
19463 char *zTable = 0; /* Insert data into this table */
 
19464 char *zFile = 0; /* Name of file to extra content from */
19465 sqlite3_stmt *pStmt = NULL; /* A statement */
19466 int nCol; /* Number of columns in the table */
19467 int nByte; /* Number of bytes in an SQL string */
19468 int i, j; /* Loop counters */
19469 int needCommit; /* True to COMMIT or ROLLBACK at end */
19470 int nSep; /* Number of bytes in p->colSeparator[] */
19471 char *zSql; /* An SQL statement */
 
19472 ImportCtx sCtx; /* Reader context */
19473 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
19474 int eVerbose = 0; /* Larger for more console output */
19475 int nSkip = 0; /* Initial lines to skip */
19476 int useOutputMode = 1; /* Use output mode to determine separators */
 
19477
19478 failIfSafeMode(p, "cannot run .import in safe mode");
19479 memset(&sCtx, 0, sizeof(sCtx));
19480 sCtx.z = sqlite3_malloc64(120);
19481 if( sCtx.z==0 ){
@@ -19501,10 +19960,12 @@
19501 rc = 1;
19502 goto meta_command_exit;
19503 }
19504 }else if( strcmp(z,"-v")==0 ){
19505 eVerbose++;
 
 
19506 }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
19507 nSkip = integerValue(azArg[++i]);
19508 }else if( strcmp(z,"-ascii")==0 ){
19509 sCtx.cColSep = SEP_Unit[0];
19510 sCtx.cRowSep = SEP_Record[0];
@@ -19603,69 +20064,83 @@
19603 utf8_printf(p->out, ", row separator ");
19604 zSep[0] = sCtx.cRowSep;
19605 output_c_string(p->out, zSep);
19606 utf8_printf(p->out, "\n");
19607 }
 
19608 while( (nSkip--)>0 ){
19609 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
19610 }
19611 zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
19612 if( zSql==0 ){
 
 
 
 
 
19613 import_cleanup(&sCtx);
19614 shell_out_of_memory();
19615 }
19616 nByte = strlen30(zSql);
19617 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19618 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
19619 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
19620 char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
19621 char cSep = '(';
19622 while( xRead(&sCtx) ){
19623 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
19624 cSep = ',';
19625 if( sCtx.cTerm!=sCtx.cColSep ) break;
19626 }
19627 if( cSep=='(' ){
19628 sqlite3_free(zCreate);
19629 import_cleanup(&sCtx);
19630 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
19631 rc = 1;
19632 goto meta_command_exit;
19633 }
19634 zCreate = sqlite3_mprintf("%z\n)", zCreate);
19635 if( eVerbose>=1 ){
19636 utf8_printf(p->out, "%s\n", zCreate);
19637 }
19638 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
19639 sqlite3_free(zCreate);
19640 if( rc ){
19641 utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
19642 sqlite3_errmsg(p->db));
19643 import_cleanup(&sCtx);
19644 rc = 1;
19645 goto meta_command_exit;
19646 }
19647 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19648 }
19649 sqlite3_free(zSql);
19650 if( rc ){
19651 if (pStmt) sqlite3_finalize(pStmt);
19652 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
19653 import_cleanup(&sCtx);
19654 rc = 1;
19655 goto meta_command_exit;
19656 }
 
 
 
 
 
 
 
 
19657 nCol = sqlite3_column_count(pStmt);
19658 sqlite3_finalize(pStmt);
19659 pStmt = 0;
19660 if( nCol==0 ) return 0; /* no columns, no error */
19661 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
19662 if( zSql==0 ){
19663 import_cleanup(&sCtx);
19664 shell_out_of_memory();
19665 }
19666 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
19667 j = strlen30(zSql);
19668 for(i=1; i<nCol; i++){
19669 zSql[j++] = ',';
19670 zSql[j++] = '?';
19671 }
@@ -19673,18 +20148,17 @@
19673 zSql[j] = 0;
19674 if( eVerbose>=2 ){
19675 utf8_printf(p->out, "Insert using: %s\n", zSql);
19676 }
19677 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19678 sqlite3_free(zSql);
19679 if( rc ){
19680 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
19681 if (pStmt) sqlite3_finalize(pStmt);
19682 import_cleanup(&sCtx);
19683 rc = 1;
19684 goto meta_command_exit;
19685 }
 
 
19686 needCommit = sqlite3_get_autocommit(p->db);
19687 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
19688 do{
19689 int startLine = sCtx.nLine;
19690 for(i=0; i<nCol; i++){
@@ -19962,68 +20436,127 @@
19962 p->pLog = output_file_open(zFile, 0);
19963 }
19964 }else
19965
19966 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
19967 const char *zMode = nArg>=2 ? azArg[1] : "";
19968 int n2 = strlen30(zMode);
19969 int c2 = zMode[0];
19970 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19971 p->mode = MODE_Line;
19972 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19973 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
19974 p->mode = MODE_Column;
19975 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
19976 p->showHeader = 1;
19977 }
19978 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19979 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
 
19980 p->mode = MODE_List;
19981 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
19982 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19983 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
19984 p->mode = MODE_Html;
19985 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
19986 p->mode = MODE_Tcl;
19987 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
19988 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19989 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
19990 p->mode = MODE_Csv;
19991 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
19992 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
19993 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
19994 p->mode = MODE_List;
19995 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
19996 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
19997 p->mode = MODE_Insert;
19998 set_table_name(p, nArg>=3 ? azArg[2] : "table");
19999 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
20000 p->mode = MODE_Quote;
20001 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20002 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20003 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
20004 p->mode = MODE_Ascii;
20005 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
20006 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20007 }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
20008 p->mode = MODE_Markdown;
20009 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
 
20010 p->mode = MODE_Table;
20011 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
 
20012 p->mode = MODE_Box;
20013 }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
 
20014 p->mode = MODE_Count;
20015 }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
20016 p->mode = MODE_Off;
20017 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
20018 p->mode = MODE_Json;
20019 }else if( nArg==1 ){
20020 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20021 }else{
20022 raw_printf(stderr, "Error: mode should be one of: "
20023 "ascii box column csv html insert json line list markdown "
20024 "quote table tabs tcl\n");
20025 rc = 1;
20026 }
20027 p->cMode = p->mode;
20028 }else
20029
@@ -20144,13 +20677,14 @@
20144 ){
20145 char *zFile = 0;
20146 int bTxtMode = 0;
20147 int i;
20148 int eMode = 0;
20149 int bBOM = 0;
20150 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20151
 
20152 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
20153 if( c=='e' ){
20154 eMode = 'x';
20155 bOnce = 2;
20156 }else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20159,11 +20693,14 @@
20159 for(i=1; i<nArg; i++){
20160 char *z = azArg[i];
20161 if( z[0]=='-' ){
20162 if( z[1]=='-' ) z++;
20163 if( strcmp(z,"-bom")==0 ){
20164 bBOM = 1;
 
 
 
20165 }else if( c!='e' && strcmp(z,"-x")==0 ){
20166 eMode = 'x'; /* spreadsheet */
20167 }else if( c!='e' && strcmp(z,"-e")==0 ){
20168 eMode = 'e'; /* text editor */
20169 }else{
@@ -20228,11 +20765,11 @@
20228 if( p->out==0 ){
20229 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
20230 p->out = stdout;
20231 rc = 1;
20232 }else{
20233 if( bBOM ) fprintf(p->out,"\357\273\277");
20234 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20235 }
20236 #endif
20237 }else{
20238 p->out = output_file_open(zFile, bTxtMode);
@@ -20241,11 +20778,11 @@
20241 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
20242 }
20243 p->out = stdout;
20244 rc = 1;
20245 } else {
20246 if( bBOM ) fprintf(p->out,"\357\273\277");
20247 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20248 }
20249 }
20250 sqlite3_free(zFile);
20251 }else
@@ -21167,11 +21704,21 @@
21167 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21168 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21169 utf8_printf(p->out, "%12.12s: %s\n","explain",
21170 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21171 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21172 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
 
 
 
 
 
 
 
 
 
 
21173 utf8_printf(p->out, "%12.12s: ", "nullvalue");
21174 output_c_string(p->out, p->nullValue);
21175 raw_printf(p->out, "\n");
21176 utf8_printf(p->out,"%12.12s: %s\n","output",
21177 strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21965,23 +22512,34 @@
21965 BEGIN_TIMER;
21966 rc = shell_exec(p, zSql, &zErrMsg);
21967 END_TIMER;
21968 if( rc || zErrMsg ){
21969 char zPrefix[100];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21970 if( in!=0 || !stdin_is_interactive ){
21971 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
21972 "Error: near line %d:", startline);
21973 }else{
21974 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
21975 }
21976 if( zErrMsg!=0 ){
21977 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
21978 sqlite3_free(zErrMsg);
21979 zErrMsg = 0;
21980 }else{
21981 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
21982 }
21983 return 1;
21984 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
21985 char zLineBuf[2000];
21986 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
21987 "changes: %lld total_changes: %lld",
@@ -22010,10 +22568,17 @@
22010 int rc; /* Error code */
22011 int errCnt = 0; /* Number of errors seen */
22012 int startline = 0; /* Line number for start of current input */
22013 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
22014
 
 
 
 
 
 
 
22015 p->lineno = 0;
22016 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
22017 fflush(p->out);
22018 zLine = one_input_line(p->in, zLine, nSql>0);
22019 if( zLine==0 ){
@@ -22087,15 +22652,17 @@
22087 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22088 nSql = 0;
22089 qss = QSS_Start;
22090 }
22091 }
22092 if( nSql && QSS_PLAINDARK(qss) ){
 
22093 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22094 }
22095 free(zSql);
22096 free(zLine);
 
22097 return errCnt>0;
22098 }
22099
22100 /*
22101 ** Return a pathname which is the user's home directory. A
22102
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
39 ** Optionally #include a user-defined header, whereby compilation options
40 ** may be set prior to where they take effect, but after platform setup.
41 ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
42 ** file. Note that this macro has a like effect on sqlite3.c compilation.
43 */
44 # define SHELL_STRINGIFY_(f) #f
45 # define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f)
46 #ifdef SQLITE_CUSTOM_INCLUDE
47 # include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
 
 
48 #endif
49
50 /*
51 ** Determine if we are dealing with WinRT, which provides only a subset of
52 ** the full Win32 API.
@@ -1401,11 +1401,11 @@
1401 ** sha3_query(Y,SIZE)
1402 **
1403 ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
1404 ** X is NULL.
1405 **
1406 ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
1407 ** and returns a hash of their results.
1408 **
1409 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1410 ** is used. If SIZE is included it must be one of the integers 224, 256,
1411 ** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
5449 unsigned int i;
5450 int rc = SQLITE_OK;
5451 SQLITE_EXTENSION_INIT2(pApi);
5452 (void)pzErrMsg; /* Unused parameter */
5453 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454 rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5455 SQLITE_UTF8|SQLITE_INNOCUOUS,
5456 (void*)&aFunc[i].iAux,
5457 aFunc[i].xFunc, 0, 0);
5458 }
5459 return rc;
@@ -7962,13 +7962,18 @@
7962 zFile = pTab->zFile;
7963 }else if( idxNum==0 ){
7964 zipfileCursorErr(pCsr, "zipfile() function requires an argument");
7965 return SQLITE_ERROR;
7966 }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
7967 static const u8 aEmptyBlob = 0;
7968 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
7969 int nBlob = sqlite3_value_bytes(argv[0]);
7970 assert( pTab->pFirstEntry==0 );
7971 if( aBlob==0 ){
7972 aBlob = &aEmptyBlob;
7973 nBlob = 0;
7974 }
7975 rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
7976 pCsr->pFreeEntry = pTab->pFirstEntry;
7977 pTab->pFirstEntry = pTab->pLastEntry = 0;
7978 if( rc!=SQLITE_OK ) return rc;
7979 bInMemory = 1;
@@ -8870,10 +8875,14 @@
8875 0, /* xSync */
8876 zipfileCommit, /* xCommit */
8877 zipfileRollback, /* xRollback */
8878 zipfileFindFunction, /* xFindMethod */
8879 0, /* xRename */
8880 0, /* xSavepoint */
8881 0, /* xRelease */
8882 0, /* xRollback */
8883 0 /* xShadowName */
8884 };
8885
8886 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
8887 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
8888 if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
12152 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
12153 EQPGraphRow *pLast; /* Last element of the pRow list */
12154 char zPrefix[100]; /* Graph prefix */
12155 };
12156
12157 /* Parameters affecting columnar mode result display (defaulting together) */
12158 typedef struct ColModeOpts {
12159 int iWrap; /* In columnar modes, wrap lines reaching this limit */
12160 u8 bQuote; /* Quote results for .mode box and table */
12161 u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
12162 } ColModeOpts;
12163 #define ColModeOpts_default { 60, 0, 0 }
12164 #define ColModeOpts_default_qbox { 60, 1, 0 }
12165
12166 /*
12167 ** State information about the database connection is contained in an
12168 ** instance of the following structure.
12169 */
12170 typedef struct ShellState ShellState;
@@ -12161,12 +12179,14 @@
12179 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
12180 u8 nEqpLevel; /* Depth of the EQP output graph */
12181 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
12182 u8 bSafeMode; /* True to prohibit unsafe operations */
12183 u8 bSafeModePersist; /* The long-term value of bSafeMode */
12184 ColModeOpts cmOpts; /* Option values affecting columnar mode output */
12185 unsigned statsOn; /* True to display memory stats before each finalize */
12186 unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
12187 int inputNesting; /* Track nesting level of .read and other redirects */
12188 int outCount; /* Revert to stdout when reaching zero */
12189 int cnt; /* Number of records displayed so far */
12190 int lineno; /* Line number of last line read from in */
12191 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
12192 FILE *in; /* Read commands from this stream */
@@ -12327,10 +12347,16 @@
12347 #define SEP_Comma ","
12348 #define SEP_CrLf "\r\n"
12349 #define SEP_Unit "\x1F"
12350 #define SEP_Record "\x1E"
12351
12352 /*
12353 ** Limit input nesting via .read or any other input redirect.
12354 ** It's not too expensive, so a generous allowance can be made.
12355 */
12356 #define MAX_INPUT_NESTING 25
12357
12358 /*
12359 ** A callback for the sqlite3_log() interface.
12360 */
12361 static void shellLog(void *pArg, int iErrCode, const char *zMsg){
12362 ShellState *p = (ShellState*)pArg;
@@ -13371,11 +13397,16 @@
13397 if( ur==0x7ff0000000000000LL ){
13398 raw_printf(p->out, "1e999");
13399 }else if( ur==0xfff0000000000000LL ){
13400 raw_printf(p->out, "-1e999");
13401 }else{
13402 sqlite3_int64 ir = (sqlite3_int64)r;
13403 if( r==(double)ir ){
13404 sqlite3_snprintf(50,z,"%lld.0", ir);
13405 }else{
13406 sqlite3_snprintf(50,z,"%!.20g", r);
13407 }
13408 raw_printf(p->out, "%s", z);
13409 }
13410 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
13411 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
13412 int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13697,21 +13728,28 @@
13728 /*
13729 ** Allocate space and save off string indicating current error.
13730 */
13731 static char *save_err_msg(
13732 sqlite3 *db, /* Database to query */
13733 const char *zPhase, /* When the error occcurs */
13734 int rc, /* Error code returned from API */
13735 const char *zSql /* SQL string, or NULL */
13736 ){
13737 char *zErr;
13738 char *zContext;
13739 sqlite3_str *pStr = sqlite3_str_new(0);
13740 sqlite3_str_appendf(pStr, "%s, %s", zPhase, sqlite3_errmsg(db));
13741 if( rc>1 ){
13742 sqlite3_str_appendf(pStr, " (%d)", rc);
13743 }
13744 zContext = shell_error_context(zSql, db);
13745 if( zContext ){
13746 sqlite3_str_appendall(pStr, zContext);
13747 sqlite3_free(zContext);
13748 }
13749 zErr = sqlite3_str_finish(pStr);
13750 shell_check_oom(zErr);
 
13751 return zErr;
13752 }
13753
13754 #ifdef __linux__
13755 /*
@@ -14234,11 +14272,138 @@
14272 utf8_printf(p->out, "%s", zSep3);
14273 }
14274 fputs("\n", p->out);
14275 }
14276
14277 /*
14278 ** z[] is a line of text that is to be displayed the .mode box or table or
14279 ** similar tabular formats. z[] might contain control characters such
14280 ** as \n, \t, \f, or \r.
14281 **
14282 ** Compute characters to display on the first line of z[]. Stop at the
14283 ** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
14284 ** from malloc()) of that first line, which caller should free sometime.
14285 ** Write anything to display on the next line into *pzTail. If this is
14286 ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
14287 */
14288 static char *translateForDisplayAndDup(
14289 const unsigned char *z, /* Input text to be transformed */
14290 const unsigned char **pzTail, /* OUT: Tail of the input for next line */
14291 int mxWidth, /* Max width. 0 means no limit */
14292 u8 bWordWrap /* If true, avoid breaking mid-word */
14293 ){
14294 int i; /* Input bytes consumed */
14295 int j; /* Output bytes generated */
14296 int k; /* Input bytes to be displayed */
14297 int n; /* Output column number */
14298 unsigned char *zOut; /* Output text */
14299
14300 if( z==0 ){
14301 *pzTail = 0;
14302 return 0;
14303 }
14304 if( mxWidth<0 ) mxWidth = -mxWidth;
14305 if( mxWidth==0 ) mxWidth = 1000000;
14306 i = j = n = 0;
14307 while( n<mxWidth ){
14308 if( z[i]>=' ' ){
14309 n++;
14310 do{ i++; j++; }while( (z[i]&0xc0)==0x80 );
14311 continue;
14312 }
14313 if( z[i]=='\t' ){
14314 do{
14315 n++;
14316 j++;
14317 }while( (n&7)!=0 && n<mxWidth );
14318 i++;
14319 continue;
14320 }
14321 break;
14322 }
14323 if( n>=mxWidth && bWordWrap ){
14324 /* Perhaps try to back up to a better place to break the line */
14325 for(k=i; k>i/2; k--){
14326 if( isspace(z[k-1]) ) break;
14327 }
14328 if( k<=i/2 ){
14329 for(k=i; k>i/2; k--){
14330 if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
14331 }
14332 }
14333 if( k<=i/2 ){
14334 k = i;
14335 }else{
14336 i = k;
14337 while( z[i]==' ' ) i++;
14338 }
14339 }else{
14340 k = i;
14341 }
14342 if( n>=mxWidth && z[i]>=' ' ){
14343 *pzTail = &z[i];
14344 }else if( z[i]=='\r' && z[i+1]=='\n' ){
14345 *pzTail = z[i+2] ? &z[i+2] : 0;
14346 }else if( z[i]==0 || z[i+1]==0 ){
14347 *pzTail = 0;
14348 }else{
14349 *pzTail = &z[i+1];
14350 }
14351 zOut = malloc( j+1 );
14352 shell_check_oom(zOut);
14353 i = j = n = 0;
14354 while( i<k ){
14355 if( z[i]>=' ' ){
14356 n++;
14357 do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 );
14358 continue;
14359 }
14360 if( z[i]=='\t' ){
14361 do{
14362 n++;
14363 zOut[j++] = ' ';
14364 }while( (n&7)!=0 && n<mxWidth );
14365 i++;
14366 continue;
14367 }
14368 break;
14369 }
14370 zOut[j] = 0;
14371 return (char*)zOut;
14372 }
14373
14374 /* Extract the value of the i-th current column for pStmt as an SQL literal
14375 ** value. Memory is obtained from sqlite3_malloc64() and must be freed by
14376 ** the caller.
14377 */
14378 static char *quoted_column(sqlite3_stmt *pStmt, int i){
14379 switch( sqlite3_column_type(pStmt, i) ){
14380 case SQLITE_NULL: {
14381 return sqlite3_mprintf("NULL");
14382 }
14383 case SQLITE_INTEGER:
14384 case SQLITE_FLOAT: {
14385 return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
14386 }
14387 case SQLITE_TEXT: {
14388 return sqlite3_mprintf("%Q",sqlite3_column_text(pStmt,i));
14389 }
14390 case SQLITE_BLOB: {
14391 int j;
14392 sqlite3_str *pStr = sqlite3_str_new(0);
14393 const unsigned char *a = sqlite3_column_blob(pStmt,i);
14394 int n = sqlite3_column_bytes(pStmt,i);
14395 sqlite3_str_append(pStr, "x'", 2);
14396 for(j=0; j<n; j++){
14397 sqlite3_str_appendf(pStr, "%02x", a[j]);
14398 }
14399 sqlite3_str_append(pStr, "'", 1);
14400 return sqlite3_str_finish(pStr);
14401 }
14402 }
14403 return 0; /* Not reached */
14404 }
14405
14406 /*
14407 ** Run a prepared statement and output the result in one of the
14408 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
14409 ** or MODE_Box.
@@ -14254,39 +14419,41 @@
14419 ){
14420 sqlite3_int64 nRow = 0;
14421 int nColumn = 0;
14422 char **azData = 0;
14423 sqlite3_int64 nAlloc = 0;
14424 char *abRowDiv = 0;
14425 const unsigned char *uz;
14426 const char *z;
14427 char **azQuoted = 0;
14428 int rc;
14429 sqlite3_int64 i, nData;
14430 int j, nTotal, w, n;
14431 const char *colSep = 0;
14432 const char *rowSep = 0;
14433 const unsigned char **azNextLine = 0;
14434 int bNextLine = 0;
14435 int bMultiLineRowExists = 0;
14436 int bw = p->cmOpts.bWordWrap;
14437
14438 rc = sqlite3_step(pStmt);
14439 if( rc!=SQLITE_ROW ) return;
14440 nColumn = sqlite3_column_count(pStmt);
14441 nAlloc = nColumn*4;
14442 if( nAlloc<=0 ) nAlloc = 1;
14443 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
14444 shell_check_oom(azData);
14445 azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
14446 shell_check_oom((void*)azNextLine);
14447 memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
14448 if( p->cmOpts.bQuote ){
14449 azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
14450 shell_check_oom(azQuoted);
14451 memset(azQuoted, 0, nColumn*sizeof(char*) );
14452 }
14453 abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
14454 shell_check_oom(abRowDiv);
 
 
 
 
 
14455 if( nColumn>p->nWidth ){
14456 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
14457 shell_check_oom(p->colWidth);
14458 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
14459 p->nWidth = nColumn;
@@ -14296,10 +14463,56 @@
14463 for(i=0; i<nColumn; i++){
14464 w = p->colWidth[i];
14465 if( w<0 ) w = -w;
14466 p->actualWidth[i] = w;
14467 }
14468 for(i=0; i<nColumn; i++){
14469 const unsigned char *zNotUsed;
14470 int wx = p->colWidth[i];
14471 if( wx==0 ){
14472 wx = p->cmOpts.iWrap;
14473 }
14474 if( wx<0 ) wx = -wx;
14475 uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
14476 azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw);
14477 }
14478 do{
14479 int useNextLine = bNextLine;
14480 bNextLine = 0;
14481 if( (nRow+2)*nColumn >= nAlloc ){
14482 nAlloc *= 2;
14483 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14484 shell_check_oom(azData);
14485 abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
14486 shell_check_oom(abRowDiv);
14487 }
14488 abRowDiv[nRow] = 1;
14489 nRow++;
14490 for(i=0; i<nColumn; i++){
14491 int wx = p->colWidth[i];
14492 if( wx==0 ){
14493 wx = p->cmOpts.iWrap;
14494 }
14495 if( wx<0 ) wx = -wx;
14496 if( useNextLine ){
14497 uz = azNextLine[i];
14498 }else if( p->cmOpts.bQuote ){
14499 sqlite3_free(azQuoted[i]);
14500 azQuoted[i] = quoted_column(pStmt,i);
14501 uz = (const unsigned char*)azQuoted[i];
14502 }else{
14503 uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14504 }
14505 azData[nRow*nColumn + i]
14506 = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14507 if( azNextLine[i] ){
14508 bNextLine = 1;
14509 abRowDiv[nRow-1] = 0;
14510 bMultiLineRowExists = 1;
14511 }
14512 }
14513 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
14514 nTotal = nColumn*(nRow+1);
14515 for(i=0; i<nTotal; i++){
14516 z = azData[i];
14517 if( z==0 ) z = p->nullValue;
14518 n = strlenChar(z);
@@ -14378,10 +14591,19 @@
14591 w = p->actualWidth[j];
14592 if( p->colWidth[j]<0 ) w = -w;
14593 utf8_width_print(p->out, w, z);
14594 if( j==nColumn-1 ){
14595 utf8_printf(p->out, "%s", rowSep);
14596 if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
14597 if( p->cMode==MODE_Table ){
14598 print_row_separator(p, nColumn, "+");
14599 }else if( p->cMode==MODE_Box ){
14600 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
14601 }else if( p->cMode==MODE_Column ){
14602 raw_printf(p->out, "\n");
14603 }
14604 }
14605 j = -1;
14606 if( seenInterrupt ) goto columnar_end;
14607 }else{
14608 utf8_printf(p->out, "%s", colSep);
14609 }
@@ -14396,10 +14618,16 @@
14618 utf8_printf(p->out, "Interrupt\n");
14619 }
14620 nData = (nRow+1)*nColumn;
14621 for(i=0; i<nData; i++) free(azData[i]);
14622 sqlite3_free(azData);
14623 sqlite3_free((void*)azNextLine);
14624 sqlite3_free(abRowDiv);
14625 if( azQuoted ){
14626 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
14627 sqlite3_free(azQuoted);
14628 }
14629 }
14630
14631 /*
14632 ** Run a prepared statement
14633 */
@@ -14648,11 +14876,11 @@
14876 while( zSql[0] && (SQLITE_OK == rc) ){
14877 static const char *zStmtSql;
14878 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14879 if( SQLITE_OK != rc ){
14880 if( pzErrMsg ){
14881 *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
14882 }
14883 }else{
14884 if( !pStmt ){
14885 /* this happens for a comment or white-space */
14886 zSql = zLeftover;
@@ -14764,11 +14992,11 @@
14992 if( rc!=SQLITE_NOMEM ) rc = rc2;
14993 if( rc==SQLITE_OK ){
14994 zSql = zLeftover;
14995 while( IsSpace(zSql[0]) ) zSql++;
14996 }else if( pzErrMsg ){
14997 *pzErrMsg = save_err_msg(db, "stepping", rc, 0);
14998 }
14999
15000 /* clear saved stmt handle */
15001 if( pArg ){
15002 pArg->pStmt = NULL;
@@ -15103,10 +15331,11 @@
15331 #endif
15332 #ifndef SQLITE_OMIT_AUTHORIZATION
15333 ".auth ON|OFF Show authorizer callbacks",
15334 #endif
15335 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15336 " Options:",
15337 " --append Use the appendvfs",
15338 " --async Write to FILE without journal and fsync()",
15339 ".bail on|off Stop after hitting an error. Default OFF",
15340 ".binary on|off Turn binary output on or off. Default OFF",
15341 ".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15147,10 +15376,11 @@
15376 ".import FILE TABLE Import data from FILE into TABLE",
15377 " Options:",
15378 " --ascii Use \\037 and \\036 as column and row separators",
15379 " --csv Use , and \\n as column and row separators",
15380 " --skip N Skip the first N rows of input",
15381 " --schema S Target table to be S.TABLE",
15382 " -v \"Verbose\" - increase auxiliary output",
15383 " Notes:",
15384 " * If TABLE does not exist, it is created. The first row of input",
15385 " determines the column names.",
15386 " * If neither --csv or --ascii are used, the input mode is derived",
@@ -15172,27 +15402,35 @@
15402 " fkey-indexes Find missing foreign key indexes",
15403 #ifndef SQLITE_OMIT_LOAD_EXTENSION
15404 ".load FILE ?ENTRY? Load an extension library",
15405 #endif
15406 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15407 ".mode MODE ?OPTIONS? Set output mode",
15408 " MODE is one of:",
15409 " ascii Columns/rows delimited by 0x1F and 0x1E",
15410 " box Tables using unicode box-drawing characters",
15411 " csv Comma-separated values",
15412 " column Output in columns. (See .width)",
15413 " html HTML <table> code",
15414 " insert SQL insert statements for TABLE",
15415 " json Results in a JSON array",
15416 " line One value per line",
15417 " list Values delimited by \"|\"",
15418 " markdown Markdown table format",
15419 " qbox Shorthand for \"box --width 60 --quote\"",
15420 " quote Escape answers as for SQL",
15421 " table ASCII-art table",
15422 " tabs Tab-separated values",
15423 " tcl TCL list elements",
15424 " OPTIONS: (for columnar modes or insert mode):",
15425 " --wrap N Wrap output lines to no longer than N characters",
15426 " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15427 " --ww Shorthand for \"--wordwrap 1\"",
15428 " --quote Quote output text as SQL literals",
15429 " --noquote Do not quote output text",
15430 " TABLE The name of SQL table used for \"insert\" mode",
15431 ".nonce STRING Suspend safe mode for one command if nonce matches",
15432 ".nullvalue STRING Use STRING in place of NULL values",
15433 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15434 " If FILE begins with '|' then open as a pipe",
15435 " --bom Put a UTF8 byte-order mark at the beginning",
15436 " -e Send output to the system text editor",
@@ -15241,11 +15479,11 @@
15479 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15480 " --no-rowids Do not attempt to recover rowid values",
15481 " that are not also INTEGER PRIMARY KEYs",
15482 #endif
15483 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15484 ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
15485 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15486 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15487 " Options:",
15488 " --indent Try to pretty-print the schema",
15489 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15845,12 +16083,14 @@
16083 sqlite3_series_init(p->db, 0, 0);
16084 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16085 sqlite3_dbdata_init(p->db, 0, 0);
16086 #endif
16087 #ifdef SQLITE_HAVE_ZLIB
16088 if( !p->bSafeModePersist ){
16089 sqlite3_zipfile_init(p->db, 0, 0);
16090 sqlite3_sqlar_init(p->db, 0, 0);
16091 }
16092 #endif
16093 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
16094 shellAddSchemaName, 0, 0);
16095 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
16096 shellModuleSchema, 0, 0);
@@ -16605,14 +16845,14 @@
16845 }
16846
16847 /*
16848 ** Run an SQL command and return the single integer result.
16849 */
16850 static int db_int(sqlite3 *db, const char *zSql){
16851 sqlite3_stmt *pStmt;
16852 int res = 0;
16853 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
16854 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
16855 res = sqlite3_column_int(pStmt,0);
16856 }
16857 sqlite3_finalize(pStmt);
16858 return res;
@@ -16713,11 +16953,11 @@
16953 }else{
16954 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
16955 }
16956 for(i=0; i<ArraySize(aQuery); i++){
16957 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16958 int val = db_int(p->db, zSql);
16959 sqlite3_free(zSql);
16960 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
16961 }
16962 sqlite3_free(zSchemaTab);
16963 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18076,10 +18316,11 @@
18316 *pRc = SQLITE_NOMEM;
18317 }
18318 }
18319 return z;
18320 }
18321
18322
18323 /*
18324 ** When running the ".recover" command, each output table, and the special
18325 ** orphaned row table if it is required, is represented by an instance
18326 ** of the following struct.
@@ -18673,10 +18914,225 @@
18914 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
18915 return rc;
18916 }
18917 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18918
18919
18920 /*
18921 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18922 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18923 * close db and set it to 0, and return the columns spec, to later
18924 * be sqlite3_free()'ed by the caller.
18925 * The return is 0 when either:
18926 * (a) The db was not initialized and zCol==0 (There are no columns.)
18927 * (b) zCol!=0 (Column was added, db initialized as needed.)
18928 * The 3rd argument, pRenamed, references an out parameter. If the
18929 * pointer is non-zero, its referent will be set to a summary of renames
18930 * done if renaming was necessary, or set to 0 if none was done. The out
18931 * string (if any) must be sqlite3_free()'ed by the caller.
18932 */
18933 #ifdef SHELL_DEBUG
18934 #define rc_err_oom_die(rc) \
18935 if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
18936 else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
18937 fprintf(stderr,"E:%d\n",rc), assert(0)
18938 #else
18939 static void rc_err_oom_die(int rc){
18940 if( rc==SQLITE_NOMEM ) shell_check_oom(0);
18941 assert(rc==SQLITE_OK||rc==SQLITE_DONE);
18942 }
18943 #endif
18944
18945 #ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
18946 static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB);
18947 #else /* Otherwise, memory is faster/better for the transient DB. */
18948 static const char *zCOL_DB = ":memory:";
18949 #endif
18950
18951 /* Define character (as C string) to separate generated column ordinal
18952 * from protected part of incoming column names. This defaults to "_"
18953 * so that incoming column identifiers that did not need not be quoted
18954 * remain usable without being quoted. It must be one character.
18955 */
18956 #ifndef SHELL_AUTOCOLUMN_SEP
18957 # define AUTOCOLUMN_SEP "_"
18958 #else
18959 # define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
18960 #endif
18961
18962 static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){
18963 /* Queries and D{D,M}L used here */
18964 static const char * const zTabMake = "\
18965 CREATE TABLE ColNames(\
18966 cpos INTEGER PRIMARY KEY,\
18967 name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\
18968 CREATE VIEW RepeatedNames AS \
18969 SELECT DISTINCT t.name FROM ColNames t \
18970 WHERE t.name COLLATE NOCASE IN (\
18971 SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\
18972 );\
18973 ";
18974 static const char * const zTabFill = "\
18975 INSERT INTO ColNames(name,nlen,chop,reps,suff)\
18976 VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
18977 ";
18978 static const char * const zHasDupes = "\
18979 SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
18980 <count(name) FROM ColNames\
18981 ";
18982 #ifdef SHELL_COLUMN_RENAME_CLEAN
18983 static const char * const zDedoctor = "\
18984 UPDATE ColNames SET chop=iif(\
18985 (substring(name,nlen,1) BETWEEN '0' AND '9')\
18986 AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\
18987 nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\
18988 0\
18989 )\
18990 ";
18991 #endif
18992 static const char * const zSetReps = "\
18993 UPDATE ColNames AS t SET reps=\
18994 (SELECT count(*) FROM ColNames d \
18995 WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
18996 COLLATE NOCASE\
18997 )\
18998 ";
18999 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19000 static const char * const zColDigits = "\
19001 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19002 ";
19003 #endif
19004 static const char * const zRenameRank =
19005 #ifdef SHELL_COLUMN_RENAME_CLEAN
19006 "UPDATE ColNames AS t SET suff="
19007 "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
19008 #else /* ...RENAME_MINIMAL_ONE_PASS */
19009 "WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */
19010 " SELECT 0 AS nlz"
19011 " UNION"
19012 " SELECT nlz+1 AS nlz FROM Lzn"
19013 " WHERE EXISTS("
19014 " SELECT 1"
19015 " FROM ColNames t, ColNames o"
19016 " WHERE"
19017 " iif(t.name IN (SELECT * FROM RepeatedNames),"
19018 " printf('%s"AUTOCOLUMN_SEP"%s',"
19019 " t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2)),"
19020 " t.name"
19021 " )"
19022 " ="
19023 " iif(o.name IN (SELECT * FROM RepeatedNames),"
19024 " printf('%s"AUTOCOLUMN_SEP"%s',"
19025 " o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2)),"
19026 " o.name"
19027 " )"
19028 " COLLATE NOCASE"
19029 " AND o.cpos<>t.cpos"
19030 " GROUP BY t.cpos"
19031 " )"
19032 ") UPDATE Colnames AS t SET"
19033 " chop = 0," /* No chopping, never touch incoming names. */
19034 " suff = iif(name IN (SELECT * FROM RepeatedNames),"
19035 " printf('"AUTOCOLUMN_SEP"%s', substring("
19036 " printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2)),"
19037 " ''"
19038 " )"
19039 #endif
19040 ;
19041 static const char * const zCollectVar = "\
19042 SELECT\
19043 '('||x'0a'\
19044 || group_concat(\
19045 cname||' TEXT',\
19046 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19047 ||')' AS ColsSpec \
19048 FROM (\
19049 SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19050 FROM ColNames ORDER BY cpos\
19051 )";
19052 static const char * const zRenamesDone =
19053 "SELECT group_concat("
19054 " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19055 " ','||x'0a')"
19056 "FROM ColNames WHERE suff<>'' OR chop!=0"
19057 ;
19058 int rc;
19059 sqlite3_stmt *pStmt = 0;
19060 assert(pDb!=0);
19061 if( zColNew ){
19062 /* Add initial or additional column. Init db if necessary. */
19063 if( *pDb==0 ){
19064 if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
19065 #ifdef SHELL_COLFIX_DB
19066 if(*zCOL_DB!=':')
19067 sqlite3_exec(*pDb,"drop table if exists ColNames;"
19068 "drop view if exists RepeatedNames;",0,0,0);
19069 #endif
19070 rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
19071 rc_err_oom_die(rc);
19072 }
19073 assert(*pDb!=0);
19074 rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
19075 rc_err_oom_die(rc);
19076 rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
19077 rc_err_oom_die(rc);
19078 rc = sqlite3_step(pStmt);
19079 rc_err_oom_die(rc);
19080 sqlite3_finalize(pStmt);
19081 return 0;
19082 }else if( *pDb==0 ){
19083 return 0;
19084 }else{
19085 /* Formulate the columns spec, close the DB, zero *pDb. */
19086 char *zColsSpec = 0;
19087 int hasDupes = db_int(*pDb, zHasDupes);
19088 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19089 int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090 #else
19091 # define nDigits 2
19092 #endif
19093 if( hasDupes ){
19094 #ifdef SHELL_COLUMN_RENAME_CLEAN
19095 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19096 rc_err_oom_die(rc);
19097 #endif
19098 rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
19099 rc_err_oom_die(rc);
19100 rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
19101 rc_err_oom_die(rc);
19102 sqlite3_bind_int(pStmt, 1, nDigits);
19103 rc = sqlite3_step(pStmt);
19104 sqlite3_finalize(pStmt);
19105 assert(rc==SQLITE_DONE);
19106 }
19107 assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
19108 rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
19109 rc_err_oom_die(rc);
19110 rc = sqlite3_step(pStmt);
19111 if( rc==SQLITE_ROW ){
19112 zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19113 }else{
19114 zColsSpec = 0;
19115 }
19116 if( pzRenamed!=0 ){
19117 if( !hasDupes ) *pzRenamed = 0;
19118 else{
19119 sqlite3_finalize(pStmt);
19120 if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0)
19121 && SQLITE_ROW==sqlite3_step(pStmt) ){
19122 *pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19123 }else
19124 *pzRenamed = 0;
19125 }
19126 }
19127 sqlite3_finalize(pStmt);
19128 sqlite3_close(*pDb);
19129 *pDb = 0;
19130 return zColsSpec;
19131 }
19132 }
19133
19134 /*
19135 ** If an input line begins with "." then invoke this routine to
19136 ** process that line.
19137 **
19138 ** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19459,23 +19915,26 @@
19915 }
19916 }else
19917
19918 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
19919 char *zTable = 0; /* Insert data into this table */
19920 char *zSchema = 0; /* within this schema (may default to "main") */
19921 char *zFile = 0; /* Name of file to extra content from */
19922 sqlite3_stmt *pStmt = NULL; /* A statement */
19923 int nCol; /* Number of columns in the table */
19924 int nByte; /* Number of bytes in an SQL string */
19925 int i, j; /* Loop counters */
19926 int needCommit; /* True to COMMIT or ROLLBACK at end */
19927 int nSep; /* Number of bytes in p->colSeparator[] */
19928 char *zSql; /* An SQL statement */
19929 char *zFullTabName; /* Table name with schema if applicable */
19930 ImportCtx sCtx; /* Reader context */
19931 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
19932 int eVerbose = 0; /* Larger for more console output */
19933 int nSkip = 0; /* Initial lines to skip */
19934 int useOutputMode = 1; /* Use output mode to determine separators */
19935 char *zCreate = 0; /* CREATE TABLE statement text */
19936
19937 failIfSafeMode(p, "cannot run .import in safe mode");
19938 memset(&sCtx, 0, sizeof(sCtx));
19939 sCtx.z = sqlite3_malloc64(120);
19940 if( sCtx.z==0 ){
@@ -19501,10 +19960,12 @@
19960 rc = 1;
19961 goto meta_command_exit;
19962 }
19963 }else if( strcmp(z,"-v")==0 ){
19964 eVerbose++;
19965 }else if( strcmp(z,"-schema")==0 && i<nArg-1 ){
19966 zSchema = azArg[++i];
19967 }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
19968 nSkip = integerValue(azArg[++i]);
19969 }else if( strcmp(z,"-ascii")==0 ){
19970 sCtx.cColSep = SEP_Unit[0];
19971 sCtx.cRowSep = SEP_Record[0];
@@ -19603,69 +20064,83 @@
20064 utf8_printf(p->out, ", row separator ");
20065 zSep[0] = sCtx.cRowSep;
20066 output_c_string(p->out, zSep);
20067 utf8_printf(p->out, "\n");
20068 }
20069 /* Below, resources must be freed before exit. */
20070 while( (nSkip--)>0 ){
20071 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
20072 }
20073 if( zSchema!=0 ){
20074 zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
20075 }else{
20076 zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
20077 }
20078 zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
20079 if( zSql==0 || zFullTabName==0 ){
20080 import_cleanup(&sCtx);
20081 shell_out_of_memory();
20082 }
20083 nByte = strlen30(zSql);
20084 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
20085 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
20086 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
20087 sqlite3 *dbCols = 0;
20088 char *zRenames = 0;
20089 char *zColDefs;
20090 zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
20091 while( xRead(&sCtx) ){
20092 zAutoColumn(sCtx.z, &dbCols, 0);
20093 if( sCtx.cTerm!=sCtx.cColSep ) break;
20094 }
20095 zColDefs = zAutoColumn(0, &dbCols, &zRenames);
20096 if( zRenames!=0 ){
20097 utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
20098 "Columns renamed during .import %s due to duplicates:\n"
20099 "%s\n", sCtx.zFile, zRenames);
20100 sqlite3_free(zRenames);
20101 }
20102 assert(dbCols==0);
20103 if( zColDefs==0 ){
20104 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
20105 import_fail:
20106 sqlite3_free(zCreate);
20107 sqlite3_free(zSql);
20108 sqlite3_free(zFullTabName);
20109 import_cleanup(&sCtx);
20110 rc = 1;
20111 goto meta_command_exit;
20112 }
20113 zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
20114 if( eVerbose>=1 ){
20115 utf8_printf(p->out, "%s\n", zCreate);
20116 }
20117 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
20118 if( rc ){
20119 utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
20120 goto import_fail;
20121 }
20122 sqlite3_free(zCreate);
20123 zCreate = 0;
20124 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
20125 }
20126 if( rc ){
20127 if (pStmt) sqlite3_finalize(pStmt);
20128 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
20129 goto import_fail;
20130 }
20131 sqlite3_free(zSql);
20132 nCol = sqlite3_column_count(pStmt);
20133 sqlite3_finalize(pStmt);
20134 pStmt = 0;
20135 if( nCol==0 ) return 0; /* no columns, no error */
20136 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
20137 if( zSql==0 ){
20138 import_cleanup(&sCtx);
20139 shell_out_of_memory();
20140 }
20141 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
20142 j = strlen30(zSql);
20143 for(i=1; i<nCol; i++){
20144 zSql[j++] = ',';
20145 zSql[j++] = '?';
20146 }
@@ -19673,18 +20148,17 @@
20148 zSql[j] = 0;
20149 if( eVerbose>=2 ){
20150 utf8_printf(p->out, "Insert using: %s\n", zSql);
20151 }
20152 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
 
20153 if( rc ){
20154 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
20155 if (pStmt) sqlite3_finalize(pStmt);
20156 goto import_fail;
 
 
20157 }
20158 sqlite3_free(zSql);
20159 sqlite3_free(zFullTabName);
20160 needCommit = sqlite3_get_autocommit(p->db);
20161 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
20162 do{
20163 int startLine = sCtx.nLine;
20164 for(i=0; i<nCol; i++){
@@ -19962,68 +20436,127 @@
20436 p->pLog = output_file_open(zFile, 0);
20437 }
20438 }else
20439
20440 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
20441 const char *zMode = 0;
20442 const char *zTabname = 0;
20443 int i, n2;
20444 ColModeOpts cmOpts = ColModeOpts_default;
20445 for(i=1; i<nArg; i++){
20446 const char *z = azArg[i];
20447 if( optionMatch(z,"wrap") && i+1<nArg ){
20448 cmOpts.iWrap = integerValue(azArg[++i]);
20449 }else if( optionMatch(z,"ww") ){
20450 cmOpts.bWordWrap = 1;
20451 }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
20452 cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
20453 }else if( optionMatch(z,"quote") ){
20454 cmOpts.bQuote = 1;
20455 }else if( optionMatch(z,"noquote") ){
20456 cmOpts.bQuote = 0;
20457 }else if( zMode==0 ){
20458 zMode = z;
20459 /* Apply defaults for qbox pseudo-mods. If that
20460 * overwrites already-set values, user was informed of this.
20461 */
20462 if( strcmp(z, "qbox")==0 ){
20463 ColModeOpts cmo = ColModeOpts_default_qbox;
20464 zMode = "box";
20465 cmOpts = cmo;
20466 }
20467 }else if( zTabname==0 ){
20468 zTabname = z;
20469 }else if( z[0]=='-' ){
20470 utf8_printf(stderr, "unknown option: %s\n", z);
20471 utf8_printf(stderr, "options:\n"
20472 " --noquote\n"
20473 " --quote\n"
20474 " --wordwrap on/off\n"
20475 " --wrap N\n"
20476 " --ww\n");
20477 rc = 1;
20478 goto meta_command_exit;
20479 }else{
20480 utf8_printf(stderr, "extra argument: \"%s\"\n", z);
20481 rc = 1;
20482 goto meta_command_exit;
20483 }
20484 }
20485 if( zMode==0 ){
20486 if( p->mode==MODE_Column
20487 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
20488 ){
20489 raw_printf
20490 (p->out,
20491 "current output mode: %s --wrap %d --wordwrap %s --%squote\n",
20492 modeDescr[p->mode], p->cmOpts.iWrap,
20493 p->cmOpts.bWordWrap ? "on" : "off",
20494 p->cmOpts.bQuote ? "" : "no");
20495 }else{
20496 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20497 }
20498 zMode = modeDescr[p->mode];
20499 }
20500 n2 = strlen30(zMode);
20501 if( strncmp(zMode,"lines",n2)==0 ){
20502 p->mode = MODE_Line;
20503 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20504 }else if( strncmp(zMode,"columns",n2)==0 ){
20505 p->mode = MODE_Column;
20506 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
20507 p->showHeader = 1;
20508 }
20509 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20510 p->cmOpts = cmOpts;
20511 }else if( strncmp(zMode,"list",n2)==0 ){
20512 p->mode = MODE_List;
20513 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
20514 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20515 }else if( strncmp(zMode,"html",n2)==0 ){
20516 p->mode = MODE_Html;
20517 }else if( strncmp(zMode,"tcl",n2)==0 ){
20518 p->mode = MODE_Tcl;
20519 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
20520 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20521 }else if( strncmp(zMode,"csv",n2)==0 ){
20522 p->mode = MODE_Csv;
20523 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20524 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
20525 }else if( strncmp(zMode,"tabs",n2)==0 ){
20526 p->mode = MODE_List;
20527 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
20528 }else if( strncmp(zMode,"insert",n2)==0 ){
20529 p->mode = MODE_Insert;
20530 set_table_name(p, zTabname ? zTabname : "table");
20531 }else if( strncmp(zMode,"quote",n2)==0 ){
20532 p->mode = MODE_Quote;
20533 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20534 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20535 }else if( strncmp(zMode,"ascii",n2)==0 ){
20536 p->mode = MODE_Ascii;
20537 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
20538 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20539 }else if( strncmp(zMode,"markdown",n2)==0 ){
20540 p->mode = MODE_Markdown;
20541 p->cmOpts = cmOpts;
20542 }else if( strncmp(zMode,"table",n2)==0 ){
20543 p->mode = MODE_Table;
20544 p->cmOpts = cmOpts;
20545 }else if( strncmp(zMode,"box",n2)==0 ){
20546 p->mode = MODE_Box;
20547 p->cmOpts = cmOpts;
20548 }else if( strncmp(zMode,"count",n2)==0 ){
20549 p->mode = MODE_Count;
20550 }else if( strncmp(zMode,"off",n2)==0 ){
20551 p->mode = MODE_Off;
20552 }else if( strncmp(zMode,"json",n2)==0 ){
20553 p->mode = MODE_Json;
 
 
20554 }else{
20555 raw_printf(stderr, "Error: mode should be one of: "
20556 "ascii box column csv html insert json line list markdown "
20557 "qbox quote table tabs tcl\n");
20558 rc = 1;
20559 }
20560 p->cMode = p->mode;
20561 }else
20562
@@ -20144,13 +20677,14 @@
20677 ){
20678 char *zFile = 0;
20679 int bTxtMode = 0;
20680 int i;
20681 int eMode = 0;
20682 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20683 unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */
20684
20685 zBOM[0] = 0;
20686 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
20687 if( c=='e' ){
20688 eMode = 'x';
20689 bOnce = 2;
20690 }else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20159,11 +20693,14 @@
20693 for(i=1; i<nArg; i++){
20694 char *z = azArg[i];
20695 if( z[0]=='-' ){
20696 if( z[1]=='-' ) z++;
20697 if( strcmp(z,"-bom")==0 ){
20698 zBOM[0] = 0xef;
20699 zBOM[1] = 0xbb;
20700 zBOM[2] = 0xbf;
20701 zBOM[3] = 0;
20702 }else if( c!='e' && strcmp(z,"-x")==0 ){
20703 eMode = 'x'; /* spreadsheet */
20704 }else if( c!='e' && strcmp(z,"-e")==0 ){
20705 eMode = 'e'; /* text editor */
20706 }else{
@@ -20228,11 +20765,11 @@
20765 if( p->out==0 ){
20766 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
20767 p->out = stdout;
20768 rc = 1;
20769 }else{
20770 if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
20771 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20772 }
20773 #endif
20774 }else{
20775 p->out = output_file_open(zFile, bTxtMode);
@@ -20241,11 +20778,11 @@
20778 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
20779 }
20780 p->out = stdout;
20781 rc = 1;
20782 } else {
20783 if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
20784 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20785 }
20786 }
20787 sqlite3_free(zFile);
20788 }else
@@ -21167,11 +21704,21 @@
21704 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21705 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21706 utf8_printf(p->out, "%12.12s: %s\n","explain",
21707 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21708 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21709 if( p->mode==MODE_Column
21710 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
21711 ){
21712 utf8_printf
21713 (p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
21714 modeDescr[p->mode], p->cmOpts.iWrap,
21715 p->cmOpts.bWordWrap ? "on" : "off",
21716 p->cmOpts.bQuote ? "" : "no");
21717 }else{
21718 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21719 }
21720 utf8_printf(p->out, "%12.12s: ", "nullvalue");
21721 output_c_string(p->out, p->nullValue);
21722 raw_printf(p->out, "\n");
21723 utf8_printf(p->out,"%12.12s: %s\n","output",
21724 strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21965,23 +22512,34 @@
22512 BEGIN_TIMER;
22513 rc = shell_exec(p, zSql, &zErrMsg);
22514 END_TIMER;
22515 if( rc || zErrMsg ){
22516 char zPrefix[100];
22517 const char *zErrorTail;
22518 const char *zErrorType;
22519 if( zErrMsg==0 ){
22520 zErrorType = "Error";
22521 zErrorTail = sqlite3_errmsg(p->db);
22522 }else if( strncmp(zErrMsg, "in prepare, ",12)==0 ){
22523 zErrorType = "Parse error";
22524 zErrorTail = &zErrMsg[12];
22525 }else if( strncmp(zErrMsg, "stepping, ", 10)==0 ){
22526 zErrorType = "Runtime error";
22527 zErrorTail = &zErrMsg[10];
22528 }else{
22529 zErrorType = "Error";
22530 zErrorTail = zErrMsg;
22531 }
22532 if( in!=0 || !stdin_is_interactive ){
22533 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
22534 "%s near line %d:", zErrorType, startline);
22535 }else{
22536 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
22537 }
22538 utf8_printf(stderr, "%s %s\n", zPrefix, zErrorTail);
22539 sqlite3_free(zErrMsg);
22540 zErrMsg = 0;
 
 
 
 
22541 return 1;
22542 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
22543 char zLineBuf[2000];
22544 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
22545 "changes: %lld total_changes: %lld",
@@ -22010,10 +22568,17 @@
22568 int rc; /* Error code */
22569 int errCnt = 0; /* Number of errors seen */
22570 int startline = 0; /* Line number for start of current input */
22571 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
22572
22573 if( p->inputNesting==MAX_INPUT_NESTING ){
22574 /* This will be more informative in a later version. */
22575 utf8_printf(stderr,"Input nesting limit (%d) reached at line %d."
22576 " Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
22577 return 1;
22578 }
22579 ++p->inputNesting;
22580 p->lineno = 0;
22581 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
22582 fflush(p->out);
22583 zLine = one_input_line(p->in, zLine, nSql>0);
22584 if( zLine==0 ){
@@ -22087,15 +22652,17 @@
22652 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22653 nSql = 0;
22654 qss = QSS_Start;
22655 }
22656 }
22657 if( nSql ){
22658 /* This may be incomplete. Let the SQL parser deal with that. */
22659 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22660 }
22661 free(zSql);
22662 free(zLine);
22663 --p->inputNesting;
22664 return errCnt>0;
22665 }
22666
22667 /*
22668 ** Return a pathname which is the user's home directory. A
22669
+2408 -1050
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.38.0. By combining all the individual C code files into this
3
+** version 3.39.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -450,13 +450,13 @@
450450
**
451451
** See also: [sqlite3_libversion()],
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455
-#define SQLITE_VERSION "3.38.0"
456
-#define SQLITE_VERSION_NUMBER 3038000
457
-#define SQLITE_SOURCE_ID "2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec"
455
+#define SQLITE_VERSION "3.39.0"
456
+#define SQLITE_VERSION_NUMBER 3039000
457
+#define SQLITE_SOURCE_ID "2022-03-23 10:04:52 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -870,11 +870,11 @@
870870
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871871
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872872
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873873
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874874
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875
-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
875
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
876876
877877
/*
878878
** CAPI3REF: Flags For File Open Operations
879879
**
880880
** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
41544154
**
41554155
** ^If the most recent error references a specific token in the input
41564156
** SQL, the sqlite3_error_offset() interface returns the byte offset
41574157
** of the start of that token. ^The byte offset returned by
41584158
** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159
-** ^If the most error does not reference a specific token in the input
4159
+** ^If the most recent error does not reference a specific token in the input
41604160
** SQL, then the sqlite3_error_offset() function returns -1.
41614161
**
41624162
** When the serialized [threading mode] is in use, it might be the
41634163
** case that a second error occurs on a separate thread in between
41644164
** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
45884588
** ^For example, an UPDATE statement might have a WHERE clause that
45894589
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
45904590
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
45914591
** read-only no-op if the table already exists, but
45924592
** sqlite3_stmt_readonly() still returns false for such a statement.
4593
+**
4594
+** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4595
+** statement, then sqlite3_stmt_readonly(X) returns the same value as
4596
+** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
45934597
*/
45944598
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
45954599
45964600
/*
45974601
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
46564660
** still make the distinction between protected and unprotected
46574661
** sqlite3_value objects even when not strictly required.
46584662
**
46594663
** ^The sqlite3_value objects that are passed as parameters into the
46604664
** implementation of [application-defined SQL functions] are protected.
4665
+** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4666
+** are protected.
46614667
** ^The sqlite3_value object returned by
46624668
** [sqlite3_column_value()] is unprotected.
46634669
** Unprotected sqlite3_value objects may only be used as arguments
46644670
** to [sqlite3_result_value()], [sqlite3_bind_value()], and
46654671
** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
52765282
** bytes in the string, not the number of characters.
52775283
**
52785284
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
52795285
** even empty strings, are always zero-terminated. ^The return
52805286
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
5287
+**
5288
+** ^Strings returned by sqlite3_column_text16() always have the endianness
5289
+** which is native to the platform, regardless of the text encoding set
5290
+** for the database.
52815291
**
52825292
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
52835293
** [unprotected sqlite3_value] object. In a multithreaded environment,
52845294
** an unprotected sqlite3_value object may only be used safely with
52855295
** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
52905300
** Hence, the sqlite3_column_value() interface
52915301
** is normally only useful within the implementation of
52925302
** [application-defined SQL functions] or [virtual tables], not within
52935303
** top-level application code.
52945304
**
5295
-** The these routines may attempt to convert the datatype of the result.
5305
+** These routines may attempt to convert the datatype of the result.
52965306
** ^For example, if the internal representation is FLOAT and a text result
52975307
** is requested, [sqlite3_snprintf()] is used internally to perform the
52985308
** conversion automatically. ^(The following table details the conversions
52995309
** that are applied:
53005310
**
@@ -5315,11 +5325,11 @@
53155325
** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
53165326
** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
53175327
** <tr><td> TEXT <td> BLOB <td> No change
53185328
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
53195329
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5320
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5330
+** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
53215331
** </table>
53225332
** </blockquote>)^
53235333
**
53245334
** Note that when type conversions occur, pointers returned by prior
53255335
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
58875897
**
58885898
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
58895899
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
58905900
** is a [protected sqlite3_value] object even if the input is not.
58915901
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5892
-** memory allocation fails.
5902
+** memory allocation fails. ^If V is a [pointer value], then the result
5903
+** of sqlite3_value_dup(V) is a NULL value.
58935904
**
58945905
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
58955906
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
58965907
** then sqlite3_value_free(V) is a harmless no-op.
58975908
*/
@@ -7435,28 +7446,60 @@
74357446
/*
74367447
** CAPI3REF: Virtual Table Constraint Operator Codes
74377448
**
74387449
** These macros define the allowed values for the
74397450
** [sqlite3_index_info].aConstraint[].op field. Each value represents
7440
-** an operator that is part of a constraint term in the wHERE clause of
7451
+** an operator that is part of a constraint term in the WHERE clause of
74417452
** a query that uses a [virtual table].
7453
+**
7454
+** ^The left-hand operand of the operator is given by the corresponding
7455
+** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7456
+** operand is the rowid.
7457
+** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7458
+** operators have no left-hand operand, and so for those operators the
7459
+** corresponding aConstraint[].iColumn is meaningless and should not be
7460
+** used.
7461
+**
7462
+** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7463
+** value 255 are reserved to represent functions that are overloaded
7464
+** by the [xFindFunction|xFindFunction method] of the virtual table
7465
+** implementation.
7466
+**
7467
+** The right-hand operands for each constraint might be accessible using
7468
+** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7469
+** operand is only available if it appears as a single constant literal
7470
+** in the input SQL. If the right-hand operand is another column or an
7471
+** expression (even a constant expression) or a parameter, then the
7472
+** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7473
+** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7474
+** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7475
+** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7476
+** always return SQLITE_NOTFOUND.
7477
+**
7478
+** The collating sequence to be used for comparison can be found using
7479
+** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7480
+** tables, the collating sequence of constraints does not matter (for example
7481
+** because the constraints are numeric) and so the sqlite3_vtab_collation()
7482
+** interface is no commonly needed.
74427483
*/
7443
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
7444
-#define SQLITE_INDEX_CONSTRAINT_GT 4
7445
-#define SQLITE_INDEX_CONSTRAINT_LE 8
7446
-#define SQLITE_INDEX_CONSTRAINT_LT 16
7447
-#define SQLITE_INDEX_CONSTRAINT_GE 32
7448
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7449
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7450
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7451
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7452
-#define SQLITE_INDEX_CONSTRAINT_NE 68
7453
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7454
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7455
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7456
-#define SQLITE_INDEX_CONSTRAINT_IS 72
7457
-#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7484
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
7485
+#define SQLITE_INDEX_CONSTRAINT_GT 4
7486
+#define SQLITE_INDEX_CONSTRAINT_LE 8
7487
+#define SQLITE_INDEX_CONSTRAINT_LT 16
7488
+#define SQLITE_INDEX_CONSTRAINT_GE 32
7489
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7490
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7491
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7492
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7493
+#define SQLITE_INDEX_CONSTRAINT_NE 68
7494
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7495
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7496
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7497
+#define SQLITE_INDEX_CONSTRAINT_IS 72
7498
+#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7499
+#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7500
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
74587501
74597502
/*
74607503
** CAPI3REF: Register A Virtual Table Implementation
74617504
** METHOD: sqlite3
74627505
**
@@ -7481,11 +7524,11 @@
74817524
** ^The sqlite3_create_module()
74827525
** interface is equivalent to sqlite3_create_module_v2() with a NULL
74837526
** destructor.
74847527
**
74857528
** ^If the third parameter (the pointer to the sqlite3_module object) is
7486
-** NULL then no new module is create and any existing modules with the
7529
+** NULL then no new module is created and any existing modules with the
74877530
** same name are dropped.
74887531
**
74897532
** See also: [sqlite3_drop_modules()]
74907533
*/
74917534
SQLITE_API int sqlite3_create_module(
@@ -9775,25 +9818,26 @@
97759818
*/
97769819
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
97779820
97789821
/*
97799822
** CAPI3REF: Determine The Collation For a Virtual Table Constraint
9823
+** METHOD: sqlite3_index_info
97809824
**
97819825
** This function may only be called from within a call to the [xBestIndex]
97829826
** method of a [virtual table]. This function returns a pointer to a string
97839827
** that is the name of the appropriate collation sequence to use for text
97849828
** comparisons on the constraint identified by its arguments.
97859829
**
9786
-** The first argument must be the pointer to the sqlite3_index_info object
9830
+** The first argument must be the pointer to the [sqlite3_index_info] object
97879831
** that is the first parameter to the xBestIndex() method. The second argument
97889832
** must be an index into the aConstraint[] array belonging to the
97899833
** sqlite3_index_info structure passed to xBestIndex.
97909834
**
97919835
** Important:
97929836
** The first parameter must be the same pointer that is passed into the
97939837
** xBestMethod() method. The first parameter may not be a pointer to a
9794
-** different sqlite3_index_info object, even an exact copy.
9838
+** different [sqlite3_index_info] object, even an exact copy.
97959839
**
97969840
** The return value is computed as follows:
97979841
**
97989842
** <ol>
97999843
** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9807,10 +9851,247 @@
98079851
** <li><p> Otherwise, "BINARY" is returned.
98089852
** </ol>
98099853
*/
98109854
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
98119855
9856
+/*
9857
+** CAPI3REF: Determine if a virtual table query is DISTINCT
9858
+** METHOD: sqlite3_index_info
9859
+**
9860
+** This API may only be used from within an [xBestIndex|xBestIndex method]
9861
+** of a [virtual table] implementation. The result of calling this
9862
+** interface from outside of xBestIndex() is undefined and probably harmful.
9863
+**
9864
+** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9865
+** 3. The integer returned by sqlite3_vtab_distinct()
9866
+** gives the virtual table additional information about how the query
9867
+** planner wants the output to be ordered. As long as the virtual table
9868
+** can meet the ordering requirements of the query planner, it may set
9869
+** the "orderByConsumed" flag.
9870
+**
9871
+** <ol><li value="0"><p>
9872
+** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9873
+** that the query planner needs the virtual table to return all rows in the
9874
+** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9875
+** [sqlite3_index_info] object. This is the default expectation. If the
9876
+** virtual table outputs all rows in sorted order, then it is always safe for
9877
+** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9878
+** the return value from sqlite3_vtab_distinct().
9879
+** <li value="1"><p>
9880
+** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9881
+** that the query planner does not need the rows to be returned in sorted order
9882
+** as long as all rows with the same values in all columns identified by the
9883
+** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
9884
+** is doing a GROUP BY.
9885
+** <li value="2"><p>
9886
+** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9887
+** that the query planner does not need the rows returned in any particular
9888
+** order, as long as rows with the same values in all "aOrderBy" columns
9889
+** are adjacent.)^ ^(Furthermore, only a single row for each particular
9890
+** combination of values in the columns identified by the "aOrderBy" field
9891
+** needs to be returned.)^ ^It is always ok for two or more rows with the same
9892
+** values in all "aOrderBy" columns to be returned, as long as all such rows
9893
+** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9894
+** that have the same value for all columns identified by "aOrderBy".
9895
+** ^However omitting the extra rows is optional.
9896
+** This mode is used for a DISTINCT query.
9897
+** <li value="3"><p>
9898
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9899
+** that the query planner needs only distinct rows but it does need the
9900
+** rows to be sorted.)^ ^The virtual table implementation is free to omit
9901
+** rows that are identical in all aOrderBy columns, if it wants to, but
9902
+** it is not required to omit any rows. This mode is used for queries
9903
+** that have both DISTINCT and ORDER BY clauses.
9904
+** </ol>
9905
+**
9906
+** ^For the purposes of comparing virtual table output values to see if the
9907
+** values are same value for sorting purposes, two NULL values are considered
9908
+** to be the same. In other words, the comparison operator is "IS"
9909
+** (or "IS NOT DISTINCT FROM") and not "==".
9910
+**
9911
+** If a virtual table implementation is unable to meet the requirements
9912
+** specified above, then it must not set the "orderByConsumed" flag in the
9913
+** [sqlite3_index_info] object or an incorrect answer may result.
9914
+**
9915
+** ^A virtual table implementation is always free to return rows in any order
9916
+** it wants, as long as the "orderByConsumed" flag is not set. ^When the
9917
+** the "orderByConsumed" flag is unset, the query planner will add extra
9918
+** [bytecode] to ensure that the final results returned by the SQL query are
9919
+** ordered correctly. The use of the "orderByConsumed" flag and the
9920
+** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful
9921
+** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed"
9922
+** flag might help queries against a virtual table to run faster. Being
9923
+** overly aggressive and setting the "orderByConsumed" flag when it is not
9924
+** valid to do so, on the other hand, might cause SQLite to return incorrect
9925
+** results.
9926
+*/
9927
+SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9928
+
9929
+/*
9930
+** CAPI3REF: Identify and handle IN constraints in xBestIndex
9931
+**
9932
+** This interface may only be used from within an
9933
+** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9934
+** The result of invoking this interface from any other context is
9935
+** undefined and probably harmful.
9936
+**
9937
+** ^(A constraint on a virtual table of the form
9938
+** "[IN operator|column IN (...)]" is
9939
+** communicated to the xBestIndex method as a
9940
+** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9941
+** this constraint, it must set the corresponding
9942
+** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9943
+** the usual mode of handling IN operators, SQLite generates [bytecode]
9944
+** that invokes the [xFilter|xFilter() method] once for each value
9945
+** on the right-hand side of the IN operator.)^ Thus the virtual table
9946
+** only sees a single value from the right-hand side of the IN operator
9947
+** at a time.
9948
+**
9949
+** In some cases, however, it would be advantageous for the virtual
9950
+** table to see all values on the right-hand of the IN operator all at
9951
+** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9952
+**
9953
+** <ol>
9954
+** <li><p>
9955
+** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9956
+** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9957
+** is an [IN operator] that can be processed all at once. ^In other words,
9958
+** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9959
+** by which the virtual table can ask SQLite if all-at-once processing
9960
+** of the IN operator is even possible.
9961
+**
9962
+** <li><p>
9963
+** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9964
+** to SQLite that the virtual table does or does not want to process
9965
+** the IN operator all-at-once, respectively. ^Thus when the third
9966
+** parameter (F) is non-negative, this interface is the mechanism by
9967
+** which the virtual table tells SQLite how it wants to process the
9968
+** IN operator.
9969
+** </ol>
9970
+**
9971
+** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9972
+** within the same xBestIndex method call. ^For any given P,N pair,
9973
+** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9974
+** within the same xBestIndex call. ^If the interface returns true
9975
+** (non-zero), that means that the constraint is an IN operator
9976
+** that can be processed all-at-once. ^If the constraint is not an IN
9977
+** operator or cannot be processed all-at-once, then the interface returns
9978
+** false.
9979
+**
9980
+** ^(All-at-once processing of the IN operator is selected if both of the
9981
+** following conditions are met:
9982
+**
9983
+** <ol>
9984
+** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9985
+** integer. This is how the virtual table tells SQLite that it wants to
9986
+** use the N-th constraint.
9987
+**
9988
+** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9989
+** non-negative had F>=1.
9990
+** </ol>)^
9991
+**
9992
+** ^If either or both of the conditions above are false, then SQLite uses
9993
+** the traditional one-at-a-time processing strategy for the IN constraint.
9994
+** ^If both conditions are true, then the argvIndex-th parameter to the
9995
+** xFilter method will be an [sqlite3_value] that appears to be NULL,
9996
+** but which can be passed to [sqlite3_vtab_in_first()] and
9997
+** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9998
+** of the IN constraint.
9999
+*/
10000
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
10001
+
10002
+/*
10003
+** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
10004
+**
10005
+** These interfaces are only useful from within the
10006
+** [xFilter|xFilter() method] of a [virtual table] implementation.
10007
+** The result of invoking these interfaces from any other context
10008
+** is undefined and probably harmful.
10009
+**
10010
+** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
10011
+** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
10012
+** xFilter method which invokes these routines, and specifically
10013
+** a parameter that was previously selected for all-at-once IN constraint
10014
+** processing use the [sqlite3_vtab_in()] interface in the
10015
+** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
10016
+** an xFilter argument that was selected for all-at-once IN constraint
10017
+** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
10018
+** exhibit some other undefined or harmful behavior.
10019
+**
10020
+** ^(Use these routines to access all values on the right-hand side
10021
+** of the IN constraint using code like the following:
10022
+**
10023
+** <blockquote><pre>
10024
+** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
10025
+** &nbsp; rc==SQLITE_OK && pVal
10026
+** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10027
+** &nbsp; ){
10028
+** &nbsp; // do something with pVal
10029
+** &nbsp; }
10030
+** &nbsp; if( rc!=SQLITE_OK ){
10031
+** &nbsp; // an error has occurred
10032
+** &nbsp; }
10033
+** </pre></blockquote>)^
10034
+**
10035
+** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
10036
+** routines return SQLITE_OK and set *P to point to the first or next value
10037
+** on the RHS of the IN constraint. ^If there are no more values on the
10038
+** right hand side of the IN constraint, then *P is set to NULL and these
10039
+** routines return [SQLITE_DONE]. ^The return value might be
10040
+** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
10041
+**
10042
+** The *ppOut values returned by these routines are only valid until the
10043
+** next call to either of these routines or until the end of the xFilter
10044
+** method from which these routines were called. If the virtual table
10045
+** implementation needs to retain the *ppOut values for longer, it must make
10046
+** copies. The *ppOut values are [protected sqlite3_value|protected].
10047
+*/
10048
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
10049
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
10050
+
10051
+/*
10052
+** CAPI3REF: Constraint values in xBestIndex()
10053
+** METHOD: sqlite3_index_info
10054
+**
10055
+** This API may only be used from within the [xBestIndex|xBestIndex method]
10056
+** of a [virtual table] implementation. The result of calling this interface
10057
+** from outside of an xBestIndex method are undefined and probably harmful.
10058
+**
10059
+** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
10060
+** the [xBestIndex] method of a [virtual table] implementation, with P being
10061
+** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
10062
+** J being a 0-based index into P->aConstraint[], then this routine
10063
+** attempts to set *V to the value of the right-hand operand of
10064
+** that constraint if the right-hand operand is known. ^If the
10065
+** right-hand operand is not known, then *V is set to a NULL pointer.
10066
+** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
10067
+** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
10068
+** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
10069
+** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
10070
+** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
10071
+** something goes wrong.
10072
+**
10073
+** The sqlite3_vtab_rhs_value() interface is usually only successful if
10074
+** the right-hand operand of a constraint is a literal value in the original
10075
+** SQL statement. If the right-hand operand is an expression or a reference
10076
+** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
10077
+** will probably return [SQLITE_NOTFOUND].
10078
+**
10079
+** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
10080
+** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
10081
+** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
10082
+**
10083
+** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
10084
+** and remains valid for the duration of the xBestIndex method call.
10085
+** ^When xBestIndex returns, the sqlite3_value object returned by
10086
+** sqlite3_vtab_rhs_value() is automatically deallocated.
10087
+**
10088
+** The "_rhs_" in the name of this routine is an abbreviation for
10089
+** "Right-Hand Side".
10090
+*/
10091
+SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
10092
+
981210093
/*
981310094
** CAPI3REF: Conflict resolution modes
981410095
** KEYWORDS: {conflict resolution mode}
981510096
**
981610097
** These constants are returned by [sqlite3_vtab_on_conflict()] to
@@ -14246,11 +14527,11 @@
1424614527
** one parameter that destructors normally want. So we have to introduce
1424714528
** this magic value that the code knows to handle differently. Any
1424814529
** pointer will work here as long as it is distinct from SQLITE_STATIC
1424914530
** and SQLITE_TRANSIENT.
1425014531
*/
14251
-#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomFault)
14532
+#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear)
1425214533
1425314534
/*
1425414535
** When SQLITE_OMIT_WSD is defined, it means that the target platform does
1425514536
** not support Writable Static Data (WSD) such as global and static variables.
1425614537
** All variables must either be on the stack or dynamically allocated from
@@ -14374,14 +14655,15 @@
1437414655
#define BMS ((int)(sizeof(Bitmask)*8))
1437514656
1437614657
/*
1437714658
** A bit in a Bitmask
1437814659
*/
14379
-#define MASKBIT(n) (((Bitmask)1)<<(n))
14380
-#define MASKBIT64(n) (((u64)1)<<(n))
14381
-#define MASKBIT32(n) (((unsigned int)1)<<(n))
14382
-#define ALLBITS ((Bitmask)-1)
14660
+#define MASKBIT(n) (((Bitmask)1)<<(n))
14661
+#define MASKBIT64(n) (((u64)1)<<(n))
14662
+#define MASKBIT32(n) (((unsigned int)1)<<(n))
14663
+#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0)
14664
+#define ALLBITS ((Bitmask)-1)
1438314665
1438414666
/* A VList object records a mapping between parameters/variables/wildcards
1438514667
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
1438614668
** variable number associated with that parameter. See the format description
1438714669
** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14439,18 +14721,19 @@
1443914721
** Handle type for pages.
1444014722
*/
1444114723
typedef struct PgHdr DbPage;
1444214724
1444314725
/*
14444
-** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
14726
+** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is
1444514727
** reserved for working around a windows/posix incompatibility). It is
1444614728
** used in the journal to signify that the remainder of the journal file
1444714729
** is devoted to storing a super-journal name - there are no more pages to
1444814730
** roll back. See comments for function writeSuperJournal() in pager.c
1444914731
** for details.
1445014732
*/
14451
-#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14733
+#define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14734
+#define PAGER_SJ_PGNO(x) ((x)->lckPgno)
1445214735
1445314736
/*
1445414737
** Allowed values for the flags parameter to sqlite3PagerOpen().
1445514738
**
1445614739
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15123,11 +15406,10 @@
1512315406
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
1512415407
Table *pTab; /* Used when p4type is P4_TABLE */
1512515408
#ifdef SQLITE_ENABLE_CURSOR_HINTS
1512615409
Expr *pExpr; /* Used when p4type is P4_EXPR */
1512715410
#endif
15128
- int (*xAdvance)(BtCursor *, int);
1512915411
} p4;
1513015412
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
1513115413
char *zComment; /* Comment to improve readability */
1513215414
#endif
1513315415
#ifdef VDBE_PROFILE
@@ -15174,25 +15456,23 @@
1517415456
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
1517515457
#define P4_STATIC (-1) /* Pointer to a static string */
1517615458
#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
1517715459
#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
1517815460
#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15179
-#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
15180
-#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
15461
+#define P4_TABLE (-5) /* P4 is a pointer to a Table structure */
1518115462
/* Above do not own any resources. Must free those below */
15182
-#define P4_FREE_IF_LE (-7)
15183
-#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
15184
-#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
15185
-#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
15186
-#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
15187
-#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
15188
-#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
15189
-#define P4_REAL (-13) /* P4 is a 64-bit floating point value */
15190
-#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
15191
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
15192
-#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
15193
-#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
15463
+#define P4_FREE_IF_LE (-6)
15464
+#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */
15465
+#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */
15466
+#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */
15467
+#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */
15468
+#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */
15469
+#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
15470
+#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
15471
+#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
15472
+#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
15473
+#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
1519415474
1519515475
/* Error message codes for OP_Halt */
1519615476
#define P5_ConstraintNotNull 1
1519715477
#define P5_ConstraintUnique 2
1519815478
#define P5_ConstraintCheck 3
@@ -15233,46 +15513,46 @@
1523315513
/* Automatically generated. Do not edit */
1523415514
/* See the tool/mkopcodeh.tcl script for details */
1523515515
#define OP_Savepoint 0
1523615516
#define OP_AutoCommit 1
1523715517
#define OP_Transaction 2
15238
-#define OP_SorterNext 3 /* jump */
15239
-#define OP_Prev 4 /* jump */
15240
-#define OP_Next 5 /* jump */
15241
-#define OP_Checkpoint 6
15242
-#define OP_JournalMode 7
15243
-#define OP_Vacuum 8
15244
-#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15245
-#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */
15246
-#define OP_Goto 11 /* jump */
15247
-#define OP_Gosub 12 /* jump */
15248
-#define OP_InitCoroutine 13 /* jump */
15249
-#define OP_Yield 14 /* jump */
15250
-#define OP_MustBeInt 15 /* jump */
15251
-#define OP_Jump 16 /* jump */
15252
-#define OP_Once 17 /* jump */
15253
-#define OP_If 18 /* jump */
15518
+#define OP_Checkpoint 3
15519
+#define OP_JournalMode 4
15520
+#define OP_Vacuum 5
15521
+#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15522
+#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
15523
+#define OP_Goto 8 /* jump */
15524
+#define OP_Gosub 9 /* jump */
15525
+#define OP_InitCoroutine 10 /* jump */
15526
+#define OP_Yield 11 /* jump */
15527
+#define OP_MustBeInt 12 /* jump */
15528
+#define OP_Jump 13 /* jump */
15529
+#define OP_Once 14 /* jump */
15530
+#define OP_If 15 /* jump */
15531
+#define OP_IfNot 16 /* jump */
15532
+#define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15533
+#define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
1525415534
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15255
-#define OP_IfNot 20 /* jump */
15256
-#define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15257
-#define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15258
-#define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */
15259
-#define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */
15260
-#define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */
15261
-#define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */
15262
-#define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15263
-#define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */
15264
-#define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */
15265
-#define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */
15266
-#define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */
15267
-#define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */
15268
-#define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */
15269
-#define OP_Last 34 /* jump */
15270
-#define OP_IfSmaller 35 /* jump */
15271
-#define OP_SorterSort 36 /* jump */
15272
-#define OP_Sort 37 /* jump */
15273
-#define OP_Rewind 38 /* jump */
15535
+#define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */
15536
+#define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */
15537
+#define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */
15538
+#define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */
15539
+#define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15540
+#define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */
15541
+#define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */
15542
+#define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */
15543
+#define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */
15544
+#define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */
15545
+#define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */
15546
+#define OP_Last 31 /* jump */
15547
+#define OP_IfSmaller 32 /* jump */
15548
+#define OP_SorterSort 33 /* jump */
15549
+#define OP_Sort 34 /* jump */
15550
+#define OP_Rewind 35 /* jump */
15551
+#define OP_SorterNext 36 /* jump */
15552
+#define OP_Prev 37 /* jump */
15553
+#define OP_Next 38 /* jump */
1527415554
#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
1527515555
#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
1527615556
#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
1527715557
#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
1527815558
#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15301,41 +15581,41 @@
1530115581
#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
1530215582
#define OP_Return 67
1530315583
#define OP_EndCoroutine 68
1530415584
#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
1530515585
#define OP_Halt 70
15306
-#define OP_Integer 71 /* synopsis: r[P2]=P1 */
15307
-#define OP_Int64 72 /* synopsis: r[P2]=P4 */
15308
-#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15309
-#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15310
-#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15311
-#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15312
-#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15313
-#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15314
-#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15315
-#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15316
-#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15317
-#define OP_FkCheck 82
15318
-#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15319
-#define OP_CollSeq 84
15320
-#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15321
-#define OP_RealAffinity 86
15322
-#define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15323
-#define OP_Permutation 88
15324
-#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15325
-#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15326
-#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15327
-#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15328
-#define OP_Column 93 /* synopsis: r[P3]=PX */
15329
-#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15330
-#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15331
-#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15332
-#define OP_Count 97 /* synopsis: r[P2]=count() */
15333
-#define OP_ReadCookie 98
15334
-#define OP_SetCookie 99
15335
-#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15336
-#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
15586
+#define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587
+#define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588
+#define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589
+#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15590
+#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15591
+#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15592
+#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15593
+#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15594
+#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
15595
+#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15596
+#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
15597
+#define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */
15598
+#define OP_FkCheck 83
15599
+#define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */
15600
+#define OP_CollSeq 85
15601
+#define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */
15602
+#define OP_RealAffinity 87
15603
+#define OP_Cast 88 /* synopsis: affinity(r[P1]) */
15604
+#define OP_Permutation 89
15605
+#define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15606
+#define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15607
+#define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15608
+#define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609
+#define OP_Column 94 /* synopsis: r[P3]=PX */
15610
+#define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15611
+#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15612
+#define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15613
+#define OP_Count 98 /* synopsis: r[P2]=count() */
15614
+#define OP_ReadCookie 99
15615
+#define OP_SetCookie 100
15616
+#define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */
1533715617
#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
1533815618
#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
1533915619
#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
1534015620
#define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
1534115621
#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15342,82 +15622,84 @@
1534215622
#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
1534315623
#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
1534415624
#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
1534515625
#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
1534615626
#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15347
-#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
15348
-#define OP_OpenDup 113
15627
+#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */
15628
+#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */
1534915629
#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15350
-#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
15351
-#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */
15630
+#define OP_OpenDup 115
15631
+#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
1535215632
#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15353
-#define OP_SorterOpen 118
15354
-#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15355
-#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15356
-#define OP_Close 121
15357
-#define OP_ColumnsUsed 122
15358
-#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15359
-#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15360
-#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15361
-#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15362
-#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15363
-#define OP_RowCell 128
15364
-#define OP_Delete 129
15365
-#define OP_ResetCount 130
15366
-#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15367
-#define OP_SorterData 132 /* synopsis: r[P2]=data */
15368
-#define OP_RowData 133 /* synopsis: r[P2]=data */
15369
-#define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15370
-#define OP_NullRow 135
15371
-#define OP_SeekEnd 136
15372
-#define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15373
-#define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15374
-#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15375
-#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15376
-#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15377
-#define OP_FinishSeek 142
15378
-#define OP_Destroy 143
15379
-#define OP_Clear 144
15380
-#define OP_ResetSorter 145
15381
-#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15382
-#define OP_SqlExec 147
15383
-#define OP_ParseSchema 148
15384
-#define OP_LoadAnalysis 149
15385
-#define OP_DropTable 150
15386
-#define OP_DropIndex 151
15387
-#define OP_DropTrigger 152
15633
+#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */
15634
+#define OP_SorterOpen 119
15635
+#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15636
+#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
15637
+#define OP_Close 122
15638
+#define OP_ColumnsUsed 123
15639
+#define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */
15640
+#define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */
15641
+#define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */
15642
+#define OP_NewRowid 127 /* synopsis: r[P2]=rowid */
15643
+#define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */
15644
+#define OP_RowCell 129
15645
+#define OP_Delete 130
15646
+#define OP_ResetCount 131
15647
+#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15648
+#define OP_SorterData 133 /* synopsis: r[P2]=data */
15649
+#define OP_RowData 134 /* synopsis: r[P2]=data */
15650
+#define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15651
+#define OP_NullRow 136
15652
+#define OP_SeekEnd 137
15653
+#define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15654
+#define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15655
+#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
15656
+#define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */
15657
+#define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */
15658
+#define OP_FinishSeek 143
15659
+#define OP_Destroy 144
15660
+#define OP_Clear 145
15661
+#define OP_ResetSorter 146
15662
+#define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15663
+#define OP_SqlExec 148
15664
+#define OP_ParseSchema 149
15665
+#define OP_LoadAnalysis 150
15666
+#define OP_DropTable 151
15667
+#define OP_DropIndex 152
1538815668
#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15389
-#define OP_IntegrityCk 154
15390
-#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15391
-#define OP_Param 156
15392
-#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15393
-#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15394
-#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15395
-#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15396
-#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15397
-#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15398
-#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15399
-#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15400
-#define OP_Expire 165
15401
-#define OP_CursorLock 166
15402
-#define OP_CursorUnlock 167
15403
-#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15404
-#define OP_VBegin 169
15405
-#define OP_VCreate 170
15406
-#define OP_VDestroy 171
15407
-#define OP_VOpen 172
15408
-#define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15409
-#define OP_VRename 174
15410
-#define OP_Pagecount 175
15411
-#define OP_MaxPgcnt 176
15412
-#define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15413
-#define OP_Trace 178
15414
-#define OP_CursorHint 179
15415
-#define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15416
-#define OP_Noop 181
15417
-#define OP_Explain 182
15418
-#define OP_Abortable 183
15669
+#define OP_DropTrigger 154
15670
+#define OP_IntegrityCk 155
15671
+#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */
15672
+#define OP_Param 157
15673
+#define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */
15674
+#define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15675
+#define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15676
+#define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15677
+#define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15678
+#define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15679
+#define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */
15680
+#define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */
15681
+#define OP_Expire 166
15682
+#define OP_CursorLock 167
15683
+#define OP_CursorUnlock 168
15684
+#define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */
15685
+#define OP_VBegin 170
15686
+#define OP_VCreate 171
15687
+#define OP_VDestroy 172
15688
+#define OP_VOpen 173
15689
+#define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15690
+#define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15691
+#define OP_VRename 176
15692
+#define OP_Pagecount 177
15693
+#define OP_MaxPgcnt 178
15694
+#define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15695
+#define OP_Trace 180
15696
+#define OP_CursorHint 181
15697
+#define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15698
+#define OP_Noop 183
15699
+#define OP_Explain 184
15700
+#define OP_Abortable 185
1541915701
1542015702
/* Properties such as "out2" or "jump" that are specified in
1542115703
** comments following the "case" for each opcode in the vdbe.c
1542215704
** are encoded into bitvectors as follows:
1542315705
*/
@@ -15426,34 +15708,34 @@
1542615708
#define OPFLG_IN2 0x04 /* in2: P2 is an input */
1542715709
#define OPFLG_IN3 0x08 /* in3: P3 is an input */
1542815710
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
1542915711
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
1543015712
#define OPFLG_INITIALIZER {\
15431
-/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
15432
-/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
15433
-/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\
15434
-/* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15435
-/* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15713
+/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
15714
+/* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\
15715
+/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\
15716
+/* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15717
+/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
1543615718
/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
1543715719
/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
1543815720
/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15439
-/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15440
-/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15441
-/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15442
-/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15443
-/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
15721
+/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722
+/* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15723
+/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15724
+/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15725
+/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
1544415726
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
1544515727
/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15446
-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15447
-/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15448
-/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15449
-/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15450
-/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
15451
-/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15452
-/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15453
-/* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15454
-}
15728
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15729
+/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15730
+/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15731
+/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15732
+/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15733
+/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15734
+/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15735
+/* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15736
+/* 184 */ 0x00, 0x00,}
1545515737
1545615738
/* The resolve3P2Values() routine is able to run faster if it knows
1545715739
** the value of the largest JUMP opcode. The smaller the maximum
1545815740
** JUMP opcode the better, so the mkopcodeh.tcl script that
1545915741
** generated this include file strives to group all JUMP opcodes
@@ -17507,10 +17789,15 @@
1750717789
** b-tree.
1750817790
*/
1750917791
struct UnpackedRecord {
1751017792
KeyInfo *pKeyInfo; /* Collation and sort-order information */
1751117793
Mem *aMem; /* Values */
17794
+ union {
17795
+ char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */
17796
+ i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
17797
+ } u;
17798
+ int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */
1751217799
u16 nField; /* Number of entries in apMem[] */
1751317800
i8 default_rc; /* Comparison result if keys are equal */
1751417801
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
1751517802
i8 r1; /* Value to return if (lhs < rhs) */
1751617803
i8 r2; /* Value to return if (lhs > rhs) */
@@ -17814,11 +18101,14 @@
1781418101
** TK_SELECT: 1st register of result vector */
1781518102
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
1781618103
** TK_VARIABLE: variable number (always >= 1).
1781718104
** TK_SELECT_COLUMN: column of the result vector */
1781818105
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
17819
- int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18106
+ union {
18107
+ int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18108
+ int iOfst; /* else: start of token from start of statement */
18109
+ } w;
1782018110
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
1782118111
union {
1782218112
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
1782318113
** for a column of an index on an expression */
1782418114
Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -18576,10 +18866,11 @@
1857618866
** initialized as they will be set before being used. The boundary is
1857718867
** determined by offsetof(Parse,aTempReg).
1857818868
**************************************************************************/
1857918869
1858018870
int aTempReg[8]; /* Holding area for temporary registers */
18871
+ Parse *pOuterParse; /* Outer Parse object when nested */
1858118872
Token sNameToken; /* Token with unqualified schema object name */
1858218873
1858318874
/************************************************************************
1858418875
** Above is constant between recursions. Below is reset before and after
1858518876
** each recursion. The boundary between these two regions is determined
@@ -18626,11 +18917,12 @@
1862618917
#define PARSE_MODE_UNMAP 3
1862718918
1862818919
/*
1862918920
** Sizes and pointers of various parts of the Parse object.
1863018921
*/
18631
-#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
18922
+#define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg))
18923
+#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/
1863218924
#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
1863318925
#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
1863418926
#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
1863518927
1863618928
/*
@@ -18921,10 +19213,11 @@
1892119213
#endif
1892219214
#ifndef SQLITE_UNTESTABLE
1892319215
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
1892419216
#endif
1892519217
int bLocaltimeFault; /* True to fail localtime() calls */
19218
+ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
1892619219
int iOnceResetThreshold; /* When to reset OP_Once counters */
1892719220
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
1892819221
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
1892919222
/* vvvv--- must be last ---vvv */
1893019223
#ifdef SQLITE_DEBUG
@@ -19125,11 +19418,11 @@
1912519418
Expr *pStart; /* Expression for "<expr> PRECEDING" */
1912619419
Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
1912719420
Window **ppThis; /* Pointer to this object in Select.pWin list */
1912819421
Window *pNextWin; /* Next window function belonging to this SELECT */
1912919422
Expr *pFilter; /* The FILTER expression */
19130
- FuncDef *pFunc; /* The function */
19423
+ FuncDef *pWFunc; /* The function */
1913119424
int iEphCsr; /* Partition buffer or Peer buffer */
1913219425
int regAccum; /* Accumulator */
1913319426
int regResult; /* Interim result */
1913419427
int csrApp; /* Function cursor (used by min/max) */
1913519428
int regApp; /* Function register (also used by min/max) */
@@ -19566,11 +19859,12 @@
1956619859
#endif
1956719860
SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
1956819861
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
1956919862
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
1957019863
Upsert*);
19571
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
19864
+SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,
19865
+ ExprList*,Select*,u16,int);
1957219866
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
1957319867
SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
1957419868
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
1957519869
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
1957619870
SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -19966,11 +20260,11 @@
1996620260
void (*)(sqlite3_context*),
1996720261
void (*)(sqlite3_context*,int,sqlite3_value **),
1996820262
FuncDestructor *pDestructor
1996920263
);
1997020264
SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
19971
-SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
20265
+SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*);
1997220266
SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
1997320267
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
1997420268
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
1997520269
1997620270
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
@@ -19979,10 +20273,11 @@
1997920273
SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
1998020274
SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
1998120275
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
1998220276
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
1998320277
SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
20278
+SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
1998420279
1998520280
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
1998620281
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
1998720282
1998820283
#ifndef SQLITE_OMIT_SUBQUERY
@@ -20083,15 +20378,21 @@
2008320378
SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
2008420379
SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
2008520380
SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
2008620381
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
2008720382
SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20383
+
2008820384
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20385
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20386
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
20387
+SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20388
+#endif
2008920389
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
2009020390
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
2009120391
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20092
-SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
20392
+SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
20393
+SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*);
2009320394
SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
2009420395
#ifdef SQLITE_ENABLE_NORMALIZE
2009520396
SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
2009620397
#endif
2009720398
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
@@ -20520,10 +20821,18 @@
2052020821
2052120822
#endif /* !defined(_OS_COMMON_H_) */
2052220823
2052320824
/************** End of os_common.h *******************************************/
2052420825
/************** Begin file ctime.c *******************************************/
20826
+/* DO NOT EDIT!
20827
+** This file is automatically generated by the script in the canonical
20828
+** SQLite source tree at tool/mkctimec.tcl.
20829
+**
20830
+** To modify this header, edit any of the various lists in that script
20831
+** which specify categories of generated conditionals in this file.
20832
+*/
20833
+
2052520834
/*
2052620835
** 2010 February 23
2052720836
**
2052820837
** The author disclaims copyright to this source code. In place of
2052920838
** a legal notice, here is a blessing:
@@ -20568,13 +20877,10 @@
2056820877
** only a handful of compile-time options, so most times this array is usually
2056920878
** rather short and uses little memory space.
2057020879
*/
2057120880
static const char * const sqlite3azCompileOpt[] = {
2057220881
20573
-/*
20574
-** BEGIN CODE GENERATED BY tool/mkctime.tcl
20575
-*/
2057620882
#ifdef SQLITE_32BIT_ROWID
2057720883
"32BIT_ROWID",
2057820884
#endif
2057920885
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
2058020886
"4_BYTE_ALIGNED_MALLOC",
@@ -20701,13 +21007,10 @@
2070121007
"DISABLE_FTS4_DEFERRED",
2070221008
#endif
2070321009
#ifdef SQLITE_DISABLE_INTRINSIC
2070421010
"DISABLE_INTRINSIC",
2070521011
#endif
20706
-#ifdef SQLITE_DISABLE_JSON
20707
- "DISABLE_JSON",
20708
-#endif
2070921012
#ifdef SQLITE_DISABLE_LFS
2071021013
"DISABLE_LFS",
2071121014
#endif
2071221015
#ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
2071321016
"DISABLE_PAGECACHE_OVERFLOW_STATS",
@@ -21104,10 +21407,13 @@
2110421407
#ifdef SQLITE_OMIT_INTEGRITY_CHECK
2110521408
"OMIT_INTEGRITY_CHECK",
2110621409
#endif
2110721410
#ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS
2110821411
"OMIT_INTROSPECTION_PRAGMAS",
21412
+#endif
21413
+#ifdef SQLITE_OMIT_JSON
21414
+ "OMIT_JSON",
2110921415
#endif
2111021416
#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
2111121417
"OMIT_LIKE_OPTIMIZATION",
2111221418
#endif
2111321419
#ifdef SQLITE_OMIT_LOAD_EXTENSION
@@ -21293,14 +21599,12 @@
2129321599
"WIN32_MALLOC",
2129421600
#endif
2129521601
#ifdef SQLITE_ZERO_MALLOC
2129621602
"ZERO_MALLOC",
2129721603
#endif
21298
-/*
21299
-** END CODE GENERATED BY tool/mkctime.tcl
21300
-*/
21301
-};
21604
+
21605
+} ;
2130221606
2130321607
SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
2130421608
*pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
2130521609
return (const char**)sqlite3azCompileOpt;
2130621610
}
@@ -21595,13 +21899,17 @@
2159521899
#endif
2159621900
#ifndef SQLITE_UNTESTABLE
2159721901
0, /* xTestCallback */
2159821902
#endif
2159921903
0, /* bLocaltimeFault */
21904
+ 0, /* xAltLocaltime */
2160021905
0x7ffffffe, /* iOnceResetThreshold */
2160121906
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
2160221907
0, /* iPrngSeed */
21908
+#ifdef SQLITE_DEBUG
21909
+ {0,0,0,0,0,0} /* aTune */
21910
+#endif
2160321911
};
2160421912
2160521913
/*
2160621914
** Hash table for global functions - functions common to all
2160721915
** database connections. After initialization, this table is
@@ -21941,20 +22249,20 @@
2194122249
i64 i; /* Integer value used when MEM_Int is set in flags */
2194222250
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
2194322251
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
2194422252
FuncDef *pDef; /* Used only when flags==MEM_Agg */
2194522253
} u;
22254
+ char *z; /* String or BLOB value */
22255
+ int n; /* Number of characters in string value, excluding '\0' */
2194622256
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
2194722257
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
2194822258
u8 eSubtype; /* Subtype for this value */
21949
- int n; /* Number of characters in string value, excluding '\0' */
21950
- char *z; /* String or BLOB value */
2195122259
/* ShallowCopy only needs to copy the information above */
21952
- char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
22260
+ sqlite3 *db; /* The associated database connection */
2195322261
int szMalloc; /* Size of the zMalloc allocation */
2195422262
u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
21955
- sqlite3 *db; /* The associated database connection */
22263
+ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
2195622264
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
2195722265
#ifdef SQLITE_DEBUG
2195822266
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
2195922267
u16 mScopyFlags; /* flags value immediately after the shallow copy */
2196022268
#endif
@@ -21962,15 +22270,47 @@
2196222270
2196322271
/*
2196422272
** Size of struct Mem not including the Mem.zMalloc member or anything that
2196522273
** follows.
2196622274
*/
21967
-#define MEMCELLSIZE offsetof(Mem,zMalloc)
22275
+#define MEMCELLSIZE offsetof(Mem,db)
2196822276
21969
-/* One or more of the following flags are set to indicate the validOK
22277
+/* One or more of the following flags are set to indicate the
2197022278
** representations of the value stored in the Mem struct.
2197122279
**
22280
+** * MEM_Null An SQL NULL value
22281
+**
22282
+** * MEM_Null|MEM_Zero An SQL NULL with the virtual table
22283
+** UPDATE no-change flag set
22284
+**
22285
+** * MEM_Null|MEM_Term| An SQL NULL, but also contains a
22286
+** MEM_Subtype pointer accessible using
22287
+** sqlite3_value_pointer().
22288
+**
22289
+** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal
22290
+** to other NULLs even using the IS operator.
22291
+**
22292
+** * MEM_Str A string, stored in Mem.z with
22293
+** length Mem.n. Zero-terminated if
22294
+** MEM_Term is set. This flag is
22295
+** incompatible with MEM_Blob and
22296
+** MEM_Null, but can appear with MEM_Int,
22297
+** MEM_Real, and MEM_IntReal.
22298
+**
22299
+** * MEM_Blob A blob, stored in Mem.z length Mem.n.
22300
+** Incompatible with MEM_Str, MEM_Null,
22301
+** MEM_Int, MEM_Real, and MEM_IntReal.
22302
+**
22303
+** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus
22304
+** MEM.u.i extra 0x00 bytes at the end.
22305
+**
22306
+** * MEM_Int Integer stored in Mem.u.i.
22307
+**
22308
+** * MEM_Real Real stored in Mem.u.r.
22309
+**
22310
+** * MEM_IntReal Real stored as an integer in Mem.u.i.
22311
+**
2197222312
** If the MEM_Null flag is set, then the value is an SQL NULL value.
2197322313
** For a pointer type created using sqlite3_bind_pointer() or
2197422314
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
2197522315
**
2197622316
** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -21977,39 +22317,36 @@
2197722317
** Usually this is encoded in the same unicode encoding as the main
2197822318
** database (see below for exceptions). If the MEM_Term flag is also
2197922319
** set, then the string is nul terminated. The MEM_Int and MEM_Real
2198022320
** flags may coexist with the MEM_Str flag.
2198122321
*/
22322
+#define MEM_Undefined 0x0000 /* Value is undefined */
2198222323
#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
2198322324
#define MEM_Str 0x0002 /* Value is a string */
2198422325
#define MEM_Int 0x0004 /* Value is an integer */
2198522326
#define MEM_Real 0x0008 /* Value is a real number */
2198622327
#define MEM_Blob 0x0010 /* Value is a BLOB */
2198722328
#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
2198822329
#define MEM_AffMask 0x003f /* Mask of affinity bits */
22330
+
22331
+/* Extra bits that modify the meanings of the core datatypes above
22332
+*/
2198922333
#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
21990
-#define MEM_Undefined 0x0080 /* Value is undefined */
22334
+ /* 0x0080 // Available */
2199122335
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
21992
-#define MEM_TypeMask 0xc1bf /* Mask of type bits */
21993
-
21994
-
21995
-/* Whenever Mem contains a valid string or blob representation, one of
21996
-** the following flags must be set to determine the memory management
21997
-** policy for Mem.z. The MEM_Term flag tells us whether or not the
21998
-** string is \000 or \u0000 terminated
21999
-*/
2200022336
#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22001
-#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
22002
-#define MEM_Static 0x0800 /* Mem.z points to a static string */
22003
-#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
22004
-#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
22005
-#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
22006
-#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
22007
-#ifdef SQLITE_OMIT_INCRBLOB
22008
- #undef MEM_Zero
22009
- #define MEM_Zero 0x0000
22010
-#endif
22337
+#define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */
22338
+#define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */
22339
+#define MEM_TypeMask 0x0dbf /* Mask of type bits */
22340
+
22341
+/* Bits that determine the storage for Mem.z for a string or blob or
22342
+** aggregate accumulator.
22343
+*/
22344
+#define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */
22345
+#define MEM_Static 0x2000 /* Mem.z points to a static string */
22346
+#define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */
22347
+#define MEM_Agg 0x8000 /* Mem.z points to an agg function context */
2201122348
2201222349
/* Return TRUE if Mem X contains dynamically allocated content - anything
2201322350
** that needs to be deallocated to avoid a leak.
2201422351
*/
2201522352
#define VdbeMemDynamic(X) \
@@ -22027,15 +22364,19 @@
2202722364
#define MemNullNochng(X) \
2202822365
(((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
2202922366
&& (X)->n==0 && (X)->u.nZero==0)
2203022367
2203122368
/*
22032
-** Return true if a memory cell is not marked as invalid. This macro
22369
+** Return true if a memory cell has been initialized and is valid.
2203322370
** is for use inside assert() statements only.
22371
+**
22372
+** A Memory cell is initialized if at least one of the
22373
+** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits
22374
+** is set. It is "undefined" if all those bits are zero.
2203422375
*/
2203522376
#ifdef SQLITE_DEBUG
22036
-#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
22377
+#define memIsValid(M) ((M)->flags & MEM_AffMask)!=0
2203722378
#endif
2203822379
2203922380
/*
2204022381
** Each auxiliary data pointer stored by a user defined function
2204122382
** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22215,18 +22556,36 @@
2221522556
Mem *aNew; /* Array of new.* values */
2221622557
Table *pTab; /* Schema object being upated */
2221722558
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
2221822559
};
2221922560
22561
+/*
22562
+** An instance of this object is used to pass an vector of values into
22563
+** OP_VFilter, the xFilter method of a virtual table. The vector is the
22564
+** set of values on the right-hand side of an IN constraint.
22565
+**
22566
+** The value as passed into xFilter is an sqlite3_value with a "pointer"
22567
+** type, such as is generated by sqlite3_result_pointer() and read by
22568
+** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
22569
+** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
22570
+** know how to use this object to step through all the values in the
22571
+** right operand of the IN constraint.
22572
+*/
22573
+typedef struct ValueList ValueList;
22574
+struct ValueList {
22575
+ BtCursor *pCsr; /* An ephemeral table holding all values */
22576
+ sqlite3_value *pOut; /* Register to hold each decoded output value */
22577
+};
22578
+
2222022579
/*
2222122580
** Function prototypes
2222222581
*/
2222322582
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
2222422583
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
2222522584
void sqliteVdbePopStack(Vdbe*,int);
22585
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
2222622586
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22227
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
2222822587
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
2222922588
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
2223022589
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
2223122590
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
2223222591
SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22284,10 +22643,11 @@
2228422643
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
2228522644
SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
2228622645
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
2228722646
SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
2228822647
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
22648
+SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p);
2228922649
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
2229022650
#ifndef SQLITE_OMIT_WINDOWFUNC
2229122651
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
2229222652
#endif
2229322653
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23251,12 +23611,14 @@
2325123611
** The following routine implements the rough equivalent of localtime_r()
2325223612
** using whatever operating-system specific localtime facility that
2325323613
** is available. This routine returns 0 on success and
2325423614
** non-zero on any kind of error.
2325523615
**
23256
-** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
23257
-** routine will always fail.
23616
+** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
23617
+** routine will always fail. If bLocaltimeFault is nonzero and
23618
+** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
23619
+** invoked in place of the OS-defined localtime() function.
2325823620
**
2325923621
** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
2326023622
** library function localtime_r() is used to assist in the calculation of
2326123623
** local time.
2326223624
*/
@@ -23268,20 +23630,34 @@
2326823630
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
2326923631
#endif
2327023632
sqlite3_mutex_enter(mutex);
2327123633
pX = localtime(t);
2327223634
#ifndef SQLITE_UNTESTABLE
23273
- if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
23635
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
23636
+ if( sqlite3GlobalConfig.xAltLocaltime!=0
23637
+ && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
23638
+ ){
23639
+ pX = pTm;
23640
+ }else{
23641
+ pX = 0;
23642
+ }
23643
+ }
2327423644
#endif
2327523645
if( pX ) *pTm = *pX;
2327623646
#if SQLITE_THREADSAFE>0
2327723647
sqlite3_mutex_leave(mutex);
2327823648
#endif
2327923649
rc = pX==0;
2328023650
#else
2328123651
#ifndef SQLITE_UNTESTABLE
23282
- if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
23652
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
23653
+ if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
23654
+ return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
23655
+ }else{
23656
+ return 1;
23657
+ }
23658
+ }
2328323659
#endif
2328423660
#if HAVE_LOCALTIME_R
2328523661
rc = localtime_r(t, pTm)==0;
2328623662
#else
2328723663
rc = localtime_s(pTm, t);
@@ -23292,71 +23668,60 @@
2329223668
#endif /* SQLITE_OMIT_LOCALTIME */
2329323669
2329423670
2329523671
#ifndef SQLITE_OMIT_LOCALTIME
2329623672
/*
23297
-** Compute the difference (in milliseconds) between localtime and UTC
23298
-** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
23299
-** return this value and set *pRc to SQLITE_OK.
23300
-**
23301
-** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
23302
-** is undefined in this case.
23673
+** Assuming the input DateTime is UTC, move it to its localtime equivalent.
2330323674
*/
23304
-static sqlite3_int64 localtimeOffset(
23305
- DateTime *p, /* Date at which to calculate offset */
23306
- sqlite3_context *pCtx, /* Write error here if one occurs */
23307
- int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
23675
+static int toLocaltime(
23676
+ DateTime *p, /* Date at which to calculate offset */
23677
+ sqlite3_context *pCtx /* Write error here if one occurs */
2330823678
){
23309
- DateTime x, y;
2331023679
time_t t;
2331123680
struct tm sLocal;
23681
+ int iYearDiff;
2331223682
2331323683
/* Initialize the contents of sLocal to avoid a compiler warning. */
2331423684
memset(&sLocal, 0, sizeof(sLocal));
2331523685
23316
- x = *p;
23317
- computeYMD_HMS(&x);
23318
- if( x.Y<1971 || x.Y>=2038 ){
23686
+ computeJD(p);
23687
+ if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
23688
+ || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
23689
+ ){
2331923690
/* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
2332023691
** works for years between 1970 and 2037. For dates outside this range,
2332123692
** SQLite attempts to map the year into an equivalent year within this
2332223693
** range, do the calculation, then map the year back.
2332323694
*/
23324
- x.Y = 2000;
23325
- x.M = 1;
23326
- x.D = 1;
23327
- x.h = 0;
23328
- x.m = 0;
23329
- x.s = 0.0;
23330
- } else {
23331
- int s = (int)(x.s + 0.5);
23332
- x.s = s;
23333
- }
23334
- x.tz = 0;
23335
- x.validJD = 0;
23336
- computeJD(&x);
23337
- t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23695
+ DateTime x = *p;
23696
+ computeYMD_HMS(&x);
23697
+ iYearDiff = (2000 + x.Y%4) - x.Y;
23698
+ x.Y += iYearDiff;
23699
+ x.validJD = 0;
23700
+ computeJD(&x);
23701
+ t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23702
+ }else{
23703
+ iYearDiff = 0;
23704
+ t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
23705
+ }
2333823706
if( osLocaltime(&t, &sLocal) ){
2333923707
sqlite3_result_error(pCtx, "local time unavailable", -1);
23340
- *pRc = SQLITE_ERROR;
23341
- return 0;
23342
- }
23343
- y.Y = sLocal.tm_year + 1900;
23344
- y.M = sLocal.tm_mon + 1;
23345
- y.D = sLocal.tm_mday;
23346
- y.h = sLocal.tm_hour;
23347
- y.m = sLocal.tm_min;
23348
- y.s = sLocal.tm_sec;
23349
- y.validYMD = 1;
23350
- y.validHMS = 1;
23351
- y.validJD = 0;
23352
- y.rawS = 0;
23353
- y.validTZ = 0;
23354
- y.isError = 0;
23355
- computeJD(&y);
23356
- *pRc = SQLITE_OK;
23357
- return y.iJD - x.iJD;
23708
+ return SQLITE_ERROR;
23709
+ }
23710
+ p->Y = sLocal.tm_year + 1900 - iYearDiff;
23711
+ p->M = sLocal.tm_mon + 1;
23712
+ p->D = sLocal.tm_mday;
23713
+ p->h = sLocal.tm_hour;
23714
+ p->m = sLocal.tm_min;
23715
+ p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
23716
+ p->validYMD = 1;
23717
+ p->validHMS = 1;
23718
+ p->validJD = 0;
23719
+ p->rawS = 0;
23720
+ p->validTZ = 0;
23721
+ p->isError = 0;
23722
+ return SQLITE_OK;
2335823723
}
2335923724
#endif /* SQLITE_OMIT_LOCALTIME */
2336023725
2336123726
/*
2336223727
** The following table defines various date transformations of the form
@@ -23406,11 +23771,12 @@
2340623771
*/
2340723772
static int parseModifier(
2340823773
sqlite3_context *pCtx, /* Function context */
2340923774
const char *z, /* The text of the modifier */
2341023775
int n, /* Length of zMod in bytes */
23411
- DateTime *p /* The date/time value to be modified */
23776
+ DateTime *p, /* The date/time value to be modified */
23777
+ int idx /* Parameter index of the modifier */
2341223778
){
2341323779
int rc = 1;
2341423780
double r;
2341523781
switch(sqlite3UpperToLower[(u8)z[0]] ){
2341623782
case 'a': {
@@ -23419,14 +23785,17 @@
2341923785
**
2342023786
** If rawS is available, then interpret as a julian day number, or
2342123787
** a unix timestamp, depending on its magnitude.
2342223788
*/
2342323789
if( sqlite3_stricmp(z, "auto")==0 ){
23790
+ if( idx>1 ) return 1; /* IMP: R-33611-57934 */
2342423791
if( !p->rawS || p->validJD ){
2342523792
rc = 0;
2342623793
p->rawS = 0;
23427
- }else if( p->s>=-210866760000 && p->s<=253402300799 ){
23794
+ }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
23795
+ && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
23796
+ ){
2342823797
r = p->s*1000.0 + 210866760000000.0;
2342923798
clearYMD_HMS_TZ(p);
2343023799
p->iJD = (sqlite3_int64)(r + 0.5);
2343123800
p->validJD = 1;
2343223801
p->rawS = 0;
@@ -23443,10 +23812,11 @@
2344323812
** is not the first modifier, or if the prior argument is not a numeric
2344423813
** value in the allowed range of julian day numbers understood by
2344523814
** SQLite (0..5373484.5) then the result will be NULL.
2344623815
*/
2344723816
if( sqlite3_stricmp(z, "julianday")==0 ){
23817
+ if( idx>1 ) return 1; /* IMP: R-31176-64601 */
2344823818
if( p->validJD && p->rawS ){
2344923819
rc = 0;
2345023820
p->rawS = 0;
2345123821
}
2345223822
}
@@ -23458,13 +23828,11 @@
2345823828
**
2345923829
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
2346023830
** show local time.
2346123831
*/
2346223832
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23463
- computeJD(p);
23464
- p->iJD += localtimeOffset(p, pCtx, &rc);
23465
- clearYMD_HMS_TZ(p);
23833
+ rc = toLocaltime(p, pCtx);
2346623834
}
2346723835
break;
2346823836
}
2346923837
#endif
2347023838
case 'u': {
@@ -23473,10 +23841,11 @@
2347323841
**
2347423842
** Treat the current value of p->s as the number of
2347523843
** seconds since 1970. Convert to a real julian day number.
2347623844
*/
2347723845
if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
23846
+ if( idx>1 ) return 1; /* IMP: R-49255-55373 */
2347823847
r = p->s*1000.0 + 210866760000000.0;
2347923848
if( r>=0.0 && r<464269060800000.0 ){
2348023849
clearYMD_HMS_TZ(p);
2348123850
p->iJD = (sqlite3_int64)(r + 0.5);
2348223851
p->validJD = 1;
@@ -23485,22 +23854,35 @@
2348523854
}
2348623855
}
2348723856
#ifndef SQLITE_OMIT_LOCALTIME
2348823857
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
2348923858
if( p->tzSet==0 ){
23490
- sqlite3_int64 c1;
23859
+ i64 iOrigJD; /* Original localtime */
23860
+ i64 iGuess; /* Guess at the corresponding utc time */
23861
+ int cnt = 0; /* Safety to prevent infinite loop */
23862
+ int iErr; /* Guess is off by this much */
23863
+
2349123864
computeJD(p);
23492
- c1 = localtimeOffset(p, pCtx, &rc);
23493
- if( rc==SQLITE_OK ){
23494
- p->iJD -= c1;
23495
- clearYMD_HMS_TZ(p);
23496
- p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
23497
- }
23865
+ iGuess = iOrigJD = p->iJD;
23866
+ iErr = 0;
23867
+ do{
23868
+ DateTime new;
23869
+ memset(&new, 0, sizeof(new));
23870
+ iGuess -= iErr;
23871
+ new.iJD = iGuess;
23872
+ new.validJD = 1;
23873
+ rc = toLocaltime(&new, pCtx);
23874
+ if( rc ) return rc;
23875
+ computeJD(&new);
23876
+ iErr = new.iJD - iOrigJD;
23877
+ }while( iErr && cnt++<3 );
23878
+ memset(p, 0, sizeof(*p));
23879
+ p->iJD = iGuess;
23880
+ p->validJD = 1;
2349823881
p->tzSet = 1;
23499
- }else{
23500
- rc = SQLITE_OK;
2350123882
}
23883
+ rc = SQLITE_OK;
2350223884
}
2350323885
#endif
2350423886
break;
2350523887
}
2350623888
case 'w': {
@@ -23686,11 +24068,11 @@
2368624068
}
2368724069
}
2368824070
for(i=1; i<argc; i++){
2368924071
z = sqlite3_value_text(argv[i]);
2369024072
n = sqlite3_value_bytes(argv[i]);
23691
- if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
24073
+ if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
2369224074
}
2369324075
computeJD(p);
2369424076
if( p->isError || !validJulianDay(p->iJD) ) return 1;
2369524077
return 0;
2369624078
}
@@ -23746,15 +24128,42 @@
2374624128
int argc,
2374724129
sqlite3_value **argv
2374824130
){
2374924131
DateTime x;
2375024132
if( isDate(context, argc, argv, &x)==0 ){
23751
- char zBuf[100];
24133
+ int Y, s;
24134
+ char zBuf[24];
2375224135
computeYMD_HMS(&x);
23753
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
23754
- x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
23755
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24136
+ Y = x.Y;
24137
+ if( Y<0 ) Y = -Y;
24138
+ zBuf[1] = '0' + (Y/1000)%10;
24139
+ zBuf[2] = '0' + (Y/100)%10;
24140
+ zBuf[3] = '0' + (Y/10)%10;
24141
+ zBuf[4] = '0' + (Y)%10;
24142
+ zBuf[5] = '-';
24143
+ zBuf[6] = '0' + (x.M/10)%10;
24144
+ zBuf[7] = '0' + (x.M)%10;
24145
+ zBuf[8] = '-';
24146
+ zBuf[9] = '0' + (x.D/10)%10;
24147
+ zBuf[10] = '0' + (x.D)%10;
24148
+ zBuf[11] = ' ';
24149
+ zBuf[12] = '0' + (x.h/10)%10;
24150
+ zBuf[13] = '0' + (x.h)%10;
24151
+ zBuf[14] = ':';
24152
+ zBuf[15] = '0' + (x.m/10)%10;
24153
+ zBuf[16] = '0' + (x.m)%10;
24154
+ zBuf[17] = ':';
24155
+ s = (int)x.s;
24156
+ zBuf[18] = '0' + (s/10)%10;
24157
+ zBuf[19] = '0' + (s)%10;
24158
+ zBuf[20] = 0;
24159
+ if( x.Y<0 ){
24160
+ zBuf[0] = '-';
24161
+ sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
24162
+ }else{
24163
+ sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
24164
+ }
2375624165
}
2375724166
}
2375824167
2375924168
/*
2376024169
** time( TIMESTRING, MOD, MOD, ...)
@@ -23766,14 +24175,24 @@
2376624175
int argc,
2376724176
sqlite3_value **argv
2376824177
){
2376924178
DateTime x;
2377024179
if( isDate(context, argc, argv, &x)==0 ){
23771
- char zBuf[100];
24180
+ int s;
24181
+ char zBuf[16];
2377224182
computeHMS(&x);
23773
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
23774
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24183
+ zBuf[0] = '0' + (x.h/10)%10;
24184
+ zBuf[1] = '0' + (x.h)%10;
24185
+ zBuf[2] = ':';
24186
+ zBuf[3] = '0' + (x.m/10)%10;
24187
+ zBuf[4] = '0' + (x.m)%10;
24188
+ zBuf[5] = ':';
24189
+ s = (int)x.s;
24190
+ zBuf[6] = '0' + (s/10)%10;
24191
+ zBuf[7] = '0' + (s)%10;
24192
+ zBuf[8] = 0;
24193
+ sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
2377524194
}
2377624195
}
2377724196
2377824197
/*
2377924198
** date( TIMESTRING, MOD, MOD, ...)
@@ -23785,14 +24204,32 @@
2378524204
int argc,
2378624205
sqlite3_value **argv
2378724206
){
2378824207
DateTime x;
2378924208
if( isDate(context, argc, argv, &x)==0 ){
23790
- char zBuf[100];
24209
+ int Y;
24210
+ char zBuf[16];
2379124211
computeYMD(&x);
23792
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
23793
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24212
+ Y = x.Y;
24213
+ if( Y<0 ) Y = -Y;
24214
+ zBuf[1] = '0' + (Y/1000)%10;
24215
+ zBuf[2] = '0' + (Y/100)%10;
24216
+ zBuf[3] = '0' + (Y/10)%10;
24217
+ zBuf[4] = '0' + (Y)%10;
24218
+ zBuf[5] = '-';
24219
+ zBuf[6] = '0' + (x.M/10)%10;
24220
+ zBuf[7] = '0' + (x.M)%10;
24221
+ zBuf[8] = '-';
24222
+ zBuf[9] = '0' + (x.D/10)%10;
24223
+ zBuf[10] = '0' + (x.D)%10;
24224
+ zBuf[11] = 0;
24225
+ if( x.Y<0 ){
24226
+ zBuf[0] = '-';
24227
+ sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
24228
+ }else{
24229
+ sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
24230
+ }
2379424231
}
2379524232
}
2379624233
2379724234
/*
2379824235
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -28956,22 +29393,31 @@
2895629393
/*
2895729394
** Call this routine to record the fact that an OOM (out-of-memory) error
2895829395
** has happened. This routine will set db->mallocFailed, and also
2895929396
** temporarily disable the lookaside memory allocator and interrupt
2896029397
** any running VDBEs.
29398
+**
29399
+** Always return a NULL pointer so that this routine can be invoked using
29400
+**
29401
+** return sqlite3OomFault(db);
29402
+**
29403
+** and thereby avoid unnecessary stack frame allocations for the overwhelmingly
29404
+** common case where no OOM occurs.
2896129405
*/
28962
-SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
29406
+SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){
2896329407
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
2896429408
db->mallocFailed = 1;
2896529409
if( db->nVdbeExec>0 ){
2896629410
AtomicStore(&db->u1.isInterrupted, 1);
2896729411
}
2896829412
DisableLookaside;
2896929413
if( db->pParse ){
29414
+ sqlite3ErrorMsg(db->pParse, "out of memory");
2897029415
db->pParse->rc = SQLITE_NOMEM_BKPT;
2897129416
}
2897229417
}
29418
+ return 0;
2897329419
}
2897429420
2897529421
/*
2897629422
** This routine reactivates the memory allocator and clears the
2897729423
** db->mallocFailed flag as necessary.
@@ -29876,17 +30322,26 @@
2987630322
bufpt[j] = 0;
2987730323
length = j;
2987830324
goto adjust_width_for_utf8;
2987930325
}
2988030326
case etTOKEN: {
29881
- Token *pToken;
2988230327
if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
29883
- pToken = va_arg(ap, Token*);
29884
- assert( bArgList==0 );
29885
- if( pToken && pToken->n ){
29886
- sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
29887
- sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30328
+ if( flag_alternateform ){
30329
+ /* %#T means an Expr pointer that uses Expr.u.zToken */
30330
+ Expr *pExpr = va_arg(ap,Expr*);
30331
+ if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){
30332
+ sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken);
30333
+ sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr);
30334
+ }
30335
+ }else{
30336
+ /* %T means a Token pointer */
30337
+ Token *pToken = va_arg(ap, Token*);
30338
+ assert( bArgList==0 );
30339
+ if( pToken && pToken->n ){
30340
+ sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
30341
+ sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30342
+ }
2988830343
}
2988930344
length = width = 0;
2989030345
break;
2989130346
}
2989230347
case etSRCITEM: {
@@ -29960,10 +30415,22 @@
2996030415
zEnd = &zText[strlen(zText)];
2996130416
if( SQLITE_WITHIN(z,zText,zEnd) ){
2996230417
db->errByteOffset = (int)(z-zText);
2996330418
}
2996430419
}
30420
+
30421
+/*
30422
+** If pExpr has a byte offset for the start of a token, record that as
30423
+** as the error offset.
30424
+*/
30425
+SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30426
+ while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
30427
+ pExpr = pExpr->pLeft;
30428
+ }
30429
+ if( pExpr==0 ) return;
30430
+ db->errByteOffset = pExpr->w.iOfst;
30431
+}
2996530432
2996630433
/*
2996730434
** Enlarge the memory allocation on a StrAccum object so that it is
2996830435
** able to accept at least N more bytes of text.
2996930436
**
@@ -30423,11 +30890,11 @@
3042330890
memset(p, 0, sizeof(*p));
3042430891
}else{
3042530892
p->iLevel++;
3042630893
}
3042730894
assert( moreToFollow==0 || moreToFollow==1 );
30428
- if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30895
+ if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
3042930896
return p;
3043030897
}
3043130898
3043230899
/*
3043330900
** Finished with one layer of the tree
@@ -30447,11 +30914,11 @@
3044730914
int i;
3044830915
StrAccum acc;
3044930916
char zBuf[500];
3045030917
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
3045130918
if( p ){
30452
- for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
30919
+ for(i=0; i<p->iLevel && i<(int)sizeof(p->bLine)-1; i++){
3045330920
sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
3045430921
}
3045530922
sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
3045630923
}
3045730924
if( zFormat!=0 ){
@@ -30777,11 +31244,11 @@
3077731244
** Generate a human-readable explanation for a Window Function object
3077831245
*/
3077931246
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
3078031247
pView = sqlite3TreeViewPush(pView, more);
3078131248
sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
30782
- pWin->pFunc->zName, pWin->pFunc->nArg);
31249
+ pWin->pWFunc->zName, pWin->pWFunc->nArg);
3078331250
sqlite3TreeViewWindow(pView, pWin, 0);
3078431251
sqlite3TreeViewPop(pView);
3078531252
}
3078631253
#endif /* SQLITE_OMIT_WINDOWFUNC */
3078731254
@@ -30802,11 +31269,11 @@
3080231269
StrAccum x;
3080331270
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
3080431271
sqlite3_str_appendf(&x, " fg.af=%x.%c",
3080531272
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
3080631273
if( ExprHasProperty(pExpr, EP_FromJoin) ){
30807
- sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
31274
+ sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
3080831275
}
3080931276
if( ExprHasProperty(pExpr, EP_FromDDL) ){
3081031277
sqlite3_str_appendf(&x, " DDL");
3081131278
}
3081231279
if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -32356,17 +32823,23 @@
3235632823
*/
3235732824
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
3235832825
char *zMsg;
3235932826
va_list ap;
3236032827
sqlite3 *db = pParse->db;
32828
+ assert( db!=0 );
32829
+ assert( db->pParse==pParse );
3236132830
db->errByteOffset = -2;
3236232831
va_start(ap, zFormat);
3236332832
zMsg = sqlite3VMPrintf(db, zFormat, ap);
3236432833
va_end(ap);
3236532834
if( db->errByteOffset<-1 ) db->errByteOffset = -1;
3236632835
if( db->suppressErr ){
3236732836
sqlite3DbFree(db, zMsg);
32837
+ if( db->mallocFailed ){
32838
+ pParse->nErr++;
32839
+ pParse->rc = SQLITE_NOMEM;
32840
+ }
3236832841
}else{
3236932842
pParse->nErr++;
3237032843
sqlite3DbFree(db, pParse->zErrMsg);
3237132844
pParse->zErrMsg = zMsg;
3237232845
pParse->rc = SQLITE_ERROR;
@@ -34164,46 +34637,46 @@
3416434637
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
3416534638
static const char *const azName[] = {
3416634639
/* 0 */ "Savepoint" OpHelp(""),
3416734640
/* 1 */ "AutoCommit" OpHelp(""),
3416834641
/* 2 */ "Transaction" OpHelp(""),
34169
- /* 3 */ "SorterNext" OpHelp(""),
34170
- /* 4 */ "Prev" OpHelp(""),
34171
- /* 5 */ "Next" OpHelp(""),
34172
- /* 6 */ "Checkpoint" OpHelp(""),
34173
- /* 7 */ "JournalMode" OpHelp(""),
34174
- /* 8 */ "Vacuum" OpHelp(""),
34175
- /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34176
- /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34177
- /* 11 */ "Goto" OpHelp(""),
34178
- /* 12 */ "Gosub" OpHelp(""),
34179
- /* 13 */ "InitCoroutine" OpHelp(""),
34180
- /* 14 */ "Yield" OpHelp(""),
34181
- /* 15 */ "MustBeInt" OpHelp(""),
34182
- /* 16 */ "Jump" OpHelp(""),
34183
- /* 17 */ "Once" OpHelp(""),
34184
- /* 18 */ "If" OpHelp(""),
34642
+ /* 3 */ "Checkpoint" OpHelp(""),
34643
+ /* 4 */ "JournalMode" OpHelp(""),
34644
+ /* 5 */ "Vacuum" OpHelp(""),
34645
+ /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34646
+ /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34647
+ /* 8 */ "Goto" OpHelp(""),
34648
+ /* 9 */ "Gosub" OpHelp(""),
34649
+ /* 10 */ "InitCoroutine" OpHelp(""),
34650
+ /* 11 */ "Yield" OpHelp(""),
34651
+ /* 12 */ "MustBeInt" OpHelp(""),
34652
+ /* 13 */ "Jump" OpHelp(""),
34653
+ /* 14 */ "Once" OpHelp(""),
34654
+ /* 15 */ "If" OpHelp(""),
34655
+ /* 16 */ "IfNot" OpHelp(""),
34656
+ /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34657
+ /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
3418534658
/* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34186
- /* 20 */ "IfNot" OpHelp(""),
34187
- /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34188
- /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34189
- /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34190
- /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34191
- /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34192
- /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34193
- /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34194
- /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34195
- /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34196
- /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
34197
- /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
34198
- /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34199
- /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
34200
- /* 34 */ "Last" OpHelp(""),
34201
- /* 35 */ "IfSmaller" OpHelp(""),
34202
- /* 36 */ "SorterSort" OpHelp(""),
34203
- /* 37 */ "Sort" OpHelp(""),
34204
- /* 38 */ "Rewind" OpHelp(""),
34659
+ /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34660
+ /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34661
+ /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34662
+ /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34663
+ /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34664
+ /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34665
+ /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34666
+ /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"),
34667
+ /* 28 */ "Found" OpHelp("key=r[P3@P4]"),
34668
+ /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34669
+ /* 30 */ "NotExists" OpHelp("intkey=r[P3]"),
34670
+ /* 31 */ "Last" OpHelp(""),
34671
+ /* 32 */ "IfSmaller" OpHelp(""),
34672
+ /* 33 */ "SorterSort" OpHelp(""),
34673
+ /* 34 */ "Sort" OpHelp(""),
34674
+ /* 35 */ "Rewind" OpHelp(""),
34675
+ /* 36 */ "SorterNext" OpHelp(""),
34676
+ /* 37 */ "Prev" OpHelp(""),
34677
+ /* 38 */ "Next" OpHelp(""),
3420534678
/* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
3420634679
/* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
3420734680
/* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
3420834681
/* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
3420934682
/* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34232,41 +34705,41 @@
3423234705
/* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
3423334706
/* 67 */ "Return" OpHelp(""),
3423434707
/* 68 */ "EndCoroutine" OpHelp(""),
3423534708
/* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
3423634709
/* 70 */ "Halt" OpHelp(""),
34237
- /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34238
- /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34239
- /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34240
- /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34241
- /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34242
- /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34243
- /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34244
- /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34245
- /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34246
- /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34247
- /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34248
- /* 82 */ "FkCheck" OpHelp(""),
34249
- /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34250
- /* 84 */ "CollSeq" OpHelp(""),
34251
- /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34252
- /* 86 */ "RealAffinity" OpHelp(""),
34253
- /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34254
- /* 88 */ "Permutation" OpHelp(""),
34255
- /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34256
- /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34257
- /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34258
- /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34259
- /* 93 */ "Column" OpHelp("r[P3]=PX"),
34260
- /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34261
- /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34262
- /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34263
- /* 97 */ "Count" OpHelp("r[P2]=count()"),
34264
- /* 98 */ "ReadCookie" OpHelp(""),
34265
- /* 99 */ "SetCookie" OpHelp(""),
34266
- /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34267
- /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34710
+ /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34711
+ /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34712
+ /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34713
+ /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34714
+ /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
34715
+ /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
34716
+ /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34717
+ /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34718
+ /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34719
+ /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34720
+ /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34721
+ /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34722
+ /* 83 */ "FkCheck" OpHelp(""),
34723
+ /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34724
+ /* 85 */ "CollSeq" OpHelp(""),
34725
+ /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34726
+ /* 87 */ "RealAffinity" OpHelp(""),
34727
+ /* 88 */ "Cast" OpHelp("affinity(r[P1])"),
34728
+ /* 89 */ "Permutation" OpHelp(""),
34729
+ /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34730
+ /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34731
+ /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34732
+ /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34733
+ /* 94 */ "Column" OpHelp("r[P3]=PX"),
34734
+ /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34735
+ /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34736
+ /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34737
+ /* 98 */ "Count" OpHelp("r[P2]=count()"),
34738
+ /* 99 */ "ReadCookie" OpHelp(""),
34739
+ /* 100 */ "SetCookie" OpHelp(""),
34740
+ /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
3426834741
/* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
3426934742
/* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
3427034743
/* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
3427134744
/* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
3427234745
/* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34273,82 +34746,84 @@
3427334746
/* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
3427434747
/* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
3427534748
/* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
3427634749
/* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
3427734750
/* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34278
- /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34279
- /* 113 */ "OpenDup" OpHelp(""),
34751
+ /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34752
+ /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
3428034753
/* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34281
- /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34282
- /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34754
+ /* 115 */ "OpenDup" OpHelp(""),
34755
+ /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
3428334756
/* 117 */ "String8" OpHelp("r[P2]='P4'"),
34284
- /* 118 */ "SorterOpen" OpHelp(""),
34285
- /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34286
- /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34287
- /* 121 */ "Close" OpHelp(""),
34288
- /* 122 */ "ColumnsUsed" OpHelp(""),
34289
- /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34290
- /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34291
- /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34292
- /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34293
- /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34294
- /* 128 */ "RowCell" OpHelp(""),
34295
- /* 129 */ "Delete" OpHelp(""),
34296
- /* 130 */ "ResetCount" OpHelp(""),
34297
- /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34298
- /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34299
- /* 133 */ "RowData" OpHelp("r[P2]=data"),
34300
- /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34301
- /* 135 */ "NullRow" OpHelp(""),
34302
- /* 136 */ "SeekEnd" OpHelp(""),
34303
- /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34304
- /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34305
- /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34306
- /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34307
- /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34308
- /* 142 */ "FinishSeek" OpHelp(""),
34309
- /* 143 */ "Destroy" OpHelp(""),
34310
- /* 144 */ "Clear" OpHelp(""),
34311
- /* 145 */ "ResetSorter" OpHelp(""),
34312
- /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34313
- /* 147 */ "SqlExec" OpHelp(""),
34314
- /* 148 */ "ParseSchema" OpHelp(""),
34315
- /* 149 */ "LoadAnalysis" OpHelp(""),
34316
- /* 150 */ "DropTable" OpHelp(""),
34317
- /* 151 */ "DropIndex" OpHelp(""),
34318
- /* 152 */ "DropTrigger" OpHelp(""),
34757
+ /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34758
+ /* 119 */ "SorterOpen" OpHelp(""),
34759
+ /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34760
+ /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34761
+ /* 122 */ "Close" OpHelp(""),
34762
+ /* 123 */ "ColumnsUsed" OpHelp(""),
34763
+ /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34764
+ /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34765
+ /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34766
+ /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"),
34767
+ /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34768
+ /* 129 */ "RowCell" OpHelp(""),
34769
+ /* 130 */ "Delete" OpHelp(""),
34770
+ /* 131 */ "ResetCount" OpHelp(""),
34771
+ /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34772
+ /* 133 */ "SorterData" OpHelp("r[P2]=data"),
34773
+ /* 134 */ "RowData" OpHelp("r[P2]=data"),
34774
+ /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
34775
+ /* 136 */ "NullRow" OpHelp(""),
34776
+ /* 137 */ "SeekEnd" OpHelp(""),
34777
+ /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
34778
+ /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
34779
+ /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34780
+ /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34781
+ /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34782
+ /* 143 */ "FinishSeek" OpHelp(""),
34783
+ /* 144 */ "Destroy" OpHelp(""),
34784
+ /* 145 */ "Clear" OpHelp(""),
34785
+ /* 146 */ "ResetSorter" OpHelp(""),
34786
+ /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34787
+ /* 148 */ "SqlExec" OpHelp(""),
34788
+ /* 149 */ "ParseSchema" OpHelp(""),
34789
+ /* 150 */ "LoadAnalysis" OpHelp(""),
34790
+ /* 151 */ "DropTable" OpHelp(""),
34791
+ /* 152 */ "DropIndex" OpHelp(""),
3431934792
/* 153 */ "Real" OpHelp("r[P2]=P4"),
34320
- /* 154 */ "IntegrityCk" OpHelp(""),
34321
- /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34322
- /* 156 */ "Param" OpHelp(""),
34323
- /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34324
- /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34325
- /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34326
- /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34327
- /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34328
- /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34329
- /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34330
- /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34331
- /* 165 */ "Expire" OpHelp(""),
34332
- /* 166 */ "CursorLock" OpHelp(""),
34333
- /* 167 */ "CursorUnlock" OpHelp(""),
34334
- /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34335
- /* 169 */ "VBegin" OpHelp(""),
34336
- /* 170 */ "VCreate" OpHelp(""),
34337
- /* 171 */ "VDestroy" OpHelp(""),
34338
- /* 172 */ "VOpen" OpHelp(""),
34339
- /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34340
- /* 174 */ "VRename" OpHelp(""),
34341
- /* 175 */ "Pagecount" OpHelp(""),
34342
- /* 176 */ "MaxPgcnt" OpHelp(""),
34343
- /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34344
- /* 178 */ "Trace" OpHelp(""),
34345
- /* 179 */ "CursorHint" OpHelp(""),
34346
- /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34347
- /* 181 */ "Noop" OpHelp(""),
34348
- /* 182 */ "Explain" OpHelp(""),
34349
- /* 183 */ "Abortable" OpHelp(""),
34793
+ /* 154 */ "DropTrigger" OpHelp(""),
34794
+ /* 155 */ "IntegrityCk" OpHelp(""),
34795
+ /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34796
+ /* 157 */ "Param" OpHelp(""),
34797
+ /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34798
+ /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34799
+ /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34800
+ /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34801
+ /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34802
+ /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34803
+ /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34804
+ /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34805
+ /* 166 */ "Expire" OpHelp(""),
34806
+ /* 167 */ "CursorLock" OpHelp(""),
34807
+ /* 168 */ "CursorUnlock" OpHelp(""),
34808
+ /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34809
+ /* 170 */ "VBegin" OpHelp(""),
34810
+ /* 171 */ "VCreate" OpHelp(""),
34811
+ /* 172 */ "VDestroy" OpHelp(""),
34812
+ /* 173 */ "VOpen" OpHelp(""),
34813
+ /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
34814
+ /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34815
+ /* 176 */ "VRename" OpHelp(""),
34816
+ /* 177 */ "Pagecount" OpHelp(""),
34817
+ /* 178 */ "MaxPgcnt" OpHelp(""),
34818
+ /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34819
+ /* 180 */ "Trace" OpHelp(""),
34820
+ /* 181 */ "CursorHint" OpHelp(""),
34821
+ /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34822
+ /* 183 */ "Noop" OpHelp(""),
34823
+ /* 184 */ "Explain" OpHelp(""),
34824
+ /* 185 */ "Abortable" OpHelp(""),
3435034825
};
3435134826
return azName[i];
3435234827
}
3435334828
#endif
3435434829
@@ -39264,15 +39739,21 @@
3926439739
int ofst, /* First lock to acquire or release */
3926539740
int n, /* Number of locks to acquire or release */
3926639741
int flags /* What to do with the lock */
3926739742
){
3926839743
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39269
- unixShm *p = pDbFd->pShm; /* The shared memory being locked */
39270
- unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
39744
+ unixShm *p; /* The shared memory being locked */
39745
+ unixShmNode *pShmNode; /* The underlying file iNode */
3927139746
int rc = SQLITE_OK; /* Result code */
3927239747
u16 mask; /* Mask of locks to take or release */
39273
- int *aLock = pShmNode->aLock;
39748
+ int *aLock;
39749
+
39750
+ p = pDbFd->pShm;
39751
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
39752
+ pShmNode = p->pShmNode;
39753
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
39754
+ aLock = pShmNode->aLock;
3927439755
3927539756
assert( pShmNode==pDbFd->pInode->pShmNode );
3927639757
assert( pShmNode->pInode==pDbFd->pInode );
3927739758
assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
3927839759
assert( n>=1 );
@@ -40365,24 +40846,27 @@
4036540846
** "<path to db>-journalNN"
4036640847
** "<path to db>-walNN"
4036740848
**
4036840849
** where NN is a decimal number. The NN naming schemes are
4036940850
** used by the test_multiplex.c module.
40851
+ **
40852
+ ** In normal operation, the journal file name will always contain
40853
+ ** a '-' character. However in 8+3 filename mode, or if a corrupt
40854
+ ** rollback journal specifies a super-journal with a goofy name, then
40855
+ ** the '-' might be missing or the '-' might be the first character in
40856
+ ** the filename. In that case, just return SQLITE_OK with *pMode==0.
4037040857
*/
4037140858
nDb = sqlite3Strlen30(zPath) - 1;
40372
- while( zPath[nDb]!='-' ){
40373
- /* In normal operation, the journal file name will always contain
40374
- ** a '-' character. However in 8+3 filename mode, or if a corrupt
40375
- ** rollback journal specifies a super-journal with a goofy name, then
40376
- ** the '-' might be missing. */
40377
- if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
40859
+ while( nDb>0 && zPath[nDb]!='.' ){
40860
+ if( zPath[nDb]=='-' ){
40861
+ memcpy(zDb, zPath, nDb);
40862
+ zDb[nDb] = '\0';
40863
+ rc = getFileMode(zDb, pMode, pUid, pGid);
40864
+ break;
40865
+ }
4037840866
nDb--;
4037940867
}
40380
- memcpy(zDb, zPath, nDb);
40381
- zDb[nDb] = '\0';
40382
-
40383
- rc = getFileMode(zDb, pMode, pUid, pGid);
4038440868
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
4038540869
*pMode = 0600;
4038640870
}else if( flags & SQLITE_OPEN_URI ){
4038740871
/* If this is a main database file and the file was opened using a URI
4038840872
** filename, check for the "modeof" parameter. If present, interpret
@@ -46556,14 +47040,18 @@
4655647040
int flags /* What to do with the lock */
4655747041
){
4655847042
winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
4655947043
winShm *p = pDbFd->pShm; /* The shared memory being locked */
4656047044
winShm *pX; /* For looping over all siblings */
46561
- winShmNode *pShmNode = p->pShmNode;
47045
+ winShmNode *pShmNode;
4656247046
int rc = SQLITE_OK; /* Result code */
4656347047
u16 mask; /* Mask of locks to take or release */
4656447048
47049
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
47050
+ pShmNode = p->pShmNode;
47051
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
47052
+
4656547053
assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
4656647054
assert( n>=1 );
4656747055
assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
4656847056
|| flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
4656947057
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53458,10 +53946,11 @@
5345853946
u16 nExtra; /* Add this many bytes to each in-memory page */
5345953947
i16 nReserve; /* Number of unused bytes at end of each page */
5346053948
u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
5346153949
u32 sectorSize; /* Assumed sector size during rollback */
5346253950
Pgno mxPgno; /* Maximum allowed size of the database */
53951
+ Pgno lckPgno; /* Page number for the locking page */
5346353952
i64 pageSize; /* Number of bytes in a page */
5346453953
i64 journalSizeLimit; /* Size limit for persistent journal files */
5346553954
char *zFilename; /* Name of the database file */
5346653955
char *zJournal; /* Name of the journal file */
5346753956
int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54444,11 +54933,11 @@
5444454933
** pPager at the current location. The super-journal name must be the last
5444554934
** thing written to a journal file. If the pager is in full-sync mode, the
5444654935
** journal file descriptor is advanced to the next sector boundary before
5444754936
** anything is written. The format is:
5444854937
**
54449
-** + 4 bytes: PAGER_MJ_PGNO.
54938
+** + 4 bytes: PAGER_SJ_PGNO.
5445054939
** + N bytes: super-journal filename in utf-8.
5445154940
** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
5445254941
** + 4 bytes: super-journal name checksum.
5445354942
** + 8 bytes: aJournalMagic[].
5445454943
**
@@ -54492,11 +54981,11 @@
5449254981
iHdrOff = pPager->journalOff;
5449354982
5449454983
/* Write the super-journal data to the end of the journal file. If
5449554984
** an error occurs, return the error code to the caller.
5449654985
*/
54497
- if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
54986
+ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager))))
5449854987
|| (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
5449954988
|| (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
5450054989
|| (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
5450154990
|| (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
5450254991
iHdrOff+4+nSuper+8)))
@@ -55002,11 +55491,11 @@
5500255491
** to the database file, then the IO error code is returned. If data
5500355492
** is successfully read from the (sub-)journal file but appears to be
5500455493
** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
5500555494
** two circumstances:
5500655495
**
55007
-** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
55496
+** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
5500855497
** * If the record is being rolled back from the main journal file
5500955498
** and the checksum field does not match the record content.
5501055499
**
5501155500
** Neither of these two scenarios are possible during a savepoint rollback.
5501255501
**
@@ -55062,11 +55551,11 @@
5506255551
/* Sanity checking on the page. This is more important that I originally
5506355552
** thought. If a power failure occurs while the journal is being written,
5506455553
** it could cause invalid data to be written into the journal. We need to
5506555554
** detect this invalid data (with high probability) and ignore it.
5506655555
*/
55067
- if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
55556
+ if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){
5506855557
assert( !isSavepnt );
5506955558
return SQLITE_DONE;
5507055559
}
5507155560
if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
5507255561
return SQLITE_OK;
@@ -55621,10 +56110,13 @@
5562156110
rc = pager_truncate(pPager, mxPg);
5562256111
if( rc!=SQLITE_OK ){
5562356112
goto end_playback;
5562456113
}
5562556114
pPager->dbSize = mxPg;
56115
+ if( pPager->mxPgno<mxPg ){
56116
+ pPager->mxPgno = mxPg;
56117
+ }
5562656118
}
5562756119
5562856120
/* Copy original pages out of the journal and back into the
5562956121
** database file and/or page cache.
5563056122
*/
@@ -56517,10 +57009,11 @@
5651757009
if( rc==SQLITE_OK ){
5651857010
sqlite3PageFree(pPager->pTmpSpace);
5651957011
pPager->pTmpSpace = pNew;
5652057012
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
5652157013
pPager->pageSize = pageSize;
57014
+ pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1;
5652257015
}else{
5652357016
sqlite3PageFree(pNew);
5652457017
}
5652557018
}
5652657019
@@ -56723,11 +57216,10 @@
5672357216
** rolled back or committed. It is not safe to call this function and
5672457217
** then continue writing to the database.
5672557218
*/
5672657219
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
5672757220
assert( pPager->dbSize>=nPage || CORRUPT_DB );
56728
- testcase( pPager->dbSize<nPage );
5672957221
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
5673057222
pPager->dbSize = nPage;
5673157223
5673257224
/* At one point the code here called assertTruncateConstraint() to
5673357225
** ensure that all pages being truncated away by this operation are,
@@ -58287,11 +58779,11 @@
5828758779
5828858780
noContent = (flags & PAGER_GET_NOCONTENT)!=0;
5828958781
if( pPg->pPager && !noContent ){
5829058782
/* In this case the pcache already contains an initialized copy of
5829158783
** the page. Return without further ado. */
58292
- assert( pgno!=PAGER_MJ_PGNO(pPager) );
58784
+ assert( pgno!=PAGER_SJ_PGNO(pPager) );
5829358785
pPager->aStat[PAGER_STAT_HIT]++;
5829458786
return SQLITE_OK;
5829558787
5829658788
}else{
5829758789
/* The pager cache has created a new page. Its content needs to
@@ -58298,11 +58790,11 @@
5829858790
** be initialized. But first some error checks:
5829958791
**
5830058792
** (*) obsolete. Was: maximum page number is 2^31
5830158793
** (2) Never try to fetch the locking page
5830258794
*/
58303
- if( pgno==PAGER_MJ_PGNO(pPager) ){
58795
+ if( pgno==PAGER_SJ_PGNO(pPager) ){
5830458796
rc = SQLITE_CORRUPT_BKPT;
5830558797
goto pager_acquire_err;
5830658798
}
5830758799
5830858800
pPg->pPager = pPager;
@@ -58697,11 +59189,11 @@
5869759189
i64 iOff = pPager->journalOff;
5869859190
5869959191
/* We should never write to the journal file the page that
5870059192
** contains the database locks. The following assert verifies
5870159193
** that we do not. */
58702
- assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
59194
+ assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );
5870359195
5870459196
assert( pPager->journalHdr<=pPager->journalOff );
5870559197
pData2 = pPg->pData;
5870659198
cksum = pager_cksum(pPager, (u8*)pData2);
5870759199
@@ -58876,11 +59368,11 @@
5887659368
5887759369
for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
5887859370
Pgno pg = pg1+ii;
5887959371
PgHdr *pPage;
5888059372
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
58881
- if( pg!=PAGER_MJ_PGNO(pPager) ){
59373
+ if( pg!=PAGER_SJ_PGNO(pPager) ){
5888259374
rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
5888359375
if( rc==SQLITE_OK ){
5888459376
rc = pager_write(pPage);
5888559377
if( pPage->flags&PGHDR_NEED_SYNC ){
5888659378
needSync = 1;
@@ -59354,11 +59846,11 @@
5935459846
** image was extended as part of the current transaction and then the
5935559847
** last page in the db image moved to the free-list. In this case the
5935659848
** last page is never written out to disk, leaving the database file
5935759849
** undersized. Fix this now if it is the case. */
5935859850
if( pPager->dbSize>pPager->dbFileSize ){
59359
- Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
59851
+ Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager));
5936059852
assert( pPager->eState==PAGER_WRITER_DBMOD );
5936159853
rc = pager_truncate(pPager, nNew);
5936259854
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
5936359855
}
5936459856
@@ -60203,10 +60695,22 @@
6020360695
int eMode, /* Type of checkpoint */
6020460696
int *pnLog, /* OUT: Final number of frames in log */
6020560697
int *pnCkpt /* OUT: Final number of checkpointed frames */
6020660698
){
6020760699
int rc = SQLITE_OK;
60700
+ if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){
60701
+ /* This only happens when a database file is zero bytes in size opened and
60702
+ ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint()
60703
+ ** is invoked without any intervening transactions. We need to start
60704
+ ** a transaction to initialize pWal. The PRAGMA table_list statement is
60705
+ ** used for this since it starts transactions on every database file,
60706
+ ** including all ATTACHed databases. This seems expensive for a single
60707
+ ** sqlite3_wal_checkpoint() call, but it happens very rarely.
60708
+ ** https://sqlite.org/forum/forumpost/fd0f19d229156939
60709
+ */
60710
+ sqlite3_exec(db, "PRAGMA table_list",0,0,0);
60711
+ }
6020860712
if( pPager->pWal ){
6020960713
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
6021060714
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
6021160715
pPager->pBusyHandlerArg,
6021260716
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -63102,11 +63606,13 @@
6310263606
rc = WAL_RETRY;
6310363607
goto begin_unreliable_shm_out;
6310463608
}
6310563609
6310663610
/* Allocate a buffer to read frames into */
63107
- szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
63611
+ assert( (pWal->szPage & (pWal->szPage-1))==0 );
63612
+ assert( pWal->szPage>=512 && pWal->szPage<=65536 );
63613
+ szFrame = pWal->szPage + WAL_FRAME_HDRSIZE;
6310863614
aFrame = (u8 *)sqlite3_malloc64(szFrame);
6310963615
if( aFrame==0 ){
6311063616
rc = SQLITE_NOMEM_BKPT;
6311163617
goto begin_unreliable_shm_out;
6311263618
}
@@ -63116,11 +63622,11 @@
6311663622
** wal file since the heap-memory wal-index was created. If so, the
6311763623
** heap-memory wal-index is discarded and WAL_RETRY returned to
6311863624
** the caller. */
6311963625
aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
6312063626
aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
63121
- for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
63627
+ for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage);
6312263628
iOffset+szFrame<=szWal;
6312363629
iOffset+=szFrame
6312463630
){
6312563631
u32 pgno; /* Database page number for frame */
6312663632
u32 nTruncate; /* dbsize field from frame header */
@@ -64967,11 +65473,13 @@
6496765473
u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
6496865474
** non-overflow cell */
6496965475
u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
6497065476
BtShared *pBt; /* Pointer to BtShared that this page is part of */
6497165477
u8 *aData; /* Pointer to disk image of the page data */
64972
- u8 *aDataEnd; /* One byte past the end of usable data */
65478
+ u8 *aDataEnd; /* One byte past the end of the entire page - not just
65479
+ ** the usable space, the entire page. Used to prevent
65480
+ ** corruption-induced buffer overflow. */
6497365481
u8 *aCellIdx; /* The cell index area */
6497465482
u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
6497565483
DbPage *pDbPage; /* Pager page handle */
6497665484
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
6497765485
void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65272,11 +65780,11 @@
6527265780
#define CURSOR_FAULT 4
6527365781
6527465782
/*
6527565783
** The database page the PENDING_BYTE occupies. This page is never used.
6527665784
*/
65277
-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
65785
+#define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1))
6527865786
6527965787
/*
6528065788
** These macros define the location of the pointer-map entry for a
6528165789
** database page. The first argument to each is the number of usable
6528265790
** bytes on each page of the database (often 1024). The second is the
@@ -65913,11 +66421,11 @@
6591366421
if( isIndex ){
6591466422
HashElem *p;
6591566423
int bSeen = 0;
6591666424
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
6591766425
Index *pIdx = (Index *)sqliteHashData(p);
65918
- if( pIdx->tnum==(int)iRoot ){
66426
+ if( pIdx->tnum==iRoot ){
6591966427
if( bSeen ){
6592066428
/* Two or more indexes share the same root page. There must
6592166429
** be imposter tables. So just return true. The assert is not
6592266430
** useful in that case. */
6592366431
return 1;
@@ -66506,11 +67014,11 @@
6650667014
}
6650767015
6650867016
/*
6650967017
** In this version of BtreeMoveto, pKey is a packed index record
6651067018
** such as is generated by the OP_MakeRecord opcode. Unpack the
66511
-** record and then call BtreeMovetoUnpacked() to do the work.
67019
+** record and then call sqlite3BtreeIndexMoveto() to do the work.
6651267020
*/
6651367021
static int btreeMoveto(
6651467022
BtCursor *pCur, /* Cursor open on the btree to be searched */
6651567023
const void *pKey, /* Packed key if the btree is an index */
6651667024
i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67026,10 +67534,11 @@
6702667534
** data area of the btree-page. The return number includes the cell
6702767535
** data header and the local payload, but not any overflow page or
6702867536
** the space used by the cell pointer.
6702967537
**
6703067538
** cellSizePtrNoPayload() => table internal nodes
67539
+** cellSizePtrTableLeaf() => table leaf nodes
6703167540
** cellSizePtr() => all index nodes & table leaf nodes
6703267541
*/
6703367542
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
6703467543
u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
6703567544
u8 *pEnd; /* End mark for a varint */
@@ -67051,17 +67560,10 @@
6705167560
do{
6705267561
nSize = (nSize<<7) | (*++pIter & 0x7f);
6705367562
}while( *(pIter)>=0x80 && pIter<pEnd );
6705467563
}
6705567564
pIter++;
67056
- if( pPage->intKey ){
67057
- /* pIter now points at the 64-bit integer key value, a variable length
67058
- ** integer. The following block moves pIter to point at the first byte
67059
- ** past the end of the key value. */
67060
- pEnd = &pIter[9];
67061
- while( (*pIter++)&0x80 && pIter<pEnd );
67062
- }
6706367565
testcase( nSize==pPage->maxLocal );
6706467566
testcase( nSize==(u32)pPage->maxLocal+1 );
6706567567
if( nSize<=pPage->maxLocal ){
6706667568
nSize += (u32)(pIter - pCell);
6706767569
if( nSize<4 ) nSize = 4;
@@ -67097,10 +67599,62 @@
6709767599
pEnd = pIter + 9;
6709867600
while( (*pIter++)&0x80 && pIter<pEnd );
6709967601
assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
6710067602
return (u16)(pIter - pCell);
6710167603
}
67604
+static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){
67605
+ u8 *pIter = pCell; /* For looping over bytes of pCell */
67606
+ u8 *pEnd; /* End mark for a varint */
67607
+ u32 nSize; /* Size value to return */
67608
+
67609
+#ifdef SQLITE_DEBUG
67610
+ /* The value returned by this function should always be the same as
67611
+ ** the (CellInfo.nSize) value found by doing a full parse of the
67612
+ ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
67613
+ ** this function verifies that this invariant is not violated. */
67614
+ CellInfo debuginfo;
67615
+ pPage->xParseCell(pPage, pCell, &debuginfo);
67616
+#endif
67617
+
67618
+ nSize = *pIter;
67619
+ if( nSize>=0x80 ){
67620
+ pEnd = &pIter[8];
67621
+ nSize &= 0x7f;
67622
+ do{
67623
+ nSize = (nSize<<7) | (*++pIter & 0x7f);
67624
+ }while( *(pIter)>=0x80 && pIter<pEnd );
67625
+ }
67626
+ pIter++;
67627
+ /* pIter now points at the 64-bit integer key value, a variable length
67628
+ ** integer. The following block moves pIter to point at the first byte
67629
+ ** past the end of the key value. */
67630
+ if( (*pIter++)&0x80
67631
+ && (*pIter++)&0x80
67632
+ && (*pIter++)&0x80
67633
+ && (*pIter++)&0x80
67634
+ && (*pIter++)&0x80
67635
+ && (*pIter++)&0x80
67636
+ && (*pIter++)&0x80
67637
+ && (*pIter++)&0x80 ){ pIter++; }
67638
+ testcase( nSize==pPage->maxLocal );
67639
+ testcase( nSize==(u32)pPage->maxLocal+1 );
67640
+ if( nSize<=pPage->maxLocal ){
67641
+ nSize += (u32)(pIter - pCell);
67642
+ if( nSize<4 ) nSize = 4;
67643
+ }else{
67644
+ int minLocal = pPage->minLocal;
67645
+ nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
67646
+ testcase( nSize==pPage->maxLocal );
67647
+ testcase( nSize==(u32)pPage->maxLocal+1 );
67648
+ if( nSize>pPage->maxLocal ){
67649
+ nSize = minLocal;
67650
+ }
67651
+ nSize += 4 + (u16)(pIter - pCell);
67652
+ }
67653
+ assert( nSize==debuginfo.nSize || CORRUPT_DB );
67654
+ return (u16)nSize;
67655
+}
6710267656
6710367657
6710467658
#ifdef SQLITE_DEBUG
6710567659
/* This variation on cellSizePtr() is used inside of assert() statements
6710667660
** only. */
@@ -67110,11 +67664,11 @@
6711067664
#endif
6711167665
6711267666
#ifndef SQLITE_OMIT_AUTOVACUUM
6711367667
/*
6711467668
** The cell pCell is currently part of page pSrc but will ultimately be part
67115
-** of pPage. (pSrc and pPager are often the same.) If pCell contains a
67669
+** of pPage. (pSrc and pPage are often the same.) If pCell contains a
6711667670
** pointer to an overflow page, insert an entry into the pointer-map for
6711767671
** the overflow page that will be valid after pCell has been moved to pPage.
6711867672
*/
6711967673
static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
6712067674
CellInfo info;
@@ -67285,21 +67839,23 @@
6728567839
*/
6728667840
static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
6728767841
const int hdr = pPg->hdrOffset; /* Offset to page header */
6728867842
u8 * const aData = pPg->aData; /* Page data */
6728967843
int iAddr = hdr + 1; /* Address of ptr to pc */
67290
- int pc = get2byte(&aData[iAddr]); /* Address of a free slot */
67844
+ u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */
67845
+ int pc = get2byte(pTmp); /* Address of a free slot */
6729167846
int x; /* Excess size of the slot */
6729267847
int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
6729367848
int size; /* Size of the free slot */
6729467849
6729567850
assert( pc>0 );
6729667851
while( pc<=maxPC ){
6729767852
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
6729867853
** freeblock form a big-endian integer which is the size of the freeblock
6729967854
** in bytes, including the 4-byte header. */
67300
- size = get2byte(&aData[pc+2]);
67855
+ pTmp = &aData[pc+2];
67856
+ size = get2byte(pTmp);
6730167857
if( (x = size - nByte)>=0 ){
6730267858
testcase( x==4 );
6730367859
testcase( x==3 );
6730467860
if( x<4 ){
6730567861
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67320,11 +67876,12 @@
6732067876
put2byte(&aData[pc+2], x);
6732167877
}
6732267878
return &aData[pc + x];
6732367879
}
6732467880
iAddr = pc;
67325
- pc = get2byte(&aData[pc]);
67881
+ pTmp = &aData[pc];
67882
+ pc = get2byte(pTmp);
6732667883
if( pc<=iAddr+size ){
6732767884
if( pc ){
6732867885
/* The next slot in the chain is not past the end of the current slot */
6732967886
*pRc = SQLITE_CORRUPT_PAGE(pPg);
6733067887
}
@@ -67354,10 +67911,11 @@
6735467911
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
6735567912
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
6735667913
u8 * const data = pPage->aData; /* Local cache of pPage->aData */
6735767914
int top; /* First byte of cell content area */
6735867915
int rc = SQLITE_OK; /* Integer return code */
67916
+ u8 *pTmp; /* Temp ptr into data[] */
6735967917
int gap; /* First byte of gap between cell pointers and cell content */
6736067918
6736167919
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6736267920
assert( pPage->pBt );
6736367921
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67372,11 +67930,12 @@
6737267930
/* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
6737367931
** and the reserved space is zero (the usual value for reserved space)
6737467932
** then the cell content offset of an empty page wants to be 65536.
6737567933
** However, that integer is too large to be stored in a 2-byte unsigned
6737667934
** integer, so a value of 0 is used in its place. */
67377
- top = get2byte(&data[hdr+5]);
67935
+ pTmp = &data[hdr+5];
67936
+ top = get2byte(pTmp);
6737867937
assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
6737967938
if( gap>top ){
6738067939
if( top==0 && pPage->pBt->usableSize==65536 ){
6738167940
top = 65536;
6738267941
}else{
@@ -67454,10 +68013,11 @@
6745468013
u8 nFrag = 0; /* Reduction in fragmentation */
6745568014
u16 iOrigSize = iSize; /* Original value of iSize */
6745668015
u16 x; /* Offset to cell content area */
6745768016
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
6745868017
unsigned char *data = pPage->aData; /* Page content */
68018
+ u8 *pTmp; /* Temporary ptr into data[] */
6745968019
6746068020
assert( pPage->pBt!=0 );
6746168021
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6746268022
assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
6746368023
assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67481,11 +68041,11 @@
6748168041
iPtr = iFreeBlk;
6748268042
}
6748368043
if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
6748468044
return SQLITE_CORRUPT_PAGE(pPage);
6748568045
}
67486
- assert( iFreeBlk>iPtr || iFreeBlk==0 );
68046
+ assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB );
6748768047
6748868048
/* At this point:
6748968049
** iFreeBlk: First freeblock after iStart, or zero if none
6749068050
** iPtr: The address of a pointer to iFreeBlk
6749168051
**
@@ -67516,11 +68076,12 @@
6751668076
}
6751768077
}
6751868078
if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
6751968079
data[hdr+7] -= nFrag;
6752068080
}
67521
- x = get2byte(&data[hdr+5]);
68081
+ pTmp = &data[hdr+5];
68082
+ x = get2byte(pTmp);
6752268083
if( iStart<=x ){
6752368084
/* The new freeblock is at the beginning of the cell content area,
6752468085
** so just extend the cell content area rather than create another
6752568086
** freelist entry */
6752668087
if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67560,11 +68121,10 @@
6756068121
assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
6756168122
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
6756268123
pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
6756368124
flagByte &= ~PTF_LEAF;
6756468125
pPage->childPtrSize = 4-4*pPage->leaf;
67565
- pPage->xCellSize = cellSizePtr;
6756668126
pBt = pPage->pBt;
6756768127
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
6756868128
/* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
6756968129
** interior table b-tree page. */
6757068130
assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67572,10 +68132,11 @@
6757268132
** leaf table b-tree page. */
6757368133
assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
6757468134
pPage->intKey = 1;
6757568135
if( pPage->leaf ){
6757668136
pPage->intKeyLeaf = 1;
68137
+ pPage->xCellSize = cellSizePtrTableLeaf;
6757768138
pPage->xParseCell = btreeParseCellPtr;
6757868139
}else{
6757968140
pPage->intKeyLeaf = 0;
6758068141
pPage->xCellSize = cellSizePtrNoPayload;
6758168142
pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67589,16 +68150,21 @@
6758968150
/* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
6759068151
** leaf index b-tree page. */
6759168152
assert( (PTF_ZERODATA|PTF_LEAF)==10 );
6759268153
pPage->intKey = 0;
6759368154
pPage->intKeyLeaf = 0;
68155
+ pPage->xCellSize = cellSizePtr;
6759468156
pPage->xParseCell = btreeParseCellPtrIndex;
6759568157
pPage->maxLocal = pBt->maxLocal;
6759668158
pPage->minLocal = pBt->minLocal;
6759768159
}else{
6759868160
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
6759968161
** an error. */
68162
+ pPage->intKey = 0;
68163
+ pPage->intKeyLeaf = 0;
68164
+ pPage->xCellSize = cellSizePtr;
68165
+ pPage->xParseCell = btreeParseCellPtrIndex;
6760068166
return SQLITE_CORRUPT_PAGE(pPage);
6760168167
}
6760268168
pPage->max1bytePayload = pBt->max1bytePayload;
6760368169
return SQLITE_OK;
6760468170
}
@@ -67752,11 +68318,11 @@
6775268318
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
6775368319
pPage->maskPage = (u16)(pBt->pageSize - 1);
6775468320
pPage->nOverflow = 0;
6775568321
pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
6775668322
pPage->aCellIdx = data + pPage->childPtrSize + 8;
67757
- pPage->aDataEnd = pPage->aData + pBt->usableSize;
68323
+ pPage->aDataEnd = pPage->aData + pBt->pageSize;
6775868324
pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
6775968325
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
6776068326
** number of cells on the page. */
6776168327
pPage->nCell = get2byte(&data[3]);
6776268328
if( pPage->nCell>MX_CELL(pBt) ){
@@ -67787,11 +68353,11 @@
6778768353
unsigned char *data = pPage->aData;
6778868354
BtShared *pBt = pPage->pBt;
6778968355
u8 hdr = pPage->hdrOffset;
6779068356
u16 first;
6779168357
67792
- assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
68358
+ assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB );
6779368359
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
6779468360
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
6779568361
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6779668362
assert( sqlite3_mutex_held(pBt->mutex) );
6779768363
if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67803,11 +68369,11 @@
6780368369
data[hdr+7] = 0;
6780468370
put2byte(&data[hdr+5], pBt->usableSize);
6780568371
pPage->nFree = (u16)(pBt->usableSize - first);
6780668372
decodeFlags(pPage, flags);
6780768373
pPage->cellOffset = first;
67808
- pPage->aDataEnd = &data[pBt->usableSize];
68374
+ pPage->aDataEnd = &data[pBt->pageSize];
6780968375
pPage->aCellIdx = &data[first];
6781068376
pPage->aDataOfst = &data[pPage->childPtrSize];
6781168377
pPage->nOverflow = 0;
6781268378
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
6781368379
pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -67929,11 +68495,11 @@
6792968495
rc = btreeInitPage(*ppPage);
6793068496
if( rc!=SQLITE_OK ){
6793168497
goto getAndInitPage_error2;
6793268498
}
6793368499
}
67934
- assert( (*ppPage)->pgno==pgno );
68500
+ assert( (*ppPage)->pgno==pgno || CORRUPT_DB );
6793568501
assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
6793668502
6793768503
/* If obtaining a child page for a cursor, we must verify that the page is
6793868504
** compatible with the root page. */
6793968505
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -67948,11 +68514,13 @@
6794868514
if( pCur ){
6794968515
pCur->iPage--;
6795068516
pCur->pPage = pCur->apPage[pCur->iPage];
6795168517
}
6795268518
testcase( pgno==0 );
67953
- assert( pgno!=0 || rc==SQLITE_CORRUPT );
68519
+ assert( pgno!=0 || rc==SQLITE_CORRUPT
68520
+ || rc==SQLITE_IOERR_NOMEM
68521
+ || rc==SQLITE_NOMEM );
6795468522
return rc;
6795568523
}
6795668524
6795768525
/*
6795868526
** Release a MemPage. This should be called once for each prior
@@ -68934,13 +69502,17 @@
6893469502
freeTempSpace(pBt);
6893569503
rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
6893669504
pageSize-usableSize);
6893769505
return rc;
6893869506
}
68939
- if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
68940
- rc = SQLITE_CORRUPT_BKPT;
68941
- goto page1_init_failed;
69507
+ if( nPage>nPageFile ){
69508
+ if( sqlite3WritableSchema(pBt->db)==0 ){
69509
+ rc = SQLITE_CORRUPT_BKPT;
69510
+ goto page1_init_failed;
69511
+ }else{
69512
+ nPage = nPageFile;
69513
+ }
6894269514
}
6894369515
/* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
6894469516
** be less than 480. In other words, if the page size is 512, then the
6894569517
** reserved space size cannot exceed 32. */
6894669518
if( usableSize<480 ){
@@ -71012,11 +71584,11 @@
7101271584
}
7101371585
pCur->iPage = 0;
7101471586
pCur->curIntKey = pCur->pPage->intKey;
7101571587
}
7101671588
pRoot = pCur->pPage;
71017
- assert( pRoot->pgno==pCur->pgnoRoot );
71589
+ assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB );
7101871590
7101971591
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
7102071592
** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
7102171593
** NULL, the caller expects a table b-tree. If this is not the case,
7102271594
** return an SQLITE_CORRUPT error.
@@ -71332,10 +71904,73 @@
7133271904
moveto_table_finish:
7133371905
pCur->info.nSize = 0;
7133471906
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
7133571907
return rc;
7133671908
}
71909
+
71910
+/*
71911
+** Compare the "idx"-th cell on the page the cursor pCur is currently
71912
+** pointing to to pIdxKey using xRecordCompare. Return negative or
71913
+** zero if the cell is less than or equal pIdxKey. Return positive
71914
+** if unknown.
71915
+**
71916
+** Return value negative: Cell at pCur[idx] less than pIdxKey
71917
+**
71918
+** Return value is zero: Cell at pCur[idx] equals pIdxKey
71919
+**
71920
+** Return value positive: Nothing is known about the relationship
71921
+** of the cell at pCur[idx] and pIdxKey.
71922
+**
71923
+** This routine is part of an optimization. It is always safe to return
71924
+** a positive value as that will cause the optimization to be skipped.
71925
+*/
71926
+static int indexCellCompare(
71927
+ BtCursor *pCur,
71928
+ int idx,
71929
+ UnpackedRecord *pIdxKey,
71930
+ RecordCompare xRecordCompare
71931
+){
71932
+ MemPage *pPage = pCur->pPage;
71933
+ int c;
71934
+ int nCell; /* Size of the pCell cell in bytes */
71935
+ u8 *pCell = findCellPastPtr(pPage, idx);
71936
+
71937
+ nCell = pCell[0];
71938
+ if( nCell<=pPage->max1bytePayload ){
71939
+ /* This branch runs if the record-size field of the cell is a
71940
+ ** single byte varint and the record fits entirely on the main
71941
+ ** b-tree page. */
71942
+ testcase( pCell+nCell+1==pPage->aDataEnd );
71943
+ c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
71944
+ }else if( !(pCell[1] & 0x80)
71945
+ && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
71946
+ ){
71947
+ /* The record-size field is a 2 byte varint and the record
71948
+ ** fits entirely on the main b-tree page. */
71949
+ testcase( pCell+nCell+2==pPage->aDataEnd );
71950
+ c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
71951
+ }else{
71952
+ /* If the record extends into overflow pages, do not attempt
71953
+ ** the optimization. */
71954
+ c = 99;
71955
+ }
71956
+ return c;
71957
+}
71958
+
71959
+/*
71960
+** Return true (non-zero) if pCur is current pointing to the last
71961
+** page of a table.
71962
+*/
71963
+static int cursorOnLastPage(BtCursor *pCur){
71964
+ int i;
71965
+ assert( pCur->eState==CURSOR_VALID );
71966
+ for(i=0; i<pCur->iPage; i++){
71967
+ MemPage *pPage = pCur->apPage[i];
71968
+ if( pCur->aiIdx[i]<pPage->nCell ) return 0;
71969
+ }
71970
+ return 1;
71971
+}
7133771972
7133871973
/* Move the cursor so that it points to an entry in an index table
7133971974
** near the key pIdxKey. Return a success code.
7134071975
**
7134171976
** If an exact match is not found, then the cursor is always
@@ -71383,25 +72018,61 @@
7138372018
assert( pIdxKey->default_rc==1
7138472019
|| pIdxKey->default_rc==0
7138572020
|| pIdxKey->default_rc==-1
7138672021
);
7138772022
72023
+
72024
+ /* Check to see if we can skip a lot of work. Two cases:
72025
+ **
72026
+ ** (1) If the cursor is already pointing to the very last cell
72027
+ ** in the table and the pIdxKey search key is greater than or
72028
+ ** equal to that last cell, then no movement is required.
72029
+ **
72030
+ ** (2) If the cursor is on the last page of the table and the first
72031
+ ** cell on that last page is less than or equal to the pIdxKey
72032
+ ** search key, then we can start the search on the current page
72033
+ ** without needing to go back to root.
72034
+ */
72035
+ if( pCur->eState==CURSOR_VALID
72036
+ && pCur->pPage->leaf
72037
+ && cursorOnLastPage(pCur)
72038
+ ){
72039
+ int c;
72040
+ if( pCur->ix==pCur->pPage->nCell-1
72041
+ && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0
72042
+ && pIdxKey->errCode==SQLITE_OK
72043
+ ){
72044
+ *pRes = c;
72045
+ return SQLITE_OK; /* Cursor already pointing at the correct spot */
72046
+ }
72047
+ if( pCur->iPage>0
72048
+ && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
72049
+ && pIdxKey->errCode==SQLITE_OK
72050
+ ){
72051
+ pCur->curFlags &= ~BTCF_ValidOvfl;
72052
+ goto bypass_moveto_root; /* Start search on the current page */
72053
+ }
72054
+ pIdxKey->errCode = SQLITE_OK;
72055
+ }
72056
+
7138872057
rc = moveToRoot(pCur);
7138972058
if( rc ){
7139072059
if( rc==SQLITE_EMPTY ){
7139172060
assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
7139272061
*pRes = -1;
7139372062
return SQLITE_OK;
7139472063
}
7139572064
return rc;
7139672065
}
72066
+
72067
+bypass_moveto_root:
7139772068
assert( pCur->pPage );
7139872069
assert( pCur->pPage->isInit );
7139972070
assert( pCur->eState==CURSOR_VALID );
7140072071
assert( pCur->pPage->nCell > 0 );
71401
- assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
71402
- assert( pCur->curIntKey || pIdxKey );
72072
+ assert( pCur->curIntKey==0 );
72073
+ assert( pIdxKey!=0 );
7140372074
for(;;){
7140472075
int lwr, upr, idx, c;
7140572076
Pgno chldPg;
7140672077
MemPage *pPage = pCur->pPage;
7140772078
u8 *pCell; /* Pointer to current cell in pPage */
@@ -71411,11 +72082,11 @@
7141172082
** not run. If this is not the root-page, then the moveToChild() routine
7141272083
** would have already detected db corruption. Similarly, pPage must
7141372084
** be the right kind (index or table) of b-tree page. Otherwise
7141472085
** a moveToChild() or moveToRoot() call would have detected corruption. */
7141572086
assert( pPage->nCell>0 );
71416
- assert( pPage->intKey==(pIdxKey==0) );
72087
+ assert( pPage->intKey==0 );
7141772088
lwr = 0;
7141872089
upr = pPage->nCell-1;
7141972090
idx = upr>>1; /* idx = (lwr+upr)/2; */
7142072091
for(;;){
7142172092
int nCell; /* Size of the pCell cell in bytes */
@@ -72106,11 +72777,11 @@
7210672777
7210772778
assert( sqlite3_mutex_held(pBt->mutex) );
7210872779
assert( CORRUPT_DB || iPage>1 );
7210972780
assert( !pMemPage || pMemPage->pgno==iPage );
7211072781
72111
- if( NEVER(iPage<2) || iPage>pBt->nPage ){
72782
+ if( iPage<2 || iPage>pBt->nPage ){
7211272783
return SQLITE_CORRUPT_BKPT;
7211372784
}
7211472785
if( pMemPage ){
7211572786
pPage = pMemPage;
7211672787
sqlite3PagerRef(pPage->pDbPage);
@@ -72541,10 +73212,16 @@
7254173212
data = pPage->aData;
7254273213
ptr = &pPage->aCellIdx[2*idx];
7254373214
assert( pPage->pBt->usableSize > (u32)(ptr-data) );
7254473215
pc = get2byte(ptr);
7254573216
hdr = pPage->hdrOffset;
73217
+#if 0 /* Not required. Omit for efficiency */
73218
+ if( pc<hdr+pPage->nCell*2 ){
73219
+ *pRC = SQLITE_CORRUPT_BKPT;
73220
+ return;
73221
+ }
73222
+#endif
7254673223
testcase( pc==(u32)get2byte(&data[hdr+5]) );
7254773224
testcase( pc+sz==pPage->pBt->usableSize );
7254873225
if( pc+sz > pPage->pBt->usableSize ){
7254973226
*pRC = SQLITE_CORRUPT_BKPT;
7255073227
return;
@@ -74504,11 +75181,11 @@
7450475181
** For an index btree (used for indexes and WITHOUT ROWID tables), the
7450575182
** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
7450675183
** pX.pData,nData,nZero fields must be zero.
7450775184
**
7450875185
** If the seekResult parameter is non-zero, then a successful call to
74509
-** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
75186
+** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
7451075187
** been performed. In other words, if seekResult!=0 then the cursor
7451175188
** is currently pointing to a cell that will be adjacent to the cell
7451275189
** to be inserted. If seekResult<0 then pCur points to a cell that is
7451375190
** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
7451475191
** that is larger than (pKey,nKey).
@@ -74522,11 +75199,11 @@
7452275199
*/
7452375200
SQLITE_PRIVATE int sqlite3BtreeInsert(
7452475201
BtCursor *pCur, /* Insert data into the table of this cursor */
7452575202
const BtreePayload *pX, /* Content of the row to be inserted */
7452675203
int flags, /* True if this is likely an append */
74527
- int seekResult /* Result of prior MovetoUnpacked() call */
75204
+ int seekResult /* Result of prior IndexMoveto() call */
7452875205
){
7452975206
int rc;
7453075207
int loc = seekResult; /* -1: before desired location +1: after */
7453175208
int szNew = 0;
7453275209
int idx;
@@ -74537,28 +75214,10 @@
7453775214
unsigned char *newCell = 0;
7453875215
7453975216
assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
7454075217
assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
7454175218
74542
- if( pCur->eState==CURSOR_FAULT ){
74543
- assert( pCur->skipNext!=SQLITE_OK );
74544
- return pCur->skipNext;
74545
- }
74546
-
74547
- assert( cursorOwnsBtShared(pCur) );
74548
- assert( (pCur->curFlags & BTCF_WriteFlag)!=0
74549
- && pBt->inTransaction==TRANS_WRITE
74550
- && (pBt->btsFlags & BTS_READ_ONLY)==0 );
74551
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
74552
-
74553
- /* Assert that the caller has been consistent. If this cursor was opened
74554
- ** expecting an index b-tree, then the caller should be inserting blob
74555
- ** keys with no associated data. If the cursor was opened expecting an
74556
- ** intkey table, the caller should be inserting integer keys with a
74557
- ** blob of associated data. */
74558
- assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
74559
-
7456075219
/* Save the positions of any other cursors open on this table.
7456175220
**
7456275221
** In some cases, the call to btreeMoveto() below is a no-op. For
7456375222
** example, when inserting data into a table with auto-generated integer
7456475223
** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74579,10 +75238,33 @@
7457975238
** set the flag, load the schema, and then unset the flag. */
7458075239
return SQLITE_CORRUPT_BKPT;
7458175240
}
7458275241
}
7458375242
75243
+ /* Ensure that the cursor is not in the CURSOR_FAULT state and that it
75244
+ ** points to a valid cell.
75245
+ */
75246
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75247
+ testcase( pCur->eState==CURSOR_REQUIRESEEK );
75248
+ testcase( pCur->eState==CURSOR_FAULT );
75249
+ rc = moveToRoot(pCur);
75250
+ if( rc && rc!=SQLITE_EMPTY ) return rc;
75251
+ }
75252
+
75253
+ assert( cursorOwnsBtShared(pCur) );
75254
+ assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75255
+ && pBt->inTransaction==TRANS_WRITE
75256
+ && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75257
+ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75258
+
75259
+ /* Assert that the caller has been consistent. If this cursor was opened
75260
+ ** expecting an index b-tree, then the caller should be inserting blob
75261
+ ** keys with no associated data. If the cursor was opened expecting an
75262
+ ** intkey table, the caller should be inserting integer keys with a
75263
+ ** blob of associated data. */
75264
+ assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75265
+
7458475266
if( pCur->pKeyInfo==0 ){
7458575267
assert( pX->pKey==0 );
7458675268
/* If this is an insert into a table b-tree, invalidate any incrblob
7458775269
** cursors open on the row being replaced */
7458875270
if( p->hasIncrblobCur ){
@@ -74667,18 +75349,18 @@
7466775349
return btreeOverwriteCell(pCur, &x2);
7466875350
}
7466975351
}
7467075352
}
7467175353
assert( pCur->eState==CURSOR_VALID
74672
- || (pCur->eState==CURSOR_INVALID && loc)
74673
- || CORRUPT_DB );
75354
+ || (pCur->eState==CURSOR_INVALID && loc) );
7467475355
7467575356
pPage = pCur->pPage;
7467675357
assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
7467775358
assert( pPage->leaf || !pPage->intKey );
7467875359
if( pPage->nFree<0 ){
7467975360
if( NEVER(pCur->eState>CURSOR_INVALID) ){
75361
+ /* ^^^^^--- due to the moveToRoot() call above */
7468075362
rc = SQLITE_CORRUPT_BKPT;
7468175363
}else{
7468275364
rc = btreeComputeFreeSpace(pPage);
7468375365
}
7468475366
if( rc ) return rc;
@@ -74955,16 +75637,20 @@
7495575637
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
7495675638
assert( pCur->curFlags & BTCF_WriteFlag );
7495775639
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
7495875640
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
7495975641
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
74960
- if( pCur->eState==CURSOR_REQUIRESEEK ){
74961
- rc = btreeRestoreCursorPosition(pCur);
74962
- assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
74963
- if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75642
+ if( pCur->eState!=CURSOR_VALID ){
75643
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75644
+ rc = btreeRestoreCursorPosition(pCur);
75645
+ assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75646
+ if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75647
+ }else{
75648
+ return SQLITE_CORRUPT_BKPT;
75649
+ }
7496475650
}
74965
- assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
75651
+ assert( pCur->eState==CURSOR_VALID );
7496675652
7496775653
iCellDepth = pCur->iPage;
7496875654
iCellIdx = pCur->ix;
7496975655
pPage = pCur->pPage;
7497075656
if( pPage->nCell<=iCellIdx ){
@@ -74992,11 +75678,12 @@
7499275678
** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
7499375679
*/
7499475680
bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
7499575681
if( bPreserve ){
7499675682
if( !pPage->leaf
74997
- || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
75683
+ || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) >
75684
+ (int)(pBt->usableSize*2/3)
7499875685
|| pPage->nCell==1 /* See dbfuzz001.test for a test case */
7499975686
){
7500075687
/* A b-tree rebalance will be required after deleting this entry.
7500175688
** Save the cursor key. */
7500275689
rc = saveCursorKey(pCur);
@@ -75311,11 +75998,11 @@
7531175998
return SQLITE_CORRUPT_BKPT;
7531275999
}
7531376000
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
7531476001
if( rc ) return rc;
7531576002
if( (pBt->openFlags & BTREE_SINGLE)==0
75316
- && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
76003
+ && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
7531776004
){
7531876005
rc = SQLITE_CORRUPT_BKPT;
7531976006
goto cleardatabasepage_out;
7532076007
}
7532176008
hdr = pPage->hdrOffset;
@@ -76691,18 +77378,17 @@
7669177378
int i = sqlite3FindDbName(pDb, zDb);
7669277379
7669377380
if( i==1 ){
7669477381
Parse sParse;
7669577382
int rc = 0;
76696
- memset(&sParse, 0, sizeof(sParse));
76697
- sParse.db = pDb;
77383
+ sqlite3ParseObjectInit(&sParse,pDb);
7669877384
if( sqlite3OpenTempDatabase(&sParse) ){
7669977385
sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
7670077386
rc = SQLITE_ERROR;
7670177387
}
7670277388
sqlite3DbFree(pErrorDb, sParse.zErrMsg);
76703
- sqlite3ParserReset(&sParse);
77389
+ sqlite3ParseObjectReset(&sParse);
7670477390
if( rc ){
7670577391
return 0;
7670677392
}
7670777393
}
7670877394
@@ -77934,10 +78620,18 @@
7793478620
assert( sqlite3VdbeCheckMemInvariants(p) );
7793578621
if( VdbeMemDynamic(p) || p->szMalloc ){
7793678622
vdbeMemClear(p);
7793778623
}
7793878624
}
78625
+
78626
+/* Like sqlite3VdbeMemRelease() but faster for cases where we
78627
+** know in advance that the Mem is not MEM_Dyn or MEM_Agg.
78628
+*/
78629
+SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){
78630
+ assert( !VdbeMemDynamic(p) );
78631
+ if( p->szMalloc ) vdbeMemClear(p);
78632
+}
7793978633
7794078634
/*
7794178635
** Convert a 64-bit IEEE double into a 64-bit signed integer.
7794278636
** If the double is out of range of a 64-bit signed integer then
7794378637
** return the closest available 64-bit signed integer.
@@ -78296,10 +78990,11 @@
7829678990
void *pPtr,
7829778991
const char *zPType,
7829878992
void (*xDestructor)(void*)
7829978993
){
7830078994
assert( pMem->flags==MEM_Null );
78995
+ vdbeMemClear(pMem);
7830178996
pMem->u.zPType = zPType ? zPType : "";
7830278997
pMem->z = pPtr;
7830378998
pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
7830478999
pMem->eSubtype = 'p';
7830579000
pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78910,15 +79605,11 @@
7891079605
const char *zNeg = "";
7891179606
int rc = SQLITE_OK;
7891279607
7891379608
assert( pExpr!=0 );
7891479609
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
78915
-#if defined(SQLITE_ENABLE_STAT4)
7891679610
if( op==TK_REGISTER ) op = pExpr->op2;
78917
-#else
78918
- if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
78919
-#endif
7892079611
7892179612
/* Compressed expressions only appear when parsing the DEFAULT clause
7892279613
** on a table column definition, and hence only when pCtx==0. This
7892379614
** check ensures that an EP_TokenOnly expression is never passed down
7892479615
** into valueFromFunction(). */
@@ -79029,11 +79720,11 @@
7902979720
*ppVal = pVal;
7903079721
return rc;
7903179722
7903279723
no_mem:
7903379724
#ifdef SQLITE_ENABLE_STAT4
79034
- if( pCtx==0 || pCtx->pParse->nErr==0 )
79725
+ if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) )
7903579726
#endif
7903679727
sqlite3OomFault(db);
7903779728
sqlite3DbFree(db, zVal);
7903879729
assert( *ppVal==0 );
7903979730
#ifdef SQLITE_ENABLE_STAT4
@@ -79509,11 +80200,11 @@
7950980200
if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
7951080201
sqlite3OomFault(p->db);
7951180202
return SQLITE_NOMEM;
7951280203
}
7951380204
79514
- assert( nOp<=(1024/sizeof(Op)) );
80205
+ assert( nOp<=(int)(1024/sizeof(Op)) );
7951580206
assert( nNew>=(v->nOpAlloc+nOp) );
7951680207
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
7951780208
if( pNew ){
7951880209
p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
7951980210
v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -80111,11 +80802,11 @@
8011180802
** and store that value in *pMaxFuncArgs.
8011280803
**
8011380804
** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
8011480805
** indicate what the prepared statement actually does.
8011580806
**
80116
-** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
80807
+** (4) (discontinued)
8011780808
**
8011880809
** (5) Reclaim the memory allocated for storing labels.
8011980810
**
8012080811
** This routine will only function correctly if the mkopcodeh.tcl generator
8012180812
** script numbers the opcodes correctly. Changes to this routine must be
@@ -80157,29 +80848,10 @@
8015780848
case OP_JournalMode: {
8015880849
p->readOnly = 0;
8015980850
p->bIsReader = 1;
8016080851
break;
8016180852
}
80162
- case OP_Next:
80163
- case OP_SorterNext: {
80164
- pOp->p4.xAdvance = sqlite3BtreeNext;
80165
- pOp->p4type = P4_ADVANCE;
80166
- /* The code generator never codes any of these opcodes as a jump
80167
- ** to a label. They are always coded as a jump backwards to a
80168
- ** known address */
80169
- assert( pOp->p2>=0 );
80170
- break;
80171
- }
80172
- case OP_Prev: {
80173
- pOp->p4.xAdvance = sqlite3BtreePrevious;
80174
- pOp->p4type = P4_ADVANCE;
80175
- /* The code generator never codes any of these opcodes as a jump
80176
- ** to a label. They are always coded as a jump backwards to a
80177
- ** known address */
80178
- assert( pOp->p2>=0 );
80179
- break;
80180
- }
8018180853
#ifndef SQLITE_OMIT_VIRTUALTABLE
8018280854
case OP_VUpdate: {
8018380855
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
8018480856
break;
8018580857
}
@@ -80459,11 +81131,10 @@
8045981131
break;
8046081132
}
8046181133
case P4_REAL:
8046281134
case P4_INT64:
8046381135
case P4_DYNAMIC:
80464
- case P4_DYNBLOB:
8046581136
case P4_INTARRAY: {
8046681137
sqlite3DbFree(db, p4);
8046781138
break;
8046881139
}
8046981140
case P4_KEYINFO: {
@@ -80707,12 +81378,11 @@
8070781378
** makes the code easier to read during debugging. None of this happens
8070881379
** in a production build.
8070981380
*/
8071081381
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
8071181382
assert( p->nOp>0 || p->aOp==0 );
80712
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
80713
- || p->pParse->nErr>0 );
81383
+ assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 );
8071481384
if( p->nOp ){
8071581385
assert( p->aOp );
8071681386
sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
8071781387
p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
8071881388
}
@@ -81057,14 +81727,10 @@
8105781727
}
8105881728
case P4_SUBPROGRAM: {
8105981729
zP4 = "program";
8106081730
break;
8106181731
}
81062
- case P4_DYNBLOB:
81063
- case P4_ADVANCE: {
81064
- break;
81065
- }
8106681732
case P4_TABLE: {
8106781733
zP4 = pOp->p4.pTab->zName;
8106881734
break;
8106981735
}
8107081736
default: {
@@ -81192,25 +81858,44 @@
8119281858
}
8119381859
#endif
8119481860
8119581861
/*
8119681862
** Initialize an array of N Mem element.
81863
+**
81864
+** This is a high-runner, so only those fields that really do need to
81865
+** be initialized are set. The Mem structure is organized so that
81866
+** the fields that get initialized are nearby and hopefully on the same
81867
+** cache line.
81868
+**
81869
+** Mem.flags = flags
81870
+** Mem.db = db
81871
+** Mem.szMalloc = 0
81872
+**
81873
+** All other fields of Mem can safely remain uninitialized for now. They
81874
+** will be initialized before use.
8119781875
*/
8119881876
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81199
- while( (N--)>0 ){
81200
- p->db = db;
81201
- p->flags = flags;
81202
- p->szMalloc = 0;
81877
+ if( N>0 ){
81878
+ do{
81879
+ p->flags = flags;
81880
+ p->db = db;
81881
+ p->szMalloc = 0;
8120381882
#ifdef SQLITE_DEBUG
81204
- p->pScopyFrom = 0;
81883
+ p->pScopyFrom = 0;
8120581884
#endif
81206
- p++;
81885
+ p++;
81886
+ }while( (--N)>0 );
8120781887
}
8120881888
}
8120981889
8121081890
/*
81211
-** Release an array of N Mem elements
81891
+** Release auxiliary memory held in an array of N Mem elements.
81892
+**
81893
+** After this routine returns, all Mem elements in the array will still
81894
+** be valid. Those Mem elements that were not holding auxiliary resources
81895
+** will be unchanged. Mem elements which had something freed will be
81896
+** set to MEM_Undefined.
8121281897
*/
8121381898
static void releaseMemArray(Mem *p, int N){
8121481899
if( p && N ){
8121581900
Mem *pEnd = &p[N];
8121681901
sqlite3 *db = p->db;
@@ -81239,16 +81924,21 @@
8123981924
testcase( p->flags & MEM_Agg );
8124081925
testcase( p->flags & MEM_Dyn );
8124181926
if( p->flags&(MEM_Agg|MEM_Dyn) ){
8124281927
testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
8124381928
sqlite3VdbeMemRelease(p);
81929
+ p->flags = MEM_Undefined;
8124481930
}else if( p->szMalloc ){
8124581931
sqlite3DbFreeNN(db, p->zMalloc);
8124681932
p->szMalloc = 0;
81933
+ p->flags = MEM_Undefined;
8124781934
}
81248
-
81249
- p->flags = MEM_Undefined;
81935
+#ifdef SQLITE_DEBUG
81936
+ else{
81937
+ p->flags = MEM_Undefined;
81938
+ }
81939
+#endif
8125081940
}while( (++p)<pEnd );
8125181941
}
8125281942
}
8125381943
8125481944
#ifdef SQLITE_DEBUG
@@ -82324,11 +83014,11 @@
8232483014
|| (!deferred && p->nFkConstraint>0)
8232583015
){
8232683016
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
8232783017
p->errorAction = OE_Abort;
8232883018
sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
82329
- return SQLITE_ERROR;
83019
+ return SQLITE_CONSTRAINT_FOREIGNKEY;
8233083020
}
8233183021
return SQLITE_OK;
8233283022
}
8233383023
#endif
8233483024
@@ -82579,10 +83269,11 @@
8257983269
db->bBenignMalloc--;
8258083270
}else if( db->pErr ){
8258183271
sqlite3ValueSetNull(db->pErr);
8258283272
}
8258383273
db->errCode = rc;
83274
+ db->errByteOffset = -1;
8258483275
return rc;
8258583276
}
8258683277
8258783278
#ifdef SQLITE_ENABLE_SQLLOG
8258883279
/*
@@ -82858,11 +83549,11 @@
8285883549
** pointed to was deleted out from under it. Or maybe the btree was
8285983550
** rebalanced. Whatever the cause, try to restore "p" to the place it
8286083551
** is supposed to be pointing. If the row was deleted out from under the
8286183552
** cursor, set the cursor to point to a NULL row.
8286283553
*/
82863
-static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
83554
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){
8286483555
int isDifferentRow, rc;
8286583556
assert( p->eCurType==CURTYPE_BTREE );
8286683557
assert( p->uc.pCursor!=0 );
8286783558
assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
8286883559
rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82876,43 +83567,11 @@
8287683567
** if need be. Return any I/O error from the restore operation.
8287783568
*/
8287883569
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
8287983570
assert( p->eCurType==CURTYPE_BTREE );
8288083571
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
82881
- return handleMovedCursor(p);
82882
- }
82883
- return SQLITE_OK;
82884
-}
82885
-
82886
-/*
82887
-** Make sure the cursor p is ready to read or write the row to which it
82888
-** was last positioned. Return an error code if an OOM fault or I/O error
82889
-** prevents us from positioning the cursor to its correct position.
82890
-**
82891
-** If a MoveTo operation is pending on the given cursor, then do that
82892
-** MoveTo now. If no move is pending, check to see if the row has been
82893
-** deleted out from under the cursor and if it has, mark the row as
82894
-** a NULL row.
82895
-**
82896
-** If the cursor is already pointing to the correct row and that row has
82897
-** not been deleted out from under the cursor, then this routine is a no-op.
82898
-*/
82899
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
82900
- VdbeCursor *p = *pp;
82901
- assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
82902
- if( p->deferredMoveto ){
82903
- u32 iMap;
82904
- assert( !p->isEphemeral );
82905
- if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){
82906
- *pp = p->pAltCursor;
82907
- *piCol = iMap - 1;
82908
- return SQLITE_OK;
82909
- }
82910
- return sqlite3VdbeFinishMoveto(p);
82911
- }
82912
- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
82913
- return handleMovedCursor(p);
83572
+ return sqlite3VdbeHandleMovedCursor(p);
8291483573
}
8291583574
return SQLITE_OK;
8291683575
}
8291783576
8291883577
/*
@@ -83570,12 +84229,12 @@
8357084229
if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
8357184230
rc = 0;
8357284231
}else{
8357384232
rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
8357484233
}
83575
- sqlite3VdbeMemRelease(&c1);
83576
- sqlite3VdbeMemRelease(&c2);
84234
+ sqlite3VdbeMemReleaseMalloc(&c1);
84235
+ sqlite3VdbeMemReleaseMalloc(&c2);
8357784236
return rc;
8357884237
}
8357984238
}
8358084239
8358184240
/*
@@ -84095,11 +84754,12 @@
8409584754
8409684755
default:
8409784756
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
8409884757
}
8409984758
84100
- v = pPKey2->aMem[0].u.i;
84759
+ assert( pPKey2->u.i == pPKey2->aMem[0].u.i );
84760
+ v = pPKey2->u.i;
8410184761
if( v>lhs ){
8410284762
res = pPKey2->r1;
8410384763
}else if( v<lhs ){
8410484764
res = pPKey2->r2;
8410584765
}else if( pPKey2->nField>1 ){
@@ -84130,16 +84790,22 @@
8413084790
const u8 *aKey1 = (const u8*)pKey1;
8413184791
int serial_type;
8413284792
int res;
8413384793
8413484794
assert( pPKey2->aMem[0].flags & MEM_Str );
84795
+ assert( pPKey2->aMem[0].n == pPKey2->n );
84796
+ assert( pPKey2->aMem[0].z == pPKey2->u.z );
8413584797
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84136
- serial_type = (u8)(aKey1[1]);
84137
- if( serial_type >= 0x80 ){
84138
- sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84139
- }
84798
+ serial_type = (signed char)(aKey1[1]);
84799
+
84800
+vrcs_restart:
8414084801
if( serial_type<12 ){
84802
+ if( serial_type<0 ){
84803
+ sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84804
+ if( serial_type>=12 ) goto vrcs_restart;
84805
+ assert( CORRUPT_DB );
84806
+ }
8414184807
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
8414284808
}else if( !(serial_type & 0x01) ){
8414384809
res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
8414484810
}else{
8414584811
int nCmp;
@@ -84149,19 +84815,19 @@
8414984815
nStr = (serial_type-12) / 2;
8415084816
if( (szHdr + nStr) > nKey1 ){
8415184817
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
8415284818
return 0; /* Corruption */
8415384819
}
84154
- nCmp = MIN( pPKey2->aMem[0].n, nStr );
84155
- res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
84820
+ nCmp = MIN( pPKey2->n, nStr );
84821
+ res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp);
8415684822
8415784823
if( res>0 ){
8415884824
res = pPKey2->r2;
8415984825
}else if( res<0 ){
8416084826
res = pPKey2->r1;
8416184827
}else{
84162
- res = nStr - pPKey2->aMem[0].n;
84828
+ res = nStr - pPKey2->n;
8416384829
if( res==0 ){
8416484830
if( pPKey2->nField>1 ){
8416584831
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
8416684832
}else{
8416784833
res = pPKey2->default_rc;
@@ -84212,19 +84878,22 @@
8421284878
}else{
8421384879
p->r1 = -1;
8421484880
p->r2 = 1;
8421584881
}
8421684882
if( (flags & MEM_Int) ){
84883
+ p->u.i = p->aMem[0].u.i;
8421784884
return vdbeRecordCompareInt;
8421884885
}
8421984886
testcase( flags & MEM_Real );
8422084887
testcase( flags & MEM_Null );
8422184888
testcase( flags & MEM_Blob );
8422284889
if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
8422384890
&& p->pKeyInfo->aColl[0]==0
8422484891
){
8422584892
assert( flags & MEM_Str );
84893
+ p->u.z = p->aMem[0].z;
84894
+ p->n = p->aMem[0].n;
8422684895
return vdbeRecordCompareString;
8422784896
}
8422884897
}
8422984898
8423084899
return sqlite3VdbeRecordCompare;
@@ -84293,18 +84962,18 @@
8429384962
}
8429484963
8429584964
/* Fetch the integer off the end of the index record */
8429684965
sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
8429784966
*rowid = v.u.i;
84298
- sqlite3VdbeMemRelease(&m);
84967
+ sqlite3VdbeMemReleaseMalloc(&m);
8429984968
return SQLITE_OK;
8430084969
8430184970
/* Jump here if database corruption is detected after m has been
8430284971
** allocated. Free the m object and return SQLITE_CORRUPT. */
8430384972
idx_rowid_corruption:
8430484973
testcase( m.szMalloc!=0 );
84305
- sqlite3VdbeMemRelease(&m);
84974
+ sqlite3VdbeMemReleaseMalloc(&m);
8430684975
return SQLITE_CORRUPT_BKPT;
8430784976
}
8430884977
8430984978
/*
8431084979
** Compare the key of the index entry that cursor pC is pointing to against
@@ -84342,11 +85011,11 @@
8434285011
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
8434385012
if( rc ){
8434485013
return rc;
8434585014
}
8434685015
*res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
84347
- sqlite3VdbeMemRelease(&m);
85016
+ sqlite3VdbeMemReleaseMalloc(&m);
8434885017
return SQLITE_OK;
8434985018
}
8435085019
8435185020
/*
8435285021
** This routine sets the value to be returned by subsequent calls to
@@ -84509,11 +85178,11 @@
8450985178
static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
8451085179
if( p ){
8451185180
int i;
8451285181
for(i=0; i<nField; i++){
8451385182
Mem *pMem = &p->aMem[i];
84514
- if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
85183
+ if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem);
8451585184
}
8451685185
sqlite3DbFreeNN(db, p);
8451785186
}
8451885187
}
8451985188
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -84936,10 +85605,13 @@
8493685605
pNew->flags |= MEM_Ephem;
8493785606
if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
8493885607
sqlite3ValueFree(pNew);
8493985608
pNew = 0;
8494085609
}
85610
+ }else if( pNew->flags & MEM_Null ){
85611
+ /* Do not duplicate pointer values */
85612
+ pNew->flags &= ~(MEM_Term|MEM_Subtype);
8494185613
}
8494285614
return pNew;
8494385615
}
8494485616
8494585617
/* Destroy an sqlite3_value object previously obtained from
@@ -85436,10 +86108,74 @@
8543686108
*/
8543786109
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
8543886110
assert( p );
8543986111
return sqlite3_value_nochange(p->pOut);
8544086112
}
86113
+
86114
+/*
86115
+** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
86116
+** sqlite3_vtab_in_next() (if bNext!=0).
86117
+*/
86118
+static int valueFromValueList(
86119
+ sqlite3_value *pVal, /* Pointer to the ValueList object */
86120
+ sqlite3_value **ppOut, /* Store the next value from the list here */
86121
+ int bNext /* 1 for _next(). 0 for _first() */
86122
+){
86123
+ int rc;
86124
+ ValueList *pRhs;
86125
+
86126
+ *ppOut = 0;
86127
+ if( pVal==0 ) return SQLITE_MISUSE;
86128
+ pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
86129
+ if( pRhs==0 ) return SQLITE_MISUSE;
86130
+ if( bNext ){
86131
+ rc = sqlite3BtreeNext(pRhs->pCsr, 0);
86132
+ }else{
86133
+ int dummy = 0;
86134
+ rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy);
86135
+ assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) );
86136
+ if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE;
86137
+ }
86138
+ if( rc==SQLITE_OK ){
86139
+ u32 sz; /* Size of current row in bytes */
86140
+ Mem sMem; /* Raw content of current row */
86141
+ memset(&sMem, 0, sizeof(sMem));
86142
+ sz = sqlite3BtreePayloadSize(pRhs->pCsr);
86143
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem);
86144
+ if( rc==SQLITE_OK ){
86145
+ u8 *zBuf = (u8*)sMem.z;
86146
+ u32 iSerial;
86147
+ sqlite3_value *pOut = pRhs->pOut;
86148
+ int iOff = 1 + getVarint32(&zBuf[1], iSerial);
86149
+ sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut);
86150
+ pOut->enc = ENC(pOut->db);
86151
+ if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){
86152
+ rc = SQLITE_NOMEM;
86153
+ }else{
86154
+ *ppOut = pOut;
86155
+ }
86156
+ }
86157
+ sqlite3VdbeMemRelease(&sMem);
86158
+ }
86159
+ return rc;
86160
+}
86161
+
86162
+/*
86163
+** Set the iterator value pVal to point to the first value in the set.
86164
+** Set (*ppOut) to point to this value before returning.
86165
+*/
86166
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){
86167
+ return valueFromValueList(pVal, ppOut, 0);
86168
+}
86169
+
86170
+/*
86171
+** Set the iterator value pVal to point to the next value in the set.
86172
+** Set (*ppOut) to point to this value before returning.
86173
+*/
86174
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){
86175
+ return valueFromValueList(pVal, ppOut, 1);
86176
+}
8544186177
8544286178
/*
8544386179
** Return the current time for a statement. If the current time
8544486180
** is requested more than once within the same run of a single prepared
8544586181
** statement, the exact same time is returned for each invocation regardless
@@ -85631,19 +86367,19 @@
8563186367
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
8563286368
__attribute__((aligned(8)))
8563386369
#endif
8563486370
= {
8563586371
/* .u = */ {0},
86372
+ /* .z = */ (char*)0,
86373
+ /* .n = */ (int)0,
8563686374
/* .flags = */ (u16)MEM_Null,
8563786375
/* .enc = */ (u8)0,
8563886376
/* .eSubtype = */ (u8)0,
85639
- /* .n = */ (int)0,
85640
- /* .z = */ (char*)0,
85641
- /* .zMalloc = */ (char*)0,
86377
+ /* .db = */ (sqlite3*)0,
8564286378
/* .szMalloc = */ (int)0,
8564386379
/* .uTemp = */ (u32)0,
85644
- /* .db = */ (sqlite3*)0,
86380
+ /* .zMalloc = */ (char*)0,
8564586381
/* .xDel = */ (void(*)(void*))0,
8564686382
#ifdef SQLITE_DEBUG
8564786383
/* .pScopyFrom = */ (Mem*)0,
8564886384
/* .mScopyFlags= */ 0,
8564986385
#endif
@@ -86121,11 +86857,14 @@
8612186857
case SQLITE_INTEGER: {
8612286858
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
8612386859
break;
8612486860
}
8612586861
case SQLITE_FLOAT: {
86126
- rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
86862
+ assert( pValue->flags & (MEM_Real|MEM_IntReal) );
86863
+ rc = sqlite3_bind_double(pStmt, i,
86864
+ (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i
86865
+ );
8612786866
break;
8612886867
}
8612986868
case SQLITE_BLOB: {
8613086869
if( pValue->flags & MEM_Zero ){
8613186870
rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -87537,11 +88276,10 @@
8753788276
*/
8753888277
static u64 filterHash(const Mem *aMem, const Op *pOp){
8753988278
int i, mx;
8754088279
u64 h = 0;
8754188280
87542
- i = pOp->p3;
8754388281
assert( pOp->p4type==P4_INT32 );
8754488282
for(i=pOp->p3, mx=i+pOp->p4.i; i<mx; i++){
8754588283
const Mem *p = &aMem[i];
8754688284
if( p->flags & (MEM_Int|MEM_IntReal) ){
8754788285
h += p->u.i;
@@ -87852,14 +88590,18 @@
8785288590
jump_to_p2:
8785388591
pOp = &aOp[pOp->p2 - 1];
8785488592
break;
8785588593
}
8785688594
87857
-/* Opcode: Return P1 * * * *
88595
+/* Opcode: Return P1 * P3 * *
8785888596
**
8785988597
** Jump to the next instruction after the address in register P1. After
8786088598
** the jump, register P1 becomes undefined.
88599
+**
88600
+** P3 is not used by the byte-code engine. However, the code generator
88601
+** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88602
+** one.
8786188603
*/
8786288604
case OP_Return: { /* in1 */
8786388605
pIn1 = &aMem[pOp->p1];
8786488606
assert( pIn1->flags==MEM_Int );
8786588607
pOp = &aOp[pIn1->u.i];
@@ -88043,15 +88785,26 @@
8804388785
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
8804488786
}
8804588787
goto vdbe_return;
8804688788
}
8804788789
88790
+/* Opcode: BeginSubrtn P1 P2 * * *
88791
+** Synopsis: r[P2]=P1
88792
+**
88793
+** Mark the beginning of a subroutine by loading the integer value P1
88794
+** into register r[P2]. The P2 register is used to store the return
88795
+** address of the subroutine call.
88796
+**
88797
+** This opcode is identical to OP_Integer. It has a different name
88798
+** only to make the byte code easier to read and verify.
88799
+*/
8804888800
/* Opcode: Integer P1 P2 * * *
8804988801
** Synopsis: r[P2]=P1
8805088802
**
8805188803
** The 32-bit integer value P1 is written into register P2.
8805288804
*/
88805
+case OP_BeginSubrtn:
8805388806
case OP_Integer: { /* out2 */
8805488807
pOut = out2Prerelease(p, pOp);
8805588808
pOut->u.i = pOp->p1;
8805688809
break;
8805788810
}
@@ -89020,11 +89773,11 @@
8902089773
testcase( pIn1->flags & MEM_Real );
8902189774
testcase( pIn1->flags & MEM_IntReal );
8902289775
sqlite3VdbeMemStringify(pIn1, encoding, 1);
8902389776
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
8902489777
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
89025
- if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
89778
+ if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str;
8902689779
}
8902789780
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
8902889781
testcase( pIn3->flags & MEM_Int );
8902989782
testcase( pIn3->flags & MEM_Real );
8903089783
testcase( pIn3->flags & MEM_IntReal );
@@ -89488,14 +90241,22 @@
8948890241
case OP_Offset: { /* out3 */
8948990242
VdbeCursor *pC; /* The VDBE cursor */
8949090243
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
8949190244
pC = p->apCsr[pOp->p1];
8949290245
pOut = &p->aMem[pOp->p3];
89493
- if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
90246
+ if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
8949490247
sqlite3VdbeMemSetNull(pOut);
8949590248
}else{
89496
- sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90249
+ if( pC->deferredMoveto ){
90250
+ rc = sqlite3VdbeFinishMoveto(pC);
90251
+ if( rc ) goto abort_due_to_error;
90252
+ }
90253
+ if( sqlite3BtreeEof(pC->uc.pCursor) ){
90254
+ sqlite3VdbeMemSetNull(pOut);
90255
+ }else{
90256
+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90257
+ }
8949790258
}
8949890259
break;
8949990260
}
8950090261
#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
8950190262
@@ -89520,11 +90281,11 @@
8952090281
** skipped for length() and all content loading can be skipped for typeof().
8952190282
*/
8952290283
case OP_Column: {
8952390284
u32 p2; /* column number to retrieve */
8952490285
VdbeCursor *pC; /* The VDBE cursor */
89525
- BtCursor *pCrsr; /* The BTree cursor */
90286
+ BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
8952690287
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
8952790288
int len; /* The length of the serialized data for the column */
8952890289
int i; /* Loop counter */
8952990290
Mem *pDest; /* Where to write the extracted value */
8953090291
Mem sMem; /* For storing the record being decoded */
@@ -89534,23 +90295,15 @@
8953490295
u64 offset64; /* 64-bit offset */
8953590296
u32 t; /* A type code from the record header */
8953690297
Mem *pReg; /* PseudoTable input register */
8953790298
8953890299
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90300
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
8953990301
pC = p->apCsr[pOp->p1];
89540
- assert( pC!=0 );
8954190302
p2 = (u32)pOp->p2;
8954290303
89543
- /* If the cursor cache is stale (meaning it is not currently point at
89544
- ** the correct row) then bring it up-to-date by doing the necessary
89545
- ** B-Tree seek. */
89546
- rc = sqlite3VdbeCursorMoveto(&pC, &p2);
89547
- if( rc ) goto abort_due_to_error;
89548
-
89549
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
89550
- pDest = &aMem[pOp->p3];
89551
- memAboutToChange(p, pDest);
90304
+op_column_restart:
8955290305
assert( pC!=0 );
8955390306
assert( p2<(u32)pC->nField );
8955490307
aOffset = pC->aOffset;
8955590308
assert( aOffset==pC->aType+pC->nField );
8955690309
assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89567,30 +90320,43 @@
8956790320
assert( pReg->flags & MEM_Blob );
8956890321
assert( memIsValid(pReg) );
8956990322
pC->payloadSize = pC->szRow = pReg->n;
8957090323
pC->aRow = (u8*)pReg->z;
8957190324
}else{
90325
+ pDest = &aMem[pOp->p3];
90326
+ memAboutToChange(p, pDest);
8957290327
sqlite3VdbeMemSetNull(pDest);
8957390328
goto op_column_out;
8957490329
}
8957590330
}else{
8957690331
pCrsr = pC->uc.pCursor;
90332
+ if( pC->deferredMoveto ){
90333
+ u32 iMap;
90334
+ assert( !pC->isEphemeral );
90335
+ if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
90336
+ pC = pC->pAltCursor;
90337
+ p2 = iMap - 1;
90338
+ goto op_column_restart;
90339
+ }
90340
+ rc = sqlite3VdbeFinishMoveto(pC);
90341
+ if( rc ) goto abort_due_to_error;
90342
+ }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
90343
+ rc = sqlite3VdbeHandleMovedCursor(pC);
90344
+ if( rc ) goto abort_due_to_error;
90345
+ goto op_column_restart;
90346
+ }
8957790347
assert( pC->eCurType==CURTYPE_BTREE );
8957890348
assert( pCrsr );
8957990349
assert( sqlite3BtreeCursorIsValid(pCrsr) );
8958090350
pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
8958190351
pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
8958290352
assert( pC->szRow<=pC->payloadSize );
8958390353
assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
89584
- if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
89585
- goto too_big;
89586
- }
8958790354
}
8958890355
pC->cacheStatus = p->cacheCtr;
8958990356
pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
8959090357
pC->nHdrParsed = 0;
89591
-
8959290358
8959390359
if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
8959490360
/* pC->aRow does not have to hold the entire row, but it does at least
8959590361
** need to cover the header of the record. If pC->aRow does not contain
8959690362
** the complete header, then set it to zero, forcing the header to be
@@ -89627,10 +90393,14 @@
8962790393
zData = pC->aRow;
8962890394
assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
8962990395
testcase( aOffset[0]==0 );
8963090396
goto op_column_read_header;
8963190397
}
90398
+ }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){
90399
+ rc = sqlite3VdbeHandleMovedCursor(pC);
90400
+ if( rc ) goto abort_due_to_error;
90401
+ goto op_column_restart;
8963290402
}
8963390403
8963490404
/* Make sure at least the first p2+1 entries of the header have been
8963590405
** parsed and valid information is in aOffset[] and pC->aType[].
8963690406
*/
@@ -89695,10 +90465,12 @@
8969590465
/* If after trying to extract new entries from the header, nHdrParsed is
8969690466
** still not up to p2, that means that the record has fewer than p2
8969790467
** columns. So the result will be either the default value or a NULL.
8969890468
*/
8969990469
if( pC->nHdrParsed<=p2 ){
90470
+ pDest = &aMem[pOp->p3];
90471
+ memAboutToChange(p, pDest);
8970090472
if( pOp->p4type==P4_MEM ){
8970190473
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
8970290474
}else{
8970390475
sqlite3VdbeMemSetNull(pDest);
8970490476
}
@@ -89712,10 +90484,12 @@
8971290484
** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
8971390485
** all valid.
8971490486
*/
8971590487
assert( p2<pC->nHdrParsed );
8971690488
assert( rc==SQLITE_OK );
90489
+ pDest = &aMem[pOp->p3];
90490
+ memAboutToChange(p, pDest);
8971790491
assert( sqlite3VdbeCheckMemInvariants(pDest) );
8971890492
if( VdbeMemDynamic(pDest) ){
8971990493
sqlite3VdbeMemSetNull(pDest);
8972090494
}
8972190495
assert( t==pC->aType[p2] );
@@ -89732,10 +90506,11 @@
8973290506
*/
8973390507
static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
8973490508
pDest->n = len = (t-12)/2;
8973590509
pDest->enc = encoding;
8973690510
if( pDest->szMalloc < len+2 ){
90511
+ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
8973790512
pDest->flags = MEM_Null;
8973890513
if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
8973990514
}else{
8974090515
pDest->z = pDest->zMalloc;
8974190516
}
@@ -89764,10 +90539,11 @@
8976490539
** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
8976590540
** and it begins with a bunch of zeros.
8976690541
*/
8976790542
sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
8976890543
}else{
90544
+ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
8976990545
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
8977090546
if( rc!=SQLITE_OK ) goto abort_due_to_error;
8977190547
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
8977290548
pDest->flags &= ~MEM_Ephem;
8977390549
}
@@ -89846,10 +90622,12 @@
8984690622
case COLTYPE_TEXT: {
8984790623
if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error;
8984890624
break;
8984990625
}
8985090626
case COLTYPE_REAL: {
90627
+ testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real );
90628
+ testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal );
8985190629
if( pIn1->flags & MEM_Int ){
8985290630
/* When applying REAL affinity, if the result is still an MEM_Int
8985390631
** that will fit in 6 bytes, then change the type to MEM_IntReal
8985490632
** so that we keep the high-resolution integer value but know that
8985590633
** the type really wants to be REAL. */
@@ -89863,11 +90641,11 @@
8986390641
}else{
8986490642
pIn1->u.r = (double)pIn1->u.i;
8986590643
pIn1->flags |= MEM_Real;
8986690644
pIn1->flags &= ~MEM_Int;
8986790645
}
89868
- }else if( (pIn1->flags & MEM_Real)==0 ){
90646
+ }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){
8986990647
goto vdbe_type_error;
8987090648
}
8987190649
break;
8987290650
}
8987390651
default: {
@@ -89974,11 +90752,10 @@
8997490752
u32 serial_type; /* Type field */
8997590753
Mem *pData0; /* First field to be combined into the record */
8997690754
Mem *pLast; /* Last field of the record */
8997790755
int nField; /* Number of fields in the record */
8997890756
char *zAffinity; /* The affinity string for the record */
89979
- int file_format; /* File format to use for encoding */
8998090757
u32 len; /* Length of a field */
8998190758
u8 *zHdr; /* Where to write next byte of the header */
8998290759
u8 *zPayload; /* Where to write next byte of the payload */
8998390760
8998490761
/* Assuming the record contains N fields, the record format looks
@@ -90003,11 +90780,10 @@
9000390780
zAffinity = pOp->p4.z;
9000490781
assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
9000590782
pData0 = &aMem[nField];
9000690783
nField = pOp->p2;
9000790784
pLast = &pData0[nField-1];
90008
- file_format = p->minWriteFileFormat;
9000990785
9001090786
/* Identify the output register */
9001190787
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
9001290788
pOut = &aMem[pOp->p3];
9001390789
memAboutToChange(p, pOut);
@@ -90102,14 +90878,14 @@
9010290878
}
9010390879
nHdr++;
9010490880
testcase( uu==127 ); testcase( uu==128 );
9010590881
testcase( uu==32767 ); testcase( uu==32768 );
9010690882
testcase( uu==8388607 ); testcase( uu==8388608 );
90107
- testcase( uu==2147483647 ); testcase( uu==2147483648 );
90883
+ testcase( uu==2147483647 ); testcase( uu==2147483648LL );
9010890884
testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
9010990885
if( uu<=127 ){
90110
- if( (i&1)==i && file_format>=4 ){
90886
+ if( (i&1)==i && p->minWriteFileFormat>=4 ){
9011190887
pRec->uTemp = 8+(u32)uu;
9011290888
}else{
9011390889
nData++;
9011490890
pRec->uTemp = 1;
9011590891
}
@@ -92568,10 +93344,14 @@
9256893344
/* Opcode: NullRow P1 * * * *
9256993345
**
9257093346
** Move the cursor P1 to a null row. Any OP_Column operations
9257193347
** that occur while the cursor is on the null row will always
9257293348
** write a NULL.
93349
+**
93350
+** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93351
+** just reset the cache for that cursor. This causes the row of
93352
+** content held by the pseudo-cursor to be reparsed.
9257393353
*/
9257493354
case OP_NullRow: {
9257593355
VdbeCursor *pC;
9257693356
9257793357
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92747,11 +93527,11 @@
9274793527
VdbeBranchTaken(res!=0,2);
9274893528
if( res ) goto jump_to_p2;
9274993529
break;
9275093530
}
9275193531
92752
-/* Opcode: Next P1 P2 P3 P4 P5
93532
+/* Opcode: Next P1 P2 P3 * P5
9275393533
**
9275493534
** Advance cursor P1 so that it points to the next key/data pair in its
9275593535
** table or index. If there are no more key/value pairs then fall through
9275693536
** to the following instruction. But if the cursor advance was successful,
9275793537
** jump immediately to P2.
@@ -92766,19 +93546,16 @@
9276693546
** The P3 value is a hint to the btree implementation. If P3==1, that
9276793547
** means P1 is an SQL index and that this instruction could have been
9276893548
** omitted if that index had been unique. P3 is usually 0. P3 is
9276993549
** always either 0 or 1.
9277093550
**
92771
-** P4 is always of type P4_ADVANCE. The function pointer points to
92772
-** sqlite3BtreeNext().
92773
-**
9277493551
** If P5 is positive and the jump is taken, then event counter
9277593552
** number P5-1 in the prepared statement is incremented.
9277693553
**
9277793554
** See also: Prev
9277893555
*/
92779
-/* Opcode: Prev P1 P2 P3 P4 P5
93556
+/* Opcode: Prev P1 P2 P3 * P5
9278093557
**
9278193558
** Back up cursor P1 so that it points to the previous key/data pair in its
9278293559
** table or index. If there is no previous key/value pairs then fall through
9278393560
** to the following instruction. But if the cursor backup was successful,
9278493561
** jump immediately to P2.
@@ -92794,13 +93571,10 @@
9279493571
** The P3 value is a hint to the btree implementation. If P3==1, that
9279593572
** means P1 is an SQL index and that this instruction could have been
9279693573
** omitted if that index had been unique. P3 is usually 0. P3 is
9279793574
** always either 0 or 1.
9279893575
**
92799
-** P4 is always of type P4_ADVANCE. The function pointer points to
92800
-** sqlite3BtreePrevious().
92801
-**
9280293576
** If P5 is positive and the jump is taken, then event counter
9280393577
** number P5-1 in the prepared statement is incremented.
9280493578
*/
9280593579
/* Opcode: SorterNext P1 P2 * * P5
9280693580
**
@@ -92814,34 +93588,37 @@
9281493588
9281593589
pC = p->apCsr[pOp->p1];
9281693590
assert( isSorter(pC) );
9281793591
rc = sqlite3VdbeSorterNext(db, pC);
9281893592
goto next_tail;
93593
+
9281993594
case OP_Prev: /* jump */
93595
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93596
+ assert( pOp->p5<ArraySize(p->aCounter) );
93597
+ pC = p->apCsr[pOp->p1];
93598
+ assert( pC!=0 );
93599
+ assert( pC->deferredMoveto==0 );
93600
+ assert( pC->eCurType==CURTYPE_BTREE );
93601
+ assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
93602
+ || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
93603
+ || pC->seekOp==OP_NullRow);
93604
+ rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
93605
+ goto next_tail;
93606
+
9282093607
case OP_Next: /* jump */
9282193608
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
9282293609
assert( pOp->p5<ArraySize(p->aCounter) );
9282393610
pC = p->apCsr[pOp->p1];
9282493611
assert( pC!=0 );
9282593612
assert( pC->deferredMoveto==0 );
9282693613
assert( pC->eCurType==CURTYPE_BTREE );
92827
- assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
92828
- assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
92829
-
92830
- /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
92831
- ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
92832
- assert( pOp->opcode!=OP_Next
92833
- || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
93614
+ assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
9283493615
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
9283593616
|| pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
9283693617
|| pC->seekOp==OP_IfNoHope);
92837
- assert( pOp->opcode!=OP_Prev
92838
- || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
92839
- || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
92840
- || pC->seekOp==OP_NullRow);
93618
+ rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3);
9284193619
92842
- rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
9284393620
next_tail:
9284493621
pC->cacheStatus = CACHE_STALE;
9284593622
VdbeBranchTaken(rc==SQLITE_OK,2);
9284693623
if( rc==SQLITE_OK ){
9284793624
pC->nullRow = 0;
@@ -93055,10 +93832,11 @@
9305593832
assert( pTabCur->uc.pCursor!=0 );
9305693833
assert( pTabCur->isTable );
9305793834
pTabCur->nullRow = 0;
9305893835
pTabCur->movetoTarget = rowid;
9305993836
pTabCur->deferredMoveto = 1;
93837
+ pTabCur->cacheStatus = CACHE_STALE;
9306093838
assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
9306193839
assert( !pTabCur->isEphemeral );
9306293840
pTabCur->ub.aAltMap = pOp->p4.ai;
9306393841
assert( !pC->isEphemeral );
9306493842
pTabCur->pAltCursor = pC;
@@ -93189,11 +93967,11 @@
9318993967
}
9319093968
sqlite3VdbeMemInit(&m, db, 0);
9319193969
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
9319293970
if( rc ) goto abort_due_to_error;
9319393971
res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
93194
- sqlite3VdbeMemRelease(&m);
93972
+ sqlite3VdbeMemReleaseMalloc(&m);
9319593973
}
9319693974
/* End of inlined sqlite3VdbeIdxKeyCompare() */
9319793975
9319893976
assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
9319993977
if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94592,10 +95370,38 @@
9459295370
goto no_mem;
9459395371
}
9459495372
break;
9459595373
}
9459695374
#endif /* SQLITE_OMIT_VIRTUALTABLE */
95375
+
95376
+#ifndef SQLITE_OMIT_VIRTUALTABLE
95377
+/* Opcode: VInitIn P1 P2 P3 * *
95378
+** Synopsis: r[P2]=ValueList(P1,P3)
95379
+**
95380
+** Set register P2 to be a pointer to a ValueList object for cursor P1
95381
+** with cache register P3 and output register P3+1. This ValueList object
95382
+** can be used as the first argument to sqlite3_vtab_in_first() and
95383
+** sqlite3_vtab_in_next() to extract all of the values stored in the P1
95384
+** cursor. Register P3 is used to hold the values returned by
95385
+** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
95386
+*/
95387
+case OP_VInitIn: { /* out2 */
95388
+ VdbeCursor *pC; /* The cursor containing the RHS values */
95389
+ ValueList *pRhs; /* New ValueList object to put in reg[P2] */
95390
+
95391
+ pC = p->apCsr[pOp->p1];
95392
+ pRhs = sqlite3_malloc64( sizeof(*pRhs) );
95393
+ if( pRhs==0 ) goto no_mem;
95394
+ pRhs->pCsr = pC->uc.pCursor;
95395
+ pRhs->pOut = &aMem[pOp->p3];
95396
+ pOut = out2Prerelease(p, pOp);
95397
+ pOut->flags = MEM_Null;
95398
+ sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
95399
+ break;
95400
+}
95401
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
95402
+
9459795403
9459895404
#ifndef SQLITE_OMIT_VIRTUALTABLE
9459995405
/* Opcode: VFilter P1 P2 P3 P4 *
9460095406
** Synopsis: iplan=r[P3] zplan='P4'
9460195407
**
@@ -95579,14 +96385,13 @@
9557996385
wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
9558096386
9558196387
sqlite3_mutex_enter(db->mutex);
9558296388
9558396389
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
95584
- do {
95585
- memset(&sParse, 0, sizeof(Parse));
96390
+ while(1){
96391
+ sqlite3ParseObjectInit(&sParse,db);
9558696392
if( !pBlob ) goto blob_open_out;
95587
- sParse.db = db;
9558896393
sqlite3DbFree(db, zErr);
9558996394
zErr = 0;
9559096395
9559196396
sqlite3BtreeEnterAll(db);
9559296397
pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
@@ -95759,11 +96564,13 @@
9575996564
sqlite3BtreeLeaveAll(db);
9576096565
if( db->mallocFailed ){
9576196566
goto blob_open_out;
9576296567
}
9576396568
rc = blobSeekToRow(pBlob, iRow, &zErr);
95764
- } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
96569
+ if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break;
96570
+ sqlite3ParseObjectReset(&sParse);
96571
+ }
9576596572
9576696573
blob_open_out:
9576796574
if( rc==SQLITE_OK && db->mallocFailed==0 ){
9576896575
*ppBlob = (sqlite3_blob *)pBlob;
9576996576
}else{
@@ -95770,11 +96577,11 @@
9577096577
if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
9577196578
sqlite3DbFree(db, pBlob);
9577296579
}
9577396580
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
9577496581
sqlite3DbFree(db, zErr);
95775
- sqlite3ParserReset(&sParse);
96582
+ sqlite3ParseObjectReset(&sParse);
9577696583
rc = sqlite3ApiExit(db, rc);
9577796584
sqlite3_mutex_leave(db->mutex);
9577896585
return rc;
9577996586
}
9578096587
@@ -99319,10 +100126,13 @@
99319100126
}
99320100127
return rc;
99321100128
}
99322100129
99323100130
100131
+/* Forward reference */
100132
+static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size);
100133
+
99324100134
/*
99325100135
** Write data to the file.
99326100136
*/
99327100137
static int memjrnlWrite(
99328100138
sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99349,26 +100159,24 @@
99349100159
/* An in-memory journal file should only ever be appended to. Random
99350100160
** access writes are not required. The only exception to this is when
99351100161
** the in-memory journal is being used by a connection using the
99352100162
** atomic-write optimization. In this case the first 28 bytes of the
99353100163
** journal file may be written as part of committing the transaction. */
99354
- assert( iOfst==p->endpoint.iOffset || iOfst==0 );
99355
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
99356
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
100164
+ assert( iOfst<=p->endpoint.iOffset );
100165
+ if( iOfst>0 && iOfst!=p->endpoint.iOffset ){
100166
+ memjrnlTruncate(pJfd, iOfst);
100167
+ }
99357100168
if( iOfst==0 && p->pFirst ){
99358100169
assert( p->nChunkSize>iAmt );
99359100170
memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
99360
- }else
99361
-#else
99362
- assert( iOfst>0 || p->pFirst==0 );
99363
-#endif
99364
- {
100171
+ }else{
99365100172
while( nWrite>0 ){
99366100173
FileChunk *pChunk = p->endpoint.pChunk;
99367100174
int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
99368100175
int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
99369100176
100177
+ assert( pChunk!=0 || iChunkOffset==0 );
99370100178
if( iChunkOffset==0 ){
99371100179
/* New chunk is required to extend the file. */
99372100180
FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
99373100181
if( !pNew ){
99374100182
return SQLITE_IOERR_NOMEM_BKPT;
@@ -99379,14 +100187,15 @@
99379100187
pChunk->pNext = pNew;
99380100188
}else{
99381100189
assert( !p->pFirst );
99382100190
p->pFirst = pNew;
99383100191
}
99384
- p->endpoint.pChunk = pNew;
100192
+ pChunk = p->endpoint.pChunk = pNew;
99385100193
}
99386100194
99387
- memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
100195
+ assert( pChunk!=0 );
100196
+ memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace);
99388100197
zWrite += iSpace;
99389100198
nWrite -= iSpace;
99390100199
p->endpoint.iOffset += iSpace;
99391100200
}
99392100201
}
@@ -100460,10 +101269,11 @@
100460101269
}else if( zTab ){
100461101270
sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
100462101271
}else{
100463101272
sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
100464101273
}
101274
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
100465101275
pParse->checkSchema = 1;
100466101276
pTopNC->nNcErr++;
100467101277
}
100468101278
100469101279
/* If a column from a table in pSrcList is referenced, then record
@@ -100568,11 +101378,12 @@
100568101378
*/
100569101379
static void notValidImpl(
100570101380
Parse *pParse, /* Leave error message here */
100571101381
NameContext *pNC, /* The name context */
100572101382
const char *zMsg, /* Type of error */
100573
- Expr *pExpr /* Invalidate this expression on error */
101383
+ Expr *pExpr, /* Invalidate this expression on error */
101384
+ Expr *pError /* Associate error with this expression */
100574101385
){
100575101386
const char *zIn = "partial index WHERE clauses";
100576101387
if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
100577101388
#ifndef SQLITE_OMIT_CHECK
100578101389
else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100580,14 +101391,15 @@
100580101391
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
100581101392
else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
100582101393
#endif
100583101394
sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
100584101395
if( pExpr ) pExpr->op = TK_NULL;
101396
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
100585101397
}
100586
-#define sqlite3ResolveNotValid(P,N,M,X,E) \
101398
+#define sqlite3ResolveNotValid(P,N,M,X,E,R) \
100587101399
assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
100588
- if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
101400
+ if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R);
100589101401
100590101402
/*
100591101403
** Expression p should encode a floating point value between 1.0 and 0.0.
100592101404
** Return 1024 times this value. Or return -1 if p is not a floating point
100593101405
** value between 1.0 and 0.0.
@@ -100718,11 +101530,11 @@
100718101530
}else{
100719101531
Expr *pLeft = pExpr->pLeft;
100720101532
testcase( pNC->ncFlags & NC_IdxExpr );
100721101533
testcase( pNC->ncFlags & NC_GenCol );
100722101534
sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
100723
- NC_IdxExpr|NC_GenCol, 0);
101535
+ NC_IdxExpr|NC_GenCol, 0, pExpr);
100724101536
pRight = pExpr->pRight;
100725101537
if( pRight->op==TK_ID ){
100726101538
zDb = 0;
100727101539
}else{
100728101540
assert( pRight->op==TK_DOT );
@@ -100749,21 +101561,19 @@
100749101561
ExprList *pList = pExpr->x.pList; /* The argument list */
100750101562
int n = pList ? pList->nExpr : 0; /* Number of arguments */
100751101563
int no_such_func = 0; /* True if no such function exists */
100752101564
int wrong_num_args = 0; /* True if wrong number of arguments */
100753101565
int is_agg = 0; /* True if is an aggregate function */
100754
- int nId; /* Number of characters in function name */
100755101566
const char *zId; /* The function name. */
100756101567
FuncDef *pDef; /* Information about the function */
100757101568
u8 enc = ENC(pParse->db); /* The database encoding */
100758101569
int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100759101570
#ifndef SQLITE_OMIT_WINDOWFUNC
100760101571
Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100761101572
#endif
100762101573
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100763101574
zId = pExpr->u.zToken;
100764
- nId = sqlite3Strlen30(zId);
100765101575
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100766101576
if( pDef==0 ){
100767101577
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
100768101578
if( pDef==0 ){
100769101579
no_such_func = 1;
@@ -100776,12 +101586,12 @@
100776101586
ExprSetProperty(pExpr, EP_Unlikely);
100777101587
if( n==2 ){
100778101588
pExpr->iTable = exprProbability(pList->a[1].pExpr);
100779101589
if( pExpr->iTable<0 ){
100780101590
sqlite3ErrorMsg(pParse,
100781
- "second argument to likelihood() must be a "
100782
- "constant between 0.0 and 1.0");
101591
+ "second argument to %#T() must be a "
101592
+ "constant between 0.0 and 1.0", pExpr);
100783101593
pNC->nNcErr++;
100784101594
}
100785101595
}else{
100786101596
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
100787101597
** equivalent to likelihood(X, 0.0625).
@@ -100798,12 +101608,12 @@
100798101608
#ifndef SQLITE_OMIT_AUTHORIZATION
100799101609
{
100800101610
int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
100801101611
if( auth!=SQLITE_OK ){
100802101612
if( auth==SQLITE_DENY ){
100803
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
100804
- pDef->zName);
101613
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %#T",
101614
+ pExpr);
100805101615
pNC->nNcErr++;
100806101616
}
100807101617
pExpr->op = TK_NULL;
100808101618
return WRC_Prune;
100809101619
}
@@ -100822,11 +101632,11 @@
100822101632
** sqlite_version() that might change over time cannot be used
100823101633
** in an index or generated column. Curiously, they can be used
100824101634
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
100825101635
** all this. */
100826101636
sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
100827
- NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
101637
+ NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
100828101638
}else{
100829101639
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
100830101640
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
100831101641
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
100832101642
}
@@ -100835,11 +101645,11 @@
100835101645
&& (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
100836101646
){
100837101647
/* Internal-use-only functions are disallowed unless the
100838101648
** SQL is being compiled using sqlite3NestedParse() or
100839101649
** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
100840
- ** used to activate internal functionsn for testing purposes */
101650
+ ** used to activate internal functions for testing purposes */
100841101651
no_such_func = 1;
100842101652
pDef = 0;
100843101653
}else
100844101654
if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
100845101655
&& !IN_RENAME_OBJECT
@@ -100854,11 +101664,11 @@
100854101664
|| (pDef->xValue==0 && pDef->xInverse==0)
100855101665
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
100856101666
);
100857101667
if( pDef && pDef->xValue==0 && pWin ){
100858101668
sqlite3ErrorMsg(pParse,
100859
- "%.*s() may not be used as a window function", nId, zId
101669
+ "%#T() may not be used as a window function", pExpr
100860101670
);
100861101671
pNC->nNcErr++;
100862101672
}else if(
100863101673
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
100864101674
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100868,38 +101678,38 @@
100868101678
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
100869101679
zType = "window";
100870101680
}else{
100871101681
zType = "aggregate";
100872101682
}
100873
- sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
101683
+ sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr);
100874101684
pNC->nNcErr++;
100875101685
is_agg = 0;
100876101686
}
100877101687
#else
100878101688
if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
100879
- sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
101689
+ sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr);
100880101690
pNC->nNcErr++;
100881101691
is_agg = 0;
100882101692
}
100883101693
#endif
100884101694
else if( no_such_func && pParse->db->init.busy==0
100885101695
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
100886101696
&& pParse->explain==0
100887101697
#endif
100888101698
){
100889
- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
101699
+ sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
100890101700
pNC->nNcErr++;
100891101701
}else if( wrong_num_args ){
100892
- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
100893
- nId, zId);
101702
+ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()",
101703
+ pExpr);
100894101704
pNC->nNcErr++;
100895101705
}
100896101706
#ifndef SQLITE_OMIT_WINDOWFUNC
100897101707
else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
100898101708
sqlite3ErrorMsg(pParse,
100899
- "FILTER may not be used with non-aggregate %.*s()",
100900
- nId, zId
101709
+ "FILTER may not be used with non-aggregate %#T()",
101710
+ pExpr
100901101711
);
100902101712
pNC->nNcErr++;
100903101713
}
100904101714
#endif
100905101715
if( is_agg ){
@@ -100980,11 +101790,11 @@
100980101790
testcase( pNC->ncFlags & NC_IsCheck );
100981101791
testcase( pNC->ncFlags & NC_PartIdx );
100982101792
testcase( pNC->ncFlags & NC_IdxExpr );
100983101793
testcase( pNC->ncFlags & NC_GenCol );
100984101794
if( pNC->ncFlags & NC_SelfRef ){
100985
- notValidImpl(pParse, pNC, "subqueries", pExpr);
101795
+ notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
100986101796
}else{
100987101797
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
100988101798
}
100989101799
assert( pNC->nRef>=nRef );
100990101800
if( nRef!=pNC->nRef ){
@@ -100998,11 +101808,11 @@
100998101808
testcase( pNC->ncFlags & NC_IsCheck );
100999101809
testcase( pNC->ncFlags & NC_PartIdx );
101000101810
testcase( pNC->ncFlags & NC_IdxExpr );
101001101811
testcase( pNC->ncFlags & NC_GenCol );
101002101812
sqlite3ResolveNotValid(pParse, pNC, "parameters",
101003
- NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
101813
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr);
101004101814
break;
101005101815
}
101006101816
case TK_IS:
101007101817
case TK_ISNOT: {
101008101818
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101050,15 +101860,17 @@
101050101860
testcase( pExpr->op==TK_GE );
101051101861
testcase( pExpr->op==TK_IS );
101052101862
testcase( pExpr->op==TK_ISNOT );
101053101863
testcase( pExpr->op==TK_BETWEEN );
101054101864
sqlite3ErrorMsg(pParse, "row value misused");
101865
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101055101866
}
101056101867
break;
101057101868
}
101058101869
}
101059
- return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
101870
+ assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
101871
+ return pParse->nErr ? WRC_Abort : WRC_Continue;
101060101872
}
101061101873
101062101874
/*
101063101875
** pEList is a list of expressions which are really the result set of the
101064101876
** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
@@ -101162,15 +101974,17 @@
101162101974
*/
101163101975
static void resolveOutOfRangeError(
101164101976
Parse *pParse, /* The error context into which to write the error */
101165101977
const char *zType, /* "ORDER" or "GROUP" */
101166101978
int i, /* The index (1-based) of the term out of range */
101167
- int mx /* Largest permissible value of i */
101979
+ int mx, /* Largest permissible value of i */
101980
+ Expr *pError /* Associate the error with the expression */
101168101981
){
101169101982
sqlite3ErrorMsg(pParse,
101170101983
"%r %s BY term out of range - should be "
101171101984
"between 1 and %d", i, zType, mx);
101985
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
101172101986
}
101173101987
101174101988
/*
101175101989
** Analyze the ORDER BY clause in a compound SELECT statement. Modify
101176101990
** each term of the ORDER BY clause is a constant integer between 1
@@ -101222,11 +102036,11 @@
101222102036
if( pItem->done ) continue;
101223102037
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
101224102038
if( NEVER(pE==0) ) continue;
101225102039
if( sqlite3ExprIsInteger(pE, &iCol) ){
101226102040
if( iCol<=0 || iCol>pEList->nExpr ){
101227
- resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
102041
+ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
101228102042
return 1;
101229102043
}
101230102044
}else{
101231102045
iCol = resolveAsName(pParse, pEList, pE);
101232102046
if( iCol==0 ){
@@ -101318,11 +102132,11 @@
101318102132
pEList = pSelect->pEList;
101319102133
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
101320102134
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
101321102135
if( pItem->u.x.iOrderByCol ){
101322102136
if( pItem->u.x.iOrderByCol>pEList->nExpr ){
101323
- resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
102137
+ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0);
101324102138
return 1;
101325102139
}
101326102140
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
101327102141
}
101328102142
}
@@ -101410,11 +102224,11 @@
101410102224
if( sqlite3ExprIsInteger(pE2, &iCol) ){
101411102225
/* The ORDER BY term is an integer constant. Again, set the column
101412102226
** number so that sqlite3ResolveOrderGroupBy() will convert the
101413102227
** order-by term to a copy of the result-set expression */
101414102228
if( iCol<1 || iCol>0xffff ){
101415
- resolveOutOfRangeError(pParse, zType, i+1, nResult);
102229
+ resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2);
101416102230
return 1;
101417102231
}
101418102232
pItem->u.x.iOrderByCol = (u16)iCol;
101419102233
continue;
101420102234
}
@@ -101468,11 +102282,11 @@
101468102282
** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and
101469102283
** this routine in the correct order.
101470102284
*/
101471102285
if( (p->selFlags & SF_Expanded)==0 ){
101472102286
sqlite3SelectPrep(pParse, p, pOuterNC);
101473
- return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
102287
+ return pParse->nErr ? WRC_Abort : WRC_Prune;
101474102288
}
101475102289
101476102290
isCompound = p->pPrior!=0;
101477102291
nCompound = 0;
101478102292
pLeftmost = p;
@@ -101516,11 +102330,12 @@
101516102330
const char *zSavedContext = pParse->zAuthContext;
101517102331
101518102332
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
101519102333
sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
101520102334
pParse->zAuthContext = zSavedContext;
101521
- if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
102335
+ if( pParse->nErr ) return WRC_Abort;
102336
+ assert( db->mallocFailed==0 );
101522102337
101523102338
/* If the number of references to the outer context changed when
101524102339
** expressions in the sub-select were resolved, the sub-select
101525102340
** is correlated. It is not required to check the refcount on any
101526102341
** but the innermost outer context object, as lookupName() increments
@@ -102662,13 +103477,12 @@
102662103477
**
102663103478
** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
102664103479
** if appropriate.
102665103480
*/
102666103481
static void exprSetHeight(Expr *p){
102667
- int nHeight = 0;
102668
- heightOfExpr(p->pLeft, &nHeight);
102669
- heightOfExpr(p->pRight, &nHeight);
103482
+ int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
103483
+ if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
102670103484
if( ExprUseXSelect(p) ){
102671103485
heightOfSelect(p->x.pSelect, &nHeight);
102672103486
}else if( p->x.pList ){
102673103487
heightOfExprList(p->x.pList, &nHeight);
102674103488
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -102963,10 +103777,11 @@
102963103777
pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
102964103778
if( pNew==0 ){
102965103779
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
102966103780
return 0;
102967103781
}
103782
+ pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
102968103783
if( pList
102969103784
&& pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
102970103785
&& !pParse->nested
102971103786
){
102972103787
sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103006,11 +103821,11 @@
103006103821
** (2) not tagged with SQLITE_INNOCUOUS (which means it
103007103822
** is tagged with SQLITE_FUNC_UNSAFE) and
103008103823
** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103009103824
** that the schema is possibly tainted).
103010103825
*/
103011
- sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
103826
+ sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
103012103827
}
103013103828
}
103014103829
}
103015103830
103016103831
/*
@@ -103062,10 +103877,11 @@
103062103877
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103063103878
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103064103879
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103065103880
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103066103881
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
103882
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103067103883
return;
103068103884
}
103069103885
x = (ynVar)i;
103070103886
if( x>pParse->nVar ){
103071103887
pParse->nVar = (int)x;
@@ -103089,10 +103905,11 @@
103089103905
}
103090103906
}
103091103907
pExpr->iColumn = x;
103092103908
if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103093103909
sqlite3ErrorMsg(pParse, "too many SQL variables");
103910
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103094103911
}
103095103912
}
103096103913
103097103914
/*
103098103915
** Recursively delete an expression tree.
@@ -104696,12 +105513,11 @@
104696105513
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104697105514
Expr *pRhs = pEList->a[i].pExpr;
104698105515
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104699105516
int j;
104700105517
104701
- assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104702
- || pParse->nErr || db->mallocFailed );
105518
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
104703105519
for(j=0; j<nExpr; j++){
104704105520
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104705105521
assert( pIdx->azColl[j] );
104706105522
if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104707105523
continue;
@@ -104932,12 +105748,11 @@
104932105748
assert( !ExprUseYWin(pExpr) );
104933105749
ExprSetProperty(pExpr, EP_Subrtn);
104934105750
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
104935105751
pExpr->y.sub.regReturn = ++pParse->nMem;
104936105752
pExpr->y.sub.iAddr =
104937
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
104938
- VdbeComment((v, "return address"));
105753
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
104939105754
104940105755
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
104941105756
}
104942105757
104943105758
/* Check to see if this is a vector IN operator */
@@ -105035,10 +105850,11 @@
105035105850
** disable the test that was generated above that makes sure
105036105851
** this code only executes once. Because for a non-constant
105037105852
** expression we need to rerun this code each time.
105038105853
*/
105039105854
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
105855
+ sqlite3VdbeChangeToNoop(v, addrOnce-1);
105040105856
sqlite3VdbeChangeToNoop(v, addrOnce);
105041105857
ExprClearProperty(pExpr, EP_Subrtn);
105042105858
addrOnce = 0;
105043105859
}
105044105860
@@ -105055,11 +105871,14 @@
105055105871
}
105056105872
if( addrOnce ){
105057105873
sqlite3VdbeJumpHere(v, addrOnce);
105058105874
/* Subroutine return */
105059105875
assert( ExprUseYSub(pExpr) );
105060
- sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
105876
+ assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105877
+ || pParse->nErr );
105878
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105879
+ pExpr->y.sub.iAddr-1);
105061105880
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105062105881
sqlite3ClearTempRegCache(pParse);
105063105882
}
105064105883
}
105065105884
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -105110,13 +105929,11 @@
105110105929
assert( !ExprUseYWin(pExpr) );
105111105930
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105112105931
ExprSetProperty(pExpr, EP_Subrtn);
105113105932
pExpr->y.sub.regReturn = ++pParse->nMem;
105114105933
pExpr->y.sub.iAddr =
105115
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105116
- VdbeComment((v, "return address"));
105117
-
105934
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
105118105935
105119105936
/* The evaluation of the EXISTS/SELECT must be repeated every time it
105120105937
** is encountered if any of the following is true:
105121105938
**
105122105939
** * The right-hand side is a correlated subquery
@@ -105173,14 +105990,12 @@
105173105990
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
105174105991
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
105175105992
}
105176105993
pSel->iLimit = 0;
105177105994
if( sqlite3Select(pParse, pSel, &dest) ){
105178
- if( pParse->nErr ){
105179
- pExpr->op2 = pExpr->op;
105180
- pExpr->op = TK_ERROR;
105181
- }
105995
+ pExpr->op2 = pExpr->op;
105996
+ pExpr->op = TK_ERROR;
105182105997
return 0;
105183105998
}
105184105999
pExpr->iTable = rReg = dest.iSDParm;
105185106000
ExprSetVVAProperty(pExpr, EP_NoReduce);
105186106001
if( addrOnce ){
@@ -105187,11 +106002,14 @@
105187106002
sqlite3VdbeJumpHere(v, addrOnce);
105188106003
}
105189106004
105190106005
/* Subroutine return */
105191106006
assert( ExprUseYSub(pExpr) );
105192
- sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
106007
+ assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106008
+ || pParse->nErr );
106009
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106010
+ pExpr->y.sub.iAddr-1);
105193106011
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105194106012
sqlite3ClearTempRegCache(pParse);
105195106013
return rReg;
105196106014
}
105197106015
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -105393,14 +106211,13 @@
105393106211
if( destIfNull==destIfFalse ){
105394106212
destStep2 = destIfFalse;
105395106213
}else{
105396106214
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
105397106215
}
105398
- if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
105399106216
for(i=0; i<nVector; i++){
105400106217
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
105401
- if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
106218
+ if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
105402106219
if( sqlite3ExprCanBeNull(p) ){
105403106220
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
105404106221
VdbeCoverage(v);
105405106222
}
105406106223
}
@@ -105534,15 +106351,16 @@
105534106351
const char *z = pExpr->u.zToken;
105535106352
assert( z!=0 );
105536106353
c = sqlite3DecOrHexToI64(z, &value);
105537106354
if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
105538106355
#ifdef SQLITE_OMIT_FLOATING_POINT
105539
- sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
106356
+ sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
105540106357
#else
105541106358
#ifndef SQLITE_OMIT_HEX_INTEGER
105542106359
if( sqlite3_strnicmp(z,"0x",2)==0 ){
105543
- sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
106360
+ sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
106361
+ negFlag?"-":"",pExpr);
105544106362
}else
105545106363
#endif
105546106364
{
105547106365
codeReal(v, z, negFlag, iMem);
105548106366
}
@@ -106214,11 +107032,11 @@
106214107032
if( pInfo==0
106215107033
|| NEVER(pExpr->iAgg<0)
106216107034
|| NEVER(pExpr->iAgg>=pInfo->nFunc)
106217107035
){
106218107036
assert( !ExprHasProperty(pExpr, EP_IntValue) );
106219
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
107037
+ sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
106220107038
}else{
106221107039
return pInfo->aFunc[pExpr->iAgg].iMem;
106222107040
}
106223107041
break;
106224107042
}
@@ -106255,11 +107073,11 @@
106255107073
if( pDef==0 && pParse->explain ){
106256107074
pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
106257107075
}
106258107076
#endif
106259107077
if( pDef==0 || pDef->xFinalize!=0 ){
106260
- sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
107078
+ sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
106261107079
break;
106262107080
}
106263107081
if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
106264107082
assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
106265107083
assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -108571,11 +109389,13 @@
108571109389
sqlite3 *db; /* The database connection; */
108572109390
Vdbe *v; /* The prepared statement under construction */
108573109391
int r1; /* Temporary registers */
108574109392
108575109393
db = pParse->db;
108576
- if( pParse->nErr || db->mallocFailed ) return;
109394
+ assert( db->pParse==pParse );
109395
+ if( pParse->nErr ) return;
109396
+ assert( db->mallocFailed==0 );
108577109397
pNew = pParse->pNewTable;
108578109398
assert( pNew );
108579109399
108580109400
assert( sqlite3BtreeHoldsAllMutexes(db) );
108581109401
iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
@@ -108697,11 +109517,11 @@
108697109517
sqlite3NestedParse(pParse,
108698109518
"SELECT CASE WHEN quick_check GLOB 'CHECK*'"
108699109519
" THEN raise(ABORT,'CHECK constraint failed')"
108700109520
" ELSE raise(ABORT,'NOT NULL constraint failed')"
108701109521
" END"
108702
- " FROM pragma_quick_check(\"%w\",\"%w\")"
109522
+ " FROM pragma_quick_check(%Q,%Q)"
108703109523
" WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'",
108704109524
zTab, zDb
108705109525
);
108706109526
}
108707109527
}
@@ -108876,11 +109696,11 @@
108876109696
if( !zOld ) goto exit_rename_column;
108877109697
for(iCol=0; iCol<pTab->nCol; iCol++){
108878109698
if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
108879109699
}
108880109700
if( iCol==pTab->nCol ){
108881
- sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
109701
+ sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
108882109702
goto exit_rename_column;
108883109703
}
108884109704
108885109705
/* Ensure the schema contains no double-quoted strings */
108886109706
renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -108982,11 +109802,13 @@
108982109802
**
108983109803
** Technically, as x no longer points into a valid object or to the byte
108984109804
** following a valid object, it may not be used in comparison operations.
108985109805
*/
108986109806
static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
108987
- if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
109807
+ assert( pParse==pParse->db->pParse );
109808
+ assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
109809
+ if( pParse->nErr==0 ){
108988109810
const RenameToken *p;
108989109811
u8 i = 0;
108990109812
for(p=pParse->pRename; p; p=p->pNext){
108991109813
if( p->p ){
108992109814
assert( p->p!=pPtr );
@@ -109304,16 +110126,16 @@
109304110126
){
109305110127
const char *zT = (const char*)sqlite3_value_text(pType);
109306110128
const char *zN = (const char*)sqlite3_value_text(pObject);
109307110129
char *zErr;
109308110130
109309
- zErr = sqlite3_mprintf("error in %s %s%s%s: %s",
110131
+ zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",
109310110132
zT, zN, (zWhen[0] ? " " : ""), zWhen,
109311110133
pParse->zErrMsg
109312110134
);
109313110135
sqlite3_result_error(pCtx, zErr, -1);
109314
- sqlite3_free(zErr);
110136
+ sqlite3DbFree(pParse->db, zErr);
109315110137
}
109316110138
109317110139
/*
109318110140
** For each name in the the expression-list pEList (i.e. each
109319110141
** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109374,23 +110196,25 @@
109374110196
const char *zSql, /* SQL to parse */
109375110197
int bTemp /* True if SQL is from temp schema */
109376110198
){
109377110199
int rc;
109378110200
110201
+ sqlite3ParseObjectInit(p, db);
110202
+ if( zSql==0 ){
110203
+ return SQLITE_NOMEM;
110204
+ }
110205
+ if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){
110206
+ return SQLITE_CORRUPT_BKPT;
110207
+ }
109379110208
db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
109380
-
109381
- /* Parse the SQL statement passed as the first argument. If no error
109382
- ** occurs and the parse does not result in a new table, index or
109383
- ** trigger object, the database must be corrupt. */
109384
- memset(p, 0, sizeof(Parse));
109385110209
p->eParseMode = PARSE_MODE_RENAME;
109386110210
p->db = db;
109387110211
p->nQueryLoop = 1;
109388
- rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM;
110212
+ rc = sqlite3RunParser(p, zSql);
109389110213
if( db->mallocFailed ) rc = SQLITE_NOMEM;
109390110214
if( rc==SQLITE_OK
109391
- && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
110215
+ && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
109392110216
){
109393110217
rc = SQLITE_CORRUPT_BKPT;
109394110218
}
109395110219
109396110220
#ifdef SQLITE_DEBUG
@@ -109664,17 +110488,17 @@
109664110488
sqlite3FreeIndex(db, pIdx);
109665110489
}
109666110490
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
109667110491
sqlite3DbFree(db, pParse->zErrMsg);
109668110492
renameTokenFree(db, pParse->pRename);
109669
- sqlite3ParserReset(pParse);
110493
+ sqlite3ParseObjectReset(pParse);
109670110494
}
109671110495
109672110496
/*
109673110497
** SQL function:
109674110498
**
109675
-** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
110499
+** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
109676110500
**
109677110501
** 0. zSql: SQL statement to rewrite
109678110502
** 1. type: Type of object ("table", "view" etc.)
109679110503
** 2. object: Name of object
109680110504
** 3. Database: Database name (e.g. "main")
@@ -109688,11 +110512,12 @@
109688110512
** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
109689110513
** into zNew. The name should be quoted if bQuote is true.
109690110514
**
109691110515
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
109692110516
** It is only accessible to SQL created using sqlite3NestedParse(). It is
109693
-** not reachable from ordinary SQL passed into sqlite3_prepare().
110517
+** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
110518
+** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
109694110519
*/
109695110520
static void renameColumnFunc(
109696110521
sqlite3_context *context,
109697110522
int NotUsed,
109698110523
sqlite3_value **argv
@@ -109837,11 +110662,13 @@
109837110662
assert( rc==SQLITE_OK );
109838110663
rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
109839110664
109840110665
renameColumnFunc_done:
109841110666
if( rc!=SQLITE_OK ){
109842
- if( sParse.zErrMsg ){
110667
+ if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110668
+ sqlite3_result_value(context, argv[0]);
110669
+ }else if( sParse.zErrMsg ){
109843110670
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
109844110671
}else{
109845110672
sqlite3_result_error_code(context, rc);
109846110673
}
109847110674
}
@@ -110036,11 +110863,13 @@
110036110863
110037110864
if( rc==SQLITE_OK ){
110038110865
rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110039110866
}
110040110867
if( rc!=SQLITE_OK ){
110041
- if( sParse.zErrMsg ){
110868
+ if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110869
+ sqlite3_result_value(context, argv[3]);
110870
+ }else if( sParse.zErrMsg ){
110042110871
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110043110872
}else{
110044110873
sqlite3_result_error_code(context, rc);
110045110874
}
110046110875
}
@@ -110061,14 +110890,14 @@
110061110890
renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110062110891
}
110063110892
return WRC_Continue;
110064110893
}
110065110894
110066
-/*
110067
-** The implementation of an SQL scalar function that rewrites DDL statements
110068
-** so that any string literals that use double-quotes are modified so that
110069
-** they use single quotes.
110895
+/* SQL function: sqlite_rename_quotefix(DB,SQL)
110896
+**
110897
+** Rewrite the DDL statement "SQL" so that any string literals that use
110898
+** double-quotes use single quotes instead.
110070110899
**
110071110900
** Two arguments must be passed:
110072110901
**
110073110902
** 0: Database name ("main", "temp" etc.).
110074110903
** 1: SQL statement to edit.
@@ -110083,10 +110912,14 @@
110083110912
** );
110084110913
**
110085110914
** returns the string:
110086110915
**
110087110916
** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
110917
+**
110918
+** If there is a error in the input SQL, then raise an error, except
110919
+** if PRAGMA writable_schema=ON, then just return the input string
110920
+** unmodified following an error.
110088110921
*/
110089110922
static void renameQuotefixFunc(
110090110923
sqlite3_context *context,
110091110924
int NotUsed,
110092110925
sqlite3_value **argv
@@ -110157,11 +110990,15 @@
110157110990
rc = renameEditSql(context, &sCtx, zInput, 0, 0);
110158110991
}
110159110992
renameTokenFree(db, sCtx.pList);
110160110993
}
110161110994
if( rc!=SQLITE_OK ){
110162
- sqlite3_result_error_code(context, rc);
110995
+ if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){
110996
+ sqlite3_result_value(context, argv[1]);
110997
+ }else{
110998
+ sqlite3_result_error_code(context, rc);
110999
+ }
110163111000
}
110164111001
renameParseCleanup(&sParse);
110165111002
}
110166111003
110167111004
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110169,11 +111006,12 @@
110169111006
#endif
110170111007
110171111008
sqlite3BtreeLeaveAll(db);
110172111009
}
110173111010
110174
-/*
111011
+/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
111012
+**
110175111013
** An SQL user function that checks that there are no parse or symbol
110176111014
** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
110177111015
** After an ALTER TABLE .. RENAME operation is performed and the schema
110178111016
** reloaded, this function is called on each SQL statement in the schema
110179111017
** to ensure that it is still usable.
@@ -110184,15 +111022,17 @@
110184111022
** 3: Object name.
110185111023
** 4: True if object is from temp schema.
110186111024
** 5: "when" part of error message.
110187111025
** 6: True to disable the DQS quirk when parsing SQL.
110188111026
**
110189
-** Unless it finds an error, this function normally returns NULL. However, it
110190
-** returns integer value 1 if:
111027
+** The return value is computed as follows:
110191111028
**
110192
-** * the SQL argument creates a trigger, and
110193
-** * the table that the trigger is attached to is in database zDb.
111029
+** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
111030
+** then raise the error.
111031
+** B. Else if a trigger is created and the the table that the trigger is
111032
+** attached to is in database zDb, then return 1.
111033
+** C. Otherwise return NULL.
110194111034
*/
110195111035
static void renameTableTest(
110196111036
sqlite3_context *context,
110197111037
int NotUsed,
110198111038
sqlite3_value **argv
@@ -110233,16 +111073,20 @@
110233111073
rc = renameResolveTrigger(&sParse);
110234111074
}
110235111075
if( rc==SQLITE_OK ){
110236111076
int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
110237111077
int i2 = sqlite3FindDbName(db, zDb);
110238
- if( i1==i2 ) sqlite3_result_int(context, 1);
111078
+ if( i1==i2 ){
111079
+ /* Handle output case B */
111080
+ sqlite3_result_int(context, 1);
111081
+ }
110239111082
}
110240111083
}
110241111084
}
110242111085
110243
- if( rc!=SQLITE_OK && zWhen ){
111086
+ if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
111087
+ /* Output case A */
110244111088
renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
110245111089
}
110246111090
renameParseCleanup(&sParse);
110247111091
}
110248111092
@@ -110354,11 +111198,11 @@
110354111198
assert( db->mallocFailed );
110355111199
goto exit_drop_column;
110356111200
}
110357111201
iCol = sqlite3ColumnIndex(pTab, zCol);
110358111202
if( iCol<0 ){
110359
- sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
111203
+ sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName);
110360111204
goto exit_drop_column;
110361111205
}
110362111206
110363111207
/* Do not allow the user to drop a PRIMARY KEY column or a column
110364111208
** constrained by a UNIQUE constraint. */
@@ -110378,10 +111222,16 @@
110378111222
110379111223
/* Edit the sqlite_schema table */
110380111224
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
110381111225
assert( iDb>=0 );
110382111226
zDb = db->aDb[iDb].zDbSName;
111227
+#ifndef SQLITE_OMIT_AUTHORIZATION
111228
+ /* Invoke the authorization callback. */
111229
+ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){
111230
+ goto exit_drop_column;
111231
+ }
111232
+#endif
110383111233
renameTestSchema(pParse, zDb, iDb==1, "", 0);
110384111234
renameFixQuotes(pParse, zDb, iDb==1);
110385111235
sqlite3NestedParse(pParse,
110386111236
"UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
110387111237
"sql = sqlite_drop_column(%d, sql, %d) "
@@ -111501,11 +112351,11 @@
111501112351
if( pStat1==0 ) return;
111502112352
pStat1->zName = (char*)&pStat1[1];
111503112353
memcpy(pStat1->zName, "sqlite_stat1", 13);
111504112354
pStat1->nCol = 3;
111505112355
pStat1->iPKey = -1;
111506
- sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
112356
+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
111507112357
}
111508112358
#endif
111509112359
111510112360
/* Establish a read-lock on the table at the shared-cache level.
111511112361
** Open a read-only cursor on the table. Also allocate a cursor number
@@ -112765,11 +113615,11 @@
112765113615
){
112766113616
goto attach_end;
112767113617
}
112768113618
112769113619
#ifndef SQLITE_OMIT_AUTHORIZATION
112770
- if( pAuthArg ){
113620
+ if( ALWAYS(pAuthArg) ){
112771113621
char *zAuthArg;
112772113622
if( pAuthArg->op==TK_STRING ){
112773113623
assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
112774113624
zAuthArg = pAuthArg->u.zToken;
112775113625
}else{
@@ -113426,15 +114276,17 @@
113426114276
sqlite3 *db;
113427114277
Vdbe *v;
113428114278
113429114279
assert( pParse->pToplevel==0 );
113430114280
db = pParse->db;
114281
+ assert( db->pParse==pParse );
113431114282
if( pParse->nested ) return;
113432
- if( db->mallocFailed || pParse->nErr ){
113433
- if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
114283
+ if( pParse->nErr ){
114284
+ if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM;
113434114285
return;
113435114286
}
114287
+ assert( db->mallocFailed==0 );
113436114288
113437114289
/* Begin by generating some termination code at the end of the
113438114290
** vdbe program
113439114291
*/
113440114292
v = pParse->pVdbe;
@@ -113563,11 +114415,13 @@
113563114415
}
113564114416
}
113565114417
113566114418
/* Get the VDBE program ready for execution
113567114419
*/
113568
- if( v && pParse->nErr==0 && !db->mallocFailed ){
114420
+ assert( v!=0 || pParse->nErr );
114421
+ assert( db->mallocFailed==0 || pParse->nErr );
114422
+ if( pParse->nErr==0 ){
113569114423
/* A minimum of one cursor is required if autoincrement is used
113570114424
* See ticket [a696379c1f08866] */
113571114425
assert( pParse->pAinc==0 || pParse->nTab>0 );
113572114426
sqlite3VdbeMakeReady(v, pParse);
113573114427
pParse->rc = SQLITE_DONE;
@@ -113612,10 +114466,12 @@
113612114466
pParse->nested++;
113613114467
memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
113614114468
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
113615114469
db->mDbFlags |= DBFLAG_PreferBuiltin;
113616114470
sqlite3RunParser(pParse, zSql);
114471
+ sqlite3DbFree(db, pParse->zErrMsg);
114472
+ pParse->zErrMsg = 0;
113617114473
db->mDbFlags = savedDbFlags;
113618114474
sqlite3DbFree(db, zSql);
113619114475
memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
113620114476
pParse->nested--;
113621114477
}
@@ -114572,11 +115428,12 @@
114572115428
goto begin_table_error;
114573115429
}
114574115430
pTable = sqlite3FindTable(db, zName, zDb);
114575115431
if( pTable ){
114576115432
if( !noErr ){
114577
- sqlite3ErrorMsg(pParse, "table %T already exists", pName);
115433
+ sqlite3ErrorMsg(pParse, "%s %T already exists",
115434
+ (IsView(pTable)? "view" : "table"), pName);
114578115435
}else{
114579115436
assert( !db->init.busy || CORRUPT_DB );
114580115437
sqlite3CodeVerifySchema(pParse, iDb);
114581115438
sqlite3ForceNotReadOnly(pParse);
114582115439
}
@@ -115667,14 +116524,15 @@
115667116524
pList->a[0].sortFlags = pParse->iPkSortOrder;
115668116525
assert( pParse->pNewTable==pTab );
115669116526
pTab->iPKey = -1;
115670116527
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
115671116528
SQLITE_IDXTYPE_PRIMARYKEY);
115672
- if( db->mallocFailed || pParse->nErr ){
116529
+ if( pParse->nErr ){
115673116530
pTab->tabFlags &= ~TF_WithoutRowid;
115674116531
return;
115675116532
}
116533
+ assert( db->mallocFailed==0 );
115676116534
pPk = sqlite3PrimaryKeyIndex(pTab);
115677116535
assert( pPk->nKeyCol==1 );
115678116536
}else{
115679116537
pPk = sqlite3PrimaryKeyIndex(pTab);
115680116538
assert( pPk!=0 );
@@ -116101,10 +116959,15 @@
116101116959
int regRec; /* A record to be insert into the new table */
116102116960
int regRowid; /* Rowid of the next row to insert */
116103116961
int addrInsLoop; /* Top of the loop for inserting rows */
116104116962
Table *pSelTab; /* A table that describes the SELECT results */
116105116963
116964
+ if( IN_SPECIAL_PARSE ){
116965
+ pParse->rc = SQLITE_ERROR;
116966
+ pParse->nErr++;
116967
+ return;
116968
+ }
116106116969
regYield = ++pParse->nMem;
116107116970
regRec = ++pParse->nMem;
116108116971
regRowid = ++pParse->nMem;
116109116972
assert(pParse->nTab==1);
116110116973
sqlite3MayAbort(pParse);
@@ -116411,14 +117274,14 @@
116411117274
** normally holds CHECK constraints on an ordinary table, but for
116412117275
** a VIEW it holds the list of column names.
116413117276
*/
116414117277
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
116415117278
&pTable->nCol, &pTable->aCol);
116416
- if( db->mallocFailed==0
116417
- && pParse->nErr==0
117279
+ if( pParse->nErr==0
116418117280
&& pTable->nCol==pSel->pEList->nExpr
116419117281
){
117282
+ assert( db->mallocFailed==0 );
116420117283
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
116421117284
SQLITE_AFF_NONE);
116422117285
}
116423117286
}else{
116424117287
/* CREATE VIEW name AS... without an argument list. Construct
@@ -117033,11 +117896,11 @@
117033117896
tnum = (Pgno)memRootPage;
117034117897
}else{
117035117898
tnum = pIndex->tnum;
117036117899
}
117037117900
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
117038
- assert( pKey!=0 || db->mallocFailed || pParse->nErr );
117901
+ assert( pKey!=0 || pParse->nErr );
117039117902
117040117903
/* Open the sorter cursor if we are to use one. */
117041117904
iSorter = pParse->nTab++;
117042117905
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
117043117906
sqlite3KeyInfoRef(pKey), P4_KEYINFO);
@@ -117197,13 +118060,15 @@
117197118060
int nExtra = 0; /* Space allocated for zExtra[] */
117198118061
int nExtraCol; /* Number of extra columns needed */
117199118062
char *zExtra = 0; /* Extra space after the Index object */
117200118063
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
117201118064
117202
- if( db->mallocFailed || pParse->nErr>0 ){
118065
+ assert( db->pParse==pParse );
118066
+ if( pParse->nErr ){
117203118067
goto exit_create_index;
117204118068
}
118069
+ assert( db->mallocFailed==0 );
117205118070
if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
117206118071
goto exit_create_index;
117207118072
}
117208118073
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
117209118074
goto exit_create_index;
@@ -117263,11 +118128,10 @@
117263118128
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
117264118129
}
117265118130
pDb = &db->aDb[iDb];
117266118131
117267118132
assert( pTab!=0 );
117268
- assert( pParse->nErr==0 );
117269118133
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
117270118134
&& db->init.busy==0
117271118135
&& pTblName!=0
117272118136
#if SQLITE_USER_AUTHENTICATION
117273118137
&& sqlite3UserAuthTable(pTab->zName)==0
@@ -117827,14 +118691,14 @@
117827118691
Index *pIndex;
117828118692
Vdbe *v;
117829118693
sqlite3 *db = pParse->db;
117830118694
int iDb;
117831118695
117832
- assert( pParse->nErr==0 ); /* Never called with prior errors */
117833118696
if( db->mallocFailed ){
117834118697
goto exit_drop_index;
117835118698
}
118699
+ assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
117836118700
assert( pName->nSrc==1 );
117837118701
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
117838118702
goto exit_drop_index;
117839118703
}
117840118704
pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
@@ -119746,13 +120610,15 @@
119746120610
Trigger *pTrigger; /* List of table triggers, if required */
119747120611
#endif
119748120612
119749120613
memset(&sContext, 0, sizeof(sContext));
119750120614
db = pParse->db;
119751
- if( pParse->nErr || db->mallocFailed ){
120615
+ assert( db->pParse==pParse );
120616
+ if( pParse->nErr ){
119752120617
goto delete_from_cleanup;
119753120618
}
120619
+ assert( db->mallocFailed==0 );
119754120620
assert( pTabList->nSrc==1 );
119755120621
119756120622
119757120623
/* Locate the table which we want to delete. This table has to be
119758120624
** put in an SrcList structure because some of the subroutines we
@@ -119929,11 +120795,11 @@
119929120795
**
119930120796
** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
119931120797
** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
119932120798
** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
119933120799
*/
119934
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
120800
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
119935120801
if( pWInfo==0 ) goto delete_from_cleanup;
119936120802
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
119937120803
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
119938120804
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
119939120805
if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120542,10 +121408,11 @@
120542121408
static void subtypeFunc(
120543121409
sqlite3_context *context,
120544121410
int argc,
120545121411
sqlite3_value **argv
120546121412
){
121413
+ UNUSED_PARAMETER(argc);
120547121414
sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
120548121415
}
120549121416
120550121417
/*
120551121418
** Implementation of the length() function
@@ -121555,12 +122422,13 @@
121555122422
UNUSED_PARAMETER(argc);
121556122423
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
121557122424
sqlite3QuoteValue(&str,argv[0]);
121558122425
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
121559122426
SQLITE_DYNAMIC);
121560
- if( str.accError==SQLITE_NOMEM ){
121561
- sqlite3_result_error_nomem(context);
122427
+ if( str.accError!=SQLITE_OK ){
122428
+ sqlite3_result_null(context);
122429
+ sqlite3_result_error_code(context, str.accError);
121562122430
}
121563122431
}
121564122432
121565122433
/*
121566122434
** The unicode() function. Return the integer unicode code-point value
@@ -122675,12 +123543,12 @@
122675123543
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
122676123544
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122677123545
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122678123546
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122679123547
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
122680
- FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
122681
- SQLITE_FUNC_TYPEOF),
123548
+ {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
123549
+ 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
122682123550
#endif
122683123551
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
122684123552
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
122685123553
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
122686123554
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123472,11 +124340,11 @@
123472124340
123473124341
/* Create VDBE to loop through the entries in pSrc that match the WHERE
123474124342
** clause. For each row found, increment either the deferred or immediate
123475124343
** foreign key constraint counter. */
123476124344
if( pParse->nErr==0 ){
123477
- pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
124345
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0);
123478124346
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
123479124347
if( pWInfo ){
123480124348
sqlite3WhereEnd(pWInfo);
123481124349
}
123482124350
}
@@ -124480,11 +125348,11 @@
124480125348
sqlite3OomFault(db);
124481125349
return;
124482125350
}
124483125351
124484125352
for(i=j=0; i<pTab->nCol; i++){
124485
- assert( pTab->aCol[i].affinity!=0 );
125353
+ assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
124486125354
if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
124487125355
zColAff[j++] = pTab->aCol[i].affinity;
124488125356
}
124489125357
}
124490125358
do{
@@ -125014,13 +125882,15 @@
125014125882
Trigger *pTrigger; /* List of triggers on pTab, if required */
125015125883
int tmask; /* Mask of trigger times */
125016125884
#endif
125017125885
125018125886
db = pParse->db;
125019
- if( pParse->nErr || db->mallocFailed ){
125887
+ assert( db->pParse==pParse );
125888
+ if( pParse->nErr ){
125020125889
goto insert_cleanup;
125021125890
}
125891
+ assert( db->mallocFailed==0 );
125022125892
dest.iSDParm = 0; /* Suppress a harmless compiler warning */
125023125893
125024125894
/* If the Select object is really just a simple VALUES() list with a
125025125895
** single row (the common case) then keep that one row of values
125026125896
** and discard the other (unused) parts of the pSelect object
@@ -125092,11 +125962,15 @@
125092125962
** Then special optimizations can be applied that make the transfer
125093125963
** very fast and which reduce fragmentation of indices.
125094125964
**
125095125965
** This is the 2nd template.
125096125966
*/
125097
- if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
125967
+ if( pColumn==0
125968
+ && pSelect!=0
125969
+ && pTrigger==0
125970
+ && xferOptimization(pParse, pTab, pSelect, onError, iDb)
125971
+ ){
125098125972
assert( !pTrigger );
125099125973
assert( pList==0 );
125100125974
goto insert_end;
125101125975
}
125102125976
#endif /* SQLITE_OMIT_XFER_OPT */
@@ -125192,11 +126066,13 @@
125192126066
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
125193126067
dest.iSdst = bIdListInOrder ? regData : 0;
125194126068
dest.nSdst = pTab->nCol;
125195126069
rc = sqlite3Select(pParse, pSelect, &dest);
125196126070
regFromSelect = dest.iSdst;
125197
- if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
126071
+ assert( db->pParse==pParse );
126072
+ if( rc || pParse->nErr ) goto insert_cleanup;
126073
+ assert( db->mallocFailed==0 );
125198126074
sqlite3VdbeEndCoroutine(v, regYield);
125199126075
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
125200126076
assert( pSelect->pEList );
125201126077
nColumn = pSelect->pEList->nExpr;
125202126078
@@ -126573,11 +127449,11 @@
126573127449
}
126574127450
}
126575127451
if( isUpdate ){
126576127452
/* If currently processing the PRIMARY KEY of a WITHOUT ROWID
126577127453
** table, only conflict if the new PRIMARY KEY values are actually
126578
- ** different from the old.
127454
+ ** different from the old. See TH3 withoutrowid04.test.
126579127455
**
126580127456
** For a UNIQUE index, only conflict if the PRIMARY KEY values
126581127457
** of the matched index row are different from the original PRIMARY
126582127458
** KEY values of this row before the update. */
126583127459
int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127061,22 +127937,17 @@
127061127937
Vdbe *v; /* The VDBE we are building */
127062127938
int regAutoinc; /* Memory register used by AUTOINC */
127063127939
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127064127940
int regData, regRowid; /* Registers holding data and rowid */
127065127941
127066
- if( pSelect==0 ){
127067
- return 0; /* Must be of the form INSERT INTO ... SELECT ... */
127068
- }
127942
+ assert( pSelect!=0 );
127069127943
if( pParse->pWith || pSelect->pWith ){
127070127944
/* Do not attempt to process this query if there are an WITH clauses
127071127945
** attached to it. Proceeding may generate a false "no such table: xxx"
127072127946
** error if pSelect reads from a CTE named "xxx". */
127073127947
return 0;
127074127948
}
127075
- if( sqlite3TriggerList(pParse, pDest) ){
127076
- return 0; /* tab1 must not have triggers */
127077
- }
127078127949
#ifndef SQLITE_OMIT_VIRTUALTABLE
127079127950
if( IsVirtual(pDest) ){
127080127951
return 0; /* tab1 must not be a virtual table */
127081127952
}
127082127953
#endif
@@ -127937,10 +128808,20 @@
127937128808
int (*autovacuum_pages)(sqlite3*,
127938128809
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127939128810
void*, void(*)(void*));
127940128811
/* Version 3.38.0 and later */
127941128812
int (*error_offset)(sqlite3*);
128813
+ int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
128814
+ int (*vtab_distinct)(sqlite3_index_info*);
128815
+ int (*vtab_in)(sqlite3_index_info*,int,int);
128816
+ int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
128817
+ int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
128818
+ /* Version 3.39.0 and later */
128819
+ int (*deserialize)(sqlite3*,const char*,unsigned char*,
128820
+ sqlite3_int64,sqlite3_int64,unsigned);
128821
+ unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
128822
+ unsigned int);
127942128823
};
127943128824
127944128825
/*
127945128826
** This is the function signature used for all extension entry points. It
127946128827
** is also defined in the file "loadext.c".
@@ -128250,10 +129131,19 @@
128250129131
#define sqlite3_total_changes64 sqlite3_api->total_changes64
128251129132
/* Version 3.37.0 and later */
128252129133
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
128253129134
/* Version 3.38.0 and later */
128254129135
#define sqlite3_error_offset sqlite3_api->error_offset
129136
+#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
129137
+#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
129138
+#define sqlite3_vtab_in sqlite3_api->vtab_in
129139
+#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
129140
+#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
129141
+#ifndef SQLITE_OMIT_DESERIALIZE
129142
+#define sqlite3_deserialize sqlite3_api->deserialize
129143
+#define sqlite3_serialize sqlite3_api->serialize
129144
+#endif
128255129145
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
128256129146
128257129147
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
128258129148
/* This case when the file really is being compiled as a loadable
128259129149
** extension */
@@ -128741,10 +129631,23 @@
128741129631
sqlite3_total_changes64,
128742129632
/* Version 3.37.0 and later */
128743129633
sqlite3_autovacuum_pages,
128744129634
/* Version 3.38.0 and later */
128745129635
sqlite3_error_offset,
129636
+ sqlite3_vtab_rhs_value,
129637
+ sqlite3_vtab_distinct,
129638
+ sqlite3_vtab_in,
129639
+ sqlite3_vtab_in_first,
129640
+ sqlite3_vtab_in_next,
129641
+ /* Version 3.39.0 and later */
129642
+#ifndef SQLITE_OMIT_DESERIALIZE
129643
+ sqlite3_deserialize,
129644
+ sqlite3_serialize
129645
+#else
129646
+ 0,
129647
+ 0
129648
+#endif
128746129649
};
128747129650
128748129651
/* True if x is the directory separator character
128749129652
*/
128750129653
#if SQLITE_OS_WIN
@@ -129411,11 +130314,11 @@
129411130314
/* iArg: */ BTREE_DATA_VERSION },
129412130315
#endif
129413130316
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
129414130317
{/* zName: */ "database_list",
129415130318
/* ePragTyp: */ PragTyp_DATABASE_LIST,
129416
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
130319
+ /* ePragFlg: */ PragFlg_Result0,
129417130320
/* ColNames: */ 47, 3,
129418130321
/* iArg: */ 0 },
129419130322
#endif
129420130323
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
129421130324
{/* zName: */ "default_cache_size",
@@ -130099,19 +131002,20 @@
130099131002
Vdbe *v, /* The prepared statement being created */
130100131003
FuncDef *p, /* A particular function definition */
130101131004
int isBuiltin, /* True if this is a built-in function */
130102131005
int showInternFuncs /* True if showing internal functions */
130103131006
){
131007
+ u32 mask =
131008
+ SQLITE_DETERMINISTIC |
131009
+ SQLITE_DIRECTONLY |
131010
+ SQLITE_SUBTYPE |
131011
+ SQLITE_INNOCUOUS |
131012
+ SQLITE_FUNC_INTERNAL
131013
+ ;
131014
+ if( showInternFuncs ) mask = 0xffffffff;
130104131015
for(; p; p=p->pNext){
130105131016
const char *zType;
130106
- static const u32 mask =
130107
- SQLITE_DETERMINISTIC |
130108
- SQLITE_DIRECTONLY |
130109
- SQLITE_SUBTYPE |
130110
- SQLITE_INNOCUOUS |
130111
- SQLITE_FUNC_INTERNAL
130112
- ;
130113131017
static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
130114131018
130115131019
assert( SQLITE_FUNC_ENCMASK==0x3 );
130116131020
assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
130117131021
assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -131042,10 +131946,14 @@
131042131946
sqlite3_stmt *pDummy = 0;
131043131947
(void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
131044131948
(void)sqlite3_finalize(pDummy);
131045131949
sqlite3DbFree(db, zSql);
131046131950
}
131951
+ if( db->mallocFailed ){
131952
+ sqlite3ErrorMsg(db->pParse, "out of memory");
131953
+ db->pParse->rc = SQLITE_NOMEM_BKPT;
131954
+ }
131047131955
pHash = &db->aDb[ii].pSchema->tblHash;
131048131956
break;
131049131957
}
131050131958
}
131051131959
}
@@ -133078,12 +133986,14 @@
133078133986
}
133079133987
133080133988
/*
133081133989
** Free all memory allocations in the pParse object
133082133990
*/
133083
-SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
133991
+SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){
133084133992
sqlite3 *db = pParse->db;
133993
+ assert( db!=0 );
133994
+ assert( db->pParse==pParse );
133085133995
assert( pParse->nested==0 );
133086133996
#ifndef SQLITE_OMIT_SHARED_CACHE
133087133997
sqlite3DbFree(db, pParse->aTableLock);
133088133998
#endif
133089133999
while( pParse->pCleanup ){
@@ -133094,15 +134004,16 @@
133094134004
}
133095134005
sqlite3DbFree(db, pParse->aLabel);
133096134006
if( pParse->pConstExpr ){
133097134007
sqlite3ExprListDelete(db, pParse->pConstExpr);
133098134008
}
133099
- if( db ){
133100
- assert( db->lookaside.bDisable >= pParse->disableLookaside );
133101
- db->lookaside.bDisable -= pParse->disableLookaside;
133102
- db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
133103
- }
134009
+ assert( db->lookaside.bDisable >= pParse->disableLookaside );
134010
+ db->lookaside.bDisable -= pParse->disableLookaside;
134011
+ db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
134012
+ assert( pParse->db->pParse==pParse );
134013
+ db->pParse = pParse->pOuterParse;
134014
+ pParse->db = 0;
133104134015
pParse->disableLookaside = 0;
133105134016
}
133106134017
133107134018
/*
133108134019
** Add a new cleanup operation to a Parser. The cleanup should happen when
@@ -133111,11 +134022,11 @@
133111134022
**
133112134023
** Use this mechanism for uncommon cleanups. There is a higher setup
133113134024
** cost for this mechansim (an extra malloc), so it should not be used
133114134025
** for common cleanups that happen on most calls. But for less
133115134026
** common cleanups, we save a single NULL-pointer comparison in
133116
-** sqlite3ParserReset(), which reduces the total CPU cycle count.
134027
+** sqlite3ParseObjectReset(), which reduces the total CPU cycle count.
133117134028
**
133118134029
** If a memory allocation error occurs, then the cleanup happens immediately.
133119134030
** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
133120134031
** pParse->earlyCleanup flag is set in that case. Calling code show verify
133121134032
** that test cases exist for which this happens, to guard against possible
@@ -133150,10 +134061,29 @@
133150134061
pParse->earlyCleanup = 1;
133151134062
#endif
133152134063
}
133153134064
return pPtr;
133154134065
}
134066
+
134067
+/*
134068
+** Turn bulk memory into a valid Parse object and link that Parse object
134069
+** into database connection db.
134070
+**
134071
+** Call sqlite3ParseObjectReset() to undo this operation.
134072
+**
134073
+** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which
134074
+** is generated by Lemon.
134075
+*/
134076
+SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){
134077
+ memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ);
134078
+ memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
134079
+ assert( db->pParse!=pParse );
134080
+ pParse->pOuterParse = db->pParse;
134081
+ db->pParse = pParse;
134082
+ pParse->db = db;
134083
+ if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory");
134084
+}
133155134085
133156134086
/*
133157134087
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
133158134088
*/
133159134089
static int sqlite3Prepare(
@@ -133167,15 +134097,19 @@
133167134097
){
133168134098
int rc = SQLITE_OK; /* Result code */
133169134099
int i; /* Loop counter */
133170134100
Parse sParse; /* Parsing context */
133171134101
133172
- memset(&sParse, 0, PARSE_HDR_SZ);
134102
+ /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */
134103
+ memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
133173134104
memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
134105
+ sParse.pOuterParse = db->pParse;
134106
+ db->pParse = &sParse;
134107
+ sParse.db = db;
133174134108
sParse.pReprepare = pReprepare;
133175134109
assert( ppStmt && *ppStmt==0 );
133176
- /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
134110
+ if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
133177134111
assert( sqlite3_mutex_held(db->mutex) );
133178134112
133179134113
/* For a long-term use prepared statement avoid the use of
133180134114
** lookaside memory.
133181134115
*/
@@ -133224,11 +134158,10 @@
133224134158
}
133225134159
}
133226134160
133227134161
sqlite3VtabUnlockList(db);
133228134162
133229
- sParse.db = db;
133230134163
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
133231134164
char *zSqlCopy;
133232134165
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
133233134166
testcase( nBytes==mxLen );
133234134167
testcase( nBytes==mxLen+1 );
@@ -133291,11 +134224,11 @@
133291134224
sqlite3DbFree(db, pT);
133292134225
}
133293134226
133294134227
end_prepare:
133295134228
133296
- sqlite3ParserReset(&sParse);
134229
+ sqlite3ParseObjectReset(&sParse);
133297134230
return rc;
133298134231
}
133299134232
static int sqlite3LockAndPrepare(
133300134233
sqlite3 *db, /* Database handle. */
133301134234
const char *zSql, /* UTF-8 encoded SQL statement. */
@@ -133563,11 +134496,11 @@
133563134496
** how to process the DISTINCT keyword, to simplify passing that information
133564134497
** into the selectInnerLoop() routine.
133565134498
*/
133566134499
typedef struct DistinctCtx DistinctCtx;
133567134500
struct DistinctCtx {
133568
- u8 isTnct; /* True if the DISTINCT keyword is present */
134501
+ u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */
133569134502
u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
133570134503
int tabTnct; /* Ephemeral table used for DISTINCT processing */
133571134504
int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
133572134505
};
133573134506
@@ -133896,29 +134829,29 @@
133896134829
** sqlite3PExpr(). */
133897134830
if( pEq && isOuterJoin ){
133898134831
ExprSetProperty(pEq, EP_FromJoin);
133899134832
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
133900134833
ExprSetVVAProperty(pEq, EP_NoReduce);
133901
- pEq->iRightJoinTable = pE2->iTable;
134834
+ pEq->w.iRightJoinTable = pE2->iTable;
133902134835
}
133903134836
*ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
133904134837
}
133905134838
133906134839
/*
133907134840
** Set the EP_FromJoin property on all terms of the given expression.
133908
-** And set the Expr.iRightJoinTable to iTable for every term in the
134841
+** And set the Expr.w.iRightJoinTable to iTable for every term in the
133909134842
** expression.
133910134843
**
133911134844
** The EP_FromJoin property is used on terms of an expression to tell
133912134845
** the LEFT OUTER JOIN processing logic that this term is part of the
133913134846
** join restriction specified in the ON or USING clause and not a part
133914134847
** of the more general WHERE clause. These terms are moved over to the
133915134848
** WHERE clause during join processing but we need to remember that they
133916134849
** originated in the ON or USING clause.
133917134850
**
133918
-** The Expr.iRightJoinTable tells the WHERE clause processing that the
133919
-** expression depends on table iRightJoinTable even if that table is not
134851
+** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134852
+** expression depends on table w.iRightJoinTable even if that table is not
133920134853
** explicitly mentioned in the expression. That information is needed
133921134854
** for cases like this:
133922134855
**
133923134856
** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
133924134857
**
@@ -133932,11 +134865,11 @@
133932134865
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
133933134866
while( p ){
133934134867
ExprSetProperty(p, EP_FromJoin);
133935134868
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
133936134869
ExprSetVVAProperty(p, EP_NoReduce);
133937
- p->iRightJoinTable = iTable;
134870
+ p->w.iRightJoinTable = iTable;
133938134871
if( p->op==TK_FUNCTION ){
133939134872
assert( ExprUseXList(p) );
133940134873
if( p->x.pList ){
133941134874
int i;
133942134875
for(i=0; i<p->x.pList->nExpr; i++){
@@ -133948,19 +134881,19 @@
133948134881
p = p->pRight;
133949134882
}
133950134883
}
133951134884
133952134885
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
133953
-** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
134886
+** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
133954134887
** an ordinary term that omits the EP_FromJoin mark.
133955134888
**
133956134889
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
133957134890
*/
133958134891
static void unsetJoinExpr(Expr *p, int iTable){
133959134892
while( p ){
133960134893
if( ExprHasProperty(p, EP_FromJoin)
133961
- && (iTable<0 || p->iRightJoinTable==iTable) ){
134894
+ && (iTable<0 || p->w.iRightJoinTable==iTable) ){
133962134895
ExprClearProperty(p, EP_FromJoin);
133963134896
}
133964134897
if( p->op==TK_COLUMN && p->iTable==iTable ){
133965134898
ExprClearProperty(p, EP_CanBeNull);
133966134899
}
@@ -134946,11 +135879,11 @@
134946135879
p->enc = ENC(db);
134947135880
p->db = db;
134948135881
p->nRef = 1;
134949135882
memset(&p[1], 0, nExtra);
134950135883
}else{
134951
- sqlite3OomFault(db);
135884
+ return (KeyInfo*)sqlite3OomFault(db);
134952135885
}
134953135886
return p;
134954135887
}
134955135888
134956135889
/*
@@ -135117,10 +136050,13 @@
135117136050
}
135118136051
#endif
135119136052
135120136053
iTab = pSort->iECursor;
135121136054
if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
136055
+ if( eDest==SRT_Mem && p->iOffset ){
136056
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst);
136057
+ }
135122136058
regRowid = 0;
135123136059
regRow = pDest->iSdst;
135124136060
}else{
135125136061
regRowid = sqlite3GetTempReg(pParse);
135126136062
if( eDest==SRT_EphemTab || eDest==SRT_Table ){
@@ -136162,11 +137098,11 @@
136162137098
** (3) There is no ORDER BY clause
136163137099
**
136164137100
** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
136165137101
** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
136166137102
** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
136167
-** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
137103
+** Since the limit is exactly 1, we only need to evaluate the left-most VALUES.
136168137104
*/
136169137105
static int multiSelectValues(
136170137106
Parse *pParse, /* Parsing context */
136171137107
Select *p, /* The right-most of SELECTs to be coded */
136172137108
SelectDest *pDest /* What to do with query results */
@@ -136975,10 +137911,11 @@
136975137911
}else{
136976137912
pSplit = p;
136977137913
for(i=2; i<nSelect; i+=2){ pSplit = pSplit->pPrior; }
136978137914
}
136979137915
pPrior = pSplit->pPrior;
137916
+ assert( pPrior!=0 );
136980137917
pSplit->pPrior = 0;
136981137918
pPrior->pNext = 0;
136982137919
assert( p->pOrderBy == pOrderBy );
136983137920
assert( pOrderBy!=0 || db->mallocFailed );
136984137921
pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
@@ -137186,13 +138123,13 @@
137186138123
SubstContext *pSubst, /* Description of the substitution */
137187138124
Expr *pExpr /* Expr in which substitution occurs */
137188138125
){
137189138126
if( pExpr==0 ) return 0;
137190138127
if( ExprHasProperty(pExpr, EP_FromJoin)
137191
- && pExpr->iRightJoinTable==pSubst->iTable
138128
+ && pExpr->w.iRightJoinTable==pSubst->iTable
137192138129
){
137193
- pExpr->iRightJoinTable = pSubst->iNewTable;
138130
+ pExpr->w.iRightJoinTable = pSubst->iNewTable;
137194138131
}
137195138132
if( pExpr->op==TK_COLUMN
137196138133
&& pExpr->iTable==pSubst->iTable
137197138134
&& !ExprHasProperty(pExpr, EP_FixedCol)
137198138135
){
@@ -137227,11 +138164,11 @@
137227138164
}
137228138165
if( pSubst->isLeftJoin ){
137229138166
ExprSetProperty(pNew, EP_CanBeNull);
137230138167
}
137231138168
if( ExprHasProperty(pExpr,EP_FromJoin) ){
137232
- sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
138169
+ sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
137233138170
}
137234138171
sqlite3ExprDelete(db, pExpr);
137235138172
pExpr = pNew;
137236138173
137237138174
/* Ensure that the expression now has an implicit collation sequence,
@@ -137392,11 +138329,11 @@
137392138329
int op = pExpr->op;
137393138330
if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
137394138331
renumberCursorDoMapping(pWalker, &pExpr->iTable);
137395138332
}
137396138333
if( ExprHasProperty(pExpr, EP_FromJoin) ){
137397
- renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
138334
+ renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
137398138335
}
137399138336
return WRC_Continue;
137400138337
}
137401138338
137402138339
/*
@@ -138402,15 +139339,17 @@
138402139339
iCursor, isLeftJoin);
138403139340
pWhere = pWhere->pLeft;
138404139341
}
138405139342
if( isLeftJoin
138406139343
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
138407
- || pWhere->iRightJoinTable!=iCursor)
139344
+ || pWhere->w.iRightJoinTable!=iCursor)
138408139345
){
138409139346
return 0; /* restriction (4) */
138410139347
}
138411
- if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
139348
+ if( ExprHasProperty(pWhere,EP_FromJoin)
139349
+ && pWhere->w.iRightJoinTable!=iCursor
139350
+ ){
138412139351
return 0; /* restriction (5) */
138413139352
}
138414139353
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
138415139354
nChng++;
138416139355
pSubq->selFlags |= SF_PushDown;
@@ -139126,11 +140065,12 @@
139126140065
}
139127140066
}
139128140067
139129140068
/* Process NATURAL keywords, and ON and USING clauses of joins.
139130140069
*/
139131
- if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
140070
+ assert( db->mallocFailed==0 || pParse->nErr!=0 );
140071
+ if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
139132140072
return WRC_Abort;
139133140073
}
139134140074
139135140075
/* For every "*" that occurs in the column list, insert the names of
139136140076
** all columns in all tables. And for every TABLE.* insert the names
@@ -139423,16 +140363,17 @@
139423140363
Parse *pParse, /* The parser context */
139424140364
Select *p, /* The SELECT statement being coded. */
139425140365
NameContext *pOuterNC /* Name context for container */
139426140366
){
139427140367
assert( p!=0 || pParse->db->mallocFailed );
140368
+ assert( pParse->db->pParse==pParse );
139428140369
if( pParse->db->mallocFailed ) return;
139429140370
if( p->selFlags & SF_HasTypeInfo ) return;
139430140371
sqlite3SelectExpand(pParse, p);
139431
- if( pParse->nErr || pParse->db->mallocFailed ) return;
140372
+ if( pParse->nErr ) return;
139432140373
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
139433
- if( pParse->nErr || pParse->db->mallocFailed ) return;
140374
+ if( pParse->nErr ) return;
139434140375
sqlite3SelectAddTypeInfo(pParse, p);
139435140376
}
139436140377
139437140378
/*
139438140379
** Reset the aggregate accumulator.
@@ -139445,12 +140386,14 @@
139445140386
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
139446140387
Vdbe *v = pParse->pVdbe;
139447140388
int i;
139448140389
struct AggInfo_func *pFunc;
139449140390
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
140391
+ assert( pParse->db->pParse==pParse );
140392
+ assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
139450140393
if( nReg==0 ) return;
139451
- if( pParse->nErr || pParse->db->mallocFailed ) return;
140394
+ if( pParse->nErr ) return;
139452140395
#ifdef SQLITE_DEBUG
139453140396
/* Verify that all AggInfo registers are within the range specified by
139454140397
** AggInfo.mnReg..AggInfo.mxReg */
139455140398
assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
139456140399
for(i=0; i<pAggInfo->nColumn; i++){
@@ -139869,14 +140812,16 @@
139869140812
sqlite3 *db; /* The database connection */
139870140813
ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
139871140814
u8 minMaxFlag; /* Flag for min/max queries */
139872140815
139873140816
db = pParse->db;
140817
+ assert( pParse==db->pParse );
139874140818
v = sqlite3GetVdbe(pParse);
139875
- if( p==0 || db->mallocFailed || pParse->nErr ){
140819
+ if( p==0 || pParse->nErr ){
139876140820
return 1;
139877140821
}
140822
+ assert( db->mallocFailed==0 );
139878140823
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
139879140824
#if SELECTTRACE_ENABLED
139880140825
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
139881140826
if( sqlite3SelectTrace & 0x100 ){
139882140827
sqlite3TreeViewSelect(0, p, 0);
@@ -139907,13 +140852,14 @@
139907140852
}
139908140853
p->selFlags &= ~SF_Distinct;
139909140854
p->selFlags |= SF_NoopOrderBy;
139910140855
}
139911140856
sqlite3SelectPrep(pParse, p, 0);
139912
- if( pParse->nErr || db->mallocFailed ){
140857
+ if( pParse->nErr ){
139913140858
goto select_end;
139914140859
}
140860
+ assert( db->mallocFailed==0 );
139915140861
assert( p->pEList!=0 );
139916140862
#if SELECTTRACE_ENABLED
139917140863
if( sqlite3SelectTrace & 0x104 ){
139918140864
SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
139919140865
sqlite3TreeViewSelect(0, p, 0);
@@ -139953,11 +140899,11 @@
139953140899
sqlite3GenerateColumnNames(pParse, p);
139954140900
}
139955140901
139956140902
#ifndef SQLITE_OMIT_WINDOWFUNC
139957140903
if( sqlite3WindowRewrite(pParse, p) ){
139958
- assert( db->mallocFailed || pParse->nErr>0 );
140904
+ assert( pParse->nErr );
139959140905
goto select_end;
139960140906
}
139961140907
#if SELECTTRACE_ENABLED
139962140908
if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
139963140909
SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
@@ -140350,10 +141296,11 @@
140350141296
p->selFlags |= SF_Aggregate;
140351141297
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
140352141298
** the sDistinct.isTnct is still set. Hence, isTnct represents the
140353141299
** original setting of the SF_Distinct flag, not the current setting */
140354141300
assert( sDistinct.isTnct );
141301
+ sDistinct.isTnct = 2;
140355141302
140356141303
#if SELECTTRACE_ENABLED
140357141304
if( sqlite3SelectTrace & 0x400 ){
140358141305
SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
140359141306
sqlite3TreeViewSelect(0, p, 0);
@@ -140429,11 +141376,11 @@
140429141376
140430141377
140431141378
/* Begin the database scan. */
140432141379
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140433141380
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
140434
- p->pEList, wctrlFlags, p->nSelectRow);
141381
+ p->pEList, p, wctrlFlags, p->nSelectRow);
140435141382
if( pWInfo==0 ) goto select_end;
140436141383
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
140437141384
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
140438141385
}
140439141386
if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140693,11 +141640,12 @@
140693141640
** in the right order to begin with.
140694141641
*/
140695141642
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
140696141643
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140697141644
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
140698
- WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
141645
+ 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
141646
+ | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
140699141647
);
140700141648
if( pWInfo==0 ){
140701141649
sqlite3ExprListDelete(db, pDistinct);
140702141650
goto select_end;
140703141651
}
@@ -140875,11 +141823,11 @@
140875141823
resetAccumulator(pParse, pAggInfo);
140876141824
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
140877141825
VdbeComment((v, "indicate accumulator empty"));
140878141826
sqlite3VdbeAddOp1(v, OP_Return, regReset);
140879141827
140880
- if( eDist!=WHERE_DISTINCT_NOOP ){
141828
+ if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
140881141829
struct AggInfo_func *pF = &pAggInfo->aFunc[0];
140882141830
fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
140883141831
}
140884141832
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
140885141833
else {
@@ -140991,11 +141939,11 @@
140991141939
assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
140992141940
assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
140993141941
140994141942
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140995141943
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
140996
- pDistinct, minMaxFlag|distFlag, 0);
141944
+ pDistinct, 0, minMaxFlag|distFlag, 0);
140997141945
if( pWInfo==0 ){
140998141946
goto select_end;
140999141947
}
141000141948
SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
141001141949
eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141048,11 +141996,11 @@
141048141996
/* Control jumps to here if an error is encountered above, or upon
141049141997
** successful coding of the SELECT.
141050141998
*/
141051141999
select_end:
141052142000
assert( db->mallocFailed==0 || db->mallocFailed==1 );
141053
- pParse->nErr += db->mallocFailed;
142001
+ assert( db->mallocFailed==0 || pParse->nErr!=0 );
141054142002
sqlite3ExprListDelete(db, pMinMaxOrderBy);
141055142003
#ifdef SQLITE_DEBUG
141056142004
if( pAggInfo && !db->mallocFailed ){
141057142005
for(i=0; i<pAggInfo->nColumn; i++){
141058142006
Expr *pExpr = pAggInfo->aCol[i].pCExpr;
@@ -141349,15 +142297,14 @@
141349142297
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
141350142298
&& pTrig->pTabSchema!=pTmpSchema
141351142299
){
141352142300
pTrig->pNext = pList;
141353142301
pList = pTrig;
141354
- }else if( pTrig->op==TK_RETURNING
142302
+ }else if( pTrig->op==TK_RETURNING ){
141355142303
#ifndef SQLITE_OMIT_VIRTUALTABLE
141356
- && pParse->db->pVtabCtx==0
142304
+ assert( pParse->db->pVtabCtx==0 );
141357142305
#endif
141358
- ){
141359142306
assert( pParse->bReturning );
141360142307
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
141361142308
pTrig->table = pTab->zName;
141362142309
pTrig->pTabSchema = pTab->pSchema;
141363142310
pTrig->pNext = pList;
@@ -141728,10 +142675,11 @@
141728142675
const char *zEnd /* End of SQL text */
141729142676
){
141730142677
sqlite3 *db = pParse->db;
141731142678
TriggerStep *pTriggerStep;
141732142679
142680
+ if( pParse->nErr ) return 0;
141733142681
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
141734142682
if( pTriggerStep ){
141735142683
char *z = (char*)&pTriggerStep[1];
141736142684
memcpy(z, pName->z, pName->n);
141737142685
sqlite3Dequote(z);
@@ -142200,10 +143148,11 @@
142200143148
Select sSelect;
142201143149
SrcList sFrom;
142202143150
142203143151
assert( v!=0 );
142204143152
assert( pParse->bReturning );
143153
+ assert( db->pParse==pParse );
142205143154
pReturning = pParse->u1.pReturning;
142206143155
assert( pTrigger == &(pReturning->retTrig) );
142207143156
memset(&sSelect, 0, sizeof(sSelect));
142208143157
memset(&sFrom, 0, sizeof(sFrom));
142209143158
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
@@ -142210,11 +143159,12 @@
142210143159
sSelect.pSrc = &sFrom;
142211143160
sFrom.nSrc = 1;
142212143161
sFrom.a[0].pTab = pTab;
142213143162
sFrom.a[0].iCursor = -1;
142214143163
sqlite3SelectPrep(pParse, &sSelect, 0);
142215
- if( db->mallocFailed==0 && pParse->nErr==0 ){
143164
+ if( pParse->nErr==0 ){
143165
+ assert( db->mallocFailed==0 );
142216143166
sqlite3GenerateColumnNames(pParse, &sSelect);
142217143167
}
142218143168
sqlite3ExprListDelete(db, sSelect.pEList);
142219143169
pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
142220143170
if( !db->mallocFailed ){
@@ -142228,11 +143178,11 @@
142228143178
sNC.uNC.iBaseReg = regIn;
142229143179
sNC.ncFlags = NC_UBaseReg;
142230143180
pParse->eTriggerOp = pTrigger->op;
142231143181
pParse->pTriggerTab = pTab;
142232143182
if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK
142233
- && !db->mallocFailed
143183
+ && ALWAYS(!db->mallocFailed)
142234143184
){
142235143185
int i;
142236143186
int nCol = pNew->nExpr;
142237143187
int reg = pParse->nMem+1;
142238143188
pParse->nMem += nCol+2;
@@ -142392,12 +143342,12 @@
142392143342
TriggerPrg *pPrg; /* Value to return */
142393143343
Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
142394143344
Vdbe *v; /* Temporary VM */
142395143345
NameContext sNC; /* Name context for sub-vdbe */
142396143346
SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
142397
- Parse *pSubParse; /* Parse context for sub-vdbe */
142398143347
int iEndTrigger = 0; /* Label to jump to if WHEN is false */
143348
+ Parse sSubParse; /* Parse context for sub-vdbe */
142399143349
142400143350
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
142401143351
assert( pTop->pVdbe );
142402143352
142403143353
/* Allocate the TriggerPrg and SubProgram objects. To ensure that they
@@ -142415,23 +143365,21 @@
142415143365
pPrg->aColmask[0] = 0xffffffff;
142416143366
pPrg->aColmask[1] = 0xffffffff;
142417143367
142418143368
/* Allocate and populate a new Parse context to use for coding the
142419143369
** trigger sub-program. */
142420
- pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
142421
- if( !pSubParse ) return 0;
143370
+ sqlite3ParseObjectInit(&sSubParse, db);
142422143371
memset(&sNC, 0, sizeof(sNC));
142423
- sNC.pParse = pSubParse;
142424
- pSubParse->db = db;
142425
- pSubParse->pTriggerTab = pTab;
142426
- pSubParse->pToplevel = pTop;
142427
- pSubParse->zAuthContext = pTrigger->zName;
142428
- pSubParse->eTriggerOp = pTrigger->op;
142429
- pSubParse->nQueryLoop = pParse->nQueryLoop;
142430
- pSubParse->disableVtab = pParse->disableVtab;
142431
-
142432
- v = sqlite3GetVdbe(pSubParse);
143372
+ sNC.pParse = &sSubParse;
143373
+ sSubParse.pTriggerTab = pTab;
143374
+ sSubParse.pToplevel = pTop;
143375
+ sSubParse.zAuthContext = pTrigger->zName;
143376
+ sSubParse.eTriggerOp = pTrigger->op;
143377
+ sSubParse.nQueryLoop = pParse->nQueryLoop;
143378
+ sSubParse.disableVtab = pParse->disableVtab;
143379
+
143380
+ v = sqlite3GetVdbe(&sSubParse);
142433143381
if( v ){
142434143382
VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
142435143383
pTrigger->zName, onErrorText(orconf),
142436143384
(pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
142437143385
(pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
@@ -142453,42 +143401,43 @@
142453143401
if( pTrigger->pWhen ){
142454143402
pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
142455143403
if( db->mallocFailed==0
142456143404
&& SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
142457143405
){
142458
- iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
142459
- sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
143406
+ iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse);
143407
+ sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
142460143408
}
142461143409
sqlite3ExprDelete(db, pWhen);
142462143410
}
142463143411
142464143412
/* Code the trigger program into the sub-vdbe. */
142465
- codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
143413
+ codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf);
142466143414
142467143415
/* Insert an OP_Halt at the end of the sub-program. */
142468143416
if( iEndTrigger ){
142469143417
sqlite3VdbeResolveLabel(v, iEndTrigger);
142470143418
}
142471143419
sqlite3VdbeAddOp0(v, OP_Halt);
142472143420
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
143421
+ transferParseError(pParse, &sSubParse);
142473143422
142474
- transferParseError(pParse, pSubParse);
142475
- if( db->mallocFailed==0 && pParse->nErr==0 ){
143423
+ if( pParse->nErr==0 ){
143424
+ assert( db->mallocFailed==0 );
142476143425
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
142477143426
}
142478
- pProgram->nMem = pSubParse->nMem;
142479
- pProgram->nCsr = pSubParse->nTab;
143427
+ pProgram->nMem = sSubParse.nMem;
143428
+ pProgram->nCsr = sSubParse.nTab;
142480143429
pProgram->token = (void *)pTrigger;
142481
- pPrg->aColmask[0] = pSubParse->oldmask;
142482
- pPrg->aColmask[1] = pSubParse->newmask;
143430
+ pPrg->aColmask[0] = sSubParse.oldmask;
143431
+ pPrg->aColmask[1] = sSubParse.newmask;
142483143432
sqlite3VdbeDelete(v);
143433
+ }else{
143434
+ transferParseError(pParse, &sSubParse);
142484143435
}
142485143436
142486
- assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
142487
- sqlite3ParserReset(pSubParse);
142488
- sqlite3StackFree(db, pSubParse);
142489
-
143437
+ assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg );
143438
+ sqlite3ParseObjectReset(&sSubParse);
142490143439
return pPrg;
142491143440
}
142492143441
142493143442
/*
142494143443
** Return a pointer to a TriggerPrg object containing the sub-program for
@@ -142517,10 +143466,11 @@
142517143466
);
142518143467
142519143468
/* If an existing TriggerPrg could not be located, create a new one. */
142520143469
if( !pPrg ){
142521143470
pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
143471
+ pParse->db->errByteOffset = -1;
142522143472
}
142523143473
142524143474
return pPrg;
142525143475
}
142526143476
@@ -142539,11 +143489,11 @@
142539143489
int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
142540143490
){
142541143491
Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
142542143492
TriggerPrg *pPrg;
142543143493
pPrg = getRowTrigger(pParse, p, pTab, orconf);
142544
- assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
143494
+ assert( pPrg || pParse->nErr );
142545143495
142546143496
/* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
142547143497
** is a pointer to the sub-vdbe containing the trigger program. */
142548143498
if( pPrg ){
142549143499
int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
@@ -143057,13 +144007,15 @@
143057144007
int regRowSet = 0; /* Rowset of rows to be updated */
143058144008
int regKey = 0; /* composite PRIMARY KEY value */
143059144009
143060144010
memset(&sContext, 0, sizeof(sContext));
143061144011
db = pParse->db;
143062
- if( pParse->nErr || db->mallocFailed ){
144012
+ assert( db->pParse==pParse );
144013
+ if( pParse->nErr ){
143063144014
goto update_cleanup;
143064144015
}
144016
+ assert( db->mallocFailed==0 );
143065144017
143066144018
/* Locate the table which we want to update.
143067144019
*/
143068144020
pTab = sqlite3SrcListLookup(pParse, pTabList);
143069144021
if( pTab==0 ) goto update_cleanup;
@@ -143431,11 +144383,11 @@
143431144383
** or index, causing a single-pass approach to malfunction. */
143432144384
flags = WHERE_ONEPASS_DESIRED;
143433144385
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
143434144386
flags |= WHERE_ONEPASS_MULTIROW;
143435144387
}
143436
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
144388
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
143437144389
if( pWInfo==0 ) goto update_cleanup;
143438144390
143439144391
/* A one-pass strategy that might update more than one row may not
143440144392
** be used if any column of the index used for the scan is being
143441144393
** updated. Otherwise, if there is an index on "b", statements like
@@ -143953,11 +144905,13 @@
143953144905
}else{
143954144906
regRec = ++pParse->nMem;
143955144907
regRowid = ++pParse->nMem;
143956144908
143957144909
/* Start scanning the virtual table */
143958
- pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
144910
+ pWInfo = sqlite3WhereBegin(
144911
+ pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0
144912
+ );
143959144913
if( pWInfo==0 ) return;
143960144914
143961144915
/* Populate the argument registers. */
143962144916
for(i=0; i<pTab->nCol; i++){
143963144917
assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145598,13 +146552,13 @@
145598146552
return SQLITE_MISUSE_BKPT;
145599146553
}
145600146554
pTab = pCtx->pTab;
145601146555
assert( IsVirtual(pTab) );
145602146556
145603
- memset(&sParse, 0, sizeof(sParse));
146557
+ sqlite3ParseObjectInit(&sParse, db);
145604146558
sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
145605
- sParse.db = db;
146559
+ sParse.disableTriggers = 1;
145606146560
/* We should never be able to reach this point while loading the
145607146561
** schema. Nevertheless, defend against that (turn off db->init.busy)
145608146562
** in case a bug arises. */
145609146563
assert( db->init.busy==0 );
145610146564
initBusy = db->init.busy;
@@ -145654,11 +146608,11 @@
145654146608
145655146609
if( sParse.pVdbe ){
145656146610
sqlite3VdbeFinalize(sParse.pVdbe);
145657146611
}
145658146612
sqlite3DeleteTable(db, sParse.pNewTable);
145659
- sqlite3ParserReset(&sParse);
146613
+ sqlite3ParseObjectReset(&sParse);
145660146614
db->init.busy = initBusy;
145661146615
145662146616
assert( (rc&0xff)==rc );
145663146617
rc = sqlite3ApiExit(db, rc);
145664146618
sqlite3_mutex_leave(db->mutex);
@@ -146265,14 +147219,16 @@
146265147219
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
146266147220
Index *pIndex; /* Index used, or NULL */
146267147221
} btree;
146268147222
struct { /* Information for virtual tables */
146269147223
int idxNum; /* Index number */
146270
- u8 needFree; /* True if sqlite3_free(idxStr) is needed */
147224
+ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
147225
+ u32 bOmitOffset : 1; /* True to let virtual table handle offset */
146271147226
i8 isOrdered; /* True if satisfies ORDER BY */
146272147227
u16 omitMask; /* Terms that may be omitted */
146273147228
char *idxStr; /* Index identifier string */
147229
+ u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
146274147230
} vtab;
146275147231
} u;
146276147232
u32 wsFlags; /* WHERE_* flags describing the plan */
146277147233
u16 nLTerm; /* Number of entries in aLTerm[] */
146278147234
u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146425,10 +147381,11 @@
146425147381
#ifdef SQLITE_ENABLE_STAT4
146426147382
# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
146427147383
#else
146428147384
# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
146429147385
#endif
147386
+#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
146430147387
146431147388
/*
146432147389
** An instance of the WhereScan object is used as an iterator for locating
146433147390
** terms in the WHERE clause that are useful to the query planner.
146434147391
*/
@@ -146528,11 +147485,10 @@
146528147485
** to construct WhereLoop objects for a particular query.
146529147486
*/
146530147487
struct WhereLoopBuilder {
146531147488
WhereInfo *pWInfo; /* Information about this WHERE */
146532147489
WhereClause *pWC; /* WHERE clause terms */
146533
- ExprList *pOrderBy; /* ORDER BY clause */
146534147490
WhereLoop *pNew; /* Template WhereLoop */
146535147491
WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
146536147492
#ifdef SQLITE_ENABLE_STAT4
146537147493
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
146538147494
int nRecValid; /* Number of valid fields currently in pRec */
@@ -146596,10 +147552,13 @@
146596147552
Parse *pParse; /* Parsing and code generating context */
146597147553
SrcList *pTabList; /* List of tables in the join */
146598147554
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
146599147555
ExprList *pResultSet; /* Result set of the query */
146600147556
Expr *pWhere; /* The complete WHERE clause */
147557
+#ifndef SQLITE_OMIT_VIRTUALTABLE
147558
+ Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */
147559
+#endif
146601147560
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
146602147561
int iContinue; /* Jump here to continue with next record */
146603147562
int iBreak; /* Jump here to break out of the loop */
146604147563
int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
146605147564
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146681,10 +147640,11 @@
146681147640
146682147641
/* whereexpr.c: */
146683147642
SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
146684147643
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
146685147644
SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
147645
+SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*);
146686147646
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
146687147647
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
146688147648
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
146689147649
SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
146690147650
SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146751,10 +147711,11 @@
146751147711
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
146752147712
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
146753147713
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146754147714
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146755147715
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
147716
+#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
146756147717
146757147718
#endif /* !defined(SQLITE_WHEREINT_H) */
146758147719
146759147720
/************** End of whereInt.h ********************************************/
146760147721
/************** Continuing where we left off in wherecode.c ******************/
@@ -147529,10 +148490,11 @@
147529148490
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
147530148491
VdbeCoverageIf(v, bRev==0);
147531148492
VdbeCoverageIf(v, bRev!=0);
147532148493
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
147533148494
j = sqlite3VdbeAddOp0(v, OP_Goto);
148495
+ assert( pLevel->addrSkip==0 );
147534148496
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
147535148497
iIdxCur, 0, regBase, nSkip);
147536148498
VdbeCoverageIf(v, bRev==0);
147537148499
VdbeCoverageIf(v, bRev!=0);
147538148500
sqlite3VdbeJumpHere(v, j);
@@ -147561,10 +148523,13 @@
147561148523
regBase = r1;
147562148524
}else{
147563148525
sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
147564148526
}
147565148527
}
148528
+ }
148529
+ for(j=nSkip; j<nEq; j++){
148530
+ pTerm = pLoop->aLTerm[j];
147566148531
if( pTerm->eOperator & WO_IN ){
147567148532
if( pTerm->pExpr->flags & EP_xIsSelect ){
147568148533
/* No affinity ever needs to be (or should be) applied to a value
147569148534
** from the RHS of an "? IN (SELECT ...)" expression. The
147570148535
** sqlite3FindInIndex() routine has already ensured that the
@@ -147575,11 +148540,12 @@
147575148540
Expr *pRight = pTerm->pExpr->pRight;
147576148541
if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
147577148542
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
147578148543
VdbeCoverage(v);
147579148544
}
147580
- if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){
148545
+ if( pParse->nErr==0 ){
148546
+ assert( pParse->db->mallocFailed==0 );
147581148547
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
147582148548
zAff[j] = SQLITE_AFF_BLOB;
147583148549
}
147584148550
if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
147585148551
zAff[j] = SQLITE_AFF_BLOB;
@@ -147795,11 +148761,11 @@
147795148761
** are also excluded. See codeCursorHintIsOrFunction() for details.
147796148762
*/
147797148763
if( pTabItem->fg.jointype & JT_LEFT ){
147798148764
Expr *pExpr = pTerm->pExpr;
147799148765
if( !ExprHasProperty(pExpr, EP_FromJoin)
147800
- || pExpr->iRightJoinTable!=pTabItem->iCursor
148766
+ || pExpr->w.iRightJoinTable!=pTabItem->iCursor
147801148767
){
147802148768
sWalker.eCode = 0;
147803148769
sWalker.xExprCallback = codeCursorHintIsOrFunction;
147804148770
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
147805148771
if( sWalker.eCode ) continue;
@@ -147850,18 +148816,26 @@
147850148816
** rowid stored in register iRowid.
147851148817
**
147852148818
** Normally, this is just:
147853148819
**
147854148820
** OP_DeferredSeek $iCur $iRowid
148821
+**
148822
+** Which causes a seek on $iCur to the row with rowid $iRowid.
147855148823
**
147856148824
** However, if the scan currently being coded is a branch of an OR-loop and
147857
-** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
147858
-** is set to iIdxCur and P4 is set to point to an array of integers
147859
-** containing one entry for each column of the table cursor iCur is open
147860
-** on. For each table column, if the column is the i'th column of the
147861
-** index, then the corresponding array entry is set to (i+1). If the column
147862
-** does not appear in the index at all, the array entry is set to 0.
148825
+** the statement currently being coded is a SELECT, then additional information
148826
+** is added that might allow OP_Column to omit the seek and instead do its
148827
+** lookup on the index, thus avoiding an expensive seek operation. To
148828
+** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur
148829
+** and P4 is set to an array of integers containing one entry for each column
148830
+** in the table. For each table column, if the column is the i'th
148831
+** column of the index, then the corresponding array entry is set to (i+1).
148832
+** If the column does not appear in the index at all, the array entry is set
148833
+** to 0. The OP_Column opcode can check this array to see if the column it
148834
+** wants is in the index and if it is, it will substitute the index cursor
148835
+** and column number and continue with those new values, rather than seeking
148836
+** the table cursor.
147863148837
*/
147864148838
static void codeDeferredSeek(
147865148839
WhereInfo *pWInfo, /* Where clause context */
147866148840
Index *pIdx, /* Index scan is using */
147867148841
int iCur, /* Cursor for IPK b-tree */
@@ -148122,10 +149096,11 @@
148122149096
){
148123149097
while( ++iLevel < pWInfo->nLevel ){
148124149098
WhereLevel *pLevel = &pWInfo->a[iLevel];
148125149099
WhereLoop *pLoop = pLevel->pWLoop;
148126149100
if( pLevel->regFilter==0 ) continue;
149101
+ if( pLevel->pWLoop->nSkip ) continue;
148127149102
/* ,--- Because sqlite3ConstructBloomFilter() has will not have set
148128149103
** vvvvv--' pLevel->regFilter if this were true. */
148129149104
if( NEVER(pLoop->prereq & notReady) ) continue;
148130149105
if( pLoop->wsFlags & WHERE_IPK ){
148131149106
WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148256,24 +149231,39 @@
148256149231
** to access the data.
148257149232
*/
148258149233
int iReg; /* P3 Value for OP_VFilter */
148259149234
int addrNotFound;
148260149235
int nConstraint = pLoop->nLTerm;
148261
- int iIn; /* Counter for IN constraints */
148262149236
148263149237
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
148264149238
addrNotFound = pLevel->addrBrk;
148265149239
for(j=0; j<nConstraint; j++){
148266149240
int iTarget = iReg+j+2;
148267149241
pTerm = pLoop->aLTerm[j];
148268149242
if( NEVER(pTerm==0) ) continue;
148269149243
if( pTerm->eOperator & WO_IN ){
148270
- codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
148271
- addrNotFound = pLevel->addrNxt;
149244
+ if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){
149245
+ int iTab = pParse->nTab++;
149246
+ int iCache = ++pParse->nMem;
149247
+ sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab);
149248
+ sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache);
149249
+ }else{
149250
+ codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
149251
+ addrNotFound = pLevel->addrNxt;
149252
+ }
148272149253
}else{
148273149254
Expr *pRight = pTerm->pExpr->pRight;
148274149255
codeExprOrVector(pParse, pRight, iTarget, 1);
149256
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
149257
+ && pLoop->u.vtab.bOmitOffset
149258
+ ){
149259
+ assert( pTerm->eOperator==WO_AUX );
149260
+ assert( pWInfo->pLimit!=0 );
149261
+ assert( pWInfo->pLimit->iOffset>0 );
149262
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
149263
+ VdbeComment((v,"Zero OFFSET counter"));
149264
+ }
148275149265
}
148276149266
}
148277149267
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
148278149268
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
148279149269
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148286,61 +149276,71 @@
148286149276
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
148287149277
pLevel->p1 = iCur;
148288149278
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
148289149279
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148290149280
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148291
- if( pLoop->wsFlags & WHERE_IN_ABLE ){
148292
- iIn = pLevel->u.in.nIn;
148293
- }else{
148294
- iIn = 0;
148295
- }
148296
- for(j=nConstraint-1; j>=0; j--){
149281
+
149282
+ for(j=0; j<nConstraint; j++){
148297149283
pTerm = pLoop->aLTerm[j];
148298
- if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
148299149284
if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
148300149285
disableTerm(pLevel, pTerm);
148301
- }else if( (pTerm->eOperator & WO_IN)!=0
148302
- && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
149286
+ continue;
149287
+ }
149288
+ if( (pTerm->eOperator & WO_IN)!=0
149289
+ && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0
149290
+ && !db->mallocFailed
148303149291
){
148304149292
Expr *pCompare; /* The comparison operator */
148305149293
Expr *pRight; /* RHS of the comparison */
148306149294
VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
149295
+ int iIn; /* IN loop corresponding to the j-th constraint */
148307149296
148308149297
/* Reload the constraint value into reg[iReg+j+2]. The same value
148309149298
** was loaded into the same register prior to the OP_VFilter, but
148310149299
** the xFilter implementation might have changed the datatype or
148311
- ** encoding of the value in the register, so it *must* be reloaded. */
148312
- assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
148313
- if( !db->mallocFailed ){
148314
- assert( iIn>=0 && iIn<pLevel->u.in.nIn );
149300
+ ** encoding of the value in the register, so it *must* be reloaded.
149301
+ */
149302
+ for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){
148315149303
pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
148316
- assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
148317
- assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
148318
- assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
148319
- testcase( pOp->opcode==OP_Rowid );
148320
- sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149304
+ if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2)
149305
+ || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2)
149306
+ ){
149307
+ testcase( pOp->opcode==OP_Rowid );
149308
+ sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149309
+ break;
149310
+ }
148321149311
}
148322149312
148323149313
/* Generate code that will continue to the next row if
148324
- ** the IN constraint is not satisfied */
149314
+ ** the IN constraint is not satisfied
149315
+ */
148325149316
pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
148326
- assert( pCompare!=0 || db->mallocFailed );
148327
- if( pCompare ){
148328
- pCompare->pLeft = pTerm->pExpr->pLeft;
149317
+ if( !db->mallocFailed ){
149318
+ int iFld = pTerm->u.x.iField;
149319
+ Expr *pLeft = pTerm->pExpr->pLeft;
149320
+ assert( pLeft!=0 );
149321
+ if( iFld>0 ){
149322
+ assert( pLeft->op==TK_VECTOR );
149323
+ assert( ExprUseXList(pLeft) );
149324
+ assert( iFld<=pLeft->x.pList->nExpr );
149325
+ pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr;
149326
+ }else{
149327
+ pCompare->pLeft = pLeft;
149328
+ }
148329149329
pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
148330149330
if( pRight ){
148331149331
pRight->iTable = iReg+j+2;
148332149332
sqlite3ExprIfFalse(
148333149333
pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
148334149334
);
148335149335
}
148336149336
pCompare->pLeft = 0;
148337
- sqlite3ExprDelete(db, pCompare);
148338149337
}
149338
+ sqlite3ExprDelete(db, pCompare);
148339149339
}
148340149340
}
148341
- assert( iIn==0 || db->mallocFailed );
149341
+
148342149342
/* These registers need to be preserved in case there is an IN operator
148343149343
** loop. So we could deallocate the registers here (and potentially
148344149344
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
148345149345
** simpler and safer to simply not reuse the registers.
148346149346
**
@@ -149028,11 +150028,11 @@
149028150028
regRowid = ++pParse->nMem;
149029150029
}
149030150030
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
149031150031
149032150032
/* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
149033
- ** Then for every term xN, evaluate as the subexpression: xN AND z
150033
+ ** Then for every term xN, evaluate as the subexpression: xN AND y
149034150034
** That way, terms in y that are factored into the disjunction will
149035150035
** be picked up by the recursive calls to sqlite3WhereBegin() below.
149036150036
**
149037150037
** Actually, each subexpression is converted to "xN AND w" where w is
149038150038
** the "interesting" terms of z - terms that did not originate in the
@@ -149040,21 +150040,38 @@
149040150040
** indices.
149041150041
**
149042150042
** This optimization also only applies if the (x1 OR x2 OR ...) term
149043150043
** is not contained in the ON clause of a LEFT JOIN.
149044150044
** See ticket http://www.sqlite.org/src/info/f2369304e4
150045
+ **
150046
+ ** 2022-02-04: Do not push down slices of a row-value comparison.
150047
+ ** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
150048
+ ** the initialization of the right-hand operand of the vector comparison
150049
+ ** might not occur, or might occur only in an OR branch that is not
150050
+ ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
150051
+ **
150052
+ ** 2022-03-03: Do not push down expressions that involve subqueries.
150053
+ ** The subquery might get coded as a subroutine. Any table-references
150054
+ ** in the subquery might be resolved to index-references for the index on
150055
+ ** the OR branch in which the subroutine is coded. But if the subroutine
150056
+ ** is invoked from a different OR branch that uses a different index, such
150057
+ ** index-references will not work. tag-20220303a
150058
+ ** https://sqlite.org/forum/forumpost/36937b197273d403
149045150059
*/
149046150060
if( pWC->nTerm>1 ){
149047150061
int iTerm;
149048150062
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
149049150063
Expr *pExpr = pWC->a[iTerm].pExpr;
149050150064
if( &pWC->a[iTerm] == pTerm ) continue;
149051150065
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
149052150066
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
149053
- if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
150067
+ testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
150068
+ if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
150069
+ continue;
150070
+ }
149054150071
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
149055
- testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
150072
+ if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */
149056150073
pExpr = sqlite3ExprDup(db, pExpr, 0);
149057150074
pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
149058150075
}
149059150076
if( pAndExpr ){
149060150077
/* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149091,13 +150108,13 @@
149091150108
pOrExpr = pAndExpr;
149092150109
}
149093150110
/* Loop through table entries that match term pOrTerm. */
149094150111
ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
149095150112
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
149096
- pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
150113
+ pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
149097150114
WHERE_OR_SUBCLAUSE, iCovCur);
149098
- assert( pSubWInfo || pParse->nErr || db->mallocFailed );
150115
+ assert( pSubWInfo || pParse->nErr );
149099150116
if( pSubWInfo ){
149100150117
WhereLoop *pSubLoop;
149101150118
int addrExplain = sqlite3WhereExplainOneScan(
149102150119
pParse, pOrTab, &pSubWInfo->a[0], 0
149103150120
);
@@ -149831,11 +150848,11 @@
149831150848
void *pNotUsed;
149832150849
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
149833150850
assert( pVtab!=0 );
149834150851
assert( pVtab->pModule!=0 );
149835150852
assert( !ExprHasProperty(pExpr, EP_IntValue) );
149836
- pMod = (sqlite3_module *)pVtab->pModule;
150853
+ pMod = (sqlite3_module *)pVtab->pModule;
149837150854
if( pMod->xFindFunction!=0 ){
149838150855
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
149839150856
if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
149840150857
*peOp2 = i;
149841150858
*ppRight = pList->a[1].pExpr;
@@ -149875,11 +150892,11 @@
149875150892
** a join, then transfer the appropriate markings over to derived.
149876150893
*/
149877150894
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
149878150895
if( pDerived ){
149879150896
pDerived->flags |= pBase->flags & EP_FromJoin;
149880
- pDerived->iRightJoinTable = pBase->iRightJoinTable;
150897
+ pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
149881150898
}
149882150899
}
149883150900
149884150901
/*
149885150902
** Mark term iChild as being a child of term iParent
@@ -150520,11 +151537,11 @@
150520151537
abort();
150521151538
}
150522151539
#endif
150523151540
150524151541
if( ExprHasProperty(pExpr, EP_FromJoin) ){
150525
- Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
151542
+ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
150526151543
prereqAll |= x;
150527151544
extraRight = x-1; /* ON clause terms may not be used with an index
150528151545
** on left table of a LEFT JOIN. Ticket #3015 */
150529151546
if( (prereqAll>>1)>=x ){
150530151547
sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150788,11 +151805,14 @@
150788151805
** new terms for each component comparison - "a = ?" and "b = ?". The
150789151806
** new terms completely replace the original vector comparison, which is
150790151807
** no longer used.
150791151808
**
150792151809
** This is only required if at least one side of the comparison operation
150793
- ** is not a sub-select. */
151810
+ ** is not a sub-select.
151811
+ **
151812
+ ** tag-20220128a
151813
+ */
150794151814
if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
150795151815
&& (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
150796151816
&& sqlite3ExprVectorSize(pExpr->pRight)==nLeft
150797151817
&& ( (pExpr->pLeft->flags & EP_xIsSelect)==0
150798151818
|| (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150805,11 +151825,11 @@
150805151825
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
150806151826
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
150807151827
150808151828
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
150809151829
transferJoinMarkings(pNew, pExpr);
150810
- idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
151830
+ idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
150811151831
exprAnalyze(pSrc, pWC, idxNew);
150812151832
}
150813151833
pTerm = &pWC->a[idxTerm];
150814151834
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
150815151835
pTerm->eOperator = 0;
@@ -150835,11 +151855,11 @@
150835151855
&& pWC->op==TK_AND
150836151856
){
150837151857
int i;
150838151858
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
150839151859
int idxNew;
150840
- idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
151860
+ idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
150841151861
pWC->a[idxNew].u.x.iField = i+1;
150842151862
exprAnalyze(pSrc, pWC, idxNew);
150843151863
markTermAsChild(pWC, idxNew, idxTerm);
150844151864
}
150845151865
}
@@ -150868,11 +151888,11 @@
150868151888
Expr *pNewExpr;
150869151889
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
150870151890
0, sqlite3ExprDup(db, pRight, 0));
150871151891
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
150872151892
ExprSetProperty(pNewExpr, EP_FromJoin);
150873
- pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
151893
+ pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
150874151894
}
150875151895
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
150876151896
testcase( idxNew==0 );
150877151897
pNewTerm = &pWC->a[idxNew];
150878151898
pNewTerm->prereqRight = prereqExpr;
@@ -150930,10 +151950,117 @@
150930151950
}else{
150931151951
sqlite3WhereSplit(pWC, pE2->pLeft, op);
150932151952
sqlite3WhereSplit(pWC, pE2->pRight, op);
150933151953
}
150934151954
}
151955
+
151956
+/*
151957
+** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or
151958
+** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the
151959
+** where-clause passed as the first argument. The value for the term
151960
+** is found in register iReg.
151961
+**
151962
+** In the common case where the value is a simple integer
151963
+** (example: "LIMIT 5 OFFSET 10") then the expression codes as a
151964
+** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value().
151965
+** If not, then it codes as a TK_REGISTER expression.
151966
+*/
151967
+static void whereAddLimitExpr(
151968
+ WhereClause *pWC, /* Add the constraint to this WHERE clause */
151969
+ int iReg, /* Register that will hold value of the limit/offset */
151970
+ Expr *pExpr, /* Expression that defines the limit/offset */
151971
+ int iCsr, /* Cursor to which the constraint applies */
151972
+ int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */
151973
+){
151974
+ Parse *pParse = pWC->pWInfo->pParse;
151975
+ sqlite3 *db = pParse->db;
151976
+ Expr *pNew;
151977
+ int iVal = 0;
151978
+
151979
+ if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
151980
+ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
151981
+ if( pVal==0 ) return;
151982
+ ExprSetProperty(pVal, EP_IntValue);
151983
+ pVal->u.iValue = iVal;
151984
+ pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
151985
+ }else{
151986
+ Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
151987
+ if( pVal==0 ) return;
151988
+ pVal->iTable = iReg;
151989
+ pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
151990
+ }
151991
+ if( pNew ){
151992
+ WhereTerm *pTerm;
151993
+ int idx;
151994
+ idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL);
151995
+ pTerm = &pWC->a[idx];
151996
+ pTerm->leftCursor = iCsr;
151997
+ pTerm->eOperator = WO_AUX;
151998
+ pTerm->eMatchOp = eMatchOp;
151999
+ }
152000
+}
152001
+
152002
+/*
152003
+** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the
152004
+** SELECT statement passed as the second argument. These terms are only
152005
+** added if:
152006
+**
152007
+** 1. The SELECT statement has a LIMIT clause, and
152008
+** 2. The SELECT statement is not an aggregate or DISTINCT query, and
152009
+** 3. The SELECT statement has exactly one object in its from clause, and
152010
+** that object is a virtual table, and
152011
+** 4. There are no terms in the WHERE clause that will not be passed
152012
+** to the virtual table xBestIndex method.
152013
+** 5. The ORDER BY clause, if any, will be made available to the xBestIndex
152014
+** method.
152015
+**
152016
+** LIMIT and OFFSET terms are ignored by most of the planner code. They
152017
+** exist only so that they may be passed to the xBestIndex method of the
152018
+** single virtual table in the FROM clause of the SELECT.
152019
+*/
152020
+SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
152021
+ assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) );
152022
+ if( (p && p->pLimit) /* 1 */
152023
+ && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
152024
+ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
152025
+ ){
152026
+ ExprList *pOrderBy = p->pOrderBy;
152027
+ int iCsr = p->pSrc->a[0].iCursor;
152028
+ int ii;
152029
+
152030
+ /* Check condition (4). Return early if it is not met. */
152031
+ for(ii=0; ii<pWC->nTerm; ii++){
152032
+ if( pWC->a[ii].wtFlags & TERM_CODED ){
152033
+ /* This term is a vector operation that has been decomposed into
152034
+ ** other, subsequent terms. It can be ignored. See tag-20220128a */
152035
+ assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
152036
+ assert( pWC->a[ii].eOperator==0 );
152037
+ continue;
152038
+ }
152039
+ if( pWC->a[ii].leftCursor!=iCsr ) return;
152040
+ }
152041
+
152042
+ /* Check condition (5). Return early if it is not met. */
152043
+ if( pOrderBy ){
152044
+ for(ii=0; ii<pOrderBy->nExpr; ii++){
152045
+ Expr *pExpr = pOrderBy->a[ii].pExpr;
152046
+ if( pExpr->op!=TK_COLUMN ) return;
152047
+ if( pExpr->iTable!=iCsr ) return;
152048
+ if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
152049
+ }
152050
+ }
152051
+
152052
+ /* All conditions are met. Add the terms to the where-clause object. */
152053
+ assert( p->pLimit->op==TK_LIMIT );
152054
+ whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
152055
+ iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
152056
+ if( p->iOffset>0 ){
152057
+ whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
152058
+ iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
152059
+ }
152060
+ }
152061
+}
150935152062
150936152063
/*
150937152064
** Initialize a preallocated WhereClause structure.
150938152065
*/
150939152066
SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -150966,10 +152093,11 @@
150966152093
for(i=pWC->nBase; i<pWC->nTerm; i++){
150967152094
assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
150968152095
}
150969152096
#endif
150970152097
while(1){
152098
+ assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
150971152099
if( a->wtFlags & TERM_DYNAMIC ){
150972152100
sqlite3ExprDelete(db, a->pExpr);
150973152101
}
150974152102
if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
150975152103
if( a->wtFlags & TERM_ORINFO ){
@@ -151123,10 +152251,11 @@
151123152251
if( pColRef==0 ) return;
151124152252
pColRef->iTable = pItem->iCursor;
151125152253
pColRef->iColumn = k++;
151126152254
assert( ExprUseYTab(pColRef) );
151127152255
pColRef->y.pTab = pTab;
152256
+ pItem->colUsed |= sqlite3ExprColUsed(pColRef);
151128152257
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
151129152258
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
151130152259
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
151131152260
if( pItem->fg.jointype & JT_LEFT ){
151132152261
sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151167,12 +152296,18 @@
151167152296
** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
151168152297
** agree on the structure, all will be well.
151169152298
*/
151170152299
typedef struct HiddenIndexInfo HiddenIndexInfo;
151171152300
struct HiddenIndexInfo {
151172
- WhereClause *pWC; /* The Where clause being analyzed */
151173
- Parse *pParse; /* The parsing context */
152301
+ WhereClause *pWC; /* The Where clause being analyzed */
152302
+ Parse *pParse; /* The parsing context */
152303
+ int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
152304
+ u32 mIn; /* Mask of terms that are <col> IN (...) */
152305
+ u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */
152306
+ sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
152307
+ ** because extra space is allocated to hold up
152308
+ ** to nTerm such values */
151174152309
};
151175152310
151176152311
/* Forward declaration of methods */
151177152312
static int whereLoopResize(sqlite3*, WhereLoop*, int);
151178152313
@@ -152209,11 +153344,14 @@
152209153344
VdbeCoverage(v);
152210153345
sqlite3VdbeJumpHere(v, addrTop);
152211153346
pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152212153347
if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152213153348
while( ++iLevel < pWInfo->nLevel ){
153349
+ const SrcItem *pTabItem;
152214153350
pLevel = &pWInfo->a[iLevel];
153351
+ pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153352
+ if( pTabItem->fg.jointype & JT_LEFT ) continue;
152215153353
pLoop = pLevel->pWLoop;
152216153354
if( NEVER(pLoop==0) ) continue;
152217153355
if( pLoop->prereq & notReady ) continue;
152218153356
if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
152219153357
==WHERE_BLOOMFILTER
@@ -152232,31 +153370,33 @@
152232153370
152233153371
#ifndef SQLITE_OMIT_VIRTUALTABLE
152234153372
/*
152235153373
** Allocate and populate an sqlite3_index_info structure. It is the
152236153374
** responsibility of the caller to eventually release the structure
152237
-** by passing the pointer returned by this function to sqlite3_free().
153375
+** by passing the pointer returned by this function to freeIndexInfo().
152238153376
*/
152239153377
static sqlite3_index_info *allocateIndexInfo(
152240
- Parse *pParse, /* The parsing context */
153378
+ WhereInfo *pWInfo, /* The WHERE clause */
152241153379
WhereClause *pWC, /* The WHERE clause being analyzed */
152242153380
Bitmask mUnusable, /* Ignore terms with these prereqs */
152243153381
SrcItem *pSrc, /* The FROM clause term that is the vtab */
152244
- ExprList *pOrderBy, /* The ORDER BY clause */
152245153382
u16 *pmNoOmit /* Mask of terms not to omit */
152246153383
){
152247153384
int i, j;
152248153385
int nTerm;
153386
+ Parse *pParse = pWInfo->pParse;
152249153387
struct sqlite3_index_constraint *pIdxCons;
152250153388
struct sqlite3_index_orderby *pIdxOrderBy;
152251153389
struct sqlite3_index_constraint_usage *pUsage;
152252153390
struct HiddenIndexInfo *pHidden;
152253153391
WhereTerm *pTerm;
152254153392
int nOrderBy;
152255153393
sqlite3_index_info *pIdxInfo;
152256153394
u16 mNoOmit = 0;
152257153395
const Table *pTab;
153396
+ int eDistinct = 0;
153397
+ ExprList *pOrderBy = pWInfo->pOrderBy;
152258153398
152259153399
assert( pSrc!=0 );
152260153400
pTab = pSrc->pTab;
152261153401
assert( pTab!=0 );
152262153402
assert( IsVirtual(pTab) );
@@ -152274,10 +153414,11 @@
152274153414
testcase( pTerm->eOperator & WO_ISNULL );
152275153415
testcase( pTerm->eOperator & WO_IS );
152276153416
testcase( pTerm->eOperator & WO_ALL );
152277153417
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
152278153418
if( pTerm->wtFlags & TERM_VNULL ) continue;
153419
+
152279153420
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152280153421
assert( pTerm->u.x.leftColumn>=XN_ROWID );
152281153422
assert( pTerm->u.x.leftColumn<pTab->nCol );
152282153423
152283153424
/* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152335,40 +153476,53 @@
152335153476
}
152336153477
152337153478
/* No matches cause a break out of the loop */
152338153479
break;
152339153480
}
152340
- if( i==n){
153481
+ if( i==n ){
152341153482
nOrderBy = n;
153483
+ if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
153484
+ eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
153485
+ }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
153486
+ eDistinct = 1;
153487
+ }
152342153488
}
152343153489
}
152344153490
152345153491
/* Allocate the sqlite3_index_info structure
152346153492
*/
152347153493
pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
152348153494
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
152349
- + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
153495
+ + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden)
153496
+ + sizeof(sqlite3_value*)*nTerm );
152350153497
if( pIdxInfo==0 ){
152351153498
sqlite3ErrorMsg(pParse, "out of memory");
152352153499
return 0;
152353153500
}
152354153501
pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
152355
- pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
153502
+ pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm];
152356153503
pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
152357153504
pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
152358153505
pIdxInfo->aConstraint = pIdxCons;
152359153506
pIdxInfo->aOrderBy = pIdxOrderBy;
152360153507
pIdxInfo->aConstraintUsage = pUsage;
152361153508
pHidden->pWC = pWC;
152362153509
pHidden->pParse = pParse;
153510
+ pHidden->eDistinct = eDistinct;
153511
+ pHidden->mIn = 0;
152363153512
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
152364153513
u16 op;
152365153514
if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
152366153515
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
152367153516
pIdxCons[j].iTermOffset = i;
152368153517
op = pTerm->eOperator & WO_ALL;
152369
- if( op==WO_IN ) op = WO_EQ;
153518
+ if( op==WO_IN ){
153519
+ if( (pTerm->wtFlags & TERM_SLICE)==0 ){
153520
+ pHidden->mIn |= SMASKBIT32(j);
153521
+ }
153522
+ op = WO_EQ;
153523
+ }
152370153524
if( op==WO_AUX ){
152371153525
pIdxCons[j].op = pTerm->eMatchOp;
152372153526
}else if( op & (WO_ISNULL|WO_IS) ){
152373153527
if( op==WO_ISNULL ){
152374153528
pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152414,10 +153568,28 @@
152414153568
pIdxInfo->nOrderBy = j;
152415153569
152416153570
*pmNoOmit = mNoOmit;
152417153571
return pIdxInfo;
152418153572
}
153573
+
153574
+/*
153575
+** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
153576
+** and possibly modified by xBestIndex methods.
153577
+*/
153578
+static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
153579
+ HiddenIndexInfo *pHidden;
153580
+ int i;
153581
+ assert( pIdxInfo!=0 );
153582
+ pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
153583
+ assert( pHidden->pParse!=0 );
153584
+ assert( pHidden->pParse->db==db );
153585
+ for(i=0; i<pIdxInfo->nConstraint; i++){
153586
+ sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */
153587
+ pHidden->aRhs[i] = 0;
153588
+ }
153589
+ sqlite3DbFree(db, pIdxInfo);
153590
+}
152419153591
152420153592
/*
152421153593
** The table object reference passed as the second argument to this function
152422153594
** must represent a virtual table. This function invokes the xBestIndex()
152423153595
** method of the virtual table with the sqlite3_index_info object that
@@ -152436,11 +153608,13 @@
152436153608
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
152437153609
sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
152438153610
int rc;
152439153611
152440153612
whereTraceIndexInfoInputs(p);
153613
+ pParse->db->nSchemaLock++;
152441153614
rc = pVtab->pModule->xBestIndex(pVtab, p);
153615
+ pParse->db->nSchemaLock--;
152442153616
whereTraceIndexInfoOutputs(p);
152443153617
152444153618
if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
152445153619
if( rc==SQLITE_NOMEM ){
152446153620
sqlite3OomFault(pParse->db);
@@ -154265,11 +155439,11 @@
154265155439
}
154266155440
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
154267155441
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
154268155442
Expr *pExpr;
154269155443
pExpr = pTerm->pExpr;
154270
- if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
155444
+ if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
154271155445
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
154272155446
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
154273155447
&& (pTerm->wtFlags & TERM_VNULL)==0
154274155448
){
154275155449
return 1;
@@ -154566,10 +155740,19 @@
154566155740
}
154567155741
return rc;
154568155742
}
154569155743
154570155744
#ifndef SQLITE_OMIT_VIRTUALTABLE
155745
+
155746
+/*
155747
+** Return true if pTerm is a virtual table LIMIT or OFFSET term.
155748
+*/
155749
+static int isLimitTerm(WhereTerm *pTerm){
155750
+ assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
155751
+ return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
155752
+ && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
155753
+}
154571155754
154572155755
/*
154573155756
** Argument pIdxInfo is already populated with all constraints that may
154574155757
** be used by the virtual table identified by pBuilder->pNew->iTab. This
154575155758
** function marks a subset of those constraints usable, invokes the
@@ -154594,13 +155777,15 @@
154594155777
Bitmask mPrereq, /* Mask of tables that must be used. */
154595155778
Bitmask mUsable, /* Mask of usable tables */
154596155779
u16 mExclude, /* Exclude terms using these operators */
154597155780
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
154598155781
u16 mNoOmit, /* Do not omit these constraints */
154599
- int *pbIn /* OUT: True if plan uses an IN(...) op */
155782
+ int *pbIn, /* OUT: True if plan uses an IN(...) op */
155783
+ int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */
154600155784
){
154601155785
WhereClause *pWC = pBuilder->pWC;
155786
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
154602155787
struct sqlite3_index_constraint *pIdxCons;
154603155788
struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
154604155789
int i;
154605155790
int mxTerm;
154606155791
int rc = SQLITE_OK;
@@ -154619,10 +155804,11 @@
154619155804
for(i=0; i<nConstraint; i++, pIdxCons++){
154620155805
WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
154621155806
pIdxCons->usable = 0;
154622155807
if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
154623155808
&& (pTerm->eOperator & mExclude)==0
155809
+ && (pbRetryLimit || !isLimitTerm(pTerm))
154624155810
){
154625155811
pIdxCons->usable = 1;
154626155812
}
154627155813
}
154628155814
@@ -154634,10 +155820,11 @@
154634155820
pIdxInfo->orderByConsumed = 0;
154635155821
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
154636155822
pIdxInfo->estimatedRows = 25;
154637155823
pIdxInfo->idxFlags = 0;
154638155824
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
155825
+ pHidden->mHandleIn = 0;
154639155826
154640155827
/* Invoke the virtual table xBestIndex() method */
154641155828
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
154642155829
if( rc ){
154643155830
if( rc==SQLITE_CONSTRAINT ){
@@ -154651,12 +155838,12 @@
154651155838
return rc;
154652155839
}
154653155840
154654155841
mxTerm = -1;
154655155842
assert( pNew->nLSlot>=nConstraint );
154656
- for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
154657
- pNew->u.vtab.omitMask = 0;
155843
+ memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
155844
+ memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
154658155845
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
154659155846
for(i=0; i<nConstraint; i++, pIdxCons++){
154660155847
int iTerm;
154661155848
if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
154662155849
WhereTerm *pTerm;
@@ -154686,21 +155873,41 @@
154686155873
testcase( i!=iTerm );
154687155874
pNew->u.vtab.omitMask |= 1<<iTerm;
154688155875
}else{
154689155876
testcase( i!=iTerm );
154690155877
}
155878
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
155879
+ pNew->u.vtab.bOmitOffset = 1;
155880
+ }
154691155881
}
154692
- if( (pTerm->eOperator & WO_IN)!=0 ){
155882
+ if( SMASKBIT32(i) & pHidden->mHandleIn ){
155883
+ pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm);
155884
+ }else if( (pTerm->eOperator & WO_IN)!=0 ){
154693155885
/* A virtual table that is constrained by an IN clause may not
154694155886
** consume the ORDER BY clause because (1) the order of IN terms
154695155887
** is not necessarily related to the order of output terms and
154696155888
** (2) Multiple outputs from a single IN value will not merge
154697155889
** together. */
154698155890
pIdxInfo->orderByConsumed = 0;
154699155891
pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
154700155892
*pbIn = 1; assert( (mExclude & WO_IN)==0 );
154701155893
}
155894
+
155895
+ if( isLimitTerm(pTerm) && *pbIn ){
155896
+ /* If there is an IN(...) term handled as an == (separate call to
155897
+ ** xFilter for each value on the RHS of the IN) and a LIMIT or
155898
+ ** OFFSET term handled as well, the plan is unusable. Set output
155899
+ ** variable *pbRetryLimit to true to tell the caller to retry with
155900
+ ** LIMIT and OFFSET disabled. */
155901
+ if( pIdxInfo->needToFreeIdxStr ){
155902
+ sqlite3_free(pIdxInfo->idxStr);
155903
+ pIdxInfo->idxStr = 0;
155904
+ pIdxInfo->needToFreeIdxStr = 0;
155905
+ }
155906
+ *pbRetryLimit = 1;
155907
+ return SQLITE_OK;
155908
+ }
154702155909
}
154703155910
}
154704155911
154705155912
pNew->nLTerm = mxTerm+1;
154706155913
for(i=0; i<=mxTerm; i++){
@@ -154770,10 +155977,90 @@
154770155977
zRet = (pC ? pC->zName : sqlite3StrBINARY);
154771155978
}
154772155979
return zRet;
154773155980
}
154774155981
155982
+/*
155983
+** Return true if constraint iCons is really an IN(...) constraint, or
155984
+** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
155985
+** or clear (if bHandle==0) the flag to handle it using an iterator.
155986
+*/
155987
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){
155988
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155989
+ u32 m = SMASKBIT32(iCons);
155990
+ if( m & pHidden->mIn ){
155991
+ if( bHandle==0 ){
155992
+ pHidden->mHandleIn &= ~m;
155993
+ }else if( bHandle>0 ){
155994
+ pHidden->mHandleIn |= m;
155995
+ }
155996
+ return 1;
155997
+ }
155998
+ return 0;
155999
+}
156000
+
156001
+/*
156002
+** This interface is callable from within the xBestIndex callback only.
156003
+**
156004
+** If possible, set (*ppVal) to point to an object containing the value
156005
+** on the right-hand-side of constraint iCons.
156006
+*/
156007
+SQLITE_API int sqlite3_vtab_rhs_value(
156008
+ sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */
156009
+ int iCons, /* Constraint for which RHS is wanted */
156010
+ sqlite3_value **ppVal /* Write value extracted here */
156011
+){
156012
+ HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1];
156013
+ sqlite3_value *pVal = 0;
156014
+ int rc = SQLITE_OK;
156015
+ if( iCons<0 || iCons>=pIdxInfo->nConstraint ){
156016
+ rc = SQLITE_MISUSE; /* EV: R-30545-25046 */
156017
+ }else{
156018
+ if( pH->aRhs[iCons]==0 ){
156019
+ WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset];
156020
+ rc = sqlite3ValueFromExpr(
156021
+ pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db),
156022
+ SQLITE_AFF_BLOB, &pH->aRhs[iCons]
156023
+ );
156024
+ testcase( rc!=SQLITE_OK );
156025
+ }
156026
+ pVal = pH->aRhs[iCons];
156027
+ }
156028
+ *ppVal = pVal;
156029
+
156030
+ if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */
156031
+ rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */
156032
+ }
156033
+
156034
+ return rc;
156035
+}
156036
+
156037
+/*
156038
+** Return true if ORDER BY clause may be handled as DISTINCT.
156039
+*/
156040
+SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
156041
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156042
+ assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 );
156043
+ return pHidden->eDistinct;
156044
+}
156045
+
156046
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156047
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
156048
+/*
156049
+** Cause the prepared statement that is associated with a call to
156050
+** xBestIndex to open write transactions on all attached schemas.
156051
+** This is used by the (built-in) sqlite_dbpage virtual table.
156052
+*/
156053
+SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
156054
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156055
+ Parse *pParse = pHidden->pParse;
156056
+ int nDb = pParse->db->nDb;
156057
+ int i;
156058
+ for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
156059
+}
156060
+#endif
156061
+
154775156062
/*
154776156063
** Add all WhereLoop objects for a table of the join identified by
154777156064
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
154778156065
**
154779156066
** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
@@ -154811,35 +156098,43 @@
154811156098
int nConstraint; /* Number of constraints in p */
154812156099
int bIn; /* True if plan uses IN(...) operator */
154813156100
WhereLoop *pNew;
154814156101
Bitmask mBest; /* Tables used by best possible plan */
154815156102
u16 mNoOmit;
156103
+ int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */
154816156104
154817156105
assert( (mPrereq & mUnusable)==0 );
154818156106
pWInfo = pBuilder->pWInfo;
154819156107
pParse = pWInfo->pParse;
154820156108
pWC = pBuilder->pWC;
154821156109
pNew = pBuilder->pNew;
154822156110
pSrc = &pWInfo->pTabList->a[pNew->iTab];
154823156111
assert( IsVirtual(pSrc->pTab) );
154824
- p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
154825
- &mNoOmit);
156112
+ p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
154826156113
if( p==0 ) return SQLITE_NOMEM_BKPT;
154827156114
pNew->rSetup = 0;
154828156115
pNew->wsFlags = WHERE_VIRTUALTABLE;
154829156116
pNew->nLTerm = 0;
154830156117
pNew->u.vtab.needFree = 0;
154831156118
nConstraint = p->nConstraint;
154832156119
if( whereLoopResize(pParse->db, pNew, nConstraint) ){
154833
- sqlite3DbFree(pParse->db, p);
156120
+ freeIndexInfo(pParse->db, p);
154834156121
return SQLITE_NOMEM_BKPT;
154835156122
}
154836156123
154837156124
/* First call xBestIndex() with all constraints usable. */
154838156125
WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
154839156126
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
154840
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
156127
+ rc = whereLoopAddVirtualOne(
156128
+ pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
156129
+ );
156130
+ if( bRetry ){
156131
+ assert( rc==SQLITE_OK );
156132
+ rc = whereLoopAddVirtualOne(
156133
+ pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0
156134
+ );
156135
+ }
154841156136
154842156137
/* If the call to xBestIndex() with all terms enabled produced a plan
154843156138
** that does not require any source tables (IOW: a plan with mBest==0)
154844156139
** and does not use an IN(...) operator, then there is no point in making
154845156140
** any further calls to xBestIndex() since they will all return the same
@@ -154853,11 +156148,11 @@
154853156148
/* If the plan produced by the earlier call uses an IN(...) term, call
154854156149
** xBestIndex again, this time with IN(...) terms disabled. */
154855156150
if( bIn ){
154856156151
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
154857156152
rc = whereLoopAddVirtualOne(
154858
- pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
156153
+ pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
154859156154
assert( bIn==0 );
154860156155
mBestNoIn = pNew->prereq & ~mPrereq;
154861156156
if( mBestNoIn==0 ){
154862156157
seenZero = 1;
154863156158
seenZeroNoIN = 1;
@@ -154880,11 +156175,11 @@
154880156175
if( mNext==ALLBITS ) break;
154881156176
if( mNext==mBest || mNext==mBestNoIn ) continue;
154882156177
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
154883156178
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
154884156179
rc = whereLoopAddVirtualOne(
154885
- pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
156180
+ pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
154886156181
if( pNew->prereq==mPrereq ){
154887156182
seenZero = 1;
154888156183
if( bIn==0 ) seenZeroNoIN = 1;
154889156184
}
154890156185
}
@@ -154893,26 +156188,26 @@
154893156188
** that requires no source tables at all (i.e. one guaranteed to be
154894156189
** usable), make a call here with all source tables disabled */
154895156190
if( rc==SQLITE_OK && seenZero==0 ){
154896156191
WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
154897156192
rc = whereLoopAddVirtualOne(
154898
- pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
156193
+ pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
154899156194
if( bIn==0 ) seenZeroNoIN = 1;
154900156195
}
154901156196
154902156197
/* If the calls to xBestIndex() have so far failed to find a plan
154903156198
** that requires no source tables at all and does not use an IN(...)
154904156199
** operator, make a final call to obtain one here. */
154905156200
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
154906156201
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
154907156202
rc = whereLoopAddVirtualOne(
154908
- pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
156203
+ pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
154909156204
}
154910156205
}
154911156206
154912156207
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
154913
- sqlite3DbFreeNN(pParse->db, p);
156208
+ freeIndexInfo(pParse->db, p);
154914156209
WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
154915156210
return rc;
154916156211
}
154917156212
#endif /* SQLITE_OMIT_VIRTUALTABLE */
154918156213
@@ -154952,11 +156247,10 @@
154952156247
WhereTerm *pOrTerm;
154953156248
int once = 1;
154954156249
int i, j;
154955156250
154956156251
sSubBuild = *pBuilder;
154957
- sSubBuild.pOrderBy = 0;
154958156252
sSubBuild.pOrSet = &sCur;
154959156253
154960156254
WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
154961156255
for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
154962156256
if( (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -155202,11 +156496,13 @@
155202156496
if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
155203156497
}else{
155204156498
pLoop = pLast;
155205156499
}
155206156500
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
155207
- if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
156501
+ if( pLoop->u.vtab.isOrdered
156502
+ && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
156503
+ ){
155208156504
obSat = obDone;
155209156505
}
155210156506
break;
155211156507
}else if( wctrlFlags & WHERE_DISTINCTBY ){
155212156508
pLoop->u.btree.nDistinctCol = 0;
@@ -155469,11 +156765,11 @@
155469156765
**
155470156766
** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
155471156767
** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
155472156768
*/
155473156769
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
155474
- assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
156770
+ assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) );
155475156771
assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
155476156772
return pWInfo->sorted;
155477156773
}
155478156774
155479156775
#ifdef WHERETRACE_ENABLED
@@ -155870,16 +157166,16 @@
155870157166
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
155871157167
}
155872157168
}
155873157169
pWInfo->bOrderedInnerLoop = 0;
155874157170
if( pWInfo->pOrderBy ){
157171
+ pWInfo->nOBSat = pFrom->isOrdered;
155875157172
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
155876157173
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
155877157174
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
155878157175
}
155879157176
}else{
155880
- pWInfo->nOBSat = pFrom->isOrdered;
155881157177
pWInfo->revMask = pFrom->revLoop;
155882157178
if( pWInfo->nOBSat<=0 ){
155883157179
pWInfo->nOBSat = 0;
155884157180
if( nLoop>0 ){
155885157181
u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156138,11 +157434,11 @@
156138157434
if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
156139157435
pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
156140157436
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
156141157437
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
156142157438
if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
156143
- || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
157439
+ || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
156144157440
){
156145157441
break;
156146157442
}
156147157443
}
156148157444
}
@@ -156310,10 +157606,11 @@
156310157606
Parse *pParse, /* The parser context */
156311157607
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
156312157608
Expr *pWhere, /* The WHERE clause */
156313157609
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
156314157610
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
157611
+ Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */
156315157612
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
156316157613
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
156317157614
** If WHERE_USE_LIMIT, then the limit amount */
156318157615
){
156319157616
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156344,11 +157641,10 @@
156344157641
memset(&sWLB, 0, sizeof(sWLB));
156345157642
156346157643
/* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
156347157644
testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
156348157645
if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
156349
- sWLB.pOrderBy = pOrderBy;
156350157646
156351157647
/* The number of tables in the FROM clause is limited by the number of
156352157648
** bits in a Bitmask
156353157649
*/
156354157650
testcase( pTabList->nSrc==BMS );
@@ -156387,10 +157683,13 @@
156387157683
pWInfo->nLevel = nTabList;
156388157684
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
156389157685
pWInfo->wctrlFlags = wctrlFlags;
156390157686
pWInfo->iLimit = iAuxArg;
156391157687
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
157688
+#ifndef SQLITE_OMIT_VIRTUALTABLE
157689
+ pWInfo->pLimit = pLimit;
157690
+#endif
156392157691
memset(&pWInfo->nOBSat, 0,
156393157692
offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
156394157693
memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
156395157694
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
156396157695
pMaskSet = &pWInfo->sMaskSet;
@@ -156455,10 +157754,11 @@
156455157754
#endif
156456157755
}
156457157756
156458157757
/* Analyze all of the subexpressions. */
156459157758
sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
157759
+ sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
156460157760
if( db->mallocFailed ) goto whereBeginError;
156461157761
156462157762
/* Special case: WHERE terms that do not refer to any tables in the join
156463157763
** (constant expressions). Evaluate each such term, and jump over all the
156464157764
** generated code if the result is not true.
@@ -156554,13 +157854,14 @@
156554157854
}
156555157855
}
156556157856
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
156557157857
pWInfo->revMask = ALLBITS;
156558157858
}
156559
- if( pParse->nErr || db->mallocFailed ){
157859
+ if( pParse->nErr ){
156560157860
goto whereBeginError;
156561157861
}
157862
+ assert( db->mallocFailed==0 );
156562157863
#ifdef WHERETRACE_ENABLED
156563157864
if( sqlite3WhereTrace ){
156564157865
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
156565157866
if( pWInfo->nOBSat>0 ){
156566157867
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
@@ -156700,10 +158001,11 @@
156700158001
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
156701158002
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
156702158003
if( pWInfo->eOnePass==ONEPASS_OFF
156703158004
&& pTab->nCol<BMS
156704158005
&& (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
158006
+ && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0
156705158007
){
156706158008
/* If we know that only a prefix of the record will be used,
156707158009
** it is advantageous to reduce the "column count" field in
156708158010
** the P4 operand of the OP_OpenRead/Write opcode. */
156709158011
Bitmask b = pTabItem->colUsed;
@@ -156860,10 +158162,30 @@
156860158162
if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
156861158163
sqlite3VdbePrintOp(0, pc, pOp);
156862158164
}
156863158165
#endif
156864158166
158167
+#ifdef SQLITE_DEBUG
158168
+/*
158169
+** Return true if cursor iCur is opened by instruction k of the
158170
+** bytecode. Used inside of assert() only.
158171
+*/
158172
+static int cursorIsOpen(Vdbe *v, int iCur, int k){
158173
+ while( k>=0 ){
158174
+ VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
158175
+ if( pOp->p1!=iCur ) continue;
158176
+ if( pOp->opcode==OP_Close ) return 0;
158177
+ if( pOp->opcode==OP_OpenRead ) return 1;
158178
+ if( pOp->opcode==OP_OpenWrite ) return 1;
158179
+ if( pOp->opcode==OP_OpenDup ) return 1;
158180
+ if( pOp->opcode==OP_OpenAutoindex ) return 1;
158181
+ if( pOp->opcode==OP_OpenEphemeral ) return 1;
158182
+ }
158183
+ return 0;
158184
+}
158185
+#endif /* SQLITE_DEBUG */
158186
+
156865158187
/*
156866158188
** Generate the end of the WHERE loop. See comments on
156867158189
** sqlite3WhereBegin() for additional information.
156868158190
*/
156869158191
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157112,10 +158434,15 @@
157112158434
|| pOp->opcode==OP_Offset
157113158435
#endif
157114158436
){
157115158437
int x = pOp->p2;
157116158438
assert( pIdx->pTable==pTab );
158439
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158440
+ if( pOp->opcode==OP_Offset ){
158441
+ /* Do not need to translate the column number */
158442
+ }else
158443
+#endif
157117158444
if( !HasRowid(pTab) ){
157118158445
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
157119158446
x = pPk->aiColumn[x];
157120158447
assert( x>=0 );
157121158448
}else{
@@ -157125,13 +158452,26 @@
157125158452
x = sqlite3TableColumnToIndex(pIdx, x);
157126158453
if( x>=0 ){
157127158454
pOp->p2 = x;
157128158455
pOp->p1 = pLevel->iIdxCur;
157129158456
OpcodeRewriteTrace(db, k, pOp);
158457
+ }else{
158458
+ /* Unable to translate the table reference into an index
158459
+ ** reference. Verify that this is harmless - that the
158460
+ ** table being referenced really is open.
158461
+ */
158462
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158463
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158464
+ || cursorIsOpen(v,pOp->p1,k)
158465
+ || pOp->opcode==OP_Offset
158466
+ );
158467
+#else
158468
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158469
+ || cursorIsOpen(v,pOp->p1,k)
158470
+ );
158471
+#endif
157130158472
}
157131
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
157132
- || pWInfo->eOnePass );
157133158473
}else if( pOp->opcode==OP_Rowid ){
157134158474
pOp->p1 = pLevel->iIdxCur;
157135158475
pOp->opcode = OP_IdxRowid;
157136158476
OpcodeRewriteTrace(db, k, pOp);
157137158477
}else if( pOp->opcode==OP_IfNullRow ){
@@ -157882,11 +159222,11 @@
157882159222
break;
157883159223
}
157884159224
}
157885159225
}
157886159226
}
157887
- pWin->pFunc = pFunc;
159227
+ pWin->pWFunc = pFunc;
157888159228
}
157889159229
157890159230
/*
157891159231
** Context object passed through sqlite3WalkExprList() to
157892159232
** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158115,11 +159455,15 @@
158115159455
** are invoked in the correct order as described under "SELECT REWRITING"
158116159456
** at the top of this file.
158117159457
*/
158118159458
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
158119159459
int rc = SQLITE_OK;
158120
- if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
159460
+ if( p->pWin
159461
+ && p->pPrior==0
159462
+ && ALWAYS((p->selFlags & SF_WinRewrite)==0)
159463
+ && ALWAYS(!IN_RENAME_OBJECT)
159464
+ ){
158121159465
Vdbe *v = sqlite3GetVdbe(pParse);
158122159466
sqlite3 *db = pParse->db;
158123159467
Select *pSub = 0; /* The subquery */
158124159468
SrcList *pSrc = p->pSrc;
158125159469
Expr *pWhere = p->pWhere;
@@ -158190,12 +159534,13 @@
158190159534
** window function - one for the accumulator, another for interim
158191159535
** results. */
158192159536
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158193159537
ExprList *pArgs;
158194159538
assert( ExprUseXList(pWin->pOwner) );
159539
+ assert( pWin->pWFunc!=0 );
158195159540
pArgs = pWin->pOwner->x.pList;
158196
- if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
159541
+ if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
158197159542
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
158198159543
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
158199159544
pWin->bExprArgs = 1;
158200159545
}else{
158201159546
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158264,16 +159609,11 @@
158264159609
** there could still be references to that table embedded in the
158265159610
** result-set or ORDER BY clause of the SELECT statement p. */
158266159611
sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
158267159612
}
158268159613
158269
- if( rc ){
158270
- if( pParse->nErr==0 ){
158271
- assert( pParse->db->mallocFailed );
158272
- sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
158273
- }
158274
- }
159614
+ assert( rc==SQLITE_OK || pParse->nErr!=0 );
158275159615
return rc;
158276159616
}
158277159617
158278159618
/*
158279159619
** Unlink the Window object from the Select to which it is attached,
@@ -158578,11 +159918,11 @@
158578159918
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
158579159919
return;
158580159920
}
158581159921
158582159922
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158583
- FuncDef *p = pWin->pFunc;
159923
+ FuncDef *p = pWin->pWFunc;
158584159924
if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
158585159925
/* The inline versions of min() and max() require a single ephemeral
158586159926
** table and 3 registers. The registers are used as follows:
158587159927
**
158588159928
** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158595,11 +159935,11 @@
158595159935
pList = pWin->pOwner->x.pList;
158596159936
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158597159937
pWin->csrApp = pParse->nTab++;
158598159938
pWin->regApp = pParse->nMem+1;
158599159939
pParse->nMem += 3;
158600
- if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
159940
+ if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
158601159941
assert( pKeyInfo->aSortFlags[0]==0 );
158602159942
pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
158603159943
}
158604159944
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
158605159945
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -158818,11 +160158,11 @@
158818160158
){
158819160159
Parse *pParse = p->pParse;
158820160160
Vdbe *v = sqlite3GetVdbe(pParse);
158821160161
Window *pWin;
158822160162
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158823
- FuncDef *pFunc = pWin->pFunc;
160163
+ FuncDef *pFunc = pWin->pWFunc;
158824160164
int regArg;
158825160165
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
158826160166
int i;
158827160167
158828160168
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -158932,11 +160272,11 @@
158932160272
Vdbe *v = sqlite3GetVdbe(pParse);
158933160273
Window *pWin;
158934160274
158935160275
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158936160276
if( pMWin->regStartRowid==0
158937
- && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
160277
+ && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
158938160278
&& (pWin->eStart!=TK_UNBOUNDED)
158939160279
){
158940160280
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
158941160281
sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
158942160282
VdbeCoverage(v);
@@ -158946,16 +160286,16 @@
158946160286
assert( pMWin->regStartRowid==0 );
158947160287
}else{
158948160288
int nArg = windowArgCount(pWin);
158949160289
if( bFin ){
158950160290
sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
158951
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
160291
+ sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
158952160292
sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
158953160293
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
158954160294
}else{
158955160295
sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
158956
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
160296
+ sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
158957160297
}
158958160298
}
158959160299
}
158960160300
}
158961160301
@@ -159080,11 +160420,11 @@
159080160420
}else{
159081160421
Parse *pParse = p->pParse;
159082160422
Window *pWin;
159083160423
159084160424
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159085
- FuncDef *pFunc = pWin->pFunc;
160425
+ FuncDef *pFunc = pWin->pWFunc;
159086160426
assert( ExprUseXList(pWin->pOwner) );
159087160427
if( pFunc->zName==nth_valueName
159088160428
|| pFunc->zName==first_valueName
159089160429
){
159090160430
int csr = pWin->csrApp;
@@ -159152,11 +160492,11 @@
159152160492
Vdbe *v = sqlite3GetVdbe(pParse);
159153160493
int regArg;
159154160494
int nArg = 0;
159155160495
Window *pWin;
159156160496
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159157
- FuncDef *pFunc = pWin->pFunc;
160497
+ FuncDef *pFunc = pWin->pWFunc;
159158160498
assert( pWin->regAccum );
159159160499
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159160160500
nArg = MAX(nArg, windowArgCount(pWin));
159161160501
if( pMWin->regStartRowid==0 ){
159162160502
if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159182,11 +160522,11 @@
159182160522
*/
159183160523
static int windowCacheFrame(Window *pMWin){
159184160524
Window *pWin;
159185160525
if( pMWin->regStartRowid ) return 1;
159186160526
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159187
- FuncDef *pFunc = pWin->pFunc;
160527
+ FuncDef *pFunc = pWin->pWFunc;
159188160528
if( (pFunc->zName==nth_valueName)
159189160529
|| (pFunc->zName==first_valueName)
159190160530
|| (pFunc->zName==leadName)
159191160531
|| (pFunc->zName==lagName)
159192160532
){
@@ -159540,11 +160880,11 @@
159540160880
pNew = sqlite3DbMallocZero(db, sizeof(Window));
159541160881
if( pNew ){
159542160882
pNew->zName = sqlite3DbStrDup(db, p->zName);
159543160883
pNew->zBase = sqlite3DbStrDup(db, p->zBase);
159544160884
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
159545
- pNew->pFunc = p->pFunc;
160885
+ pNew->pWFunc = p->pWFunc;
159546160886
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
159547160887
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
159548160888
pNew->eFrmType = p->eFrmType;
159549160889
pNew->eEnd = p->eEnd;
159550160890
pNew->eStart = p->eStart;
@@ -160417,14 +161757,11 @@
160417161757
}
160418161758
return pSelect;
160419161759
}
160420161760
160421161761
160422
- /* Construct a new Expr object from a single identifier. Use the
160423
- ** new Expr to populate pOut. Set the span of pOut to be the identifier
160424
- ** that created the expression.
160425
- */
161762
+ /* Construct a new Expr object from a single token */
160426161763
static Expr *tokenExpr(Parse *pParse, int op, Token t){
160427161764
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
160428161765
if( p ){
160429161766
/* memset(p, 0, sizeof(Expr)); */
160430161767
p->op = (u8)op;
@@ -160440,10 +161777,11 @@
160440161777
p->iTable = 0;
160441161778
p->iColumn = 0;
160442161779
p->u.zToken = (char*)&p[1];
160443161780
memcpy(p->u.zToken, t.z, t.n);
160444161781
p->u.zToken[t.n] = 0;
161782
+ p->w.iOfst = (int)(t.z - pParse->zTail);
160445161783
if( sqlite3Isquote(p->u.zToken[0]) ){
160446161784
sqlite3DequoteExpr(p);
160447161785
}
160448161786
#if SQLITE_MAX_EXPR_DEPTH>0
160449161787
p->nHeight = 1;
@@ -164251,11 +165589,11 @@
164251165589
}
164252165590
break;
164253165591
case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
164254165592
{
164255165593
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
164256
- Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
165594
+ Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
164257165595
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
164258165596
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
164259165597
}
164260165598
break;
164261165599
case 103: /* as ::= AS nm */
@@ -164536,29 +165874,24 @@
164536165874
case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
164537165875
{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164538165876
break;
164539165877
case 180: /* expr ::= nm DOT nm */
164540165878
{
164541
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164542
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164543
- if( IN_RENAME_OBJECT ){
164544
- sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
164545
- sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
164546
- }
165879
+ Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165880
+ Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
164547165881
yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
164548165882
}
164549165883
yymsp[-2].minor.yy528 = yylhsminor.yy528;
164550165884
break;
164551165885
case 181: /* expr ::= nm DOT nm DOT nm */
164552165886
{
164553
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
164554
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164555
- Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
165887
+ Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
165888
+ Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165889
+ Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
164556165890
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
164557165891
if( IN_RENAME_OBJECT ){
164558
- sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
164559
- sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
165892
+ sqlite3RenameTokenRemap(pParse, 0, temp1);
164560165893
}
164561165894
yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
164562165895
}
164563165896
yymsp[-4].minor.yy528 = yylhsminor.yy528;
164564165897
break;
@@ -164567,10 +165900,11 @@
164567165900
{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164568165901
break;
164569165902
case 184: /* term ::= INTEGER */
164570165903
{
164571165904
yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
165905
+ if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
164572165906
}
164573165907
yymsp[0].minor.yy528 = yylhsminor.yy528;
164574165908
break;
164575165909
case 185: /* expr ::= VARIABLE */
164576165910
{
@@ -166811,11 +168145,14 @@
166811168145
}else if( tokenType==TK_FILTER ){
166812168146
assert( n==6 );
166813168147
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
166814168148
#endif /* SQLITE_OMIT_WINDOWFUNC */
166815168149
}else{
166816
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
168150
+ Token x;
168151
+ x.z = zSql;
168152
+ x.n = n;
168153
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
166817168154
break;
166818168155
}
166819168156
}
166820168157
pParse->sLastToken.z = zSql;
166821168158
pParse->sLastToken.n = n;
@@ -171422,16 +172759,20 @@
171422172759
** is called immediately after installing the new callback and the return
171423172760
** value from sqlite3FaultSim(0) becomes the return from
171424172761
** sqlite3_test_control().
171425172762
*/
171426172763
case SQLITE_TESTCTRL_FAULT_INSTALL: {
171427
- /* MSVC is picky about pulling func ptrs from va lists.
171428
- ** http://support.microsoft.com/kb/47961
172764
+ /* A bug in MSVC prevents it from understanding pointers to functions
172765
+ ** types in the second argument to va_arg(). Work around the problem
172766
+ ** using a typedef.
172767
+ ** http://support.microsoft.com/kb/47961 <-- dead hyperlink
172768
+ ** Search at http://web.archive.org/ to find the 2015-03-16 archive
172769
+ ** of the link above to see the original text.
171429172770
** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
171430172771
*/
171431
- typedef int(*TESTCALLBACKFUNC_t)(int);
171432
- sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
172772
+ typedef int(*sqlite3FaultFuncType)(int);
172773
+ sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
171433172774
rc = sqlite3FaultSim(0);
171434172775
break;
171435172776
}
171436172777
171437172778
/*
@@ -171554,17 +172895,31 @@
171554172895
sqlite3 *db = va_arg(ap, sqlite3*);
171555172896
db->dbOptFlags = va_arg(ap, u32);
171556172897
break;
171557172898
}
171558172899
171559
- /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
172900
+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
172901
+ **
172902
+ ** If parameter onoff is 1, subsequent calls to localtime() fail.
172903
+ ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
172904
+ ** processing.
172905
+ **
172906
+ ** xAlt arguments are void pointers, but they really want to be:
172907
+ **
172908
+ ** int xAlt(const time_t*, struct tm*);
171560172909
**
171561
- ** If parameter onoff is non-zero, subsequent calls to localtime()
171562
- ** and its variants fail. If onoff is zero, undo this setting.
172910
+ ** xAlt should write results in to struct tm object of its 2nd argument
172911
+ ** and return zero on success, or return non-zero on failure.
171563172912
*/
171564172913
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
171565172914
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
172915
+ if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
172916
+ typedef int(*sqlite3LocaltimeType)(const void*,void*);
172917
+ sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
172918
+ }else{
172919
+ sqlite3GlobalConfig.xAltLocaltime = 0;
172920
+ }
171566172921
break;
171567172922
}
171568172923
171569172924
/* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
171570172925
**
@@ -171762,14 +173117,16 @@
171762173117
** Test access for the LogEst conversion routines.
171763173118
*/
171764173119
case SQLITE_TESTCTRL_LOGEST: {
171765173120
double rIn = va_arg(ap, double);
171766173121
LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
171767
- u64 iInt = sqlite3LogEstToInt(rLogEst);
171768
- va_arg(ap, int*)[0] = rLogEst;
171769
- va_arg(ap, u64*)[0] = iInt;
171770
- va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
173122
+ int *pI1 = va_arg(ap,int*);
173123
+ u64 *pU64 = va_arg(ap,u64*);
173124
+ int *pI2 = va_arg(ap,int*);
173125
+ *pI1 = rLogEst;
173126
+ *pU64 = sqlite3LogEstToInt(rLogEst);
173127
+ *pI2 = sqlite3LogEst(*pU64);
171771173128
break;
171772173129
}
171773173130
171774173131
171775173132
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193696,11 +195053,11 @@
193696195053
u32 iRoot;
193697195054
JsonNode *pTarget;
193698195055
if( pPatch->eType!=JSON_OBJECT ){
193699195056
return pPatch;
193700195057
}
193701
- assert( iTarget>=0 && iTarget<pParse->nNode );
195058
+ assert( iTarget<pParse->nNode );
193702195059
pTarget = &pParse->aNode[iTarget];
193703195060
assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
193704195061
if( pTarget->eType!=JSON_OBJECT ){
193705195062
jsonRemoveAllNulls(pPatch);
193706195063
return pPatch;
@@ -193955,12 +195312,12 @@
193955195312
sqlite3_result_error_nomem(ctx);
193956195313
goto jsonSetDone;
193957195314
}else if( x.nErr ){
193958195315
goto jsonSetDone;
193959195316
}else if( pNode && (bApnd || bIsSet) ){
193960
- testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 );
193961
- assert( pNode->eU!=3 || pNode->eU!=5 );
195317
+ testcase( pNode->eU!=0 && pNode->eU!=1 );
195318
+ assert( pNode->eU!=3 && pNode->eU!=5 );
193962195319
VVA( pNode->eU = 4 );
193963195320
pNode->jnFlags |= (u8)JNODE_REPLACE;
193964195321
pNode->u.iReplace = i + 1;
193965195322
}
193966195323
}
@@ -194737,11 +196094,11 @@
194737196094
sqlite3_module *pModule;
194738196095
} aMod[] = {
194739196096
{ "json_each", &jsonEachModule },
194740196097
{ "json_tree", &jsonTreeModule },
194741196098
};
194742
- int i;
196099
+ unsigned int i;
194743196100
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
194744196101
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
194745196102
}
194746196103
return rc;
194747196104
}
@@ -208991,10 +210348,11 @@
208991210348
&& pIdxInfo->aOrderBy[0].iColumn<=0
208992210349
&& pIdxInfo->aOrderBy[0].desc==0
208993210350
){
208994210351
pIdxInfo->orderByConsumed = 1;
208995210352
}
210353
+ sqlite3VtabWriteAll(pIdxInfo);
208996210354
return SQLITE_OK;
208997210355
}
208998210356
208999210357
/*
209000210358
** Open a new dbpagevfs cursor.
@@ -209168,11 +210526,11 @@
209168210526
if( iDb<0 ){
209169210527
zErr = "no such schema";
209170210528
goto update_fail;
209171210529
}
209172210530
pBt = pTab->db->aDb[iDb].pBt;
209173
- if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
210531
+ if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
209174210532
zErr = "bad page number";
209175210533
goto update_fail;
209176210534
}
209177210535
szPage = sqlite3BtreeGetPageSize(pBt);
209178210536
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231345,11 +232703,11 @@
231345232703
int rc;
231346232704
231347232705
rc = sqlite3_step(pSorter->pStmt);
231348232706
if( rc==SQLITE_DONE ){
231349232707
rc = SQLITE_OK;
231350
- CsrFlagSet(pCsr, FTS5CSR_EOF);
232708
+ CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
231351232709
}else if( rc==SQLITE_ROW ){
231352232710
const u8 *a;
231353232711
const u8 *aBlob;
231354232712
int nBlob;
231355232713
int i;
@@ -233334,11 +234692,11 @@
233334234692
int nArg, /* Number of args */
233335234693
sqlite3_value **apUnused /* Function arguments */
233336234694
){
233337234695
assert( nArg==0 );
233338234696
UNUSED_PARAM2(nArg, apUnused);
233339
- sqlite3_result_text(pCtx, "fts5: 2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec", -1, SQLITE_TRANSIENT);
234697
+ sqlite3_result_text(pCtx, "fts5: 2022-03-14 20:31:57 387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e", -1, SQLITE_TRANSIENT);
233340234698
}
233341234699
233342234700
/*
233343234701
** Return true if zName is the extension on one of the shadow tables used
233344234702
** by this module.
233345234703
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.38.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.38.0"
456 #define SQLITE_VERSION_NUMBER 3038000
457 #define SQLITE_SOURCE_ID "2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -870,11 +870,11 @@
870 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
876
877 /*
878 ** CAPI3REF: Flags For File Open Operations
879 **
880 ** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
4154 **
4155 ** ^If the most recent error references a specific token in the input
4156 ** SQL, the sqlite3_error_offset() interface returns the byte offset
4157 ** of the start of that token. ^The byte offset returned by
4158 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159 ** ^If the most error does not reference a specific token in the input
4160 ** SQL, then the sqlite3_error_offset() function returns -1.
4161 **
4162 ** When the serialized [threading mode] is in use, it might be the
4163 ** case that a second error occurs on a separate thread in between
4164 ** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
4588 ** ^For example, an UPDATE statement might have a WHERE clause that
4589 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4590 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4591 ** read-only no-op if the table already exists, but
4592 ** sqlite3_stmt_readonly() still returns false for such a statement.
 
 
 
 
4593 */
4594 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4595
4596 /*
4597 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
4656 ** still make the distinction between protected and unprotected
4657 ** sqlite3_value objects even when not strictly required.
4658 **
4659 ** ^The sqlite3_value objects that are passed as parameters into the
4660 ** implementation of [application-defined SQL functions] are protected.
 
 
4661 ** ^The sqlite3_value object returned by
4662 ** [sqlite3_column_value()] is unprotected.
4663 ** Unprotected sqlite3_value objects may only be used as arguments
4664 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4665 ** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
5276 ** bytes in the string, not the number of characters.
5277 **
5278 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
5279 ** even empty strings, are always zero-terminated. ^The return
5280 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
 
 
 
 
5281 **
5282 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
5283 ** [unprotected sqlite3_value] object. In a multithreaded environment,
5284 ** an unprotected sqlite3_value object may only be used safely with
5285 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
5290 ** Hence, the sqlite3_column_value() interface
5291 ** is normally only useful within the implementation of
5292 ** [application-defined SQL functions] or [virtual tables], not within
5293 ** top-level application code.
5294 **
5295 ** The these routines may attempt to convert the datatype of the result.
5296 ** ^For example, if the internal representation is FLOAT and a text result
5297 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5298 ** conversion automatically. ^(The following table details the conversions
5299 ** that are applied:
5300 **
@@ -5315,11 +5325,11 @@
5315 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5316 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5317 ** <tr><td> TEXT <td> BLOB <td> No change
5318 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5319 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5320 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5321 ** </table>
5322 ** </blockquote>)^
5323 **
5324 ** Note that when type conversions occur, pointers returned by prior
5325 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
5887 **
5888 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5889 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5890 ** is a [protected sqlite3_value] object even if the input is not.
5891 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5892 ** memory allocation fails.
 
5893 **
5894 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5895 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5896 ** then sqlite3_value_free(V) is a harmless no-op.
5897 */
@@ -7435,28 +7446,60 @@
7435 /*
7436 ** CAPI3REF: Virtual Table Constraint Operator Codes
7437 **
7438 ** These macros define the allowed values for the
7439 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7440 ** an operator that is part of a constraint term in the wHERE clause of
7441 ** a query that uses a [virtual table].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7442 */
7443 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7444 #define SQLITE_INDEX_CONSTRAINT_GT 4
7445 #define SQLITE_INDEX_CONSTRAINT_LE 8
7446 #define SQLITE_INDEX_CONSTRAINT_LT 16
7447 #define SQLITE_INDEX_CONSTRAINT_GE 32
7448 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7449 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7450 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7451 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7452 #define SQLITE_INDEX_CONSTRAINT_NE 68
7453 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7454 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7455 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7456 #define SQLITE_INDEX_CONSTRAINT_IS 72
7457 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
 
 
7458
7459 /*
7460 ** CAPI3REF: Register A Virtual Table Implementation
7461 ** METHOD: sqlite3
7462 **
@@ -7481,11 +7524,11 @@
7481 ** ^The sqlite3_create_module()
7482 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7483 ** destructor.
7484 **
7485 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7486 ** NULL then no new module is create and any existing modules with the
7487 ** same name are dropped.
7488 **
7489 ** See also: [sqlite3_drop_modules()]
7490 */
7491 SQLITE_API int sqlite3_create_module(
@@ -9775,25 +9818,26 @@
9775 */
9776 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
9777
9778 /*
9779 ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
 
9780 **
9781 ** This function may only be called from within a call to the [xBestIndex]
9782 ** method of a [virtual table]. This function returns a pointer to a string
9783 ** that is the name of the appropriate collation sequence to use for text
9784 ** comparisons on the constraint identified by its arguments.
9785 **
9786 ** The first argument must be the pointer to the sqlite3_index_info object
9787 ** that is the first parameter to the xBestIndex() method. The second argument
9788 ** must be an index into the aConstraint[] array belonging to the
9789 ** sqlite3_index_info structure passed to xBestIndex.
9790 **
9791 ** Important:
9792 ** The first parameter must be the same pointer that is passed into the
9793 ** xBestMethod() method. The first parameter may not be a pointer to a
9794 ** different sqlite3_index_info object, even an exact copy.
9795 **
9796 ** The return value is computed as follows:
9797 **
9798 ** <ol>
9799 ** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9807,10 +9851,247 @@
9807 ** <li><p> Otherwise, "BINARY" is returned.
9808 ** </ol>
9809 */
9810 SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
9811
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9812 /*
9813 ** CAPI3REF: Conflict resolution modes
9814 ** KEYWORDS: {conflict resolution mode}
9815 **
9816 ** These constants are returned by [sqlite3_vtab_on_conflict()] to
@@ -14246,11 +14527,11 @@
14246 ** one parameter that destructors normally want. So we have to introduce
14247 ** this magic value that the code knows to handle differently. Any
14248 ** pointer will work here as long as it is distinct from SQLITE_STATIC
14249 ** and SQLITE_TRANSIENT.
14250 */
14251 #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomFault)
14252
14253 /*
14254 ** When SQLITE_OMIT_WSD is defined, it means that the target platform does
14255 ** not support Writable Static Data (WSD) such as global and static variables.
14256 ** All variables must either be on the stack or dynamically allocated from
@@ -14374,14 +14655,15 @@
14374 #define BMS ((int)(sizeof(Bitmask)*8))
14375
14376 /*
14377 ** A bit in a Bitmask
14378 */
14379 #define MASKBIT(n) (((Bitmask)1)<<(n))
14380 #define MASKBIT64(n) (((u64)1)<<(n))
14381 #define MASKBIT32(n) (((unsigned int)1)<<(n))
14382 #define ALLBITS ((Bitmask)-1)
 
14383
14384 /* A VList object records a mapping between parameters/variables/wildcards
14385 ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
14386 ** variable number associated with that parameter. See the format description
14387 ** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14439,18 +14721,19 @@
14439 ** Handle type for pages.
14440 */
14441 typedef struct PgHdr DbPage;
14442
14443 /*
14444 ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
14445 ** reserved for working around a windows/posix incompatibility). It is
14446 ** used in the journal to signify that the remainder of the journal file
14447 ** is devoted to storing a super-journal name - there are no more pages to
14448 ** roll back. See comments for function writeSuperJournal() in pager.c
14449 ** for details.
14450 */
14451 #define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
 
14452
14453 /*
14454 ** Allowed values for the flags parameter to sqlite3PagerOpen().
14455 **
14456 ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15123,11 +15406,10 @@
15123 SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
15124 Table *pTab; /* Used when p4type is P4_TABLE */
15125 #ifdef SQLITE_ENABLE_CURSOR_HINTS
15126 Expr *pExpr; /* Used when p4type is P4_EXPR */
15127 #endif
15128 int (*xAdvance)(BtCursor *, int);
15129 } p4;
15130 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
15131 char *zComment; /* Comment to improve readability */
15132 #endif
15133 #ifdef VDBE_PROFILE
@@ -15174,25 +15456,23 @@
15174 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
15175 #define P4_STATIC (-1) /* Pointer to a static string */
15176 #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
15177 #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
15178 #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15179 #define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
15180 #define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
15181 /* Above do not own any resources. Must free those below */
15182 #define P4_FREE_IF_LE (-7)
15183 #define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
15184 #define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
15185 #define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
15186 #define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
15187 #define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
15188 #define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
15189 #define P4_REAL (-13) /* P4 is a 64-bit floating point value */
15190 #define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
15191 #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
15192 #define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
15193 #define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
15194
15195 /* Error message codes for OP_Halt */
15196 #define P5_ConstraintNotNull 1
15197 #define P5_ConstraintUnique 2
15198 #define P5_ConstraintCheck 3
@@ -15233,46 +15513,46 @@
15233 /* Automatically generated. Do not edit */
15234 /* See the tool/mkopcodeh.tcl script for details */
15235 #define OP_Savepoint 0
15236 #define OP_AutoCommit 1
15237 #define OP_Transaction 2
15238 #define OP_SorterNext 3 /* jump */
15239 #define OP_Prev 4 /* jump */
15240 #define OP_Next 5 /* jump */
15241 #define OP_Checkpoint 6
15242 #define OP_JournalMode 7
15243 #define OP_Vacuum 8
15244 #define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15245 #define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */
15246 #define OP_Goto 11 /* jump */
15247 #define OP_Gosub 12 /* jump */
15248 #define OP_InitCoroutine 13 /* jump */
15249 #define OP_Yield 14 /* jump */
15250 #define OP_MustBeInt 15 /* jump */
15251 #define OP_Jump 16 /* jump */
15252 #define OP_Once 17 /* jump */
15253 #define OP_If 18 /* jump */
15254 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15255 #define OP_IfNot 20 /* jump */
15256 #define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15257 #define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15258 #define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */
15259 #define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */
15260 #define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */
15261 #define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */
15262 #define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15263 #define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */
15264 #define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */
15265 #define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */
15266 #define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */
15267 #define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */
15268 #define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */
15269 #define OP_Last 34 /* jump */
15270 #define OP_IfSmaller 35 /* jump */
15271 #define OP_SorterSort 36 /* jump */
15272 #define OP_Sort 37 /* jump */
15273 #define OP_Rewind 38 /* jump */
15274 #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
15275 #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
15276 #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
15277 #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
15278 #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15301,41 +15581,41 @@
15301 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15302 #define OP_Return 67
15303 #define OP_EndCoroutine 68
15304 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15305 #define OP_Halt 70
15306 #define OP_Integer 71 /* synopsis: r[P2]=P1 */
15307 #define OP_Int64 72 /* synopsis: r[P2]=P4 */
15308 #define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15309 #define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15310 #define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15311 #define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15312 #define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15313 #define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15314 #define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15315 #define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15316 #define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15317 #define OP_FkCheck 82
15318 #define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15319 #define OP_CollSeq 84
15320 #define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15321 #define OP_RealAffinity 86
15322 #define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15323 #define OP_Permutation 88
15324 #define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15325 #define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15326 #define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15327 #define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15328 #define OP_Column 93 /* synopsis: r[P3]=PX */
15329 #define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15330 #define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15331 #define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15332 #define OP_Count 97 /* synopsis: r[P2]=count() */
15333 #define OP_ReadCookie 98
15334 #define OP_SetCookie 99
15335 #define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15336 #define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
15337 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15338 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15339 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15340 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15341 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15342,82 +15622,84 @@
15342 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15343 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15344 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15345 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15346 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15347 #define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
15348 #define OP_OpenDup 113
15349 #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15350 #define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
15351 #define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */
15352 #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15353 #define OP_SorterOpen 118
15354 #define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15355 #define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15356 #define OP_Close 121
15357 #define OP_ColumnsUsed 122
15358 #define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15359 #define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15360 #define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15361 #define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15362 #define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15363 #define OP_RowCell 128
15364 #define OP_Delete 129
15365 #define OP_ResetCount 130
15366 #define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15367 #define OP_SorterData 132 /* synopsis: r[P2]=data */
15368 #define OP_RowData 133 /* synopsis: r[P2]=data */
15369 #define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15370 #define OP_NullRow 135
15371 #define OP_SeekEnd 136
15372 #define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15373 #define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15374 #define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15375 #define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15376 #define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15377 #define OP_FinishSeek 142
15378 #define OP_Destroy 143
15379 #define OP_Clear 144
15380 #define OP_ResetSorter 145
15381 #define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15382 #define OP_SqlExec 147
15383 #define OP_ParseSchema 148
15384 #define OP_LoadAnalysis 149
15385 #define OP_DropTable 150
15386 #define OP_DropIndex 151
15387 #define OP_DropTrigger 152
15388 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15389 #define OP_IntegrityCk 154
15390 #define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15391 #define OP_Param 156
15392 #define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15393 #define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15394 #define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15395 #define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15396 #define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15397 #define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15398 #define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15399 #define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15400 #define OP_Expire 165
15401 #define OP_CursorLock 166
15402 #define OP_CursorUnlock 167
15403 #define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15404 #define OP_VBegin 169
15405 #define OP_VCreate 170
15406 #define OP_VDestroy 171
15407 #define OP_VOpen 172
15408 #define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15409 #define OP_VRename 174
15410 #define OP_Pagecount 175
15411 #define OP_MaxPgcnt 176
15412 #define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15413 #define OP_Trace 178
15414 #define OP_CursorHint 179
15415 #define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15416 #define OP_Noop 181
15417 #define OP_Explain 182
15418 #define OP_Abortable 183
 
 
15419
15420 /* Properties such as "out2" or "jump" that are specified in
15421 ** comments following the "case" for each opcode in the vdbe.c
15422 ** are encoded into bitvectors as follows:
15423 */
@@ -15426,34 +15708,34 @@
15426 #define OPFLG_IN2 0x04 /* in2: P2 is an input */
15427 #define OPFLG_IN3 0x08 /* in3: P3 is an input */
15428 #define OPFLG_OUT2 0x10 /* out2: P2 is an output */
15429 #define OPFLG_OUT3 0x20 /* out3: P3 is an output */
15430 #define OPFLG_INITIALIZER {\
15431 /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
15432 /* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
15433 /* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\
15434 /* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15435 /* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15436 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15437 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15438 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15439 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15440 /* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15441 /* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15442 /* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15443 /* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
15444 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15445 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15446 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15447 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15448 /* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15449 /* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15450 /* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
15451 /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15452 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15453 /* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15454 }
15455
15456 /* The resolve3P2Values() routine is able to run faster if it knows
15457 ** the value of the largest JUMP opcode. The smaller the maximum
15458 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15459 ** generated this include file strives to group all JUMP opcodes
@@ -17507,10 +17789,15 @@
17507 ** b-tree.
17508 */
17509 struct UnpackedRecord {
17510 KeyInfo *pKeyInfo; /* Collation and sort-order information */
17511 Mem *aMem; /* Values */
 
 
 
 
 
17512 u16 nField; /* Number of entries in apMem[] */
17513 i8 default_rc; /* Comparison result if keys are equal */
17514 u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
17515 i8 r1; /* Value to return if (lhs < rhs) */
17516 i8 r2; /* Value to return if (lhs > rhs) */
@@ -17814,11 +18101,14 @@
17814 ** TK_SELECT: 1st register of result vector */
17815 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
17816 ** TK_VARIABLE: variable number (always >= 1).
17817 ** TK_SELECT_COLUMN: column of the result vector */
17818 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
17819 int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
 
 
 
17820 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
17821 union {
17822 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
17823 ** for a column of an index on an expression */
17824 Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -18576,10 +18866,11 @@
18576 ** initialized as they will be set before being used. The boundary is
18577 ** determined by offsetof(Parse,aTempReg).
18578 **************************************************************************/
18579
18580 int aTempReg[8]; /* Holding area for temporary registers */
 
18581 Token sNameToken; /* Token with unqualified schema object name */
18582
18583 /************************************************************************
18584 ** Above is constant between recursions. Below is reset before and after
18585 ** each recursion. The boundary between these two regions is determined
@@ -18626,11 +18917,12 @@
18626 #define PARSE_MODE_UNMAP 3
18627
18628 /*
18629 ** Sizes and pointers of various parts of the Parse object.
18630 */
18631 #define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
 
18632 #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
18633 #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
18634 #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
18635
18636 /*
@@ -18921,10 +19213,11 @@
18921 #endif
18922 #ifndef SQLITE_UNTESTABLE
18923 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
18924 #endif
18925 int bLocaltimeFault; /* True to fail localtime() calls */
 
18926 int iOnceResetThreshold; /* When to reset OP_Once counters */
18927 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
18928 unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
18929 /* vvvv--- must be last ---vvv */
18930 #ifdef SQLITE_DEBUG
@@ -19125,11 +19418,11 @@
19125 Expr *pStart; /* Expression for "<expr> PRECEDING" */
19126 Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
19127 Window **ppThis; /* Pointer to this object in Select.pWin list */
19128 Window *pNextWin; /* Next window function belonging to this SELECT */
19129 Expr *pFilter; /* The FILTER expression */
19130 FuncDef *pFunc; /* The function */
19131 int iEphCsr; /* Partition buffer or Peer buffer */
19132 int regAccum; /* Accumulator */
19133 int regResult; /* Interim result */
19134 int csrApp; /* Function cursor (used by min/max) */
19135 int regApp; /* Function register (also used by min/max) */
@@ -19566,11 +19859,12 @@
19566 #endif
19567 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
19568 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19569 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19570 Upsert*);
19571 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 
19572 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
19573 SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
19574 SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
19575 SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
19576 SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -19966,11 +20260,11 @@
19966 void (*)(sqlite3_context*),
19967 void (*)(sqlite3_context*,int,sqlite3_value **),
19968 FuncDestructor *pDestructor
19969 );
19970 SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
19971 SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
19972 SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
19973 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
19974 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
19975
19976 SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
@@ -19979,10 +20273,11 @@
19979 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
19980 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
19981 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
19982 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
19983 SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
 
19984
19985 SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
19986 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
19987
19988 #ifndef SQLITE_OMIT_SUBQUERY
@@ -20083,15 +20378,21 @@
20083 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
20084 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
20085 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
20086 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
20087 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
 
20088 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
 
 
 
 
20089 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20090 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20091 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20092 SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
 
20093 SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
20094 #ifdef SQLITE_ENABLE_NORMALIZE
20095 SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
20096 #endif
20097 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
@@ -20520,10 +20821,18 @@
20520
20521 #endif /* !defined(_OS_COMMON_H_) */
20522
20523 /************** End of os_common.h *******************************************/
20524 /************** Begin file ctime.c *******************************************/
 
 
 
 
 
 
 
 
20525 /*
20526 ** 2010 February 23
20527 **
20528 ** The author disclaims copyright to this source code. In place of
20529 ** a legal notice, here is a blessing:
@@ -20568,13 +20877,10 @@
20568 ** only a handful of compile-time options, so most times this array is usually
20569 ** rather short and uses little memory space.
20570 */
20571 static const char * const sqlite3azCompileOpt[] = {
20572
20573 /*
20574 ** BEGIN CODE GENERATED BY tool/mkctime.tcl
20575 */
20576 #ifdef SQLITE_32BIT_ROWID
20577 "32BIT_ROWID",
20578 #endif
20579 #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
20580 "4_BYTE_ALIGNED_MALLOC",
@@ -20701,13 +21007,10 @@
20701 "DISABLE_FTS4_DEFERRED",
20702 #endif
20703 #ifdef SQLITE_DISABLE_INTRINSIC
20704 "DISABLE_INTRINSIC",
20705 #endif
20706 #ifdef SQLITE_DISABLE_JSON
20707 "DISABLE_JSON",
20708 #endif
20709 #ifdef SQLITE_DISABLE_LFS
20710 "DISABLE_LFS",
20711 #endif
20712 #ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
20713 "DISABLE_PAGECACHE_OVERFLOW_STATS",
@@ -21104,10 +21407,13 @@
21104 #ifdef SQLITE_OMIT_INTEGRITY_CHECK
21105 "OMIT_INTEGRITY_CHECK",
21106 #endif
21107 #ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS
21108 "OMIT_INTROSPECTION_PRAGMAS",
 
 
 
21109 #endif
21110 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
21111 "OMIT_LIKE_OPTIMIZATION",
21112 #endif
21113 #ifdef SQLITE_OMIT_LOAD_EXTENSION
@@ -21293,14 +21599,12 @@
21293 "WIN32_MALLOC",
21294 #endif
21295 #ifdef SQLITE_ZERO_MALLOC
21296 "ZERO_MALLOC",
21297 #endif
21298 /*
21299 ** END CODE GENERATED BY tool/mkctime.tcl
21300 */
21301 };
21302
21303 SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
21304 *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
21305 return (const char**)sqlite3azCompileOpt;
21306 }
@@ -21595,13 +21899,17 @@
21595 #endif
21596 #ifndef SQLITE_UNTESTABLE
21597 0, /* xTestCallback */
21598 #endif
21599 0, /* bLocaltimeFault */
 
21600 0x7ffffffe, /* iOnceResetThreshold */
21601 SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
21602 0, /* iPrngSeed */
 
 
 
21603 };
21604
21605 /*
21606 ** Hash table for global functions - functions common to all
21607 ** database connections. After initialization, this table is
@@ -21941,20 +22249,20 @@
21941 i64 i; /* Integer value used when MEM_Int is set in flags */
21942 int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
21943 const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
21944 FuncDef *pDef; /* Used only when flags==MEM_Agg */
21945 } u;
 
 
21946 u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
21947 u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
21948 u8 eSubtype; /* Subtype for this value */
21949 int n; /* Number of characters in string value, excluding '\0' */
21950 char *z; /* String or BLOB value */
21951 /* ShallowCopy only needs to copy the information above */
21952 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
21953 int szMalloc; /* Size of the zMalloc allocation */
21954 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
21955 sqlite3 *db; /* The associated database connection */
21956 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
21957 #ifdef SQLITE_DEBUG
21958 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
21959 u16 mScopyFlags; /* flags value immediately after the shallow copy */
21960 #endif
@@ -21962,15 +22270,47 @@
21962
21963 /*
21964 ** Size of struct Mem not including the Mem.zMalloc member or anything that
21965 ** follows.
21966 */
21967 #define MEMCELLSIZE offsetof(Mem,zMalloc)
21968
21969 /* One or more of the following flags are set to indicate the validOK
21970 ** representations of the value stored in the Mem struct.
21971 **
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21972 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
21973 ** For a pointer type created using sqlite3_bind_pointer() or
21974 ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
21975 **
21976 ** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -21977,39 +22317,36 @@
21977 ** Usually this is encoded in the same unicode encoding as the main
21978 ** database (see below for exceptions). If the MEM_Term flag is also
21979 ** set, then the string is nul terminated. The MEM_Int and MEM_Real
21980 ** flags may coexist with the MEM_Str flag.
21981 */
 
21982 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
21983 #define MEM_Str 0x0002 /* Value is a string */
21984 #define MEM_Int 0x0004 /* Value is an integer */
21985 #define MEM_Real 0x0008 /* Value is a real number */
21986 #define MEM_Blob 0x0010 /* Value is a BLOB */
21987 #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
21988 #define MEM_AffMask 0x003f /* Mask of affinity bits */
 
 
 
21989 #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
21990 #define MEM_Undefined 0x0080 /* Value is undefined */
21991 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
21992 #define MEM_TypeMask 0xc1bf /* Mask of type bits */
21993
21994
21995 /* Whenever Mem contains a valid string or blob representation, one of
21996 ** the following flags must be set to determine the memory management
21997 ** policy for Mem.z. The MEM_Term flag tells us whether or not the
21998 ** string is \000 or \u0000 terminated
21999 */
22000 #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22001 #define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
22002 #define MEM_Static 0x0800 /* Mem.z points to a static string */
22003 #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
22004 #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
22005 #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
22006 #define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
22007 #ifdef SQLITE_OMIT_INCRBLOB
22008 #undef MEM_Zero
22009 #define MEM_Zero 0x0000
22010 #endif
 
22011
22012 /* Return TRUE if Mem X contains dynamically allocated content - anything
22013 ** that needs to be deallocated to avoid a leak.
22014 */
22015 #define VdbeMemDynamic(X) \
@@ -22027,15 +22364,19 @@
22027 #define MemNullNochng(X) \
22028 (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
22029 && (X)->n==0 && (X)->u.nZero==0)
22030
22031 /*
22032 ** Return true if a memory cell is not marked as invalid. This macro
22033 ** is for use inside assert() statements only.
 
 
 
 
22034 */
22035 #ifdef SQLITE_DEBUG
22036 #define memIsValid(M) ((M)->flags & MEM_Undefined)==0
22037 #endif
22038
22039 /*
22040 ** Each auxiliary data pointer stored by a user defined function
22041 ** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22215,18 +22556,36 @@
22215 Mem *aNew; /* Array of new.* values */
22216 Table *pTab; /* Schema object being upated */
22217 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
22218 };
22219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22220 /*
22221 ** Function prototypes
22222 */
22223 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22224 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22225 void sqliteVdbePopStack(Vdbe*,int);
 
22226 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22227 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
22228 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22229 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22230 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22231 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
22232 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22284,10 +22643,11 @@
22284 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
22285 SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
22286 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
22287 SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
22288 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
 
22289 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
22290 #ifndef SQLITE_OMIT_WINDOWFUNC
22291 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
22292 #endif
22293 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23251,12 +23611,14 @@
23251 ** The following routine implements the rough equivalent of localtime_r()
23252 ** using whatever operating-system specific localtime facility that
23253 ** is available. This routine returns 0 on success and
23254 ** non-zero on any kind of error.
23255 **
23256 ** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
23257 ** routine will always fail.
 
 
23258 **
23259 ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
23260 ** library function localtime_r() is used to assist in the calculation of
23261 ** local time.
23262 */
@@ -23268,20 +23630,34 @@
23268 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
23269 #endif
23270 sqlite3_mutex_enter(mutex);
23271 pX = localtime(t);
23272 #ifndef SQLITE_UNTESTABLE
23273 if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
 
 
 
 
 
 
 
 
23274 #endif
23275 if( pX ) *pTm = *pX;
23276 #if SQLITE_THREADSAFE>0
23277 sqlite3_mutex_leave(mutex);
23278 #endif
23279 rc = pX==0;
23280 #else
23281 #ifndef SQLITE_UNTESTABLE
23282 if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
 
 
 
 
 
 
23283 #endif
23284 #if HAVE_LOCALTIME_R
23285 rc = localtime_r(t, pTm)==0;
23286 #else
23287 rc = localtime_s(pTm, t);
@@ -23292,71 +23668,60 @@
23292 #endif /* SQLITE_OMIT_LOCALTIME */
23293
23294
23295 #ifndef SQLITE_OMIT_LOCALTIME
23296 /*
23297 ** Compute the difference (in milliseconds) between localtime and UTC
23298 ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
23299 ** return this value and set *pRc to SQLITE_OK.
23300 **
23301 ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
23302 ** is undefined in this case.
23303 */
23304 static sqlite3_int64 localtimeOffset(
23305 DateTime *p, /* Date at which to calculate offset */
23306 sqlite3_context *pCtx, /* Write error here if one occurs */
23307 int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
23308 ){
23309 DateTime x, y;
23310 time_t t;
23311 struct tm sLocal;
 
23312
23313 /* Initialize the contents of sLocal to avoid a compiler warning. */
23314 memset(&sLocal, 0, sizeof(sLocal));
23315
23316 x = *p;
23317 computeYMD_HMS(&x);
23318 if( x.Y<1971 || x.Y>=2038 ){
 
23319 /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
23320 ** works for years between 1970 and 2037. For dates outside this range,
23321 ** SQLite attempts to map the year into an equivalent year within this
23322 ** range, do the calculation, then map the year back.
23323 */
23324 x.Y = 2000;
23325 x.M = 1;
23326 x.D = 1;
23327 x.h = 0;
23328 x.m = 0;
23329 x.s = 0.0;
23330 } else {
23331 int s = (int)(x.s + 0.5);
23332 x.s = s;
23333 }
23334 x.tz = 0;
23335 x.validJD = 0;
23336 computeJD(&x);
23337 t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23338 if( osLocaltime(&t, &sLocal) ){
23339 sqlite3_result_error(pCtx, "local time unavailable", -1);
23340 *pRc = SQLITE_ERROR;
23341 return 0;
23342 }
23343 y.Y = sLocal.tm_year + 1900;
23344 y.M = sLocal.tm_mon + 1;
23345 y.D = sLocal.tm_mday;
23346 y.h = sLocal.tm_hour;
23347 y.m = sLocal.tm_min;
23348 y.s = sLocal.tm_sec;
23349 y.validYMD = 1;
23350 y.validHMS = 1;
23351 y.validJD = 0;
23352 y.rawS = 0;
23353 y.validTZ = 0;
23354 y.isError = 0;
23355 computeJD(&y);
23356 *pRc = SQLITE_OK;
23357 return y.iJD - x.iJD;
23358 }
23359 #endif /* SQLITE_OMIT_LOCALTIME */
23360
23361 /*
23362 ** The following table defines various date transformations of the form
@@ -23406,11 +23771,12 @@
23406 */
23407 static int parseModifier(
23408 sqlite3_context *pCtx, /* Function context */
23409 const char *z, /* The text of the modifier */
23410 int n, /* Length of zMod in bytes */
23411 DateTime *p /* The date/time value to be modified */
 
23412 ){
23413 int rc = 1;
23414 double r;
23415 switch(sqlite3UpperToLower[(u8)z[0]] ){
23416 case 'a': {
@@ -23419,14 +23785,17 @@
23419 **
23420 ** If rawS is available, then interpret as a julian day number, or
23421 ** a unix timestamp, depending on its magnitude.
23422 */
23423 if( sqlite3_stricmp(z, "auto")==0 ){
 
23424 if( !p->rawS || p->validJD ){
23425 rc = 0;
23426 p->rawS = 0;
23427 }else if( p->s>=-210866760000 && p->s<=253402300799 ){
 
 
23428 r = p->s*1000.0 + 210866760000000.0;
23429 clearYMD_HMS_TZ(p);
23430 p->iJD = (sqlite3_int64)(r + 0.5);
23431 p->validJD = 1;
23432 p->rawS = 0;
@@ -23443,10 +23812,11 @@
23443 ** is not the first modifier, or if the prior argument is not a numeric
23444 ** value in the allowed range of julian day numbers understood by
23445 ** SQLite (0..5373484.5) then the result will be NULL.
23446 */
23447 if( sqlite3_stricmp(z, "julianday")==0 ){
 
23448 if( p->validJD && p->rawS ){
23449 rc = 0;
23450 p->rawS = 0;
23451 }
23452 }
@@ -23458,13 +23828,11 @@
23458 **
23459 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
23460 ** show local time.
23461 */
23462 if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23463 computeJD(p);
23464 p->iJD += localtimeOffset(p, pCtx, &rc);
23465 clearYMD_HMS_TZ(p);
23466 }
23467 break;
23468 }
23469 #endif
23470 case 'u': {
@@ -23473,10 +23841,11 @@
23473 **
23474 ** Treat the current value of p->s as the number of
23475 ** seconds since 1970. Convert to a real julian day number.
23476 */
23477 if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
 
23478 r = p->s*1000.0 + 210866760000000.0;
23479 if( r>=0.0 && r<464269060800000.0 ){
23480 clearYMD_HMS_TZ(p);
23481 p->iJD = (sqlite3_int64)(r + 0.5);
23482 p->validJD = 1;
@@ -23485,22 +23854,35 @@
23485 }
23486 }
23487 #ifndef SQLITE_OMIT_LOCALTIME
23488 else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
23489 if( p->tzSet==0 ){
23490 sqlite3_int64 c1;
 
 
 
 
23491 computeJD(p);
23492 c1 = localtimeOffset(p, pCtx, &rc);
23493 if( rc==SQLITE_OK ){
23494 p->iJD -= c1;
23495 clearYMD_HMS_TZ(p);
23496 p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
23497 }
 
 
 
 
 
 
 
 
 
 
23498 p->tzSet = 1;
23499 }else{
23500 rc = SQLITE_OK;
23501 }
 
23502 }
23503 #endif
23504 break;
23505 }
23506 case 'w': {
@@ -23686,11 +24068,11 @@
23686 }
23687 }
23688 for(i=1; i<argc; i++){
23689 z = sqlite3_value_text(argv[i]);
23690 n = sqlite3_value_bytes(argv[i]);
23691 if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
23692 }
23693 computeJD(p);
23694 if( p->isError || !validJulianDay(p->iJD) ) return 1;
23695 return 0;
23696 }
@@ -23746,15 +24128,42 @@
23746 int argc,
23747 sqlite3_value **argv
23748 ){
23749 DateTime x;
23750 if( isDate(context, argc, argv, &x)==0 ){
23751 char zBuf[100];
 
23752 computeYMD_HMS(&x);
23753 sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
23754 x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
23755 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23756 }
23757 }
23758
23759 /*
23760 ** time( TIMESTRING, MOD, MOD, ...)
@@ -23766,14 +24175,24 @@
23766 int argc,
23767 sqlite3_value **argv
23768 ){
23769 DateTime x;
23770 if( isDate(context, argc, argv, &x)==0 ){
23771 char zBuf[100];
 
23772 computeHMS(&x);
23773 sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
23774 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
23775 }
23776 }
23777
23778 /*
23779 ** date( TIMESTRING, MOD, MOD, ...)
@@ -23785,14 +24204,32 @@
23785 int argc,
23786 sqlite3_value **argv
23787 ){
23788 DateTime x;
23789 if( isDate(context, argc, argv, &x)==0 ){
23790 char zBuf[100];
 
23791 computeYMD(&x);
23792 sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
23793 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23794 }
23795 }
23796
23797 /*
23798 ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -28956,22 +29393,31 @@
28956 /*
28957 ** Call this routine to record the fact that an OOM (out-of-memory) error
28958 ** has happened. This routine will set db->mallocFailed, and also
28959 ** temporarily disable the lookaside memory allocator and interrupt
28960 ** any running VDBEs.
 
 
 
 
 
 
 
28961 */
28962 SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
28963 if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
28964 db->mallocFailed = 1;
28965 if( db->nVdbeExec>0 ){
28966 AtomicStore(&db->u1.isInterrupted, 1);
28967 }
28968 DisableLookaside;
28969 if( db->pParse ){
 
28970 db->pParse->rc = SQLITE_NOMEM_BKPT;
28971 }
28972 }
 
28973 }
28974
28975 /*
28976 ** This routine reactivates the memory allocator and clears the
28977 ** db->mallocFailed flag as necessary.
@@ -29876,17 +30322,26 @@
29876 bufpt[j] = 0;
29877 length = j;
29878 goto adjust_width_for_utf8;
29879 }
29880 case etTOKEN: {
29881 Token *pToken;
29882 if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
29883 pToken = va_arg(ap, Token*);
29884 assert( bArgList==0 );
29885 if( pToken && pToken->n ){
29886 sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
29887 sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
 
 
 
 
 
 
 
 
 
 
29888 }
29889 length = width = 0;
29890 break;
29891 }
29892 case etSRCITEM: {
@@ -29960,10 +30415,22 @@
29960 zEnd = &zText[strlen(zText)];
29961 if( SQLITE_WITHIN(z,zText,zEnd) ){
29962 db->errByteOffset = (int)(z-zText);
29963 }
29964 }
 
 
 
 
 
 
 
 
 
 
 
 
29965
29966 /*
29967 ** Enlarge the memory allocation on a StrAccum object so that it is
29968 ** able to accept at least N more bytes of text.
29969 **
@@ -30423,11 +30890,11 @@
30423 memset(p, 0, sizeof(*p));
30424 }else{
30425 p->iLevel++;
30426 }
30427 assert( moreToFollow==0 || moreToFollow==1 );
30428 if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30429 return p;
30430 }
30431
30432 /*
30433 ** Finished with one layer of the tree
@@ -30447,11 +30914,11 @@
30447 int i;
30448 StrAccum acc;
30449 char zBuf[500];
30450 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
30451 if( p ){
30452 for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
30453 sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
30454 }
30455 sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
30456 }
30457 if( zFormat!=0 ){
@@ -30777,11 +31244,11 @@
30777 ** Generate a human-readable explanation for a Window Function object
30778 */
30779 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
30780 pView = sqlite3TreeViewPush(pView, more);
30781 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
30782 pWin->pFunc->zName, pWin->pFunc->nArg);
30783 sqlite3TreeViewWindow(pView, pWin, 0);
30784 sqlite3TreeViewPop(pView);
30785 }
30786 #endif /* SQLITE_OMIT_WINDOWFUNC */
30787
@@ -30802,11 +31269,11 @@
30802 StrAccum x;
30803 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
30804 sqlite3_str_appendf(&x, " fg.af=%x.%c",
30805 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
30806 if( ExprHasProperty(pExpr, EP_FromJoin) ){
30807 sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
30808 }
30809 if( ExprHasProperty(pExpr, EP_FromDDL) ){
30810 sqlite3_str_appendf(&x, " DDL");
30811 }
30812 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -32356,17 +32823,23 @@
32356 */
32357 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
32358 char *zMsg;
32359 va_list ap;
32360 sqlite3 *db = pParse->db;
 
 
32361 db->errByteOffset = -2;
32362 va_start(ap, zFormat);
32363 zMsg = sqlite3VMPrintf(db, zFormat, ap);
32364 va_end(ap);
32365 if( db->errByteOffset<-1 ) db->errByteOffset = -1;
32366 if( db->suppressErr ){
32367 sqlite3DbFree(db, zMsg);
 
 
 
 
32368 }else{
32369 pParse->nErr++;
32370 sqlite3DbFree(db, pParse->zErrMsg);
32371 pParse->zErrMsg = zMsg;
32372 pParse->rc = SQLITE_ERROR;
@@ -34164,46 +34637,46 @@
34164 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
34165 static const char *const azName[] = {
34166 /* 0 */ "Savepoint" OpHelp(""),
34167 /* 1 */ "AutoCommit" OpHelp(""),
34168 /* 2 */ "Transaction" OpHelp(""),
34169 /* 3 */ "SorterNext" OpHelp(""),
34170 /* 4 */ "Prev" OpHelp(""),
34171 /* 5 */ "Next" OpHelp(""),
34172 /* 6 */ "Checkpoint" OpHelp(""),
34173 /* 7 */ "JournalMode" OpHelp(""),
34174 /* 8 */ "Vacuum" OpHelp(""),
34175 /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34176 /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34177 /* 11 */ "Goto" OpHelp(""),
34178 /* 12 */ "Gosub" OpHelp(""),
34179 /* 13 */ "InitCoroutine" OpHelp(""),
34180 /* 14 */ "Yield" OpHelp(""),
34181 /* 15 */ "MustBeInt" OpHelp(""),
34182 /* 16 */ "Jump" OpHelp(""),
34183 /* 17 */ "Once" OpHelp(""),
34184 /* 18 */ "If" OpHelp(""),
34185 /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34186 /* 20 */ "IfNot" OpHelp(""),
34187 /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34188 /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34189 /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34190 /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34191 /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34192 /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34193 /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34194 /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34195 /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34196 /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
34197 /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
34198 /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34199 /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
34200 /* 34 */ "Last" OpHelp(""),
34201 /* 35 */ "IfSmaller" OpHelp(""),
34202 /* 36 */ "SorterSort" OpHelp(""),
34203 /* 37 */ "Sort" OpHelp(""),
34204 /* 38 */ "Rewind" OpHelp(""),
34205 /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
34206 /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
34207 /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
34208 /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
34209 /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34232,41 +34705,41 @@
34232 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34233 /* 67 */ "Return" OpHelp(""),
34234 /* 68 */ "EndCoroutine" OpHelp(""),
34235 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34236 /* 70 */ "Halt" OpHelp(""),
34237 /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34238 /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34239 /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34240 /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34241 /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34242 /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34243 /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34244 /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34245 /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34246 /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34247 /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34248 /* 82 */ "FkCheck" OpHelp(""),
34249 /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34250 /* 84 */ "CollSeq" OpHelp(""),
34251 /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34252 /* 86 */ "RealAffinity" OpHelp(""),
34253 /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34254 /* 88 */ "Permutation" OpHelp(""),
34255 /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34256 /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34257 /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34258 /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34259 /* 93 */ "Column" OpHelp("r[P3]=PX"),
34260 /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34261 /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34262 /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34263 /* 97 */ "Count" OpHelp("r[P2]=count()"),
34264 /* 98 */ "ReadCookie" OpHelp(""),
34265 /* 99 */ "SetCookie" OpHelp(""),
34266 /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34267 /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34268 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
34269 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
34270 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
34271 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
34272 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34273,82 +34746,84 @@
34273 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
34274 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34275 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34276 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34277 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34278 /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34279 /* 113 */ "OpenDup" OpHelp(""),
34280 /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34281 /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34282 /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34283 /* 117 */ "String8" OpHelp("r[P2]='P4'"),
34284 /* 118 */ "SorterOpen" OpHelp(""),
34285 /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34286 /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34287 /* 121 */ "Close" OpHelp(""),
34288 /* 122 */ "ColumnsUsed" OpHelp(""),
34289 /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34290 /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34291 /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34292 /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34293 /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34294 /* 128 */ "RowCell" OpHelp(""),
34295 /* 129 */ "Delete" OpHelp(""),
34296 /* 130 */ "ResetCount" OpHelp(""),
34297 /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34298 /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34299 /* 133 */ "RowData" OpHelp("r[P2]=data"),
34300 /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34301 /* 135 */ "NullRow" OpHelp(""),
34302 /* 136 */ "SeekEnd" OpHelp(""),
34303 /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34304 /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34305 /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34306 /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34307 /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34308 /* 142 */ "FinishSeek" OpHelp(""),
34309 /* 143 */ "Destroy" OpHelp(""),
34310 /* 144 */ "Clear" OpHelp(""),
34311 /* 145 */ "ResetSorter" OpHelp(""),
34312 /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34313 /* 147 */ "SqlExec" OpHelp(""),
34314 /* 148 */ "ParseSchema" OpHelp(""),
34315 /* 149 */ "LoadAnalysis" OpHelp(""),
34316 /* 150 */ "DropTable" OpHelp(""),
34317 /* 151 */ "DropIndex" OpHelp(""),
34318 /* 152 */ "DropTrigger" OpHelp(""),
34319 /* 153 */ "Real" OpHelp("r[P2]=P4"),
34320 /* 154 */ "IntegrityCk" OpHelp(""),
34321 /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34322 /* 156 */ "Param" OpHelp(""),
34323 /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34324 /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34325 /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34326 /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34327 /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34328 /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34329 /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34330 /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34331 /* 165 */ "Expire" OpHelp(""),
34332 /* 166 */ "CursorLock" OpHelp(""),
34333 /* 167 */ "CursorUnlock" OpHelp(""),
34334 /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34335 /* 169 */ "VBegin" OpHelp(""),
34336 /* 170 */ "VCreate" OpHelp(""),
34337 /* 171 */ "VDestroy" OpHelp(""),
34338 /* 172 */ "VOpen" OpHelp(""),
34339 /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34340 /* 174 */ "VRename" OpHelp(""),
34341 /* 175 */ "Pagecount" OpHelp(""),
34342 /* 176 */ "MaxPgcnt" OpHelp(""),
34343 /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34344 /* 178 */ "Trace" OpHelp(""),
34345 /* 179 */ "CursorHint" OpHelp(""),
34346 /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34347 /* 181 */ "Noop" OpHelp(""),
34348 /* 182 */ "Explain" OpHelp(""),
34349 /* 183 */ "Abortable" OpHelp(""),
 
 
34350 };
34351 return azName[i];
34352 }
34353 #endif
34354
@@ -39264,15 +39739,21 @@
39264 int ofst, /* First lock to acquire or release */
39265 int n, /* Number of locks to acquire or release */
39266 int flags /* What to do with the lock */
39267 ){
39268 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39269 unixShm *p = pDbFd->pShm; /* The shared memory being locked */
39270 unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
39271 int rc = SQLITE_OK; /* Result code */
39272 u16 mask; /* Mask of locks to take or release */
39273 int *aLock = pShmNode->aLock;
 
 
 
 
 
 
39274
39275 assert( pShmNode==pDbFd->pInode->pShmNode );
39276 assert( pShmNode->pInode==pDbFd->pInode );
39277 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
39278 assert( n>=1 );
@@ -40365,24 +40846,27 @@
40365 ** "<path to db>-journalNN"
40366 ** "<path to db>-walNN"
40367 **
40368 ** where NN is a decimal number. The NN naming schemes are
40369 ** used by the test_multiplex.c module.
 
 
 
 
 
 
40370 */
40371 nDb = sqlite3Strlen30(zPath) - 1;
40372 while( zPath[nDb]!='-' ){
40373 /* In normal operation, the journal file name will always contain
40374 ** a '-' character. However in 8+3 filename mode, or if a corrupt
40375 ** rollback journal specifies a super-journal with a goofy name, then
40376 ** the '-' might be missing. */
40377 if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
 
40378 nDb--;
40379 }
40380 memcpy(zDb, zPath, nDb);
40381 zDb[nDb] = '\0';
40382
40383 rc = getFileMode(zDb, pMode, pUid, pGid);
40384 }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
40385 *pMode = 0600;
40386 }else if( flags & SQLITE_OPEN_URI ){
40387 /* If this is a main database file and the file was opened using a URI
40388 ** filename, check for the "modeof" parameter. If present, interpret
@@ -46556,14 +47040,18 @@
46556 int flags /* What to do with the lock */
46557 ){
46558 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
46559 winShm *p = pDbFd->pShm; /* The shared memory being locked */
46560 winShm *pX; /* For looping over all siblings */
46561 winShmNode *pShmNode = p->pShmNode;
46562 int rc = SQLITE_OK; /* Result code */
46563 u16 mask; /* Mask of locks to take or release */
46564
 
 
 
 
46565 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
46566 assert( n>=1 );
46567 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
46568 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
46569 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53458,10 +53946,11 @@
53458 u16 nExtra; /* Add this many bytes to each in-memory page */
53459 i16 nReserve; /* Number of unused bytes at end of each page */
53460 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
53461 u32 sectorSize; /* Assumed sector size during rollback */
53462 Pgno mxPgno; /* Maximum allowed size of the database */
 
53463 i64 pageSize; /* Number of bytes in a page */
53464 i64 journalSizeLimit; /* Size limit for persistent journal files */
53465 char *zFilename; /* Name of the database file */
53466 char *zJournal; /* Name of the journal file */
53467 int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54444,11 +54933,11 @@
54444 ** pPager at the current location. The super-journal name must be the last
54445 ** thing written to a journal file. If the pager is in full-sync mode, the
54446 ** journal file descriptor is advanced to the next sector boundary before
54447 ** anything is written. The format is:
54448 **
54449 ** + 4 bytes: PAGER_MJ_PGNO.
54450 ** + N bytes: super-journal filename in utf-8.
54451 ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
54452 ** + 4 bytes: super-journal name checksum.
54453 ** + 8 bytes: aJournalMagic[].
54454 **
@@ -54492,11 +54981,11 @@
54492 iHdrOff = pPager->journalOff;
54493
54494 /* Write the super-journal data to the end of the journal file. If
54495 ** an error occurs, return the error code to the caller.
54496 */
54497 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
54498 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
54499 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
54500 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
54501 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
54502 iHdrOff+4+nSuper+8)))
@@ -55002,11 +55491,11 @@
55002 ** to the database file, then the IO error code is returned. If data
55003 ** is successfully read from the (sub-)journal file but appears to be
55004 ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
55005 ** two circumstances:
55006 **
55007 ** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
55008 ** * If the record is being rolled back from the main journal file
55009 ** and the checksum field does not match the record content.
55010 **
55011 ** Neither of these two scenarios are possible during a savepoint rollback.
55012 **
@@ -55062,11 +55551,11 @@
55062 /* Sanity checking on the page. This is more important that I originally
55063 ** thought. If a power failure occurs while the journal is being written,
55064 ** it could cause invalid data to be written into the journal. We need to
55065 ** detect this invalid data (with high probability) and ignore it.
55066 */
55067 if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
55068 assert( !isSavepnt );
55069 return SQLITE_DONE;
55070 }
55071 if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
55072 return SQLITE_OK;
@@ -55621,10 +56110,13 @@
55621 rc = pager_truncate(pPager, mxPg);
55622 if( rc!=SQLITE_OK ){
55623 goto end_playback;
55624 }
55625 pPager->dbSize = mxPg;
 
 
 
55626 }
55627
55628 /* Copy original pages out of the journal and back into the
55629 ** database file and/or page cache.
55630 */
@@ -56517,10 +57009,11 @@
56517 if( rc==SQLITE_OK ){
56518 sqlite3PageFree(pPager->pTmpSpace);
56519 pPager->pTmpSpace = pNew;
56520 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
56521 pPager->pageSize = pageSize;
 
56522 }else{
56523 sqlite3PageFree(pNew);
56524 }
56525 }
56526
@@ -56723,11 +57216,10 @@
56723 ** rolled back or committed. It is not safe to call this function and
56724 ** then continue writing to the database.
56725 */
56726 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
56727 assert( pPager->dbSize>=nPage || CORRUPT_DB );
56728 testcase( pPager->dbSize<nPage );
56729 assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
56730 pPager->dbSize = nPage;
56731
56732 /* At one point the code here called assertTruncateConstraint() to
56733 ** ensure that all pages being truncated away by this operation are,
@@ -58287,11 +58779,11 @@
58287
58288 noContent = (flags & PAGER_GET_NOCONTENT)!=0;
58289 if( pPg->pPager && !noContent ){
58290 /* In this case the pcache already contains an initialized copy of
58291 ** the page. Return without further ado. */
58292 assert( pgno!=PAGER_MJ_PGNO(pPager) );
58293 pPager->aStat[PAGER_STAT_HIT]++;
58294 return SQLITE_OK;
58295
58296 }else{
58297 /* The pager cache has created a new page. Its content needs to
@@ -58298,11 +58790,11 @@
58298 ** be initialized. But first some error checks:
58299 **
58300 ** (*) obsolete. Was: maximum page number is 2^31
58301 ** (2) Never try to fetch the locking page
58302 */
58303 if( pgno==PAGER_MJ_PGNO(pPager) ){
58304 rc = SQLITE_CORRUPT_BKPT;
58305 goto pager_acquire_err;
58306 }
58307
58308 pPg->pPager = pPager;
@@ -58697,11 +59189,11 @@
58697 i64 iOff = pPager->journalOff;
58698
58699 /* We should never write to the journal file the page that
58700 ** contains the database locks. The following assert verifies
58701 ** that we do not. */
58702 assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
58703
58704 assert( pPager->journalHdr<=pPager->journalOff );
58705 pData2 = pPg->pData;
58706 cksum = pager_cksum(pPager, (u8*)pData2);
58707
@@ -58876,11 +59368,11 @@
58876
58877 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
58878 Pgno pg = pg1+ii;
58879 PgHdr *pPage;
58880 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
58881 if( pg!=PAGER_MJ_PGNO(pPager) ){
58882 rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
58883 if( rc==SQLITE_OK ){
58884 rc = pager_write(pPage);
58885 if( pPage->flags&PGHDR_NEED_SYNC ){
58886 needSync = 1;
@@ -59354,11 +59846,11 @@
59354 ** image was extended as part of the current transaction and then the
59355 ** last page in the db image moved to the free-list. In this case the
59356 ** last page is never written out to disk, leaving the database file
59357 ** undersized. Fix this now if it is the case. */
59358 if( pPager->dbSize>pPager->dbFileSize ){
59359 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
59360 assert( pPager->eState==PAGER_WRITER_DBMOD );
59361 rc = pager_truncate(pPager, nNew);
59362 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
59363 }
59364
@@ -60203,10 +60695,22 @@
60203 int eMode, /* Type of checkpoint */
60204 int *pnLog, /* OUT: Final number of frames in log */
60205 int *pnCkpt /* OUT: Final number of checkpointed frames */
60206 ){
60207 int rc = SQLITE_OK;
 
 
 
 
 
 
 
 
 
 
 
 
60208 if( pPager->pWal ){
60209 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
60210 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
60211 pPager->pBusyHandlerArg,
60212 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -63102,11 +63606,13 @@
63102 rc = WAL_RETRY;
63103 goto begin_unreliable_shm_out;
63104 }
63105
63106 /* Allocate a buffer to read frames into */
63107 szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
 
 
63108 aFrame = (u8 *)sqlite3_malloc64(szFrame);
63109 if( aFrame==0 ){
63110 rc = SQLITE_NOMEM_BKPT;
63111 goto begin_unreliable_shm_out;
63112 }
@@ -63116,11 +63622,11 @@
63116 ** wal file since the heap-memory wal-index was created. If so, the
63117 ** heap-memory wal-index is discarded and WAL_RETRY returned to
63118 ** the caller. */
63119 aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
63120 aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
63121 for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
63122 iOffset+szFrame<=szWal;
63123 iOffset+=szFrame
63124 ){
63125 u32 pgno; /* Database page number for frame */
63126 u32 nTruncate; /* dbsize field from frame header */
@@ -64967,11 +65473,13 @@
64967 u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
64968 ** non-overflow cell */
64969 u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
64970 BtShared *pBt; /* Pointer to BtShared that this page is part of */
64971 u8 *aData; /* Pointer to disk image of the page data */
64972 u8 *aDataEnd; /* One byte past the end of usable data */
 
 
64973 u8 *aCellIdx; /* The cell index area */
64974 u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
64975 DbPage *pDbPage; /* Pager page handle */
64976 u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
64977 void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65272,11 +65780,11 @@
65272 #define CURSOR_FAULT 4
65273
65274 /*
65275 ** The database page the PENDING_BYTE occupies. This page is never used.
65276 */
65277 # define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
65278
65279 /*
65280 ** These macros define the location of the pointer-map entry for a
65281 ** database page. The first argument to each is the number of usable
65282 ** bytes on each page of the database (often 1024). The second is the
@@ -65913,11 +66421,11 @@
65913 if( isIndex ){
65914 HashElem *p;
65915 int bSeen = 0;
65916 for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
65917 Index *pIdx = (Index *)sqliteHashData(p);
65918 if( pIdx->tnum==(int)iRoot ){
65919 if( bSeen ){
65920 /* Two or more indexes share the same root page. There must
65921 ** be imposter tables. So just return true. The assert is not
65922 ** useful in that case. */
65923 return 1;
@@ -66506,11 +67014,11 @@
66506 }
66507
66508 /*
66509 ** In this version of BtreeMoveto, pKey is a packed index record
66510 ** such as is generated by the OP_MakeRecord opcode. Unpack the
66511 ** record and then call BtreeMovetoUnpacked() to do the work.
66512 */
66513 static int btreeMoveto(
66514 BtCursor *pCur, /* Cursor open on the btree to be searched */
66515 const void *pKey, /* Packed key if the btree is an index */
66516 i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67026,10 +67534,11 @@
67026 ** data area of the btree-page. The return number includes the cell
67027 ** data header and the local payload, but not any overflow page or
67028 ** the space used by the cell pointer.
67029 **
67030 ** cellSizePtrNoPayload() => table internal nodes
 
67031 ** cellSizePtr() => all index nodes & table leaf nodes
67032 */
67033 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
67034 u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
67035 u8 *pEnd; /* End mark for a varint */
@@ -67051,17 +67560,10 @@
67051 do{
67052 nSize = (nSize<<7) | (*++pIter & 0x7f);
67053 }while( *(pIter)>=0x80 && pIter<pEnd );
67054 }
67055 pIter++;
67056 if( pPage->intKey ){
67057 /* pIter now points at the 64-bit integer key value, a variable length
67058 ** integer. The following block moves pIter to point at the first byte
67059 ** past the end of the key value. */
67060 pEnd = &pIter[9];
67061 while( (*pIter++)&0x80 && pIter<pEnd );
67062 }
67063 testcase( nSize==pPage->maxLocal );
67064 testcase( nSize==(u32)pPage->maxLocal+1 );
67065 if( nSize<=pPage->maxLocal ){
67066 nSize += (u32)(pIter - pCell);
67067 if( nSize<4 ) nSize = 4;
@@ -67097,10 +67599,62 @@
67097 pEnd = pIter + 9;
67098 while( (*pIter++)&0x80 && pIter<pEnd );
67099 assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
67100 return (u16)(pIter - pCell);
67101 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67102
67103
67104 #ifdef SQLITE_DEBUG
67105 /* This variation on cellSizePtr() is used inside of assert() statements
67106 ** only. */
@@ -67110,11 +67664,11 @@
67110 #endif
67111
67112 #ifndef SQLITE_OMIT_AUTOVACUUM
67113 /*
67114 ** The cell pCell is currently part of page pSrc but will ultimately be part
67115 ** of pPage. (pSrc and pPager are often the same.) If pCell contains a
67116 ** pointer to an overflow page, insert an entry into the pointer-map for
67117 ** the overflow page that will be valid after pCell has been moved to pPage.
67118 */
67119 static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
67120 CellInfo info;
@@ -67285,21 +67839,23 @@
67285 */
67286 static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
67287 const int hdr = pPg->hdrOffset; /* Offset to page header */
67288 u8 * const aData = pPg->aData; /* Page data */
67289 int iAddr = hdr + 1; /* Address of ptr to pc */
67290 int pc = get2byte(&aData[iAddr]); /* Address of a free slot */
 
67291 int x; /* Excess size of the slot */
67292 int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
67293 int size; /* Size of the free slot */
67294
67295 assert( pc>0 );
67296 while( pc<=maxPC ){
67297 /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
67298 ** freeblock form a big-endian integer which is the size of the freeblock
67299 ** in bytes, including the 4-byte header. */
67300 size = get2byte(&aData[pc+2]);
 
67301 if( (x = size - nByte)>=0 ){
67302 testcase( x==4 );
67303 testcase( x==3 );
67304 if( x<4 ){
67305 /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67320,11 +67876,12 @@
67320 put2byte(&aData[pc+2], x);
67321 }
67322 return &aData[pc + x];
67323 }
67324 iAddr = pc;
67325 pc = get2byte(&aData[pc]);
 
67326 if( pc<=iAddr+size ){
67327 if( pc ){
67328 /* The next slot in the chain is not past the end of the current slot */
67329 *pRc = SQLITE_CORRUPT_PAGE(pPg);
67330 }
@@ -67354,10 +67911,11 @@
67354 static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
67355 const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
67356 u8 * const data = pPage->aData; /* Local cache of pPage->aData */
67357 int top; /* First byte of cell content area */
67358 int rc = SQLITE_OK; /* Integer return code */
 
67359 int gap; /* First byte of gap between cell pointers and cell content */
67360
67361 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67362 assert( pPage->pBt );
67363 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67372,11 +67930,12 @@
67372 /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
67373 ** and the reserved space is zero (the usual value for reserved space)
67374 ** then the cell content offset of an empty page wants to be 65536.
67375 ** However, that integer is too large to be stored in a 2-byte unsigned
67376 ** integer, so a value of 0 is used in its place. */
67377 top = get2byte(&data[hdr+5]);
 
67378 assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
67379 if( gap>top ){
67380 if( top==0 && pPage->pBt->usableSize==65536 ){
67381 top = 65536;
67382 }else{
@@ -67454,10 +68013,11 @@
67454 u8 nFrag = 0; /* Reduction in fragmentation */
67455 u16 iOrigSize = iSize; /* Original value of iSize */
67456 u16 x; /* Offset to cell content area */
67457 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
67458 unsigned char *data = pPage->aData; /* Page content */
 
67459
67460 assert( pPage->pBt!=0 );
67461 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67462 assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
67463 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67481,11 +68041,11 @@
67481 iPtr = iFreeBlk;
67482 }
67483 if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
67484 return SQLITE_CORRUPT_PAGE(pPage);
67485 }
67486 assert( iFreeBlk>iPtr || iFreeBlk==0 );
67487
67488 /* At this point:
67489 ** iFreeBlk: First freeblock after iStart, or zero if none
67490 ** iPtr: The address of a pointer to iFreeBlk
67491 **
@@ -67516,11 +68076,12 @@
67516 }
67517 }
67518 if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
67519 data[hdr+7] -= nFrag;
67520 }
67521 x = get2byte(&data[hdr+5]);
 
67522 if( iStart<=x ){
67523 /* The new freeblock is at the beginning of the cell content area,
67524 ** so just extend the cell content area rather than create another
67525 ** freelist entry */
67526 if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67560,11 +68121,10 @@
67560 assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
67561 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
67562 pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
67563 flagByte &= ~PTF_LEAF;
67564 pPage->childPtrSize = 4-4*pPage->leaf;
67565 pPage->xCellSize = cellSizePtr;
67566 pBt = pPage->pBt;
67567 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
67568 /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
67569 ** interior table b-tree page. */
67570 assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67572,10 +68132,11 @@
67572 ** leaf table b-tree page. */
67573 assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
67574 pPage->intKey = 1;
67575 if( pPage->leaf ){
67576 pPage->intKeyLeaf = 1;
 
67577 pPage->xParseCell = btreeParseCellPtr;
67578 }else{
67579 pPage->intKeyLeaf = 0;
67580 pPage->xCellSize = cellSizePtrNoPayload;
67581 pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67589,16 +68150,21 @@
67589 /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
67590 ** leaf index b-tree page. */
67591 assert( (PTF_ZERODATA|PTF_LEAF)==10 );
67592 pPage->intKey = 0;
67593 pPage->intKeyLeaf = 0;
 
67594 pPage->xParseCell = btreeParseCellPtrIndex;
67595 pPage->maxLocal = pBt->maxLocal;
67596 pPage->minLocal = pBt->minLocal;
67597 }else{
67598 /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
67599 ** an error. */
 
 
 
 
67600 return SQLITE_CORRUPT_PAGE(pPage);
67601 }
67602 pPage->max1bytePayload = pBt->max1bytePayload;
67603 return SQLITE_OK;
67604 }
@@ -67752,11 +68318,11 @@
67752 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
67753 pPage->maskPage = (u16)(pBt->pageSize - 1);
67754 pPage->nOverflow = 0;
67755 pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
67756 pPage->aCellIdx = data + pPage->childPtrSize + 8;
67757 pPage->aDataEnd = pPage->aData + pBt->usableSize;
67758 pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
67759 /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
67760 ** number of cells on the page. */
67761 pPage->nCell = get2byte(&data[3]);
67762 if( pPage->nCell>MX_CELL(pBt) ){
@@ -67787,11 +68353,11 @@
67787 unsigned char *data = pPage->aData;
67788 BtShared *pBt = pPage->pBt;
67789 u8 hdr = pPage->hdrOffset;
67790 u16 first;
67791
67792 assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
67793 assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
67794 assert( sqlite3PagerGetData(pPage->pDbPage) == data );
67795 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67796 assert( sqlite3_mutex_held(pBt->mutex) );
67797 if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67803,11 +68369,11 @@
67803 data[hdr+7] = 0;
67804 put2byte(&data[hdr+5], pBt->usableSize);
67805 pPage->nFree = (u16)(pBt->usableSize - first);
67806 decodeFlags(pPage, flags);
67807 pPage->cellOffset = first;
67808 pPage->aDataEnd = &data[pBt->usableSize];
67809 pPage->aCellIdx = &data[first];
67810 pPage->aDataOfst = &data[pPage->childPtrSize];
67811 pPage->nOverflow = 0;
67812 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
67813 pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -67929,11 +68495,11 @@
67929 rc = btreeInitPage(*ppPage);
67930 if( rc!=SQLITE_OK ){
67931 goto getAndInitPage_error2;
67932 }
67933 }
67934 assert( (*ppPage)->pgno==pgno );
67935 assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
67936
67937 /* If obtaining a child page for a cursor, we must verify that the page is
67938 ** compatible with the root page. */
67939 if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -67948,11 +68514,13 @@
67948 if( pCur ){
67949 pCur->iPage--;
67950 pCur->pPage = pCur->apPage[pCur->iPage];
67951 }
67952 testcase( pgno==0 );
67953 assert( pgno!=0 || rc==SQLITE_CORRUPT );
 
 
67954 return rc;
67955 }
67956
67957 /*
67958 ** Release a MemPage. This should be called once for each prior
@@ -68934,13 +69502,17 @@
68934 freeTempSpace(pBt);
68935 rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
68936 pageSize-usableSize);
68937 return rc;
68938 }
68939 if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
68940 rc = SQLITE_CORRUPT_BKPT;
68941 goto page1_init_failed;
 
 
 
 
68942 }
68943 /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
68944 ** be less than 480. In other words, if the page size is 512, then the
68945 ** reserved space size cannot exceed 32. */
68946 if( usableSize<480 ){
@@ -71012,11 +71584,11 @@
71012 }
71013 pCur->iPage = 0;
71014 pCur->curIntKey = pCur->pPage->intKey;
71015 }
71016 pRoot = pCur->pPage;
71017 assert( pRoot->pgno==pCur->pgnoRoot );
71018
71019 /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
71020 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
71021 ** NULL, the caller expects a table b-tree. If this is not the case,
71022 ** return an SQLITE_CORRUPT error.
@@ -71332,10 +71904,73 @@
71332 moveto_table_finish:
71333 pCur->info.nSize = 0;
71334 assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
71335 return rc;
71336 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71337
71338 /* Move the cursor so that it points to an entry in an index table
71339 ** near the key pIdxKey. Return a success code.
71340 **
71341 ** If an exact match is not found, then the cursor is always
@@ -71383,25 +72018,61 @@
71383 assert( pIdxKey->default_rc==1
71384 || pIdxKey->default_rc==0
71385 || pIdxKey->default_rc==-1
71386 );
71387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71388 rc = moveToRoot(pCur);
71389 if( rc ){
71390 if( rc==SQLITE_EMPTY ){
71391 assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
71392 *pRes = -1;
71393 return SQLITE_OK;
71394 }
71395 return rc;
71396 }
 
 
71397 assert( pCur->pPage );
71398 assert( pCur->pPage->isInit );
71399 assert( pCur->eState==CURSOR_VALID );
71400 assert( pCur->pPage->nCell > 0 );
71401 assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
71402 assert( pCur->curIntKey || pIdxKey );
71403 for(;;){
71404 int lwr, upr, idx, c;
71405 Pgno chldPg;
71406 MemPage *pPage = pCur->pPage;
71407 u8 *pCell; /* Pointer to current cell in pPage */
@@ -71411,11 +72082,11 @@
71411 ** not run. If this is not the root-page, then the moveToChild() routine
71412 ** would have already detected db corruption. Similarly, pPage must
71413 ** be the right kind (index or table) of b-tree page. Otherwise
71414 ** a moveToChild() or moveToRoot() call would have detected corruption. */
71415 assert( pPage->nCell>0 );
71416 assert( pPage->intKey==(pIdxKey==0) );
71417 lwr = 0;
71418 upr = pPage->nCell-1;
71419 idx = upr>>1; /* idx = (lwr+upr)/2; */
71420 for(;;){
71421 int nCell; /* Size of the pCell cell in bytes */
@@ -72106,11 +72777,11 @@
72106
72107 assert( sqlite3_mutex_held(pBt->mutex) );
72108 assert( CORRUPT_DB || iPage>1 );
72109 assert( !pMemPage || pMemPage->pgno==iPage );
72110
72111 if( NEVER(iPage<2) || iPage>pBt->nPage ){
72112 return SQLITE_CORRUPT_BKPT;
72113 }
72114 if( pMemPage ){
72115 pPage = pMemPage;
72116 sqlite3PagerRef(pPage->pDbPage);
@@ -72541,10 +73212,16 @@
72541 data = pPage->aData;
72542 ptr = &pPage->aCellIdx[2*idx];
72543 assert( pPage->pBt->usableSize > (u32)(ptr-data) );
72544 pc = get2byte(ptr);
72545 hdr = pPage->hdrOffset;
 
 
 
 
 
 
72546 testcase( pc==(u32)get2byte(&data[hdr+5]) );
72547 testcase( pc+sz==pPage->pBt->usableSize );
72548 if( pc+sz > pPage->pBt->usableSize ){
72549 *pRC = SQLITE_CORRUPT_BKPT;
72550 return;
@@ -74504,11 +75181,11 @@
74504 ** For an index btree (used for indexes and WITHOUT ROWID tables), the
74505 ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
74506 ** pX.pData,nData,nZero fields must be zero.
74507 **
74508 ** If the seekResult parameter is non-zero, then a successful call to
74509 ** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
74510 ** been performed. In other words, if seekResult!=0 then the cursor
74511 ** is currently pointing to a cell that will be adjacent to the cell
74512 ** to be inserted. If seekResult<0 then pCur points to a cell that is
74513 ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
74514 ** that is larger than (pKey,nKey).
@@ -74522,11 +75199,11 @@
74522 */
74523 SQLITE_PRIVATE int sqlite3BtreeInsert(
74524 BtCursor *pCur, /* Insert data into the table of this cursor */
74525 const BtreePayload *pX, /* Content of the row to be inserted */
74526 int flags, /* True if this is likely an append */
74527 int seekResult /* Result of prior MovetoUnpacked() call */
74528 ){
74529 int rc;
74530 int loc = seekResult; /* -1: before desired location +1: after */
74531 int szNew = 0;
74532 int idx;
@@ -74537,28 +75214,10 @@
74537 unsigned char *newCell = 0;
74538
74539 assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
74540 assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
74541
74542 if( pCur->eState==CURSOR_FAULT ){
74543 assert( pCur->skipNext!=SQLITE_OK );
74544 return pCur->skipNext;
74545 }
74546
74547 assert( cursorOwnsBtShared(pCur) );
74548 assert( (pCur->curFlags & BTCF_WriteFlag)!=0
74549 && pBt->inTransaction==TRANS_WRITE
74550 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
74551 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
74552
74553 /* Assert that the caller has been consistent. If this cursor was opened
74554 ** expecting an index b-tree, then the caller should be inserting blob
74555 ** keys with no associated data. If the cursor was opened expecting an
74556 ** intkey table, the caller should be inserting integer keys with a
74557 ** blob of associated data. */
74558 assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
74559
74560 /* Save the positions of any other cursors open on this table.
74561 **
74562 ** In some cases, the call to btreeMoveto() below is a no-op. For
74563 ** example, when inserting data into a table with auto-generated integer
74564 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74579,10 +75238,33 @@
74579 ** set the flag, load the schema, and then unset the flag. */
74580 return SQLITE_CORRUPT_BKPT;
74581 }
74582 }
74583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74584 if( pCur->pKeyInfo==0 ){
74585 assert( pX->pKey==0 );
74586 /* If this is an insert into a table b-tree, invalidate any incrblob
74587 ** cursors open on the row being replaced */
74588 if( p->hasIncrblobCur ){
@@ -74667,18 +75349,18 @@
74667 return btreeOverwriteCell(pCur, &x2);
74668 }
74669 }
74670 }
74671 assert( pCur->eState==CURSOR_VALID
74672 || (pCur->eState==CURSOR_INVALID && loc)
74673 || CORRUPT_DB );
74674
74675 pPage = pCur->pPage;
74676 assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
74677 assert( pPage->leaf || !pPage->intKey );
74678 if( pPage->nFree<0 ){
74679 if( NEVER(pCur->eState>CURSOR_INVALID) ){
 
74680 rc = SQLITE_CORRUPT_BKPT;
74681 }else{
74682 rc = btreeComputeFreeSpace(pPage);
74683 }
74684 if( rc ) return rc;
@@ -74955,16 +75637,20 @@
74955 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
74956 assert( pCur->curFlags & BTCF_WriteFlag );
74957 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
74958 assert( !hasReadConflicts(p, pCur->pgnoRoot) );
74959 assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
74960 if( pCur->eState==CURSOR_REQUIRESEEK ){
74961 rc = btreeRestoreCursorPosition(pCur);
74962 assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
74963 if( rc || pCur->eState!=CURSOR_VALID ) return rc;
 
 
 
 
74964 }
74965 assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
74966
74967 iCellDepth = pCur->iPage;
74968 iCellIdx = pCur->ix;
74969 pPage = pCur->pPage;
74970 if( pPage->nCell<=iCellIdx ){
@@ -74992,11 +75678,12 @@
74992 ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
74993 */
74994 bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
74995 if( bPreserve ){
74996 if( !pPage->leaf
74997 || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
 
74998 || pPage->nCell==1 /* See dbfuzz001.test for a test case */
74999 ){
75000 /* A b-tree rebalance will be required after deleting this entry.
75001 ** Save the cursor key. */
75002 rc = saveCursorKey(pCur);
@@ -75311,11 +75998,11 @@
75311 return SQLITE_CORRUPT_BKPT;
75312 }
75313 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
75314 if( rc ) return rc;
75315 if( (pBt->openFlags & BTREE_SINGLE)==0
75316 && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
75317 ){
75318 rc = SQLITE_CORRUPT_BKPT;
75319 goto cleardatabasepage_out;
75320 }
75321 hdr = pPage->hdrOffset;
@@ -76691,18 +77378,17 @@
76691 int i = sqlite3FindDbName(pDb, zDb);
76692
76693 if( i==1 ){
76694 Parse sParse;
76695 int rc = 0;
76696 memset(&sParse, 0, sizeof(sParse));
76697 sParse.db = pDb;
76698 if( sqlite3OpenTempDatabase(&sParse) ){
76699 sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
76700 rc = SQLITE_ERROR;
76701 }
76702 sqlite3DbFree(pErrorDb, sParse.zErrMsg);
76703 sqlite3ParserReset(&sParse);
76704 if( rc ){
76705 return 0;
76706 }
76707 }
76708
@@ -77934,10 +78620,18 @@
77934 assert( sqlite3VdbeCheckMemInvariants(p) );
77935 if( VdbeMemDynamic(p) || p->szMalloc ){
77936 vdbeMemClear(p);
77937 }
77938 }
 
 
 
 
 
 
 
 
77939
77940 /*
77941 ** Convert a 64-bit IEEE double into a 64-bit signed integer.
77942 ** If the double is out of range of a 64-bit signed integer then
77943 ** return the closest available 64-bit signed integer.
@@ -78296,10 +78990,11 @@
78296 void *pPtr,
78297 const char *zPType,
78298 void (*xDestructor)(void*)
78299 ){
78300 assert( pMem->flags==MEM_Null );
 
78301 pMem->u.zPType = zPType ? zPType : "";
78302 pMem->z = pPtr;
78303 pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
78304 pMem->eSubtype = 'p';
78305 pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78910,15 +79605,11 @@
78910 const char *zNeg = "";
78911 int rc = SQLITE_OK;
78912
78913 assert( pExpr!=0 );
78914 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
78915 #if defined(SQLITE_ENABLE_STAT4)
78916 if( op==TK_REGISTER ) op = pExpr->op2;
78917 #else
78918 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
78919 #endif
78920
78921 /* Compressed expressions only appear when parsing the DEFAULT clause
78922 ** on a table column definition, and hence only when pCtx==0. This
78923 ** check ensures that an EP_TokenOnly expression is never passed down
78924 ** into valueFromFunction(). */
@@ -79029,11 +79720,11 @@
79029 *ppVal = pVal;
79030 return rc;
79031
79032 no_mem:
79033 #ifdef SQLITE_ENABLE_STAT4
79034 if( pCtx==0 || pCtx->pParse->nErr==0 )
79035 #endif
79036 sqlite3OomFault(db);
79037 sqlite3DbFree(db, zVal);
79038 assert( *ppVal==0 );
79039 #ifdef SQLITE_ENABLE_STAT4
@@ -79509,11 +80200,11 @@
79509 if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
79510 sqlite3OomFault(p->db);
79511 return SQLITE_NOMEM;
79512 }
79513
79514 assert( nOp<=(1024/sizeof(Op)) );
79515 assert( nNew>=(v->nOpAlloc+nOp) );
79516 pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
79517 if( pNew ){
79518 p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
79519 v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -80111,11 +80802,11 @@
80111 ** and store that value in *pMaxFuncArgs.
80112 **
80113 ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
80114 ** indicate what the prepared statement actually does.
80115 **
80116 ** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
80117 **
80118 ** (5) Reclaim the memory allocated for storing labels.
80119 **
80120 ** This routine will only function correctly if the mkopcodeh.tcl generator
80121 ** script numbers the opcodes correctly. Changes to this routine must be
@@ -80157,29 +80848,10 @@
80157 case OP_JournalMode: {
80158 p->readOnly = 0;
80159 p->bIsReader = 1;
80160 break;
80161 }
80162 case OP_Next:
80163 case OP_SorterNext: {
80164 pOp->p4.xAdvance = sqlite3BtreeNext;
80165 pOp->p4type = P4_ADVANCE;
80166 /* The code generator never codes any of these opcodes as a jump
80167 ** to a label. They are always coded as a jump backwards to a
80168 ** known address */
80169 assert( pOp->p2>=0 );
80170 break;
80171 }
80172 case OP_Prev: {
80173 pOp->p4.xAdvance = sqlite3BtreePrevious;
80174 pOp->p4type = P4_ADVANCE;
80175 /* The code generator never codes any of these opcodes as a jump
80176 ** to a label. They are always coded as a jump backwards to a
80177 ** known address */
80178 assert( pOp->p2>=0 );
80179 break;
80180 }
80181 #ifndef SQLITE_OMIT_VIRTUALTABLE
80182 case OP_VUpdate: {
80183 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
80184 break;
80185 }
@@ -80459,11 +81131,10 @@
80459 break;
80460 }
80461 case P4_REAL:
80462 case P4_INT64:
80463 case P4_DYNAMIC:
80464 case P4_DYNBLOB:
80465 case P4_INTARRAY: {
80466 sqlite3DbFree(db, p4);
80467 break;
80468 }
80469 case P4_KEYINFO: {
@@ -80707,12 +81378,11 @@
80707 ** makes the code easier to read during debugging. None of this happens
80708 ** in a production build.
80709 */
80710 static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
80711 assert( p->nOp>0 || p->aOp==0 );
80712 assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
80713 || p->pParse->nErr>0 );
80714 if( p->nOp ){
80715 assert( p->aOp );
80716 sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
80717 p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
80718 }
@@ -81057,14 +81727,10 @@
81057 }
81058 case P4_SUBPROGRAM: {
81059 zP4 = "program";
81060 break;
81061 }
81062 case P4_DYNBLOB:
81063 case P4_ADVANCE: {
81064 break;
81065 }
81066 case P4_TABLE: {
81067 zP4 = pOp->p4.pTab->zName;
81068 break;
81069 }
81070 default: {
@@ -81192,25 +81858,44 @@
81192 }
81193 #endif
81194
81195 /*
81196 ** Initialize an array of N Mem element.
 
 
 
 
 
 
 
 
 
 
 
 
81197 */
81198 static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81199 while( (N--)>0 ){
81200 p->db = db;
81201 p->flags = flags;
81202 p->szMalloc = 0;
 
81203 #ifdef SQLITE_DEBUG
81204 p->pScopyFrom = 0;
81205 #endif
81206 p++;
 
81207 }
81208 }
81209
81210 /*
81211 ** Release an array of N Mem elements
 
 
 
 
 
81212 */
81213 static void releaseMemArray(Mem *p, int N){
81214 if( p && N ){
81215 Mem *pEnd = &p[N];
81216 sqlite3 *db = p->db;
@@ -81239,16 +81924,21 @@
81239 testcase( p->flags & MEM_Agg );
81240 testcase( p->flags & MEM_Dyn );
81241 if( p->flags&(MEM_Agg|MEM_Dyn) ){
81242 testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
81243 sqlite3VdbeMemRelease(p);
 
81244 }else if( p->szMalloc ){
81245 sqlite3DbFreeNN(db, p->zMalloc);
81246 p->szMalloc = 0;
 
81247 }
81248
81249 p->flags = MEM_Undefined;
 
 
 
81250 }while( (++p)<pEnd );
81251 }
81252 }
81253
81254 #ifdef SQLITE_DEBUG
@@ -82324,11 +83014,11 @@
82324 || (!deferred && p->nFkConstraint>0)
82325 ){
82326 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82327 p->errorAction = OE_Abort;
82328 sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
82329 return SQLITE_ERROR;
82330 }
82331 return SQLITE_OK;
82332 }
82333 #endif
82334
@@ -82579,10 +83269,11 @@
82579 db->bBenignMalloc--;
82580 }else if( db->pErr ){
82581 sqlite3ValueSetNull(db->pErr);
82582 }
82583 db->errCode = rc;
 
82584 return rc;
82585 }
82586
82587 #ifdef SQLITE_ENABLE_SQLLOG
82588 /*
@@ -82858,11 +83549,11 @@
82858 ** pointed to was deleted out from under it. Or maybe the btree was
82859 ** rebalanced. Whatever the cause, try to restore "p" to the place it
82860 ** is supposed to be pointing. If the row was deleted out from under the
82861 ** cursor, set the cursor to point to a NULL row.
82862 */
82863 static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
82864 int isDifferentRow, rc;
82865 assert( p->eCurType==CURTYPE_BTREE );
82866 assert( p->uc.pCursor!=0 );
82867 assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
82868 rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82876,43 +83567,11 @@
82876 ** if need be. Return any I/O error from the restore operation.
82877 */
82878 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
82879 assert( p->eCurType==CURTYPE_BTREE );
82880 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
82881 return handleMovedCursor(p);
82882 }
82883 return SQLITE_OK;
82884 }
82885
82886 /*
82887 ** Make sure the cursor p is ready to read or write the row to which it
82888 ** was last positioned. Return an error code if an OOM fault or I/O error
82889 ** prevents us from positioning the cursor to its correct position.
82890 **
82891 ** If a MoveTo operation is pending on the given cursor, then do that
82892 ** MoveTo now. If no move is pending, check to see if the row has been
82893 ** deleted out from under the cursor and if it has, mark the row as
82894 ** a NULL row.
82895 **
82896 ** If the cursor is already pointing to the correct row and that row has
82897 ** not been deleted out from under the cursor, then this routine is a no-op.
82898 */
82899 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
82900 VdbeCursor *p = *pp;
82901 assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
82902 if( p->deferredMoveto ){
82903 u32 iMap;
82904 assert( !p->isEphemeral );
82905 if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){
82906 *pp = p->pAltCursor;
82907 *piCol = iMap - 1;
82908 return SQLITE_OK;
82909 }
82910 return sqlite3VdbeFinishMoveto(p);
82911 }
82912 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
82913 return handleMovedCursor(p);
82914 }
82915 return SQLITE_OK;
82916 }
82917
82918 /*
@@ -83570,12 +84229,12 @@
83570 if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
83571 rc = 0;
83572 }else{
83573 rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
83574 }
83575 sqlite3VdbeMemRelease(&c1);
83576 sqlite3VdbeMemRelease(&c2);
83577 return rc;
83578 }
83579 }
83580
83581 /*
@@ -84095,11 +84754,12 @@
84095
84096 default:
84097 return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
84098 }
84099
84100 v = pPKey2->aMem[0].u.i;
 
84101 if( v>lhs ){
84102 res = pPKey2->r1;
84103 }else if( v<lhs ){
84104 res = pPKey2->r2;
84105 }else if( pPKey2->nField>1 ){
@@ -84130,16 +84790,22 @@
84130 const u8 *aKey1 = (const u8*)pKey1;
84131 int serial_type;
84132 int res;
84133
84134 assert( pPKey2->aMem[0].flags & MEM_Str );
 
 
84135 vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84136 serial_type = (u8)(aKey1[1]);
84137 if( serial_type >= 0x80 ){
84138 sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84139 }
84140 if( serial_type<12 ){
 
 
 
 
 
84141 res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
84142 }else if( !(serial_type & 0x01) ){
84143 res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
84144 }else{
84145 int nCmp;
@@ -84149,19 +84815,19 @@
84149 nStr = (serial_type-12) / 2;
84150 if( (szHdr + nStr) > nKey1 ){
84151 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
84152 return 0; /* Corruption */
84153 }
84154 nCmp = MIN( pPKey2->aMem[0].n, nStr );
84155 res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
84156
84157 if( res>0 ){
84158 res = pPKey2->r2;
84159 }else if( res<0 ){
84160 res = pPKey2->r1;
84161 }else{
84162 res = nStr - pPKey2->aMem[0].n;
84163 if( res==0 ){
84164 if( pPKey2->nField>1 ){
84165 res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
84166 }else{
84167 res = pPKey2->default_rc;
@@ -84212,19 +84878,22 @@
84212 }else{
84213 p->r1 = -1;
84214 p->r2 = 1;
84215 }
84216 if( (flags & MEM_Int) ){
 
84217 return vdbeRecordCompareInt;
84218 }
84219 testcase( flags & MEM_Real );
84220 testcase( flags & MEM_Null );
84221 testcase( flags & MEM_Blob );
84222 if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
84223 && p->pKeyInfo->aColl[0]==0
84224 ){
84225 assert( flags & MEM_Str );
 
 
84226 return vdbeRecordCompareString;
84227 }
84228 }
84229
84230 return sqlite3VdbeRecordCompare;
@@ -84293,18 +84962,18 @@
84293 }
84294
84295 /* Fetch the integer off the end of the index record */
84296 sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
84297 *rowid = v.u.i;
84298 sqlite3VdbeMemRelease(&m);
84299 return SQLITE_OK;
84300
84301 /* Jump here if database corruption is detected after m has been
84302 ** allocated. Free the m object and return SQLITE_CORRUPT. */
84303 idx_rowid_corruption:
84304 testcase( m.szMalloc!=0 );
84305 sqlite3VdbeMemRelease(&m);
84306 return SQLITE_CORRUPT_BKPT;
84307 }
84308
84309 /*
84310 ** Compare the key of the index entry that cursor pC is pointing to against
@@ -84342,11 +85011,11 @@
84342 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
84343 if( rc ){
84344 return rc;
84345 }
84346 *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
84347 sqlite3VdbeMemRelease(&m);
84348 return SQLITE_OK;
84349 }
84350
84351 /*
84352 ** This routine sets the value to be returned by subsequent calls to
@@ -84509,11 +85178,11 @@
84509 static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
84510 if( p ){
84511 int i;
84512 for(i=0; i<nField; i++){
84513 Mem *pMem = &p->aMem[i];
84514 if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
84515 }
84516 sqlite3DbFreeNN(db, p);
84517 }
84518 }
84519 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -84936,10 +85605,13 @@
84936 pNew->flags |= MEM_Ephem;
84937 if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
84938 sqlite3ValueFree(pNew);
84939 pNew = 0;
84940 }
 
 
 
84941 }
84942 return pNew;
84943 }
84944
84945 /* Destroy an sqlite3_value object previously obtained from
@@ -85436,10 +86108,74 @@
85436 */
85437 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
85438 assert( p );
85439 return sqlite3_value_nochange(p->pOut);
85440 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85441
85442 /*
85443 ** Return the current time for a statement. If the current time
85444 ** is requested more than once within the same run of a single prepared
85445 ** statement, the exact same time is returned for each invocation regardless
@@ -85631,19 +86367,19 @@
85631 #if defined(SQLITE_DEBUG) && defined(__GNUC__)
85632 __attribute__((aligned(8)))
85633 #endif
85634 = {
85635 /* .u = */ {0},
 
 
85636 /* .flags = */ (u16)MEM_Null,
85637 /* .enc = */ (u8)0,
85638 /* .eSubtype = */ (u8)0,
85639 /* .n = */ (int)0,
85640 /* .z = */ (char*)0,
85641 /* .zMalloc = */ (char*)0,
85642 /* .szMalloc = */ (int)0,
85643 /* .uTemp = */ (u32)0,
85644 /* .db = */ (sqlite3*)0,
85645 /* .xDel = */ (void(*)(void*))0,
85646 #ifdef SQLITE_DEBUG
85647 /* .pScopyFrom = */ (Mem*)0,
85648 /* .mScopyFlags= */ 0,
85649 #endif
@@ -86121,11 +86857,14 @@
86121 case SQLITE_INTEGER: {
86122 rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
86123 break;
86124 }
86125 case SQLITE_FLOAT: {
86126 rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
 
 
 
86127 break;
86128 }
86129 case SQLITE_BLOB: {
86130 if( pValue->flags & MEM_Zero ){
86131 rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -87537,11 +88276,10 @@
87537 */
87538 static u64 filterHash(const Mem *aMem, const Op *pOp){
87539 int i, mx;
87540 u64 h = 0;
87541
87542 i = pOp->p3;
87543 assert( pOp->p4type==P4_INT32 );
87544 for(i=pOp->p3, mx=i+pOp->p4.i; i<mx; i++){
87545 const Mem *p = &aMem[i];
87546 if( p->flags & (MEM_Int|MEM_IntReal) ){
87547 h += p->u.i;
@@ -87852,14 +88590,18 @@
87852 jump_to_p2:
87853 pOp = &aOp[pOp->p2 - 1];
87854 break;
87855 }
87856
87857 /* Opcode: Return P1 * * * *
87858 **
87859 ** Jump to the next instruction after the address in register P1. After
87860 ** the jump, register P1 becomes undefined.
 
 
 
 
87861 */
87862 case OP_Return: { /* in1 */
87863 pIn1 = &aMem[pOp->p1];
87864 assert( pIn1->flags==MEM_Int );
87865 pOp = &aOp[pIn1->u.i];
@@ -88043,15 +88785,26 @@
88043 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
88044 }
88045 goto vdbe_return;
88046 }
88047
 
 
 
 
 
 
 
 
 
 
88048 /* Opcode: Integer P1 P2 * * *
88049 ** Synopsis: r[P2]=P1
88050 **
88051 ** The 32-bit integer value P1 is written into register P2.
88052 */
 
88053 case OP_Integer: { /* out2 */
88054 pOut = out2Prerelease(p, pOp);
88055 pOut->u.i = pOp->p1;
88056 break;
88057 }
@@ -89020,11 +89773,11 @@
89020 testcase( pIn1->flags & MEM_Real );
89021 testcase( pIn1->flags & MEM_IntReal );
89022 sqlite3VdbeMemStringify(pIn1, encoding, 1);
89023 testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
89024 flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
89025 if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
89026 }
89027 if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
89028 testcase( pIn3->flags & MEM_Int );
89029 testcase( pIn3->flags & MEM_Real );
89030 testcase( pIn3->flags & MEM_IntReal );
@@ -89488,14 +90241,22 @@
89488 case OP_Offset: { /* out3 */
89489 VdbeCursor *pC; /* The VDBE cursor */
89490 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
89491 pC = p->apCsr[pOp->p1];
89492 pOut = &p->aMem[pOp->p3];
89493 if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
89494 sqlite3VdbeMemSetNull(pOut);
89495 }else{
89496 sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
 
 
 
 
 
 
 
 
89497 }
89498 break;
89499 }
89500 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
89501
@@ -89520,11 +90281,11 @@
89520 ** skipped for length() and all content loading can be skipped for typeof().
89521 */
89522 case OP_Column: {
89523 u32 p2; /* column number to retrieve */
89524 VdbeCursor *pC; /* The VDBE cursor */
89525 BtCursor *pCrsr; /* The BTree cursor */
89526 u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
89527 int len; /* The length of the serialized data for the column */
89528 int i; /* Loop counter */
89529 Mem *pDest; /* Where to write the extracted value */
89530 Mem sMem; /* For storing the record being decoded */
@@ -89534,23 +90295,15 @@
89534 u64 offset64; /* 64-bit offset */
89535 u32 t; /* A type code from the record header */
89536 Mem *pReg; /* PseudoTable input register */
89537
89538 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 
89539 pC = p->apCsr[pOp->p1];
89540 assert( pC!=0 );
89541 p2 = (u32)pOp->p2;
89542
89543 /* If the cursor cache is stale (meaning it is not currently point at
89544 ** the correct row) then bring it up-to-date by doing the necessary
89545 ** B-Tree seek. */
89546 rc = sqlite3VdbeCursorMoveto(&pC, &p2);
89547 if( rc ) goto abort_due_to_error;
89548
89549 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
89550 pDest = &aMem[pOp->p3];
89551 memAboutToChange(p, pDest);
89552 assert( pC!=0 );
89553 assert( p2<(u32)pC->nField );
89554 aOffset = pC->aOffset;
89555 assert( aOffset==pC->aType+pC->nField );
89556 assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89567,30 +90320,43 @@
89567 assert( pReg->flags & MEM_Blob );
89568 assert( memIsValid(pReg) );
89569 pC->payloadSize = pC->szRow = pReg->n;
89570 pC->aRow = (u8*)pReg->z;
89571 }else{
 
 
89572 sqlite3VdbeMemSetNull(pDest);
89573 goto op_column_out;
89574 }
89575 }else{
89576 pCrsr = pC->uc.pCursor;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89577 assert( pC->eCurType==CURTYPE_BTREE );
89578 assert( pCrsr );
89579 assert( sqlite3BtreeCursorIsValid(pCrsr) );
89580 pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
89581 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
89582 assert( pC->szRow<=pC->payloadSize );
89583 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
89584 if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
89585 goto too_big;
89586 }
89587 }
89588 pC->cacheStatus = p->cacheCtr;
89589 pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
89590 pC->nHdrParsed = 0;
89591
89592
89593 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
89594 /* pC->aRow does not have to hold the entire row, but it does at least
89595 ** need to cover the header of the record. If pC->aRow does not contain
89596 ** the complete header, then set it to zero, forcing the header to be
@@ -89627,10 +90393,14 @@
89627 zData = pC->aRow;
89628 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
89629 testcase( aOffset[0]==0 );
89630 goto op_column_read_header;
89631 }
 
 
 
 
89632 }
89633
89634 /* Make sure at least the first p2+1 entries of the header have been
89635 ** parsed and valid information is in aOffset[] and pC->aType[].
89636 */
@@ -89695,10 +90465,12 @@
89695 /* If after trying to extract new entries from the header, nHdrParsed is
89696 ** still not up to p2, that means that the record has fewer than p2
89697 ** columns. So the result will be either the default value or a NULL.
89698 */
89699 if( pC->nHdrParsed<=p2 ){
 
 
89700 if( pOp->p4type==P4_MEM ){
89701 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
89702 }else{
89703 sqlite3VdbeMemSetNull(pDest);
89704 }
@@ -89712,10 +90484,12 @@
89712 ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
89713 ** all valid.
89714 */
89715 assert( p2<pC->nHdrParsed );
89716 assert( rc==SQLITE_OK );
 
 
89717 assert( sqlite3VdbeCheckMemInvariants(pDest) );
89718 if( VdbeMemDynamic(pDest) ){
89719 sqlite3VdbeMemSetNull(pDest);
89720 }
89721 assert( t==pC->aType[p2] );
@@ -89732,10 +90506,11 @@
89732 */
89733 static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
89734 pDest->n = len = (t-12)/2;
89735 pDest->enc = encoding;
89736 if( pDest->szMalloc < len+2 ){
 
89737 pDest->flags = MEM_Null;
89738 if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
89739 }else{
89740 pDest->z = pDest->zMalloc;
89741 }
@@ -89764,10 +90539,11 @@
89764 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
89765 ** and it begins with a bunch of zeros.
89766 */
89767 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
89768 }else{
 
89769 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
89770 if( rc!=SQLITE_OK ) goto abort_due_to_error;
89771 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
89772 pDest->flags &= ~MEM_Ephem;
89773 }
@@ -89846,10 +90622,12 @@
89846 case COLTYPE_TEXT: {
89847 if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error;
89848 break;
89849 }
89850 case COLTYPE_REAL: {
 
 
89851 if( pIn1->flags & MEM_Int ){
89852 /* When applying REAL affinity, if the result is still an MEM_Int
89853 ** that will fit in 6 bytes, then change the type to MEM_IntReal
89854 ** so that we keep the high-resolution integer value but know that
89855 ** the type really wants to be REAL. */
@@ -89863,11 +90641,11 @@
89863 }else{
89864 pIn1->u.r = (double)pIn1->u.i;
89865 pIn1->flags |= MEM_Real;
89866 pIn1->flags &= ~MEM_Int;
89867 }
89868 }else if( (pIn1->flags & MEM_Real)==0 ){
89869 goto vdbe_type_error;
89870 }
89871 break;
89872 }
89873 default: {
@@ -89974,11 +90752,10 @@
89974 u32 serial_type; /* Type field */
89975 Mem *pData0; /* First field to be combined into the record */
89976 Mem *pLast; /* Last field of the record */
89977 int nField; /* Number of fields in the record */
89978 char *zAffinity; /* The affinity string for the record */
89979 int file_format; /* File format to use for encoding */
89980 u32 len; /* Length of a field */
89981 u8 *zHdr; /* Where to write next byte of the header */
89982 u8 *zPayload; /* Where to write next byte of the payload */
89983
89984 /* Assuming the record contains N fields, the record format looks
@@ -90003,11 +90780,10 @@
90003 zAffinity = pOp->p4.z;
90004 assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
90005 pData0 = &aMem[nField];
90006 nField = pOp->p2;
90007 pLast = &pData0[nField-1];
90008 file_format = p->minWriteFileFormat;
90009
90010 /* Identify the output register */
90011 assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
90012 pOut = &aMem[pOp->p3];
90013 memAboutToChange(p, pOut);
@@ -90102,14 +90878,14 @@
90102 }
90103 nHdr++;
90104 testcase( uu==127 ); testcase( uu==128 );
90105 testcase( uu==32767 ); testcase( uu==32768 );
90106 testcase( uu==8388607 ); testcase( uu==8388608 );
90107 testcase( uu==2147483647 ); testcase( uu==2147483648 );
90108 testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
90109 if( uu<=127 ){
90110 if( (i&1)==i && file_format>=4 ){
90111 pRec->uTemp = 8+(u32)uu;
90112 }else{
90113 nData++;
90114 pRec->uTemp = 1;
90115 }
@@ -92568,10 +93344,14 @@
92568 /* Opcode: NullRow P1 * * * *
92569 **
92570 ** Move the cursor P1 to a null row. Any OP_Column operations
92571 ** that occur while the cursor is on the null row will always
92572 ** write a NULL.
 
 
 
 
92573 */
92574 case OP_NullRow: {
92575 VdbeCursor *pC;
92576
92577 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92747,11 +93527,11 @@
92747 VdbeBranchTaken(res!=0,2);
92748 if( res ) goto jump_to_p2;
92749 break;
92750 }
92751
92752 /* Opcode: Next P1 P2 P3 P4 P5
92753 **
92754 ** Advance cursor P1 so that it points to the next key/data pair in its
92755 ** table or index. If there are no more key/value pairs then fall through
92756 ** to the following instruction. But if the cursor advance was successful,
92757 ** jump immediately to P2.
@@ -92766,19 +93546,16 @@
92766 ** The P3 value is a hint to the btree implementation. If P3==1, that
92767 ** means P1 is an SQL index and that this instruction could have been
92768 ** omitted if that index had been unique. P3 is usually 0. P3 is
92769 ** always either 0 or 1.
92770 **
92771 ** P4 is always of type P4_ADVANCE. The function pointer points to
92772 ** sqlite3BtreeNext().
92773 **
92774 ** If P5 is positive and the jump is taken, then event counter
92775 ** number P5-1 in the prepared statement is incremented.
92776 **
92777 ** See also: Prev
92778 */
92779 /* Opcode: Prev P1 P2 P3 P4 P5
92780 **
92781 ** Back up cursor P1 so that it points to the previous key/data pair in its
92782 ** table or index. If there is no previous key/value pairs then fall through
92783 ** to the following instruction. But if the cursor backup was successful,
92784 ** jump immediately to P2.
@@ -92794,13 +93571,10 @@
92794 ** The P3 value is a hint to the btree implementation. If P3==1, that
92795 ** means P1 is an SQL index and that this instruction could have been
92796 ** omitted if that index had been unique. P3 is usually 0. P3 is
92797 ** always either 0 or 1.
92798 **
92799 ** P4 is always of type P4_ADVANCE. The function pointer points to
92800 ** sqlite3BtreePrevious().
92801 **
92802 ** If P5 is positive and the jump is taken, then event counter
92803 ** number P5-1 in the prepared statement is incremented.
92804 */
92805 /* Opcode: SorterNext P1 P2 * * P5
92806 **
@@ -92814,34 +93588,37 @@
92814
92815 pC = p->apCsr[pOp->p1];
92816 assert( isSorter(pC) );
92817 rc = sqlite3VdbeSorterNext(db, pC);
92818 goto next_tail;
 
92819 case OP_Prev: /* jump */
 
 
 
 
 
 
 
 
 
 
 
 
92820 case OP_Next: /* jump */
92821 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
92822 assert( pOp->p5<ArraySize(p->aCounter) );
92823 pC = p->apCsr[pOp->p1];
92824 assert( pC!=0 );
92825 assert( pC->deferredMoveto==0 );
92826 assert( pC->eCurType==CURTYPE_BTREE );
92827 assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
92828 assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
92829
92830 /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
92831 ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
92832 assert( pOp->opcode!=OP_Next
92833 || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
92834 || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
92835 || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
92836 || pC->seekOp==OP_IfNoHope);
92837 assert( pOp->opcode!=OP_Prev
92838 || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
92839 || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
92840 || pC->seekOp==OP_NullRow);
92841
92842 rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
92843 next_tail:
92844 pC->cacheStatus = CACHE_STALE;
92845 VdbeBranchTaken(rc==SQLITE_OK,2);
92846 if( rc==SQLITE_OK ){
92847 pC->nullRow = 0;
@@ -93055,10 +93832,11 @@
93055 assert( pTabCur->uc.pCursor!=0 );
93056 assert( pTabCur->isTable );
93057 pTabCur->nullRow = 0;
93058 pTabCur->movetoTarget = rowid;
93059 pTabCur->deferredMoveto = 1;
 
93060 assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
93061 assert( !pTabCur->isEphemeral );
93062 pTabCur->ub.aAltMap = pOp->p4.ai;
93063 assert( !pC->isEphemeral );
93064 pTabCur->pAltCursor = pC;
@@ -93189,11 +93967,11 @@
93189 }
93190 sqlite3VdbeMemInit(&m, db, 0);
93191 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
93192 if( rc ) goto abort_due_to_error;
93193 res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
93194 sqlite3VdbeMemRelease(&m);
93195 }
93196 /* End of inlined sqlite3VdbeIdxKeyCompare() */
93197
93198 assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
93199 if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94592,10 +95370,38 @@
94592 goto no_mem;
94593 }
94594 break;
94595 }
94596 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94597
94598 #ifndef SQLITE_OMIT_VIRTUALTABLE
94599 /* Opcode: VFilter P1 P2 P3 P4 *
94600 ** Synopsis: iplan=r[P3] zplan='P4'
94601 **
@@ -95579,14 +96385,13 @@
95579 wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
95580
95581 sqlite3_mutex_enter(db->mutex);
95582
95583 pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
95584 do {
95585 memset(&sParse, 0, sizeof(Parse));
95586 if( !pBlob ) goto blob_open_out;
95587 sParse.db = db;
95588 sqlite3DbFree(db, zErr);
95589 zErr = 0;
95590
95591 sqlite3BtreeEnterAll(db);
95592 pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
@@ -95759,11 +96564,13 @@
95759 sqlite3BtreeLeaveAll(db);
95760 if( db->mallocFailed ){
95761 goto blob_open_out;
95762 }
95763 rc = blobSeekToRow(pBlob, iRow, &zErr);
95764 } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
 
 
95765
95766 blob_open_out:
95767 if( rc==SQLITE_OK && db->mallocFailed==0 ){
95768 *ppBlob = (sqlite3_blob *)pBlob;
95769 }else{
@@ -95770,11 +96577,11 @@
95770 if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
95771 sqlite3DbFree(db, pBlob);
95772 }
95773 sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
95774 sqlite3DbFree(db, zErr);
95775 sqlite3ParserReset(&sParse);
95776 rc = sqlite3ApiExit(db, rc);
95777 sqlite3_mutex_leave(db->mutex);
95778 return rc;
95779 }
95780
@@ -99319,10 +100126,13 @@
99319 }
99320 return rc;
99321 }
99322
99323
 
 
 
99324 /*
99325 ** Write data to the file.
99326 */
99327 static int memjrnlWrite(
99328 sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99349,26 +100159,24 @@
99349 /* An in-memory journal file should only ever be appended to. Random
99350 ** access writes are not required. The only exception to this is when
99351 ** the in-memory journal is being used by a connection using the
99352 ** atomic-write optimization. In this case the first 28 bytes of the
99353 ** journal file may be written as part of committing the transaction. */
99354 assert( iOfst==p->endpoint.iOffset || iOfst==0 );
99355 #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
99356 || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
 
99357 if( iOfst==0 && p->pFirst ){
99358 assert( p->nChunkSize>iAmt );
99359 memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
99360 }else
99361 #else
99362 assert( iOfst>0 || p->pFirst==0 );
99363 #endif
99364 {
99365 while( nWrite>0 ){
99366 FileChunk *pChunk = p->endpoint.pChunk;
99367 int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
99368 int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
99369
 
99370 if( iChunkOffset==0 ){
99371 /* New chunk is required to extend the file. */
99372 FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
99373 if( !pNew ){
99374 return SQLITE_IOERR_NOMEM_BKPT;
@@ -99379,14 +100187,15 @@
99379 pChunk->pNext = pNew;
99380 }else{
99381 assert( !p->pFirst );
99382 p->pFirst = pNew;
99383 }
99384 p->endpoint.pChunk = pNew;
99385 }
99386
99387 memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
 
99388 zWrite += iSpace;
99389 nWrite -= iSpace;
99390 p->endpoint.iOffset += iSpace;
99391 }
99392 }
@@ -100460,10 +101269,11 @@
100460 }else if( zTab ){
100461 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
100462 }else{
100463 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
100464 }
 
100465 pParse->checkSchema = 1;
100466 pTopNC->nNcErr++;
100467 }
100468
100469 /* If a column from a table in pSrcList is referenced, then record
@@ -100568,11 +101378,12 @@
100568 */
100569 static void notValidImpl(
100570 Parse *pParse, /* Leave error message here */
100571 NameContext *pNC, /* The name context */
100572 const char *zMsg, /* Type of error */
100573 Expr *pExpr /* Invalidate this expression on error */
 
100574 ){
100575 const char *zIn = "partial index WHERE clauses";
100576 if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
100577 #ifndef SQLITE_OMIT_CHECK
100578 else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100580,14 +101391,15 @@
100580 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
100581 else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
100582 #endif
100583 sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
100584 if( pExpr ) pExpr->op = TK_NULL;
 
100585 }
100586 #define sqlite3ResolveNotValid(P,N,M,X,E) \
100587 assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
100588 if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
100589
100590 /*
100591 ** Expression p should encode a floating point value between 1.0 and 0.0.
100592 ** Return 1024 times this value. Or return -1 if p is not a floating point
100593 ** value between 1.0 and 0.0.
@@ -100718,11 +101530,11 @@
100718 }else{
100719 Expr *pLeft = pExpr->pLeft;
100720 testcase( pNC->ncFlags & NC_IdxExpr );
100721 testcase( pNC->ncFlags & NC_GenCol );
100722 sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
100723 NC_IdxExpr|NC_GenCol, 0);
100724 pRight = pExpr->pRight;
100725 if( pRight->op==TK_ID ){
100726 zDb = 0;
100727 }else{
100728 assert( pRight->op==TK_DOT );
@@ -100749,21 +101561,19 @@
100749 ExprList *pList = pExpr->x.pList; /* The argument list */
100750 int n = pList ? pList->nExpr : 0; /* Number of arguments */
100751 int no_such_func = 0; /* True if no such function exists */
100752 int wrong_num_args = 0; /* True if wrong number of arguments */
100753 int is_agg = 0; /* True if is an aggregate function */
100754 int nId; /* Number of characters in function name */
100755 const char *zId; /* The function name. */
100756 FuncDef *pDef; /* Information about the function */
100757 u8 enc = ENC(pParse->db); /* The database encoding */
100758 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100759 #ifndef SQLITE_OMIT_WINDOWFUNC
100760 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100761 #endif
100762 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100763 zId = pExpr->u.zToken;
100764 nId = sqlite3Strlen30(zId);
100765 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100766 if( pDef==0 ){
100767 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
100768 if( pDef==0 ){
100769 no_such_func = 1;
@@ -100776,12 +101586,12 @@
100776 ExprSetProperty(pExpr, EP_Unlikely);
100777 if( n==2 ){
100778 pExpr->iTable = exprProbability(pList->a[1].pExpr);
100779 if( pExpr->iTable<0 ){
100780 sqlite3ErrorMsg(pParse,
100781 "second argument to likelihood() must be a "
100782 "constant between 0.0 and 1.0");
100783 pNC->nNcErr++;
100784 }
100785 }else{
100786 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
100787 ** equivalent to likelihood(X, 0.0625).
@@ -100798,12 +101608,12 @@
100798 #ifndef SQLITE_OMIT_AUTHORIZATION
100799 {
100800 int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
100801 if( auth!=SQLITE_OK ){
100802 if( auth==SQLITE_DENY ){
100803 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
100804 pDef->zName);
100805 pNC->nNcErr++;
100806 }
100807 pExpr->op = TK_NULL;
100808 return WRC_Prune;
100809 }
@@ -100822,11 +101632,11 @@
100822 ** sqlite_version() that might change over time cannot be used
100823 ** in an index or generated column. Curiously, they can be used
100824 ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
100825 ** all this. */
100826 sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
100827 NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
100828 }else{
100829 assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
100830 pExpr->op2 = pNC->ncFlags & NC_SelfRef;
100831 if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
100832 }
@@ -100835,11 +101645,11 @@
100835 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
100836 ){
100837 /* Internal-use-only functions are disallowed unless the
100838 ** SQL is being compiled using sqlite3NestedParse() or
100839 ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
100840 ** used to activate internal functionsn for testing purposes */
100841 no_such_func = 1;
100842 pDef = 0;
100843 }else
100844 if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
100845 && !IN_RENAME_OBJECT
@@ -100854,11 +101664,11 @@
100854 || (pDef->xValue==0 && pDef->xInverse==0)
100855 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
100856 );
100857 if( pDef && pDef->xValue==0 && pWin ){
100858 sqlite3ErrorMsg(pParse,
100859 "%.*s() may not be used as a window function", nId, zId
100860 );
100861 pNC->nNcErr++;
100862 }else if(
100863 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
100864 || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100868,38 +101678,38 @@
100868 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
100869 zType = "window";
100870 }else{
100871 zType = "aggregate";
100872 }
100873 sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
100874 pNC->nNcErr++;
100875 is_agg = 0;
100876 }
100877 #else
100878 if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
100879 sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
100880 pNC->nNcErr++;
100881 is_agg = 0;
100882 }
100883 #endif
100884 else if( no_such_func && pParse->db->init.busy==0
100885 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
100886 && pParse->explain==0
100887 #endif
100888 ){
100889 sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
100890 pNC->nNcErr++;
100891 }else if( wrong_num_args ){
100892 sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
100893 nId, zId);
100894 pNC->nNcErr++;
100895 }
100896 #ifndef SQLITE_OMIT_WINDOWFUNC
100897 else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
100898 sqlite3ErrorMsg(pParse,
100899 "FILTER may not be used with non-aggregate %.*s()",
100900 nId, zId
100901 );
100902 pNC->nNcErr++;
100903 }
100904 #endif
100905 if( is_agg ){
@@ -100980,11 +101790,11 @@
100980 testcase( pNC->ncFlags & NC_IsCheck );
100981 testcase( pNC->ncFlags & NC_PartIdx );
100982 testcase( pNC->ncFlags & NC_IdxExpr );
100983 testcase( pNC->ncFlags & NC_GenCol );
100984 if( pNC->ncFlags & NC_SelfRef ){
100985 notValidImpl(pParse, pNC, "subqueries", pExpr);
100986 }else{
100987 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
100988 }
100989 assert( pNC->nRef>=nRef );
100990 if( nRef!=pNC->nRef ){
@@ -100998,11 +101808,11 @@
100998 testcase( pNC->ncFlags & NC_IsCheck );
100999 testcase( pNC->ncFlags & NC_PartIdx );
101000 testcase( pNC->ncFlags & NC_IdxExpr );
101001 testcase( pNC->ncFlags & NC_GenCol );
101002 sqlite3ResolveNotValid(pParse, pNC, "parameters",
101003 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
101004 break;
101005 }
101006 case TK_IS:
101007 case TK_ISNOT: {
101008 Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101050,15 +101860,17 @@
101050 testcase( pExpr->op==TK_GE );
101051 testcase( pExpr->op==TK_IS );
101052 testcase( pExpr->op==TK_ISNOT );
101053 testcase( pExpr->op==TK_BETWEEN );
101054 sqlite3ErrorMsg(pParse, "row value misused");
 
101055 }
101056 break;
101057 }
101058 }
101059 return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
 
101060 }
101061
101062 /*
101063 ** pEList is a list of expressions which are really the result set of the
101064 ** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
@@ -101162,15 +101974,17 @@
101162 */
101163 static void resolveOutOfRangeError(
101164 Parse *pParse, /* The error context into which to write the error */
101165 const char *zType, /* "ORDER" or "GROUP" */
101166 int i, /* The index (1-based) of the term out of range */
101167 int mx /* Largest permissible value of i */
 
101168 ){
101169 sqlite3ErrorMsg(pParse,
101170 "%r %s BY term out of range - should be "
101171 "between 1 and %d", i, zType, mx);
 
101172 }
101173
101174 /*
101175 ** Analyze the ORDER BY clause in a compound SELECT statement. Modify
101176 ** each term of the ORDER BY clause is a constant integer between 1
@@ -101222,11 +102036,11 @@
101222 if( pItem->done ) continue;
101223 pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
101224 if( NEVER(pE==0) ) continue;
101225 if( sqlite3ExprIsInteger(pE, &iCol) ){
101226 if( iCol<=0 || iCol>pEList->nExpr ){
101227 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
101228 return 1;
101229 }
101230 }else{
101231 iCol = resolveAsName(pParse, pEList, pE);
101232 if( iCol==0 ){
@@ -101318,11 +102132,11 @@
101318 pEList = pSelect->pEList;
101319 assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
101320 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
101321 if( pItem->u.x.iOrderByCol ){
101322 if( pItem->u.x.iOrderByCol>pEList->nExpr ){
101323 resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
101324 return 1;
101325 }
101326 resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
101327 }
101328 }
@@ -101410,11 +102224,11 @@
101410 if( sqlite3ExprIsInteger(pE2, &iCol) ){
101411 /* The ORDER BY term is an integer constant. Again, set the column
101412 ** number so that sqlite3ResolveOrderGroupBy() will convert the
101413 ** order-by term to a copy of the result-set expression */
101414 if( iCol<1 || iCol>0xffff ){
101415 resolveOutOfRangeError(pParse, zType, i+1, nResult);
101416 return 1;
101417 }
101418 pItem->u.x.iOrderByCol = (u16)iCol;
101419 continue;
101420 }
@@ -101468,11 +102282,11 @@
101468 ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and
101469 ** this routine in the correct order.
101470 */
101471 if( (p->selFlags & SF_Expanded)==0 ){
101472 sqlite3SelectPrep(pParse, p, pOuterNC);
101473 return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
101474 }
101475
101476 isCompound = p->pPrior!=0;
101477 nCompound = 0;
101478 pLeftmost = p;
@@ -101516,11 +102330,12 @@
101516 const char *zSavedContext = pParse->zAuthContext;
101517
101518 if( pItem->zName ) pParse->zAuthContext = pItem->zName;
101519 sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
101520 pParse->zAuthContext = zSavedContext;
101521 if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
 
101522
101523 /* If the number of references to the outer context changed when
101524 ** expressions in the sub-select were resolved, the sub-select
101525 ** is correlated. It is not required to check the refcount on any
101526 ** but the innermost outer context object, as lookupName() increments
@@ -102662,13 +103477,12 @@
102662 **
102663 ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
102664 ** if appropriate.
102665 */
102666 static void exprSetHeight(Expr *p){
102667 int nHeight = 0;
102668 heightOfExpr(p->pLeft, &nHeight);
102669 heightOfExpr(p->pRight, &nHeight);
102670 if( ExprUseXSelect(p) ){
102671 heightOfSelect(p->x.pSelect, &nHeight);
102672 }else if( p->x.pList ){
102673 heightOfExprList(p->x.pList, &nHeight);
102674 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -102963,10 +103777,11 @@
102963 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
102964 if( pNew==0 ){
102965 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
102966 return 0;
102967 }
 
102968 if( pList
102969 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
102970 && !pParse->nested
102971 ){
102972 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103006,11 +103821,11 @@
103006 ** (2) not tagged with SQLITE_INNOCUOUS (which means it
103007 ** is tagged with SQLITE_FUNC_UNSAFE) and
103008 ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103009 ** that the schema is possibly tainted).
103010 */
103011 sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
103012 }
103013 }
103014 }
103015
103016 /*
@@ -103062,10 +103877,11 @@
103062 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103063 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103064 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103065 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103066 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
 
103067 return;
103068 }
103069 x = (ynVar)i;
103070 if( x>pParse->nVar ){
103071 pParse->nVar = (int)x;
@@ -103089,10 +103905,11 @@
103089 }
103090 }
103091 pExpr->iColumn = x;
103092 if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103093 sqlite3ErrorMsg(pParse, "too many SQL variables");
 
103094 }
103095 }
103096
103097 /*
103098 ** Recursively delete an expression tree.
@@ -104696,12 +105513,11 @@
104696 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104697 Expr *pRhs = pEList->a[i].pExpr;
104698 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104699 int j;
104700
104701 assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104702 || pParse->nErr || db->mallocFailed );
104703 for(j=0; j<nExpr; j++){
104704 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104705 assert( pIdx->azColl[j] );
104706 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104707 continue;
@@ -104932,12 +105748,11 @@
104932 assert( !ExprUseYWin(pExpr) );
104933 ExprSetProperty(pExpr, EP_Subrtn);
104934 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
104935 pExpr->y.sub.regReturn = ++pParse->nMem;
104936 pExpr->y.sub.iAddr =
104937 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
104938 VdbeComment((v, "return address"));
104939
104940 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
104941 }
104942
104943 /* Check to see if this is a vector IN operator */
@@ -105035,10 +105850,11 @@
105035 ** disable the test that was generated above that makes sure
105036 ** this code only executes once. Because for a non-constant
105037 ** expression we need to rerun this code each time.
105038 */
105039 if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
 
105040 sqlite3VdbeChangeToNoop(v, addrOnce);
105041 ExprClearProperty(pExpr, EP_Subrtn);
105042 addrOnce = 0;
105043 }
105044
@@ -105055,11 +105871,14 @@
105055 }
105056 if( addrOnce ){
105057 sqlite3VdbeJumpHere(v, addrOnce);
105058 /* Subroutine return */
105059 assert( ExprUseYSub(pExpr) );
105060 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
 
 
 
105061 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105062 sqlite3ClearTempRegCache(pParse);
105063 }
105064 }
105065 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105110,13 +105929,11 @@
105110 assert( !ExprUseYWin(pExpr) );
105111 assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105112 ExprSetProperty(pExpr, EP_Subrtn);
105113 pExpr->y.sub.regReturn = ++pParse->nMem;
105114 pExpr->y.sub.iAddr =
105115 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105116 VdbeComment((v, "return address"));
105117
105118
105119 /* The evaluation of the EXISTS/SELECT must be repeated every time it
105120 ** is encountered if any of the following is true:
105121 **
105122 ** * The right-hand side is a correlated subquery
@@ -105173,14 +105990,12 @@
105173 pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
105174 pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
105175 }
105176 pSel->iLimit = 0;
105177 if( sqlite3Select(pParse, pSel, &dest) ){
105178 if( pParse->nErr ){
105179 pExpr->op2 = pExpr->op;
105180 pExpr->op = TK_ERROR;
105181 }
105182 return 0;
105183 }
105184 pExpr->iTable = rReg = dest.iSDParm;
105185 ExprSetVVAProperty(pExpr, EP_NoReduce);
105186 if( addrOnce ){
@@ -105187,11 +106002,14 @@
105187 sqlite3VdbeJumpHere(v, addrOnce);
105188 }
105189
105190 /* Subroutine return */
105191 assert( ExprUseYSub(pExpr) );
105192 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
 
 
 
105193 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105194 sqlite3ClearTempRegCache(pParse);
105195 return rReg;
105196 }
105197 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105393,14 +106211,13 @@
105393 if( destIfNull==destIfFalse ){
105394 destStep2 = destIfFalse;
105395 }else{
105396 destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
105397 }
105398 if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
105399 for(i=0; i<nVector; i++){
105400 Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
105401 if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
105402 if( sqlite3ExprCanBeNull(p) ){
105403 sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
105404 VdbeCoverage(v);
105405 }
105406 }
@@ -105534,15 +106351,16 @@
105534 const char *z = pExpr->u.zToken;
105535 assert( z!=0 );
105536 c = sqlite3DecOrHexToI64(z, &value);
105537 if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
105538 #ifdef SQLITE_OMIT_FLOATING_POINT
105539 sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
105540 #else
105541 #ifndef SQLITE_OMIT_HEX_INTEGER
105542 if( sqlite3_strnicmp(z,"0x",2)==0 ){
105543 sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
 
105544 }else
105545 #endif
105546 {
105547 codeReal(v, z, negFlag, iMem);
105548 }
@@ -106214,11 +107032,11 @@
106214 if( pInfo==0
106215 || NEVER(pExpr->iAgg<0)
106216 || NEVER(pExpr->iAgg>=pInfo->nFunc)
106217 ){
106218 assert( !ExprHasProperty(pExpr, EP_IntValue) );
106219 sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
106220 }else{
106221 return pInfo->aFunc[pExpr->iAgg].iMem;
106222 }
106223 break;
106224 }
@@ -106255,11 +107073,11 @@
106255 if( pDef==0 && pParse->explain ){
106256 pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
106257 }
106258 #endif
106259 if( pDef==0 || pDef->xFinalize!=0 ){
106260 sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
106261 break;
106262 }
106263 if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
106264 assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
106265 assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -108571,11 +109389,13 @@
108571 sqlite3 *db; /* The database connection; */
108572 Vdbe *v; /* The prepared statement under construction */
108573 int r1; /* Temporary registers */
108574
108575 db = pParse->db;
108576 if( pParse->nErr || db->mallocFailed ) return;
 
 
108577 pNew = pParse->pNewTable;
108578 assert( pNew );
108579
108580 assert( sqlite3BtreeHoldsAllMutexes(db) );
108581 iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
@@ -108697,11 +109517,11 @@
108697 sqlite3NestedParse(pParse,
108698 "SELECT CASE WHEN quick_check GLOB 'CHECK*'"
108699 " THEN raise(ABORT,'CHECK constraint failed')"
108700 " ELSE raise(ABORT,'NOT NULL constraint failed')"
108701 " END"
108702 " FROM pragma_quick_check(\"%w\",\"%w\")"
108703 " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'",
108704 zTab, zDb
108705 );
108706 }
108707 }
@@ -108876,11 +109696,11 @@
108876 if( !zOld ) goto exit_rename_column;
108877 for(iCol=0; iCol<pTab->nCol; iCol++){
108878 if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
108879 }
108880 if( iCol==pTab->nCol ){
108881 sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
108882 goto exit_rename_column;
108883 }
108884
108885 /* Ensure the schema contains no double-quoted strings */
108886 renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -108982,11 +109802,13 @@
108982 **
108983 ** Technically, as x no longer points into a valid object or to the byte
108984 ** following a valid object, it may not be used in comparison operations.
108985 */
108986 static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
108987 if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
 
 
108988 const RenameToken *p;
108989 u8 i = 0;
108990 for(p=pParse->pRename; p; p=p->pNext){
108991 if( p->p ){
108992 assert( p->p!=pPtr );
@@ -109304,16 +110126,16 @@
109304 ){
109305 const char *zT = (const char*)sqlite3_value_text(pType);
109306 const char *zN = (const char*)sqlite3_value_text(pObject);
109307 char *zErr;
109308
109309 zErr = sqlite3_mprintf("error in %s %s%s%s: %s",
109310 zT, zN, (zWhen[0] ? " " : ""), zWhen,
109311 pParse->zErrMsg
109312 );
109313 sqlite3_result_error(pCtx, zErr, -1);
109314 sqlite3_free(zErr);
109315 }
109316
109317 /*
109318 ** For each name in the the expression-list pEList (i.e. each
109319 ** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109374,23 +110196,25 @@
109374 const char *zSql, /* SQL to parse */
109375 int bTemp /* True if SQL is from temp schema */
109376 ){
109377 int rc;
109378
 
 
 
 
 
 
 
109379 db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
109380
109381 /* Parse the SQL statement passed as the first argument. If no error
109382 ** occurs and the parse does not result in a new table, index or
109383 ** trigger object, the database must be corrupt. */
109384 memset(p, 0, sizeof(Parse));
109385 p->eParseMode = PARSE_MODE_RENAME;
109386 p->db = db;
109387 p->nQueryLoop = 1;
109388 rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM;
109389 if( db->mallocFailed ) rc = SQLITE_NOMEM;
109390 if( rc==SQLITE_OK
109391 && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
109392 ){
109393 rc = SQLITE_CORRUPT_BKPT;
109394 }
109395
109396 #ifdef SQLITE_DEBUG
@@ -109664,17 +110488,17 @@
109664 sqlite3FreeIndex(db, pIdx);
109665 }
109666 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
109667 sqlite3DbFree(db, pParse->zErrMsg);
109668 renameTokenFree(db, pParse->pRename);
109669 sqlite3ParserReset(pParse);
109670 }
109671
109672 /*
109673 ** SQL function:
109674 **
109675 ** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
109676 **
109677 ** 0. zSql: SQL statement to rewrite
109678 ** 1. type: Type of object ("table", "view" etc.)
109679 ** 2. object: Name of object
109680 ** 3. Database: Database name (e.g. "main")
@@ -109688,11 +110512,12 @@
109688 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
109689 ** into zNew. The name should be quoted if bQuote is true.
109690 **
109691 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
109692 ** It is only accessible to SQL created using sqlite3NestedParse(). It is
109693 ** not reachable from ordinary SQL passed into sqlite3_prepare().
 
109694 */
109695 static void renameColumnFunc(
109696 sqlite3_context *context,
109697 int NotUsed,
109698 sqlite3_value **argv
@@ -109837,11 +110662,13 @@
109837 assert( rc==SQLITE_OK );
109838 rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
109839
109840 renameColumnFunc_done:
109841 if( rc!=SQLITE_OK ){
109842 if( sParse.zErrMsg ){
 
 
109843 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
109844 }else{
109845 sqlite3_result_error_code(context, rc);
109846 }
109847 }
@@ -110036,11 +110863,13 @@
110036
110037 if( rc==SQLITE_OK ){
110038 rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110039 }
110040 if( rc!=SQLITE_OK ){
110041 if( sParse.zErrMsg ){
 
 
110042 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110043 }else{
110044 sqlite3_result_error_code(context, rc);
110045 }
110046 }
@@ -110061,14 +110890,14 @@
110061 renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110062 }
110063 return WRC_Continue;
110064 }
110065
110066 /*
110067 ** The implementation of an SQL scalar function that rewrites DDL statements
110068 ** so that any string literals that use double-quotes are modified so that
110069 ** they use single quotes.
110070 **
110071 ** Two arguments must be passed:
110072 **
110073 ** 0: Database name ("main", "temp" etc.).
110074 ** 1: SQL statement to edit.
@@ -110083,10 +110912,14 @@
110083 ** );
110084 **
110085 ** returns the string:
110086 **
110087 ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
 
 
 
 
110088 */
110089 static void renameQuotefixFunc(
110090 sqlite3_context *context,
110091 int NotUsed,
110092 sqlite3_value **argv
@@ -110157,11 +110990,15 @@
110157 rc = renameEditSql(context, &sCtx, zInput, 0, 0);
110158 }
110159 renameTokenFree(db, sCtx.pList);
110160 }
110161 if( rc!=SQLITE_OK ){
110162 sqlite3_result_error_code(context, rc);
 
 
 
 
110163 }
110164 renameParseCleanup(&sParse);
110165 }
110166
110167 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110169,11 +111006,12 @@
110169 #endif
110170
110171 sqlite3BtreeLeaveAll(db);
110172 }
110173
110174 /*
 
110175 ** An SQL user function that checks that there are no parse or symbol
110176 ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
110177 ** After an ALTER TABLE .. RENAME operation is performed and the schema
110178 ** reloaded, this function is called on each SQL statement in the schema
110179 ** to ensure that it is still usable.
@@ -110184,15 +111022,17 @@
110184 ** 3: Object name.
110185 ** 4: True if object is from temp schema.
110186 ** 5: "when" part of error message.
110187 ** 6: True to disable the DQS quirk when parsing SQL.
110188 **
110189 ** Unless it finds an error, this function normally returns NULL. However, it
110190 ** returns integer value 1 if:
110191 **
110192 ** * the SQL argument creates a trigger, and
110193 ** * the table that the trigger is attached to is in database zDb.
 
 
 
110194 */
110195 static void renameTableTest(
110196 sqlite3_context *context,
110197 int NotUsed,
110198 sqlite3_value **argv
@@ -110233,16 +111073,20 @@
110233 rc = renameResolveTrigger(&sParse);
110234 }
110235 if( rc==SQLITE_OK ){
110236 int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
110237 int i2 = sqlite3FindDbName(db, zDb);
110238 if( i1==i2 ) sqlite3_result_int(context, 1);
 
 
 
110239 }
110240 }
110241 }
110242
110243 if( rc!=SQLITE_OK && zWhen ){
 
110244 renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
110245 }
110246 renameParseCleanup(&sParse);
110247 }
110248
@@ -110354,11 +111198,11 @@
110354 assert( db->mallocFailed );
110355 goto exit_drop_column;
110356 }
110357 iCol = sqlite3ColumnIndex(pTab, zCol);
110358 if( iCol<0 ){
110359 sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
110360 goto exit_drop_column;
110361 }
110362
110363 /* Do not allow the user to drop a PRIMARY KEY column or a column
110364 ** constrained by a UNIQUE constraint. */
@@ -110378,10 +111222,16 @@
110378
110379 /* Edit the sqlite_schema table */
110380 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
110381 assert( iDb>=0 );
110382 zDb = db->aDb[iDb].zDbSName;
 
 
 
 
 
 
110383 renameTestSchema(pParse, zDb, iDb==1, "", 0);
110384 renameFixQuotes(pParse, zDb, iDb==1);
110385 sqlite3NestedParse(pParse,
110386 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
110387 "sql = sqlite_drop_column(%d, sql, %d) "
@@ -111501,11 +112351,11 @@
111501 if( pStat1==0 ) return;
111502 pStat1->zName = (char*)&pStat1[1];
111503 memcpy(pStat1->zName, "sqlite_stat1", 13);
111504 pStat1->nCol = 3;
111505 pStat1->iPKey = -1;
111506 sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
111507 }
111508 #endif
111509
111510 /* Establish a read-lock on the table at the shared-cache level.
111511 ** Open a read-only cursor on the table. Also allocate a cursor number
@@ -112765,11 +113615,11 @@
112765 ){
112766 goto attach_end;
112767 }
112768
112769 #ifndef SQLITE_OMIT_AUTHORIZATION
112770 if( pAuthArg ){
112771 char *zAuthArg;
112772 if( pAuthArg->op==TK_STRING ){
112773 assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
112774 zAuthArg = pAuthArg->u.zToken;
112775 }else{
@@ -113426,15 +114276,17 @@
113426 sqlite3 *db;
113427 Vdbe *v;
113428
113429 assert( pParse->pToplevel==0 );
113430 db = pParse->db;
 
113431 if( pParse->nested ) return;
113432 if( db->mallocFailed || pParse->nErr ){
113433 if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
113434 return;
113435 }
 
113436
113437 /* Begin by generating some termination code at the end of the
113438 ** vdbe program
113439 */
113440 v = pParse->pVdbe;
@@ -113563,11 +114415,13 @@
113563 }
113564 }
113565
113566 /* Get the VDBE program ready for execution
113567 */
113568 if( v && pParse->nErr==0 && !db->mallocFailed ){
 
 
113569 /* A minimum of one cursor is required if autoincrement is used
113570 * See ticket [a696379c1f08866] */
113571 assert( pParse->pAinc==0 || pParse->nTab>0 );
113572 sqlite3VdbeMakeReady(v, pParse);
113573 pParse->rc = SQLITE_DONE;
@@ -113612,10 +114466,12 @@
113612 pParse->nested++;
113613 memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
113614 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
113615 db->mDbFlags |= DBFLAG_PreferBuiltin;
113616 sqlite3RunParser(pParse, zSql);
 
 
113617 db->mDbFlags = savedDbFlags;
113618 sqlite3DbFree(db, zSql);
113619 memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
113620 pParse->nested--;
113621 }
@@ -114572,11 +115428,12 @@
114572 goto begin_table_error;
114573 }
114574 pTable = sqlite3FindTable(db, zName, zDb);
114575 if( pTable ){
114576 if( !noErr ){
114577 sqlite3ErrorMsg(pParse, "table %T already exists", pName);
 
114578 }else{
114579 assert( !db->init.busy || CORRUPT_DB );
114580 sqlite3CodeVerifySchema(pParse, iDb);
114581 sqlite3ForceNotReadOnly(pParse);
114582 }
@@ -115667,14 +116524,15 @@
115667 pList->a[0].sortFlags = pParse->iPkSortOrder;
115668 assert( pParse->pNewTable==pTab );
115669 pTab->iPKey = -1;
115670 sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
115671 SQLITE_IDXTYPE_PRIMARYKEY);
115672 if( db->mallocFailed || pParse->nErr ){
115673 pTab->tabFlags &= ~TF_WithoutRowid;
115674 return;
115675 }
 
115676 pPk = sqlite3PrimaryKeyIndex(pTab);
115677 assert( pPk->nKeyCol==1 );
115678 }else{
115679 pPk = sqlite3PrimaryKeyIndex(pTab);
115680 assert( pPk!=0 );
@@ -116101,10 +116959,15 @@
116101 int regRec; /* A record to be insert into the new table */
116102 int regRowid; /* Rowid of the next row to insert */
116103 int addrInsLoop; /* Top of the loop for inserting rows */
116104 Table *pSelTab; /* A table that describes the SELECT results */
116105
 
 
 
 
 
116106 regYield = ++pParse->nMem;
116107 regRec = ++pParse->nMem;
116108 regRowid = ++pParse->nMem;
116109 assert(pParse->nTab==1);
116110 sqlite3MayAbort(pParse);
@@ -116411,14 +117274,14 @@
116411 ** normally holds CHECK constraints on an ordinary table, but for
116412 ** a VIEW it holds the list of column names.
116413 */
116414 sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
116415 &pTable->nCol, &pTable->aCol);
116416 if( db->mallocFailed==0
116417 && pParse->nErr==0
116418 && pTable->nCol==pSel->pEList->nExpr
116419 ){
 
116420 sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
116421 SQLITE_AFF_NONE);
116422 }
116423 }else{
116424 /* CREATE VIEW name AS... without an argument list. Construct
@@ -117033,11 +117896,11 @@
117033 tnum = (Pgno)memRootPage;
117034 }else{
117035 tnum = pIndex->tnum;
117036 }
117037 pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
117038 assert( pKey!=0 || db->mallocFailed || pParse->nErr );
117039
117040 /* Open the sorter cursor if we are to use one. */
117041 iSorter = pParse->nTab++;
117042 sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
117043 sqlite3KeyInfoRef(pKey), P4_KEYINFO);
@@ -117197,13 +118060,15 @@
117197 int nExtra = 0; /* Space allocated for zExtra[] */
117198 int nExtraCol; /* Number of extra columns needed */
117199 char *zExtra = 0; /* Extra space after the Index object */
117200 Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
117201
117202 if( db->mallocFailed || pParse->nErr>0 ){
 
117203 goto exit_create_index;
117204 }
 
117205 if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
117206 goto exit_create_index;
117207 }
117208 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
117209 goto exit_create_index;
@@ -117263,11 +118128,10 @@
117263 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
117264 }
117265 pDb = &db->aDb[iDb];
117266
117267 assert( pTab!=0 );
117268 assert( pParse->nErr==0 );
117269 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
117270 && db->init.busy==0
117271 && pTblName!=0
117272 #if SQLITE_USER_AUTHENTICATION
117273 && sqlite3UserAuthTable(pTab->zName)==0
@@ -117827,14 +118691,14 @@
117827 Index *pIndex;
117828 Vdbe *v;
117829 sqlite3 *db = pParse->db;
117830 int iDb;
117831
117832 assert( pParse->nErr==0 ); /* Never called with prior errors */
117833 if( db->mallocFailed ){
117834 goto exit_drop_index;
117835 }
 
117836 assert( pName->nSrc==1 );
117837 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
117838 goto exit_drop_index;
117839 }
117840 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
@@ -119746,13 +120610,15 @@
119746 Trigger *pTrigger; /* List of table triggers, if required */
119747 #endif
119748
119749 memset(&sContext, 0, sizeof(sContext));
119750 db = pParse->db;
119751 if( pParse->nErr || db->mallocFailed ){
 
119752 goto delete_from_cleanup;
119753 }
 
119754 assert( pTabList->nSrc==1 );
119755
119756
119757 /* Locate the table which we want to delete. This table has to be
119758 ** put in an SrcList structure because some of the subroutines we
@@ -119929,11 +120795,11 @@
119929 **
119930 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
119931 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
119932 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
119933 */
119934 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
119935 if( pWInfo==0 ) goto delete_from_cleanup;
119936 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
119937 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
119938 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
119939 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120542,10 +121408,11 @@
120542 static void subtypeFunc(
120543 sqlite3_context *context,
120544 int argc,
120545 sqlite3_value **argv
120546 ){
 
120547 sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
120548 }
120549
120550 /*
120551 ** Implementation of the length() function
@@ -121555,12 +122422,13 @@
121555 UNUSED_PARAMETER(argc);
121556 sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
121557 sqlite3QuoteValue(&str,argv[0]);
121558 sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
121559 SQLITE_DYNAMIC);
121560 if( str.accError==SQLITE_NOMEM ){
121561 sqlite3_result_error_nomem(context);
 
121562 }
121563 }
121564
121565 /*
121566 ** The unicode() function. Return the integer unicode code-point value
@@ -122675,12 +123543,12 @@
122675 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
122676 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122677 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122678 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122679 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
122680 FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
122681 SQLITE_FUNC_TYPEOF),
122682 #endif
122683 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
122684 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
122685 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
122686 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123472,11 +124340,11 @@
123472
123473 /* Create VDBE to loop through the entries in pSrc that match the WHERE
123474 ** clause. For each row found, increment either the deferred or immediate
123475 ** foreign key constraint counter. */
123476 if( pParse->nErr==0 ){
123477 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
123478 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
123479 if( pWInfo ){
123480 sqlite3WhereEnd(pWInfo);
123481 }
123482 }
@@ -124480,11 +125348,11 @@
124480 sqlite3OomFault(db);
124481 return;
124482 }
124483
124484 for(i=j=0; i<pTab->nCol; i++){
124485 assert( pTab->aCol[i].affinity!=0 );
124486 if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
124487 zColAff[j++] = pTab->aCol[i].affinity;
124488 }
124489 }
124490 do{
@@ -125014,13 +125882,15 @@
125014 Trigger *pTrigger; /* List of triggers on pTab, if required */
125015 int tmask; /* Mask of trigger times */
125016 #endif
125017
125018 db = pParse->db;
125019 if( pParse->nErr || db->mallocFailed ){
 
125020 goto insert_cleanup;
125021 }
 
125022 dest.iSDParm = 0; /* Suppress a harmless compiler warning */
125023
125024 /* If the Select object is really just a simple VALUES() list with a
125025 ** single row (the common case) then keep that one row of values
125026 ** and discard the other (unused) parts of the pSelect object
@@ -125092,11 +125962,15 @@
125092 ** Then special optimizations can be applied that make the transfer
125093 ** very fast and which reduce fragmentation of indices.
125094 **
125095 ** This is the 2nd template.
125096 */
125097 if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
 
 
 
 
125098 assert( !pTrigger );
125099 assert( pList==0 );
125100 goto insert_end;
125101 }
125102 #endif /* SQLITE_OMIT_XFER_OPT */
@@ -125192,11 +126066,13 @@
125192 sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
125193 dest.iSdst = bIdListInOrder ? regData : 0;
125194 dest.nSdst = pTab->nCol;
125195 rc = sqlite3Select(pParse, pSelect, &dest);
125196 regFromSelect = dest.iSdst;
125197 if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
 
 
125198 sqlite3VdbeEndCoroutine(v, regYield);
125199 sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
125200 assert( pSelect->pEList );
125201 nColumn = pSelect->pEList->nExpr;
125202
@@ -126573,11 +127449,11 @@
126573 }
126574 }
126575 if( isUpdate ){
126576 /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
126577 ** table, only conflict if the new PRIMARY KEY values are actually
126578 ** different from the old.
126579 **
126580 ** For a UNIQUE index, only conflict if the PRIMARY KEY values
126581 ** of the matched index row are different from the original PRIMARY
126582 ** KEY values of this row before the update. */
126583 int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127061,22 +127937,17 @@
127061 Vdbe *v; /* The VDBE we are building */
127062 int regAutoinc; /* Memory register used by AUTOINC */
127063 int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127064 int regData, regRowid; /* Registers holding data and rowid */
127065
127066 if( pSelect==0 ){
127067 return 0; /* Must be of the form INSERT INTO ... SELECT ... */
127068 }
127069 if( pParse->pWith || pSelect->pWith ){
127070 /* Do not attempt to process this query if there are an WITH clauses
127071 ** attached to it. Proceeding may generate a false "no such table: xxx"
127072 ** error if pSelect reads from a CTE named "xxx". */
127073 return 0;
127074 }
127075 if( sqlite3TriggerList(pParse, pDest) ){
127076 return 0; /* tab1 must not have triggers */
127077 }
127078 #ifndef SQLITE_OMIT_VIRTUALTABLE
127079 if( IsVirtual(pDest) ){
127080 return 0; /* tab1 must not be a virtual table */
127081 }
127082 #endif
@@ -127937,10 +128808,20 @@
127937 int (*autovacuum_pages)(sqlite3*,
127938 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127939 void*, void(*)(void*));
127940 /* Version 3.38.0 and later */
127941 int (*error_offset)(sqlite3*);
 
 
 
 
 
 
 
 
 
 
127942 };
127943
127944 /*
127945 ** This is the function signature used for all extension entry points. It
127946 ** is also defined in the file "loadext.c".
@@ -128250,10 +129131,19 @@
128250 #define sqlite3_total_changes64 sqlite3_api->total_changes64
128251 /* Version 3.37.0 and later */
128252 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
128253 /* Version 3.38.0 and later */
128254 #define sqlite3_error_offset sqlite3_api->error_offset
 
 
 
 
 
 
 
 
 
128255 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
128256
128257 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
128258 /* This case when the file really is being compiled as a loadable
128259 ** extension */
@@ -128741,10 +129631,23 @@
128741 sqlite3_total_changes64,
128742 /* Version 3.37.0 and later */
128743 sqlite3_autovacuum_pages,
128744 /* Version 3.38.0 and later */
128745 sqlite3_error_offset,
 
 
 
 
 
 
 
 
 
 
 
 
 
128746 };
128747
128748 /* True if x is the directory separator character
128749 */
128750 #if SQLITE_OS_WIN
@@ -129411,11 +130314,11 @@
129411 /* iArg: */ BTREE_DATA_VERSION },
129412 #endif
129413 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
129414 {/* zName: */ "database_list",
129415 /* ePragTyp: */ PragTyp_DATABASE_LIST,
129416 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
129417 /* ColNames: */ 47, 3,
129418 /* iArg: */ 0 },
129419 #endif
129420 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
129421 {/* zName: */ "default_cache_size",
@@ -130099,19 +131002,20 @@
130099 Vdbe *v, /* The prepared statement being created */
130100 FuncDef *p, /* A particular function definition */
130101 int isBuiltin, /* True if this is a built-in function */
130102 int showInternFuncs /* True if showing internal functions */
130103 ){
 
 
 
 
 
 
 
 
130104 for(; p; p=p->pNext){
130105 const char *zType;
130106 static const u32 mask =
130107 SQLITE_DETERMINISTIC |
130108 SQLITE_DIRECTONLY |
130109 SQLITE_SUBTYPE |
130110 SQLITE_INNOCUOUS |
130111 SQLITE_FUNC_INTERNAL
130112 ;
130113 static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
130114
130115 assert( SQLITE_FUNC_ENCMASK==0x3 );
130116 assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
130117 assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -131042,10 +131946,14 @@
131042 sqlite3_stmt *pDummy = 0;
131043 (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
131044 (void)sqlite3_finalize(pDummy);
131045 sqlite3DbFree(db, zSql);
131046 }
 
 
 
 
131047 pHash = &db->aDb[ii].pSchema->tblHash;
131048 break;
131049 }
131050 }
131051 }
@@ -133078,12 +133986,14 @@
133078 }
133079
133080 /*
133081 ** Free all memory allocations in the pParse object
133082 */
133083 SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
133084 sqlite3 *db = pParse->db;
 
 
133085 assert( pParse->nested==0 );
133086 #ifndef SQLITE_OMIT_SHARED_CACHE
133087 sqlite3DbFree(db, pParse->aTableLock);
133088 #endif
133089 while( pParse->pCleanup ){
@@ -133094,15 +134004,16 @@
133094 }
133095 sqlite3DbFree(db, pParse->aLabel);
133096 if( pParse->pConstExpr ){
133097 sqlite3ExprListDelete(db, pParse->pConstExpr);
133098 }
133099 if( db ){
133100 assert( db->lookaside.bDisable >= pParse->disableLookaside );
133101 db->lookaside.bDisable -= pParse->disableLookaside;
133102 db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
133103 }
 
133104 pParse->disableLookaside = 0;
133105 }
133106
133107 /*
133108 ** Add a new cleanup operation to a Parser. The cleanup should happen when
@@ -133111,11 +134022,11 @@
133111 **
133112 ** Use this mechanism for uncommon cleanups. There is a higher setup
133113 ** cost for this mechansim (an extra malloc), so it should not be used
133114 ** for common cleanups that happen on most calls. But for less
133115 ** common cleanups, we save a single NULL-pointer comparison in
133116 ** sqlite3ParserReset(), which reduces the total CPU cycle count.
133117 **
133118 ** If a memory allocation error occurs, then the cleanup happens immediately.
133119 ** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
133120 ** pParse->earlyCleanup flag is set in that case. Calling code show verify
133121 ** that test cases exist for which this happens, to guard against possible
@@ -133150,10 +134061,29 @@
133150 pParse->earlyCleanup = 1;
133151 #endif
133152 }
133153 return pPtr;
133154 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133155
133156 /*
133157 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
133158 */
133159 static int sqlite3Prepare(
@@ -133167,15 +134097,19 @@
133167 ){
133168 int rc = SQLITE_OK; /* Result code */
133169 int i; /* Loop counter */
133170 Parse sParse; /* Parsing context */
133171
133172 memset(&sParse, 0, PARSE_HDR_SZ);
 
133173 memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
 
 
 
133174 sParse.pReprepare = pReprepare;
133175 assert( ppStmt && *ppStmt==0 );
133176 /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
133177 assert( sqlite3_mutex_held(db->mutex) );
133178
133179 /* For a long-term use prepared statement avoid the use of
133180 ** lookaside memory.
133181 */
@@ -133224,11 +134158,10 @@
133224 }
133225 }
133226
133227 sqlite3VtabUnlockList(db);
133228
133229 sParse.db = db;
133230 if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
133231 char *zSqlCopy;
133232 int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
133233 testcase( nBytes==mxLen );
133234 testcase( nBytes==mxLen+1 );
@@ -133291,11 +134224,11 @@
133291 sqlite3DbFree(db, pT);
133292 }
133293
133294 end_prepare:
133295
133296 sqlite3ParserReset(&sParse);
133297 return rc;
133298 }
133299 static int sqlite3LockAndPrepare(
133300 sqlite3 *db, /* Database handle. */
133301 const char *zSql, /* UTF-8 encoded SQL statement. */
@@ -133563,11 +134496,11 @@
133563 ** how to process the DISTINCT keyword, to simplify passing that information
133564 ** into the selectInnerLoop() routine.
133565 */
133566 typedef struct DistinctCtx DistinctCtx;
133567 struct DistinctCtx {
133568 u8 isTnct; /* True if the DISTINCT keyword is present */
133569 u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
133570 int tabTnct; /* Ephemeral table used for DISTINCT processing */
133571 int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
133572 };
133573
@@ -133896,29 +134829,29 @@
133896 ** sqlite3PExpr(). */
133897 if( pEq && isOuterJoin ){
133898 ExprSetProperty(pEq, EP_FromJoin);
133899 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
133900 ExprSetVVAProperty(pEq, EP_NoReduce);
133901 pEq->iRightJoinTable = pE2->iTable;
133902 }
133903 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
133904 }
133905
133906 /*
133907 ** Set the EP_FromJoin property on all terms of the given expression.
133908 ** And set the Expr.iRightJoinTable to iTable for every term in the
133909 ** expression.
133910 **
133911 ** The EP_FromJoin property is used on terms of an expression to tell
133912 ** the LEFT OUTER JOIN processing logic that this term is part of the
133913 ** join restriction specified in the ON or USING clause and not a part
133914 ** of the more general WHERE clause. These terms are moved over to the
133915 ** WHERE clause during join processing but we need to remember that they
133916 ** originated in the ON or USING clause.
133917 **
133918 ** The Expr.iRightJoinTable tells the WHERE clause processing that the
133919 ** expression depends on table iRightJoinTable even if that table is not
133920 ** explicitly mentioned in the expression. That information is needed
133921 ** for cases like this:
133922 **
133923 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
133924 **
@@ -133932,11 +134865,11 @@
133932 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
133933 while( p ){
133934 ExprSetProperty(p, EP_FromJoin);
133935 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
133936 ExprSetVVAProperty(p, EP_NoReduce);
133937 p->iRightJoinTable = iTable;
133938 if( p->op==TK_FUNCTION ){
133939 assert( ExprUseXList(p) );
133940 if( p->x.pList ){
133941 int i;
133942 for(i=0; i<p->x.pList->nExpr; i++){
@@ -133948,19 +134881,19 @@
133948 p = p->pRight;
133949 }
133950 }
133951
133952 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
133953 ** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
133954 ** an ordinary term that omits the EP_FromJoin mark.
133955 **
133956 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
133957 */
133958 static void unsetJoinExpr(Expr *p, int iTable){
133959 while( p ){
133960 if( ExprHasProperty(p, EP_FromJoin)
133961 && (iTable<0 || p->iRightJoinTable==iTable) ){
133962 ExprClearProperty(p, EP_FromJoin);
133963 }
133964 if( p->op==TK_COLUMN && p->iTable==iTable ){
133965 ExprClearProperty(p, EP_CanBeNull);
133966 }
@@ -134946,11 +135879,11 @@
134946 p->enc = ENC(db);
134947 p->db = db;
134948 p->nRef = 1;
134949 memset(&p[1], 0, nExtra);
134950 }else{
134951 sqlite3OomFault(db);
134952 }
134953 return p;
134954 }
134955
134956 /*
@@ -135117,10 +136050,13 @@
135117 }
135118 #endif
135119
135120 iTab = pSort->iECursor;
135121 if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
 
 
 
135122 regRowid = 0;
135123 regRow = pDest->iSdst;
135124 }else{
135125 regRowid = sqlite3GetTempReg(pParse);
135126 if( eDest==SRT_EphemTab || eDest==SRT_Table ){
@@ -136162,11 +137098,11 @@
136162 ** (3) There is no ORDER BY clause
136163 **
136164 ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
136165 ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
136166 ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
136167 ** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
136168 */
136169 static int multiSelectValues(
136170 Parse *pParse, /* Parsing context */
136171 Select *p, /* The right-most of SELECTs to be coded */
136172 SelectDest *pDest /* What to do with query results */
@@ -136975,10 +137911,11 @@
136975 }else{
136976 pSplit = p;
136977 for(i=2; i<nSelect; i+=2){ pSplit = pSplit->pPrior; }
136978 }
136979 pPrior = pSplit->pPrior;
 
136980 pSplit->pPrior = 0;
136981 pPrior->pNext = 0;
136982 assert( p->pOrderBy == pOrderBy );
136983 assert( pOrderBy!=0 || db->mallocFailed );
136984 pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
@@ -137186,13 +138123,13 @@
137186 SubstContext *pSubst, /* Description of the substitution */
137187 Expr *pExpr /* Expr in which substitution occurs */
137188 ){
137189 if( pExpr==0 ) return 0;
137190 if( ExprHasProperty(pExpr, EP_FromJoin)
137191 && pExpr->iRightJoinTable==pSubst->iTable
137192 ){
137193 pExpr->iRightJoinTable = pSubst->iNewTable;
137194 }
137195 if( pExpr->op==TK_COLUMN
137196 && pExpr->iTable==pSubst->iTable
137197 && !ExprHasProperty(pExpr, EP_FixedCol)
137198 ){
@@ -137227,11 +138164,11 @@
137227 }
137228 if( pSubst->isLeftJoin ){
137229 ExprSetProperty(pNew, EP_CanBeNull);
137230 }
137231 if( ExprHasProperty(pExpr,EP_FromJoin) ){
137232 sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
137233 }
137234 sqlite3ExprDelete(db, pExpr);
137235 pExpr = pNew;
137236
137237 /* Ensure that the expression now has an implicit collation sequence,
@@ -137392,11 +138329,11 @@
137392 int op = pExpr->op;
137393 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
137394 renumberCursorDoMapping(pWalker, &pExpr->iTable);
137395 }
137396 if( ExprHasProperty(pExpr, EP_FromJoin) ){
137397 renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
137398 }
137399 return WRC_Continue;
137400 }
137401
137402 /*
@@ -138402,15 +139339,17 @@
138402 iCursor, isLeftJoin);
138403 pWhere = pWhere->pLeft;
138404 }
138405 if( isLeftJoin
138406 && (ExprHasProperty(pWhere,EP_FromJoin)==0
138407 || pWhere->iRightJoinTable!=iCursor)
138408 ){
138409 return 0; /* restriction (4) */
138410 }
138411 if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
 
 
138412 return 0; /* restriction (5) */
138413 }
138414 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
138415 nChng++;
138416 pSubq->selFlags |= SF_PushDown;
@@ -139126,11 +140065,12 @@
139126 }
139127 }
139128
139129 /* Process NATURAL keywords, and ON and USING clauses of joins.
139130 */
139131 if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
 
139132 return WRC_Abort;
139133 }
139134
139135 /* For every "*" that occurs in the column list, insert the names of
139136 ** all columns in all tables. And for every TABLE.* insert the names
@@ -139423,16 +140363,17 @@
139423 Parse *pParse, /* The parser context */
139424 Select *p, /* The SELECT statement being coded. */
139425 NameContext *pOuterNC /* Name context for container */
139426 ){
139427 assert( p!=0 || pParse->db->mallocFailed );
 
139428 if( pParse->db->mallocFailed ) return;
139429 if( p->selFlags & SF_HasTypeInfo ) return;
139430 sqlite3SelectExpand(pParse, p);
139431 if( pParse->nErr || pParse->db->mallocFailed ) return;
139432 sqlite3ResolveSelectNames(pParse, p, pOuterNC);
139433 if( pParse->nErr || pParse->db->mallocFailed ) return;
139434 sqlite3SelectAddTypeInfo(pParse, p);
139435 }
139436
139437 /*
139438 ** Reset the aggregate accumulator.
@@ -139445,12 +140386,14 @@
139445 static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
139446 Vdbe *v = pParse->pVdbe;
139447 int i;
139448 struct AggInfo_func *pFunc;
139449 int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
 
 
139450 if( nReg==0 ) return;
139451 if( pParse->nErr || pParse->db->mallocFailed ) return;
139452 #ifdef SQLITE_DEBUG
139453 /* Verify that all AggInfo registers are within the range specified by
139454 ** AggInfo.mnReg..AggInfo.mxReg */
139455 assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
139456 for(i=0; i<pAggInfo->nColumn; i++){
@@ -139869,14 +140812,16 @@
139869 sqlite3 *db; /* The database connection */
139870 ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
139871 u8 minMaxFlag; /* Flag for min/max queries */
139872
139873 db = pParse->db;
 
139874 v = sqlite3GetVdbe(pParse);
139875 if( p==0 || db->mallocFailed || pParse->nErr ){
139876 return 1;
139877 }
 
139878 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
139879 #if SELECTTRACE_ENABLED
139880 SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
139881 if( sqlite3SelectTrace & 0x100 ){
139882 sqlite3TreeViewSelect(0, p, 0);
@@ -139907,13 +140852,14 @@
139907 }
139908 p->selFlags &= ~SF_Distinct;
139909 p->selFlags |= SF_NoopOrderBy;
139910 }
139911 sqlite3SelectPrep(pParse, p, 0);
139912 if( pParse->nErr || db->mallocFailed ){
139913 goto select_end;
139914 }
 
139915 assert( p->pEList!=0 );
139916 #if SELECTTRACE_ENABLED
139917 if( sqlite3SelectTrace & 0x104 ){
139918 SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
139919 sqlite3TreeViewSelect(0, p, 0);
@@ -139953,11 +140899,11 @@
139953 sqlite3GenerateColumnNames(pParse, p);
139954 }
139955
139956 #ifndef SQLITE_OMIT_WINDOWFUNC
139957 if( sqlite3WindowRewrite(pParse, p) ){
139958 assert( db->mallocFailed || pParse->nErr>0 );
139959 goto select_end;
139960 }
139961 #if SELECTTRACE_ENABLED
139962 if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
139963 SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
@@ -140350,10 +141296,11 @@
140350 p->selFlags |= SF_Aggregate;
140351 /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
140352 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
140353 ** original setting of the SF_Distinct flag, not the current setting */
140354 assert( sDistinct.isTnct );
 
140355
140356 #if SELECTTRACE_ENABLED
140357 if( sqlite3SelectTrace & 0x400 ){
140358 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
140359 sqlite3TreeViewSelect(0, p, 0);
@@ -140429,11 +141376,11 @@
140429
140430
140431 /* Begin the database scan. */
140432 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140433 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
140434 p->pEList, wctrlFlags, p->nSelectRow);
140435 if( pWInfo==0 ) goto select_end;
140436 if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
140437 p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
140438 }
140439 if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140693,11 +141640,12 @@
140693 ** in the right order to begin with.
140694 */
140695 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
140696 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140697 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
140698 WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
 
140699 );
140700 if( pWInfo==0 ){
140701 sqlite3ExprListDelete(db, pDistinct);
140702 goto select_end;
140703 }
@@ -140875,11 +141823,11 @@
140875 resetAccumulator(pParse, pAggInfo);
140876 sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
140877 VdbeComment((v, "indicate accumulator empty"));
140878 sqlite3VdbeAddOp1(v, OP_Return, regReset);
140879
140880 if( eDist!=WHERE_DISTINCT_NOOP ){
140881 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
140882 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
140883 }
140884 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
140885 else {
@@ -140991,11 +141939,11 @@
140991 assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
140992 assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
140993
140994 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140995 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
140996 pDistinct, minMaxFlag|distFlag, 0);
140997 if( pWInfo==0 ){
140998 goto select_end;
140999 }
141000 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
141001 eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141048,11 +141996,11 @@
141048 /* Control jumps to here if an error is encountered above, or upon
141049 ** successful coding of the SELECT.
141050 */
141051 select_end:
141052 assert( db->mallocFailed==0 || db->mallocFailed==1 );
141053 pParse->nErr += db->mallocFailed;
141054 sqlite3ExprListDelete(db, pMinMaxOrderBy);
141055 #ifdef SQLITE_DEBUG
141056 if( pAggInfo && !db->mallocFailed ){
141057 for(i=0; i<pAggInfo->nColumn; i++){
141058 Expr *pExpr = pAggInfo->aCol[i].pCExpr;
@@ -141349,15 +142297,14 @@
141349 && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
141350 && pTrig->pTabSchema!=pTmpSchema
141351 ){
141352 pTrig->pNext = pList;
141353 pList = pTrig;
141354 }else if( pTrig->op==TK_RETURNING
141355 #ifndef SQLITE_OMIT_VIRTUALTABLE
141356 && pParse->db->pVtabCtx==0
141357 #endif
141358 ){
141359 assert( pParse->bReturning );
141360 assert( &(pParse->u1.pReturning->retTrig) == pTrig );
141361 pTrig->table = pTab->zName;
141362 pTrig->pTabSchema = pTab->pSchema;
141363 pTrig->pNext = pList;
@@ -141728,10 +142675,11 @@
141728 const char *zEnd /* End of SQL text */
141729 ){
141730 sqlite3 *db = pParse->db;
141731 TriggerStep *pTriggerStep;
141732
 
141733 pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
141734 if( pTriggerStep ){
141735 char *z = (char*)&pTriggerStep[1];
141736 memcpy(z, pName->z, pName->n);
141737 sqlite3Dequote(z);
@@ -142200,10 +143148,11 @@
142200 Select sSelect;
142201 SrcList sFrom;
142202
142203 assert( v!=0 );
142204 assert( pParse->bReturning );
 
142205 pReturning = pParse->u1.pReturning;
142206 assert( pTrigger == &(pReturning->retTrig) );
142207 memset(&sSelect, 0, sizeof(sSelect));
142208 memset(&sFrom, 0, sizeof(sFrom));
142209 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
@@ -142210,11 +143159,12 @@
142210 sSelect.pSrc = &sFrom;
142211 sFrom.nSrc = 1;
142212 sFrom.a[0].pTab = pTab;
142213 sFrom.a[0].iCursor = -1;
142214 sqlite3SelectPrep(pParse, &sSelect, 0);
142215 if( db->mallocFailed==0 && pParse->nErr==0 ){
 
142216 sqlite3GenerateColumnNames(pParse, &sSelect);
142217 }
142218 sqlite3ExprListDelete(db, sSelect.pEList);
142219 pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
142220 if( !db->mallocFailed ){
@@ -142228,11 +143178,11 @@
142228 sNC.uNC.iBaseReg = regIn;
142229 sNC.ncFlags = NC_UBaseReg;
142230 pParse->eTriggerOp = pTrigger->op;
142231 pParse->pTriggerTab = pTab;
142232 if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK
142233 && !db->mallocFailed
142234 ){
142235 int i;
142236 int nCol = pNew->nExpr;
142237 int reg = pParse->nMem+1;
142238 pParse->nMem += nCol+2;
@@ -142392,12 +143342,12 @@
142392 TriggerPrg *pPrg; /* Value to return */
142393 Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
142394 Vdbe *v; /* Temporary VM */
142395 NameContext sNC; /* Name context for sub-vdbe */
142396 SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
142397 Parse *pSubParse; /* Parse context for sub-vdbe */
142398 int iEndTrigger = 0; /* Label to jump to if WHEN is false */
 
142399
142400 assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
142401 assert( pTop->pVdbe );
142402
142403 /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
@@ -142415,23 +143365,21 @@
142415 pPrg->aColmask[0] = 0xffffffff;
142416 pPrg->aColmask[1] = 0xffffffff;
142417
142418 /* Allocate and populate a new Parse context to use for coding the
142419 ** trigger sub-program. */
142420 pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
142421 if( !pSubParse ) return 0;
142422 memset(&sNC, 0, sizeof(sNC));
142423 sNC.pParse = pSubParse;
142424 pSubParse->db = db;
142425 pSubParse->pTriggerTab = pTab;
142426 pSubParse->pToplevel = pTop;
142427 pSubParse->zAuthContext = pTrigger->zName;
142428 pSubParse->eTriggerOp = pTrigger->op;
142429 pSubParse->nQueryLoop = pParse->nQueryLoop;
142430 pSubParse->disableVtab = pParse->disableVtab;
142431
142432 v = sqlite3GetVdbe(pSubParse);
142433 if( v ){
142434 VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
142435 pTrigger->zName, onErrorText(orconf),
142436 (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
142437 (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
@@ -142453,42 +143401,43 @@
142453 if( pTrigger->pWhen ){
142454 pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
142455 if( db->mallocFailed==0
142456 && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
142457 ){
142458 iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
142459 sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
142460 }
142461 sqlite3ExprDelete(db, pWhen);
142462 }
142463
142464 /* Code the trigger program into the sub-vdbe. */
142465 codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
142466
142467 /* Insert an OP_Halt at the end of the sub-program. */
142468 if( iEndTrigger ){
142469 sqlite3VdbeResolveLabel(v, iEndTrigger);
142470 }
142471 sqlite3VdbeAddOp0(v, OP_Halt);
142472 VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
 
142473
142474 transferParseError(pParse, pSubParse);
142475 if( db->mallocFailed==0 && pParse->nErr==0 ){
142476 pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
142477 }
142478 pProgram->nMem = pSubParse->nMem;
142479 pProgram->nCsr = pSubParse->nTab;
142480 pProgram->token = (void *)pTrigger;
142481 pPrg->aColmask[0] = pSubParse->oldmask;
142482 pPrg->aColmask[1] = pSubParse->newmask;
142483 sqlite3VdbeDelete(v);
 
 
142484 }
142485
142486 assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
142487 sqlite3ParserReset(pSubParse);
142488 sqlite3StackFree(db, pSubParse);
142489
142490 return pPrg;
142491 }
142492
142493 /*
142494 ** Return a pointer to a TriggerPrg object containing the sub-program for
@@ -142517,10 +143466,11 @@
142517 );
142518
142519 /* If an existing TriggerPrg could not be located, create a new one. */
142520 if( !pPrg ){
142521 pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
 
142522 }
142523
142524 return pPrg;
142525 }
142526
@@ -142539,11 +143489,11 @@
142539 int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
142540 ){
142541 Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
142542 TriggerPrg *pPrg;
142543 pPrg = getRowTrigger(pParse, p, pTab, orconf);
142544 assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
142545
142546 /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
142547 ** is a pointer to the sub-vdbe containing the trigger program. */
142548 if( pPrg ){
142549 int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
@@ -143057,13 +144007,15 @@
143057 int regRowSet = 0; /* Rowset of rows to be updated */
143058 int regKey = 0; /* composite PRIMARY KEY value */
143059
143060 memset(&sContext, 0, sizeof(sContext));
143061 db = pParse->db;
143062 if( pParse->nErr || db->mallocFailed ){
 
143063 goto update_cleanup;
143064 }
 
143065
143066 /* Locate the table which we want to update.
143067 */
143068 pTab = sqlite3SrcListLookup(pParse, pTabList);
143069 if( pTab==0 ) goto update_cleanup;
@@ -143431,11 +144383,11 @@
143431 ** or index, causing a single-pass approach to malfunction. */
143432 flags = WHERE_ONEPASS_DESIRED;
143433 if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
143434 flags |= WHERE_ONEPASS_MULTIROW;
143435 }
143436 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
143437 if( pWInfo==0 ) goto update_cleanup;
143438
143439 /* A one-pass strategy that might update more than one row may not
143440 ** be used if any column of the index used for the scan is being
143441 ** updated. Otherwise, if there is an index on "b", statements like
@@ -143953,11 +144905,13 @@
143953 }else{
143954 regRec = ++pParse->nMem;
143955 regRowid = ++pParse->nMem;
143956
143957 /* Start scanning the virtual table */
143958 pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
 
 
143959 if( pWInfo==0 ) return;
143960
143961 /* Populate the argument registers. */
143962 for(i=0; i<pTab->nCol; i++){
143963 assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145598,13 +146552,13 @@
145598 return SQLITE_MISUSE_BKPT;
145599 }
145600 pTab = pCtx->pTab;
145601 assert( IsVirtual(pTab) );
145602
145603 memset(&sParse, 0, sizeof(sParse));
145604 sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
145605 sParse.db = db;
145606 /* We should never be able to reach this point while loading the
145607 ** schema. Nevertheless, defend against that (turn off db->init.busy)
145608 ** in case a bug arises. */
145609 assert( db->init.busy==0 );
145610 initBusy = db->init.busy;
@@ -145654,11 +146608,11 @@
145654
145655 if( sParse.pVdbe ){
145656 sqlite3VdbeFinalize(sParse.pVdbe);
145657 }
145658 sqlite3DeleteTable(db, sParse.pNewTable);
145659 sqlite3ParserReset(&sParse);
145660 db->init.busy = initBusy;
145661
145662 assert( (rc&0xff)==rc );
145663 rc = sqlite3ApiExit(db, rc);
145664 sqlite3_mutex_leave(db->mutex);
@@ -146265,14 +147219,16 @@
146265 u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
146266 Index *pIndex; /* Index used, or NULL */
146267 } btree;
146268 struct { /* Information for virtual tables */
146269 int idxNum; /* Index number */
146270 u8 needFree; /* True if sqlite3_free(idxStr) is needed */
 
146271 i8 isOrdered; /* True if satisfies ORDER BY */
146272 u16 omitMask; /* Terms that may be omitted */
146273 char *idxStr; /* Index identifier string */
 
146274 } vtab;
146275 } u;
146276 u32 wsFlags; /* WHERE_* flags describing the plan */
146277 u16 nLTerm; /* Number of entries in aLTerm[] */
146278 u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146425,10 +147381,11 @@
146425 #ifdef SQLITE_ENABLE_STAT4
146426 # define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
146427 #else
146428 # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
146429 #endif
 
146430
146431 /*
146432 ** An instance of the WhereScan object is used as an iterator for locating
146433 ** terms in the WHERE clause that are useful to the query planner.
146434 */
@@ -146528,11 +147485,10 @@
146528 ** to construct WhereLoop objects for a particular query.
146529 */
146530 struct WhereLoopBuilder {
146531 WhereInfo *pWInfo; /* Information about this WHERE */
146532 WhereClause *pWC; /* WHERE clause terms */
146533 ExprList *pOrderBy; /* ORDER BY clause */
146534 WhereLoop *pNew; /* Template WhereLoop */
146535 WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
146536 #ifdef SQLITE_ENABLE_STAT4
146537 UnpackedRecord *pRec; /* Probe for stat4 (if required) */
146538 int nRecValid; /* Number of valid fields currently in pRec */
@@ -146596,10 +147552,13 @@
146596 Parse *pParse; /* Parsing and code generating context */
146597 SrcList *pTabList; /* List of tables in the join */
146598 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
146599 ExprList *pResultSet; /* Result set of the query */
146600 Expr *pWhere; /* The complete WHERE clause */
 
 
 
146601 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
146602 int iContinue; /* Jump here to continue with next record */
146603 int iBreak; /* Jump here to break out of the loop */
146604 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
146605 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146681,10 +147640,11 @@
146681
146682 /* whereexpr.c: */
146683 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
146684 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
146685 SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
 
146686 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
146687 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
146688 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
146689 SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
146690 SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146751,10 +147711,11 @@
146751 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
146752 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
146753 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146754 #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146755 #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
 
146756
146757 #endif /* !defined(SQLITE_WHEREINT_H) */
146758
146759 /************** End of whereInt.h ********************************************/
146760 /************** Continuing where we left off in wherecode.c ******************/
@@ -147529,10 +148490,11 @@
147529 sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
147530 VdbeCoverageIf(v, bRev==0);
147531 VdbeCoverageIf(v, bRev!=0);
147532 VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
147533 j = sqlite3VdbeAddOp0(v, OP_Goto);
 
147534 pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
147535 iIdxCur, 0, regBase, nSkip);
147536 VdbeCoverageIf(v, bRev==0);
147537 VdbeCoverageIf(v, bRev!=0);
147538 sqlite3VdbeJumpHere(v, j);
@@ -147561,10 +148523,13 @@
147561 regBase = r1;
147562 }else{
147563 sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
147564 }
147565 }
 
 
 
147566 if( pTerm->eOperator & WO_IN ){
147567 if( pTerm->pExpr->flags & EP_xIsSelect ){
147568 /* No affinity ever needs to be (or should be) applied to a value
147569 ** from the RHS of an "? IN (SELECT ...)" expression. The
147570 ** sqlite3FindInIndex() routine has already ensured that the
@@ -147575,11 +148540,12 @@
147575 Expr *pRight = pTerm->pExpr->pRight;
147576 if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
147577 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
147578 VdbeCoverage(v);
147579 }
147580 if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){
 
147581 if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
147582 zAff[j] = SQLITE_AFF_BLOB;
147583 }
147584 if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
147585 zAff[j] = SQLITE_AFF_BLOB;
@@ -147795,11 +148761,11 @@
147795 ** are also excluded. See codeCursorHintIsOrFunction() for details.
147796 */
147797 if( pTabItem->fg.jointype & JT_LEFT ){
147798 Expr *pExpr = pTerm->pExpr;
147799 if( !ExprHasProperty(pExpr, EP_FromJoin)
147800 || pExpr->iRightJoinTable!=pTabItem->iCursor
147801 ){
147802 sWalker.eCode = 0;
147803 sWalker.xExprCallback = codeCursorHintIsOrFunction;
147804 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
147805 if( sWalker.eCode ) continue;
@@ -147850,18 +148816,26 @@
147850 ** rowid stored in register iRowid.
147851 **
147852 ** Normally, this is just:
147853 **
147854 ** OP_DeferredSeek $iCur $iRowid
 
 
147855 **
147856 ** However, if the scan currently being coded is a branch of an OR-loop and
147857 ** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
147858 ** is set to iIdxCur and P4 is set to point to an array of integers
147859 ** containing one entry for each column of the table cursor iCur is open
147860 ** on. For each table column, if the column is the i'th column of the
147861 ** index, then the corresponding array entry is set to (i+1). If the column
147862 ** does not appear in the index at all, the array entry is set to 0.
 
 
 
 
 
 
147863 */
147864 static void codeDeferredSeek(
147865 WhereInfo *pWInfo, /* Where clause context */
147866 Index *pIdx, /* Index scan is using */
147867 int iCur, /* Cursor for IPK b-tree */
@@ -148122,10 +149096,11 @@
148122 ){
148123 while( ++iLevel < pWInfo->nLevel ){
148124 WhereLevel *pLevel = &pWInfo->a[iLevel];
148125 WhereLoop *pLoop = pLevel->pWLoop;
148126 if( pLevel->regFilter==0 ) continue;
 
148127 /* ,--- Because sqlite3ConstructBloomFilter() has will not have set
148128 ** vvvvv--' pLevel->regFilter if this were true. */
148129 if( NEVER(pLoop->prereq & notReady) ) continue;
148130 if( pLoop->wsFlags & WHERE_IPK ){
148131 WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148256,24 +149231,39 @@
148256 ** to access the data.
148257 */
148258 int iReg; /* P3 Value for OP_VFilter */
148259 int addrNotFound;
148260 int nConstraint = pLoop->nLTerm;
148261 int iIn; /* Counter for IN constraints */
148262
148263 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
148264 addrNotFound = pLevel->addrBrk;
148265 for(j=0; j<nConstraint; j++){
148266 int iTarget = iReg+j+2;
148267 pTerm = pLoop->aLTerm[j];
148268 if( NEVER(pTerm==0) ) continue;
148269 if( pTerm->eOperator & WO_IN ){
148270 codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
148271 addrNotFound = pLevel->addrNxt;
 
 
 
 
 
 
 
148272 }else{
148273 Expr *pRight = pTerm->pExpr->pRight;
148274 codeExprOrVector(pParse, pRight, iTarget, 1);
 
 
 
 
 
 
 
 
 
148275 }
148276 }
148277 sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
148278 sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
148279 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148286,61 +149276,71 @@
148286 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
148287 pLevel->p1 = iCur;
148288 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
148289 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148290 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148291 if( pLoop->wsFlags & WHERE_IN_ABLE ){
148292 iIn = pLevel->u.in.nIn;
148293 }else{
148294 iIn = 0;
148295 }
148296 for(j=nConstraint-1; j>=0; j--){
148297 pTerm = pLoop->aLTerm[j];
148298 if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
148299 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
148300 disableTerm(pLevel, pTerm);
148301 }else if( (pTerm->eOperator & WO_IN)!=0
148302 && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
 
 
 
148303 ){
148304 Expr *pCompare; /* The comparison operator */
148305 Expr *pRight; /* RHS of the comparison */
148306 VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
 
148307
148308 /* Reload the constraint value into reg[iReg+j+2]. The same value
148309 ** was loaded into the same register prior to the OP_VFilter, but
148310 ** the xFilter implementation might have changed the datatype or
148311 ** encoding of the value in the register, so it *must* be reloaded. */
148312 assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
148313 if( !db->mallocFailed ){
148314 assert( iIn>=0 && iIn<pLevel->u.in.nIn );
148315 pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
148316 assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
148317 assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
148318 assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
148319 testcase( pOp->opcode==OP_Rowid );
148320 sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
 
 
148321 }
148322
148323 /* Generate code that will continue to the next row if
148324 ** the IN constraint is not satisfied */
 
148325 pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
148326 assert( pCompare!=0 || db->mallocFailed );
148327 if( pCompare ){
148328 pCompare->pLeft = pTerm->pExpr->pLeft;
 
 
 
 
 
 
 
 
 
148329 pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
148330 if( pRight ){
148331 pRight->iTable = iReg+j+2;
148332 sqlite3ExprIfFalse(
148333 pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
148334 );
148335 }
148336 pCompare->pLeft = 0;
148337 sqlite3ExprDelete(db, pCompare);
148338 }
 
148339 }
148340 }
148341 assert( iIn==0 || db->mallocFailed );
148342 /* These registers need to be preserved in case there is an IN operator
148343 ** loop. So we could deallocate the registers here (and potentially
148344 ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
148345 ** simpler and safer to simply not reuse the registers.
148346 **
@@ -149028,11 +150028,11 @@
149028 regRowid = ++pParse->nMem;
149029 }
149030 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
149031
149032 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
149033 ** Then for every term xN, evaluate as the subexpression: xN AND z
149034 ** That way, terms in y that are factored into the disjunction will
149035 ** be picked up by the recursive calls to sqlite3WhereBegin() below.
149036 **
149037 ** Actually, each subexpression is converted to "xN AND w" where w is
149038 ** the "interesting" terms of z - terms that did not originate in the
@@ -149040,21 +150040,38 @@
149040 ** indices.
149041 **
149042 ** This optimization also only applies if the (x1 OR x2 OR ...) term
149043 ** is not contained in the ON clause of a LEFT JOIN.
149044 ** See ticket http://www.sqlite.org/src/info/f2369304e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149045 */
149046 if( pWC->nTerm>1 ){
149047 int iTerm;
149048 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
149049 Expr *pExpr = pWC->a[iTerm].pExpr;
149050 if( &pWC->a[iTerm] == pTerm ) continue;
149051 testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
149052 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
149053 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
 
 
 
149054 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
149055 testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
149056 pExpr = sqlite3ExprDup(db, pExpr, 0);
149057 pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
149058 }
149059 if( pAndExpr ){
149060 /* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149091,13 +150108,13 @@
149091 pOrExpr = pAndExpr;
149092 }
149093 /* Loop through table entries that match term pOrTerm. */
149094 ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
149095 WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
149096 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
149097 WHERE_OR_SUBCLAUSE, iCovCur);
149098 assert( pSubWInfo || pParse->nErr || db->mallocFailed );
149099 if( pSubWInfo ){
149100 WhereLoop *pSubLoop;
149101 int addrExplain = sqlite3WhereExplainOneScan(
149102 pParse, pOrTab, &pSubWInfo->a[0], 0
149103 );
@@ -149831,11 +150848,11 @@
149831 void *pNotUsed;
149832 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
149833 assert( pVtab!=0 );
149834 assert( pVtab->pModule!=0 );
149835 assert( !ExprHasProperty(pExpr, EP_IntValue) );
149836 pMod = (sqlite3_module *)pVtab->pModule;
149837 if( pMod->xFindFunction!=0 ){
149838 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
149839 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
149840 *peOp2 = i;
149841 *ppRight = pList->a[1].pExpr;
@@ -149875,11 +150892,11 @@
149875 ** a join, then transfer the appropriate markings over to derived.
149876 */
149877 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
149878 if( pDerived ){
149879 pDerived->flags |= pBase->flags & EP_FromJoin;
149880 pDerived->iRightJoinTable = pBase->iRightJoinTable;
149881 }
149882 }
149883
149884 /*
149885 ** Mark term iChild as being a child of term iParent
@@ -150520,11 +151537,11 @@
150520 abort();
150521 }
150522 #endif
150523
150524 if( ExprHasProperty(pExpr, EP_FromJoin) ){
150525 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
150526 prereqAll |= x;
150527 extraRight = x-1; /* ON clause terms may not be used with an index
150528 ** on left table of a LEFT JOIN. Ticket #3015 */
150529 if( (prereqAll>>1)>=x ){
150530 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150788,11 +151805,14 @@
150788 ** new terms for each component comparison - "a = ?" and "b = ?". The
150789 ** new terms completely replace the original vector comparison, which is
150790 ** no longer used.
150791 **
150792 ** This is only required if at least one side of the comparison operation
150793 ** is not a sub-select. */
 
 
 
150794 if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
150795 && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
150796 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
150797 && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
150798 || (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150805,11 +151825,11 @@
150805 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
150806 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
150807
150808 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
150809 transferJoinMarkings(pNew, pExpr);
150810 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
150811 exprAnalyze(pSrc, pWC, idxNew);
150812 }
150813 pTerm = &pWC->a[idxTerm];
150814 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
150815 pTerm->eOperator = 0;
@@ -150835,11 +151855,11 @@
150835 && pWC->op==TK_AND
150836 ){
150837 int i;
150838 for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
150839 int idxNew;
150840 idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
150841 pWC->a[idxNew].u.x.iField = i+1;
150842 exprAnalyze(pSrc, pWC, idxNew);
150843 markTermAsChild(pWC, idxNew, idxTerm);
150844 }
150845 }
@@ -150868,11 +151888,11 @@
150868 Expr *pNewExpr;
150869 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
150870 0, sqlite3ExprDup(db, pRight, 0));
150871 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
150872 ExprSetProperty(pNewExpr, EP_FromJoin);
150873 pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
150874 }
150875 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
150876 testcase( idxNew==0 );
150877 pNewTerm = &pWC->a[idxNew];
150878 pNewTerm->prereqRight = prereqExpr;
@@ -150930,10 +151950,117 @@
150930 }else{
150931 sqlite3WhereSplit(pWC, pE2->pLeft, op);
150932 sqlite3WhereSplit(pWC, pE2->pRight, op);
150933 }
150934 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150935
150936 /*
150937 ** Initialize a preallocated WhereClause structure.
150938 */
150939 SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -150966,10 +152093,11 @@
150966 for(i=pWC->nBase; i<pWC->nTerm; i++){
150967 assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
150968 }
150969 #endif
150970 while(1){
 
150971 if( a->wtFlags & TERM_DYNAMIC ){
150972 sqlite3ExprDelete(db, a->pExpr);
150973 }
150974 if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
150975 if( a->wtFlags & TERM_ORINFO ){
@@ -151123,10 +152251,11 @@
151123 if( pColRef==0 ) return;
151124 pColRef->iTable = pItem->iCursor;
151125 pColRef->iColumn = k++;
151126 assert( ExprUseYTab(pColRef) );
151127 pColRef->y.pTab = pTab;
 
151128 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
151129 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
151130 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
151131 if( pItem->fg.jointype & JT_LEFT ){
151132 sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151167,12 +152296,18 @@
151167 ** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
151168 ** agree on the structure, all will be well.
151169 */
151170 typedef struct HiddenIndexInfo HiddenIndexInfo;
151171 struct HiddenIndexInfo {
151172 WhereClause *pWC; /* The Where clause being analyzed */
151173 Parse *pParse; /* The parsing context */
 
 
 
 
 
 
151174 };
151175
151176 /* Forward declaration of methods */
151177 static int whereLoopResize(sqlite3*, WhereLoop*, int);
151178
@@ -152209,11 +153344,14 @@
152209 VdbeCoverage(v);
152210 sqlite3VdbeJumpHere(v, addrTop);
152211 pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152212 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152213 while( ++iLevel < pWInfo->nLevel ){
 
152214 pLevel = &pWInfo->a[iLevel];
 
 
152215 pLoop = pLevel->pWLoop;
152216 if( NEVER(pLoop==0) ) continue;
152217 if( pLoop->prereq & notReady ) continue;
152218 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
152219 ==WHERE_BLOOMFILTER
@@ -152232,31 +153370,33 @@
152232
152233 #ifndef SQLITE_OMIT_VIRTUALTABLE
152234 /*
152235 ** Allocate and populate an sqlite3_index_info structure. It is the
152236 ** responsibility of the caller to eventually release the structure
152237 ** by passing the pointer returned by this function to sqlite3_free().
152238 */
152239 static sqlite3_index_info *allocateIndexInfo(
152240 Parse *pParse, /* The parsing context */
152241 WhereClause *pWC, /* The WHERE clause being analyzed */
152242 Bitmask mUnusable, /* Ignore terms with these prereqs */
152243 SrcItem *pSrc, /* The FROM clause term that is the vtab */
152244 ExprList *pOrderBy, /* The ORDER BY clause */
152245 u16 *pmNoOmit /* Mask of terms not to omit */
152246 ){
152247 int i, j;
152248 int nTerm;
 
152249 struct sqlite3_index_constraint *pIdxCons;
152250 struct sqlite3_index_orderby *pIdxOrderBy;
152251 struct sqlite3_index_constraint_usage *pUsage;
152252 struct HiddenIndexInfo *pHidden;
152253 WhereTerm *pTerm;
152254 int nOrderBy;
152255 sqlite3_index_info *pIdxInfo;
152256 u16 mNoOmit = 0;
152257 const Table *pTab;
 
 
152258
152259 assert( pSrc!=0 );
152260 pTab = pSrc->pTab;
152261 assert( pTab!=0 );
152262 assert( IsVirtual(pTab) );
@@ -152274,10 +153414,11 @@
152274 testcase( pTerm->eOperator & WO_ISNULL );
152275 testcase( pTerm->eOperator & WO_IS );
152276 testcase( pTerm->eOperator & WO_ALL );
152277 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
152278 if( pTerm->wtFlags & TERM_VNULL ) continue;
 
152279 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152280 assert( pTerm->u.x.leftColumn>=XN_ROWID );
152281 assert( pTerm->u.x.leftColumn<pTab->nCol );
152282
152283 /* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152335,40 +153476,53 @@
152335 }
152336
152337 /* No matches cause a break out of the loop */
152338 break;
152339 }
152340 if( i==n){
152341 nOrderBy = n;
 
 
 
 
 
152342 }
152343 }
152344
152345 /* Allocate the sqlite3_index_info structure
152346 */
152347 pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
152348 + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
152349 + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
 
152350 if( pIdxInfo==0 ){
152351 sqlite3ErrorMsg(pParse, "out of memory");
152352 return 0;
152353 }
152354 pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
152355 pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
152356 pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
152357 pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
152358 pIdxInfo->aConstraint = pIdxCons;
152359 pIdxInfo->aOrderBy = pIdxOrderBy;
152360 pIdxInfo->aConstraintUsage = pUsage;
152361 pHidden->pWC = pWC;
152362 pHidden->pParse = pParse;
 
 
152363 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
152364 u16 op;
152365 if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
152366 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
152367 pIdxCons[j].iTermOffset = i;
152368 op = pTerm->eOperator & WO_ALL;
152369 if( op==WO_IN ) op = WO_EQ;
 
 
 
 
 
152370 if( op==WO_AUX ){
152371 pIdxCons[j].op = pTerm->eMatchOp;
152372 }else if( op & (WO_ISNULL|WO_IS) ){
152373 if( op==WO_ISNULL ){
152374 pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152414,10 +153568,28 @@
152414 pIdxInfo->nOrderBy = j;
152415
152416 *pmNoOmit = mNoOmit;
152417 return pIdxInfo;
152418 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152419
152420 /*
152421 ** The table object reference passed as the second argument to this function
152422 ** must represent a virtual table. This function invokes the xBestIndex()
152423 ** method of the virtual table with the sqlite3_index_info object that
@@ -152436,11 +153608,13 @@
152436 static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
152437 sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
152438 int rc;
152439
152440 whereTraceIndexInfoInputs(p);
 
152441 rc = pVtab->pModule->xBestIndex(pVtab, p);
 
152442 whereTraceIndexInfoOutputs(p);
152443
152444 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
152445 if( rc==SQLITE_NOMEM ){
152446 sqlite3OomFault(pParse->db);
@@ -154265,11 +155439,11 @@
154265 }
154266 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
154267 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
154268 Expr *pExpr;
154269 pExpr = pTerm->pExpr;
154270 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
154271 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
154272 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
154273 && (pTerm->wtFlags & TERM_VNULL)==0
154274 ){
154275 return 1;
@@ -154566,10 +155740,19 @@
154566 }
154567 return rc;
154568 }
154569
154570 #ifndef SQLITE_OMIT_VIRTUALTABLE
 
 
 
 
 
 
 
 
 
154571
154572 /*
154573 ** Argument pIdxInfo is already populated with all constraints that may
154574 ** be used by the virtual table identified by pBuilder->pNew->iTab. This
154575 ** function marks a subset of those constraints usable, invokes the
@@ -154594,13 +155777,15 @@
154594 Bitmask mPrereq, /* Mask of tables that must be used. */
154595 Bitmask mUsable, /* Mask of usable tables */
154596 u16 mExclude, /* Exclude terms using these operators */
154597 sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
154598 u16 mNoOmit, /* Do not omit these constraints */
154599 int *pbIn /* OUT: True if plan uses an IN(...) op */
 
154600 ){
154601 WhereClause *pWC = pBuilder->pWC;
 
154602 struct sqlite3_index_constraint *pIdxCons;
154603 struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
154604 int i;
154605 int mxTerm;
154606 int rc = SQLITE_OK;
@@ -154619,10 +155804,11 @@
154619 for(i=0; i<nConstraint; i++, pIdxCons++){
154620 WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
154621 pIdxCons->usable = 0;
154622 if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
154623 && (pTerm->eOperator & mExclude)==0
 
154624 ){
154625 pIdxCons->usable = 1;
154626 }
154627 }
154628
@@ -154634,10 +155820,11 @@
154634 pIdxInfo->orderByConsumed = 0;
154635 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
154636 pIdxInfo->estimatedRows = 25;
154637 pIdxInfo->idxFlags = 0;
154638 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
 
154639
154640 /* Invoke the virtual table xBestIndex() method */
154641 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
154642 if( rc ){
154643 if( rc==SQLITE_CONSTRAINT ){
@@ -154651,12 +155838,12 @@
154651 return rc;
154652 }
154653
154654 mxTerm = -1;
154655 assert( pNew->nLSlot>=nConstraint );
154656 for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
154657 pNew->u.vtab.omitMask = 0;
154658 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
154659 for(i=0; i<nConstraint; i++, pIdxCons++){
154660 int iTerm;
154661 if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
154662 WhereTerm *pTerm;
@@ -154686,21 +155873,41 @@
154686 testcase( i!=iTerm );
154687 pNew->u.vtab.omitMask |= 1<<iTerm;
154688 }else{
154689 testcase( i!=iTerm );
154690 }
 
 
 
154691 }
154692 if( (pTerm->eOperator & WO_IN)!=0 ){
 
 
154693 /* A virtual table that is constrained by an IN clause may not
154694 ** consume the ORDER BY clause because (1) the order of IN terms
154695 ** is not necessarily related to the order of output terms and
154696 ** (2) Multiple outputs from a single IN value will not merge
154697 ** together. */
154698 pIdxInfo->orderByConsumed = 0;
154699 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
154700 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
154701 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154702 }
154703 }
154704
154705 pNew->nLTerm = mxTerm+1;
154706 for(i=0; i<=mxTerm; i++){
@@ -154770,10 +155977,90 @@
154770 zRet = (pC ? pC->zName : sqlite3StrBINARY);
154771 }
154772 return zRet;
154773 }
154774
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154775 /*
154776 ** Add all WhereLoop objects for a table of the join identified by
154777 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
154778 **
154779 ** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
@@ -154811,35 +156098,43 @@
154811 int nConstraint; /* Number of constraints in p */
154812 int bIn; /* True if plan uses IN(...) operator */
154813 WhereLoop *pNew;
154814 Bitmask mBest; /* Tables used by best possible plan */
154815 u16 mNoOmit;
 
154816
154817 assert( (mPrereq & mUnusable)==0 );
154818 pWInfo = pBuilder->pWInfo;
154819 pParse = pWInfo->pParse;
154820 pWC = pBuilder->pWC;
154821 pNew = pBuilder->pNew;
154822 pSrc = &pWInfo->pTabList->a[pNew->iTab];
154823 assert( IsVirtual(pSrc->pTab) );
154824 p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
154825 &mNoOmit);
154826 if( p==0 ) return SQLITE_NOMEM_BKPT;
154827 pNew->rSetup = 0;
154828 pNew->wsFlags = WHERE_VIRTUALTABLE;
154829 pNew->nLTerm = 0;
154830 pNew->u.vtab.needFree = 0;
154831 nConstraint = p->nConstraint;
154832 if( whereLoopResize(pParse->db, pNew, nConstraint) ){
154833 sqlite3DbFree(pParse->db, p);
154834 return SQLITE_NOMEM_BKPT;
154835 }
154836
154837 /* First call xBestIndex() with all constraints usable. */
154838 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
154839 WHERETRACE(0x40, (" VirtualOne: all usable\n"));
154840 rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
 
 
 
 
 
 
 
 
154841
154842 /* If the call to xBestIndex() with all terms enabled produced a plan
154843 ** that does not require any source tables (IOW: a plan with mBest==0)
154844 ** and does not use an IN(...) operator, then there is no point in making
154845 ** any further calls to xBestIndex() since they will all return the same
@@ -154853,11 +156148,11 @@
154853 /* If the plan produced by the earlier call uses an IN(...) term, call
154854 ** xBestIndex again, this time with IN(...) terms disabled. */
154855 if( bIn ){
154856 WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
154857 rc = whereLoopAddVirtualOne(
154858 pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
154859 assert( bIn==0 );
154860 mBestNoIn = pNew->prereq & ~mPrereq;
154861 if( mBestNoIn==0 ){
154862 seenZero = 1;
154863 seenZeroNoIN = 1;
@@ -154880,11 +156175,11 @@
154880 if( mNext==ALLBITS ) break;
154881 if( mNext==mBest || mNext==mBestNoIn ) continue;
154882 WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
154883 (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
154884 rc = whereLoopAddVirtualOne(
154885 pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
154886 if( pNew->prereq==mPrereq ){
154887 seenZero = 1;
154888 if( bIn==0 ) seenZeroNoIN = 1;
154889 }
154890 }
@@ -154893,26 +156188,26 @@
154893 ** that requires no source tables at all (i.e. one guaranteed to be
154894 ** usable), make a call here with all source tables disabled */
154895 if( rc==SQLITE_OK && seenZero==0 ){
154896 WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
154897 rc = whereLoopAddVirtualOne(
154898 pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
154899 if( bIn==0 ) seenZeroNoIN = 1;
154900 }
154901
154902 /* If the calls to xBestIndex() have so far failed to find a plan
154903 ** that requires no source tables at all and does not use an IN(...)
154904 ** operator, make a final call to obtain one here. */
154905 if( rc==SQLITE_OK && seenZeroNoIN==0 ){
154906 WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
154907 rc = whereLoopAddVirtualOne(
154908 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
154909 }
154910 }
154911
154912 if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
154913 sqlite3DbFreeNN(pParse->db, p);
154914 WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
154915 return rc;
154916 }
154917 #endif /* SQLITE_OMIT_VIRTUALTABLE */
154918
@@ -154952,11 +156247,10 @@
154952 WhereTerm *pOrTerm;
154953 int once = 1;
154954 int i, j;
154955
154956 sSubBuild = *pBuilder;
154957 sSubBuild.pOrderBy = 0;
154958 sSubBuild.pOrSet = &sCur;
154959
154960 WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
154961 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
154962 if( (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -155202,11 +156496,13 @@
155202 if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
155203 }else{
155204 pLoop = pLast;
155205 }
155206 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
155207 if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
 
 
155208 obSat = obDone;
155209 }
155210 break;
155211 }else if( wctrlFlags & WHERE_DISTINCTBY ){
155212 pLoop->u.btree.nDistinctCol = 0;
@@ -155469,11 +156765,11 @@
155469 **
155470 ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
155471 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
155472 */
155473 SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
155474 assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
155475 assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
155476 return pWInfo->sorted;
155477 }
155478
155479 #ifdef WHERETRACE_ENABLED
@@ -155870,16 +157166,16 @@
155870 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
155871 }
155872 }
155873 pWInfo->bOrderedInnerLoop = 0;
155874 if( pWInfo->pOrderBy ){
 
155875 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
155876 if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
155877 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
155878 }
155879 }else{
155880 pWInfo->nOBSat = pFrom->isOrdered;
155881 pWInfo->revMask = pFrom->revLoop;
155882 if( pWInfo->nOBSat<=0 ){
155883 pWInfo->nOBSat = 0;
155884 if( nLoop>0 ){
155885 u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156138,11 +157434,11 @@
156138 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
156139 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
156140 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
156141 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
156142 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
156143 || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
156144 ){
156145 break;
156146 }
156147 }
156148 }
@@ -156310,10 +157606,11 @@
156310 Parse *pParse, /* The parser context */
156311 SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
156312 Expr *pWhere, /* The WHERE clause */
156313 ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
156314 ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
 
156315 u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
156316 int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
156317 ** If WHERE_USE_LIMIT, then the limit amount */
156318 ){
156319 int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156344,11 +157641,10 @@
156344 memset(&sWLB, 0, sizeof(sWLB));
156345
156346 /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
156347 testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
156348 if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
156349 sWLB.pOrderBy = pOrderBy;
156350
156351 /* The number of tables in the FROM clause is limited by the number of
156352 ** bits in a Bitmask
156353 */
156354 testcase( pTabList->nSrc==BMS );
@@ -156387,10 +157683,13 @@
156387 pWInfo->nLevel = nTabList;
156388 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
156389 pWInfo->wctrlFlags = wctrlFlags;
156390 pWInfo->iLimit = iAuxArg;
156391 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
 
 
 
156392 memset(&pWInfo->nOBSat, 0,
156393 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
156394 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
156395 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
156396 pMaskSet = &pWInfo->sMaskSet;
@@ -156455,10 +157754,11 @@
156455 #endif
156456 }
156457
156458 /* Analyze all of the subexpressions. */
156459 sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
 
156460 if( db->mallocFailed ) goto whereBeginError;
156461
156462 /* Special case: WHERE terms that do not refer to any tables in the join
156463 ** (constant expressions). Evaluate each such term, and jump over all the
156464 ** generated code if the result is not true.
@@ -156554,13 +157854,14 @@
156554 }
156555 }
156556 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
156557 pWInfo->revMask = ALLBITS;
156558 }
156559 if( pParse->nErr || db->mallocFailed ){
156560 goto whereBeginError;
156561 }
 
156562 #ifdef WHERETRACE_ENABLED
156563 if( sqlite3WhereTrace ){
156564 sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
156565 if( pWInfo->nOBSat>0 ){
156566 sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
@@ -156700,10 +158001,11 @@
156700 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
156701 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
156702 if( pWInfo->eOnePass==ONEPASS_OFF
156703 && pTab->nCol<BMS
156704 && (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
 
156705 ){
156706 /* If we know that only a prefix of the record will be used,
156707 ** it is advantageous to reduce the "column count" field in
156708 ** the P4 operand of the OP_OpenRead/Write opcode. */
156709 Bitmask b = pTabItem->colUsed;
@@ -156860,10 +158162,30 @@
156860 if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
156861 sqlite3VdbePrintOp(0, pc, pOp);
156862 }
156863 #endif
156864
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156865 /*
156866 ** Generate the end of the WHERE loop. See comments on
156867 ** sqlite3WhereBegin() for additional information.
156868 */
156869 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157112,10 +158434,15 @@
157112 || pOp->opcode==OP_Offset
157113 #endif
157114 ){
157115 int x = pOp->p2;
157116 assert( pIdx->pTable==pTab );
 
 
 
 
 
157117 if( !HasRowid(pTab) ){
157118 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
157119 x = pPk->aiColumn[x];
157120 assert( x>=0 );
157121 }else{
@@ -157125,13 +158452,26 @@
157125 x = sqlite3TableColumnToIndex(pIdx, x);
157126 if( x>=0 ){
157127 pOp->p2 = x;
157128 pOp->p1 = pLevel->iIdxCur;
157129 OpcodeRewriteTrace(db, k, pOp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157130 }
157131 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
157132 || pWInfo->eOnePass );
157133 }else if( pOp->opcode==OP_Rowid ){
157134 pOp->p1 = pLevel->iIdxCur;
157135 pOp->opcode = OP_IdxRowid;
157136 OpcodeRewriteTrace(db, k, pOp);
157137 }else if( pOp->opcode==OP_IfNullRow ){
@@ -157882,11 +159222,11 @@
157882 break;
157883 }
157884 }
157885 }
157886 }
157887 pWin->pFunc = pFunc;
157888 }
157889
157890 /*
157891 ** Context object passed through sqlite3WalkExprList() to
157892 ** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158115,11 +159455,15 @@
158115 ** are invoked in the correct order as described under "SELECT REWRITING"
158116 ** at the top of this file.
158117 */
158118 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
158119 int rc = SQLITE_OK;
158120 if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
 
 
 
 
158121 Vdbe *v = sqlite3GetVdbe(pParse);
158122 sqlite3 *db = pParse->db;
158123 Select *pSub = 0; /* The subquery */
158124 SrcList *pSrc = p->pSrc;
158125 Expr *pWhere = p->pWhere;
@@ -158190,12 +159534,13 @@
158190 ** window function - one for the accumulator, another for interim
158191 ** results. */
158192 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158193 ExprList *pArgs;
158194 assert( ExprUseXList(pWin->pOwner) );
 
158195 pArgs = pWin->pOwner->x.pList;
158196 if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
158197 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
158198 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
158199 pWin->bExprArgs = 1;
158200 }else{
158201 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158264,16 +159609,11 @@
158264 ** there could still be references to that table embedded in the
158265 ** result-set or ORDER BY clause of the SELECT statement p. */
158266 sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
158267 }
158268
158269 if( rc ){
158270 if( pParse->nErr==0 ){
158271 assert( pParse->db->mallocFailed );
158272 sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
158273 }
158274 }
158275 return rc;
158276 }
158277
158278 /*
158279 ** Unlink the Window object from the Select to which it is attached,
@@ -158578,11 +159918,11 @@
158578 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
158579 return;
158580 }
158581
158582 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158583 FuncDef *p = pWin->pFunc;
158584 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
158585 /* The inline versions of min() and max() require a single ephemeral
158586 ** table and 3 registers. The registers are used as follows:
158587 **
158588 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158595,11 +159935,11 @@
158595 pList = pWin->pOwner->x.pList;
158596 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158597 pWin->csrApp = pParse->nTab++;
158598 pWin->regApp = pParse->nMem+1;
158599 pParse->nMem += 3;
158600 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
158601 assert( pKeyInfo->aSortFlags[0]==0 );
158602 pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
158603 }
158604 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
158605 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -158818,11 +160158,11 @@
158818 ){
158819 Parse *pParse = p->pParse;
158820 Vdbe *v = sqlite3GetVdbe(pParse);
158821 Window *pWin;
158822 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158823 FuncDef *pFunc = pWin->pFunc;
158824 int regArg;
158825 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
158826 int i;
158827
158828 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -158932,11 +160272,11 @@
158932 Vdbe *v = sqlite3GetVdbe(pParse);
158933 Window *pWin;
158934
158935 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158936 if( pMWin->regStartRowid==0
158937 && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
158938 && (pWin->eStart!=TK_UNBOUNDED)
158939 ){
158940 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
158941 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
158942 VdbeCoverage(v);
@@ -158946,16 +160286,16 @@
158946 assert( pMWin->regStartRowid==0 );
158947 }else{
158948 int nArg = windowArgCount(pWin);
158949 if( bFin ){
158950 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
158951 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
158952 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
158953 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
158954 }else{
158955 sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
158956 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
158957 }
158958 }
158959 }
158960 }
158961
@@ -159080,11 +160420,11 @@
159080 }else{
159081 Parse *pParse = p->pParse;
159082 Window *pWin;
159083
159084 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159085 FuncDef *pFunc = pWin->pFunc;
159086 assert( ExprUseXList(pWin->pOwner) );
159087 if( pFunc->zName==nth_valueName
159088 || pFunc->zName==first_valueName
159089 ){
159090 int csr = pWin->csrApp;
@@ -159152,11 +160492,11 @@
159152 Vdbe *v = sqlite3GetVdbe(pParse);
159153 int regArg;
159154 int nArg = 0;
159155 Window *pWin;
159156 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159157 FuncDef *pFunc = pWin->pFunc;
159158 assert( pWin->regAccum );
159159 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159160 nArg = MAX(nArg, windowArgCount(pWin));
159161 if( pMWin->regStartRowid==0 ){
159162 if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159182,11 +160522,11 @@
159182 */
159183 static int windowCacheFrame(Window *pMWin){
159184 Window *pWin;
159185 if( pMWin->regStartRowid ) return 1;
159186 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159187 FuncDef *pFunc = pWin->pFunc;
159188 if( (pFunc->zName==nth_valueName)
159189 || (pFunc->zName==first_valueName)
159190 || (pFunc->zName==leadName)
159191 || (pFunc->zName==lagName)
159192 ){
@@ -159540,11 +160880,11 @@
159540 pNew = sqlite3DbMallocZero(db, sizeof(Window));
159541 if( pNew ){
159542 pNew->zName = sqlite3DbStrDup(db, p->zName);
159543 pNew->zBase = sqlite3DbStrDup(db, p->zBase);
159544 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
159545 pNew->pFunc = p->pFunc;
159546 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
159547 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
159548 pNew->eFrmType = p->eFrmType;
159549 pNew->eEnd = p->eEnd;
159550 pNew->eStart = p->eStart;
@@ -160417,14 +161757,11 @@
160417 }
160418 return pSelect;
160419 }
160420
160421
160422 /* Construct a new Expr object from a single identifier. Use the
160423 ** new Expr to populate pOut. Set the span of pOut to be the identifier
160424 ** that created the expression.
160425 */
160426 static Expr *tokenExpr(Parse *pParse, int op, Token t){
160427 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
160428 if( p ){
160429 /* memset(p, 0, sizeof(Expr)); */
160430 p->op = (u8)op;
@@ -160440,10 +161777,11 @@
160440 p->iTable = 0;
160441 p->iColumn = 0;
160442 p->u.zToken = (char*)&p[1];
160443 memcpy(p->u.zToken, t.z, t.n);
160444 p->u.zToken[t.n] = 0;
 
160445 if( sqlite3Isquote(p->u.zToken[0]) ){
160446 sqlite3DequoteExpr(p);
160447 }
160448 #if SQLITE_MAX_EXPR_DEPTH>0
160449 p->nHeight = 1;
@@ -164251,11 +165589,11 @@
164251 }
164252 break;
164253 case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
164254 {
164255 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
164256 Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164257 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
164258 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
164259 }
164260 break;
164261 case 103: /* as ::= AS nm */
@@ -164536,29 +165874,24 @@
164536 case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
164537 {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164538 break;
164539 case 180: /* expr ::= nm DOT nm */
164540 {
164541 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164542 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164543 if( IN_RENAME_OBJECT ){
164544 sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
164545 sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
164546 }
164547 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
164548 }
164549 yymsp[-2].minor.yy528 = yylhsminor.yy528;
164550 break;
164551 case 181: /* expr ::= nm DOT nm DOT nm */
164552 {
164553 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
164554 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164555 Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164556 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
164557 if( IN_RENAME_OBJECT ){
164558 sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
164559 sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
164560 }
164561 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
164562 }
164563 yymsp[-4].minor.yy528 = yylhsminor.yy528;
164564 break;
@@ -164567,10 +165900,11 @@
164567 {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164568 break;
164569 case 184: /* term ::= INTEGER */
164570 {
164571 yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
 
164572 }
164573 yymsp[0].minor.yy528 = yylhsminor.yy528;
164574 break;
164575 case 185: /* expr ::= VARIABLE */
164576 {
@@ -166811,11 +168145,14 @@
166811 }else if( tokenType==TK_FILTER ){
166812 assert( n==6 );
166813 tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
166814 #endif /* SQLITE_OMIT_WINDOWFUNC */
166815 }else{
166816 sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
 
 
 
166817 break;
166818 }
166819 }
166820 pParse->sLastToken.z = zSql;
166821 pParse->sLastToken.n = n;
@@ -171422,16 +172759,20 @@
171422 ** is called immediately after installing the new callback and the return
171423 ** value from sqlite3FaultSim(0) becomes the return from
171424 ** sqlite3_test_control().
171425 */
171426 case SQLITE_TESTCTRL_FAULT_INSTALL: {
171427 /* MSVC is picky about pulling func ptrs from va lists.
171428 ** http://support.microsoft.com/kb/47961
 
 
 
 
171429 ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
171430 */
171431 typedef int(*TESTCALLBACKFUNC_t)(int);
171432 sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
171433 rc = sqlite3FaultSim(0);
171434 break;
171435 }
171436
171437 /*
@@ -171554,17 +172895,31 @@
171554 sqlite3 *db = va_arg(ap, sqlite3*);
171555 db->dbOptFlags = va_arg(ap, u32);
171556 break;
171557 }
171558
171559 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
 
 
 
 
 
 
 
 
171560 **
171561 ** If parameter onoff is non-zero, subsequent calls to localtime()
171562 ** and its variants fail. If onoff is zero, undo this setting.
171563 */
171564 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
171565 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
 
 
 
 
 
 
171566 break;
171567 }
171568
171569 /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
171570 **
@@ -171762,14 +173117,16 @@
171762 ** Test access for the LogEst conversion routines.
171763 */
171764 case SQLITE_TESTCTRL_LOGEST: {
171765 double rIn = va_arg(ap, double);
171766 LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
171767 u64 iInt = sqlite3LogEstToInt(rLogEst);
171768 va_arg(ap, int*)[0] = rLogEst;
171769 va_arg(ap, u64*)[0] = iInt;
171770 va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
 
 
171771 break;
171772 }
171773
171774
171775 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193696,11 +195053,11 @@
193696 u32 iRoot;
193697 JsonNode *pTarget;
193698 if( pPatch->eType!=JSON_OBJECT ){
193699 return pPatch;
193700 }
193701 assert( iTarget>=0 && iTarget<pParse->nNode );
193702 pTarget = &pParse->aNode[iTarget];
193703 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
193704 if( pTarget->eType!=JSON_OBJECT ){
193705 jsonRemoveAllNulls(pPatch);
193706 return pPatch;
@@ -193955,12 +195312,12 @@
193955 sqlite3_result_error_nomem(ctx);
193956 goto jsonSetDone;
193957 }else if( x.nErr ){
193958 goto jsonSetDone;
193959 }else if( pNode && (bApnd || bIsSet) ){
193960 testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 );
193961 assert( pNode->eU!=3 || pNode->eU!=5 );
193962 VVA( pNode->eU = 4 );
193963 pNode->jnFlags |= (u8)JNODE_REPLACE;
193964 pNode->u.iReplace = i + 1;
193965 }
193966 }
@@ -194737,11 +196094,11 @@
194737 sqlite3_module *pModule;
194738 } aMod[] = {
194739 { "json_each", &jsonEachModule },
194740 { "json_tree", &jsonTreeModule },
194741 };
194742 int i;
194743 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
194744 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
194745 }
194746 return rc;
194747 }
@@ -208991,10 +210348,11 @@
208991 && pIdxInfo->aOrderBy[0].iColumn<=0
208992 && pIdxInfo->aOrderBy[0].desc==0
208993 ){
208994 pIdxInfo->orderByConsumed = 1;
208995 }
 
208996 return SQLITE_OK;
208997 }
208998
208999 /*
209000 ** Open a new dbpagevfs cursor.
@@ -209168,11 +210526,11 @@
209168 if( iDb<0 ){
209169 zErr = "no such schema";
209170 goto update_fail;
209171 }
209172 pBt = pTab->db->aDb[iDb].pBt;
209173 if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
209174 zErr = "bad page number";
209175 goto update_fail;
209176 }
209177 szPage = sqlite3BtreeGetPageSize(pBt);
209178 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231345,11 +232703,11 @@
231345 int rc;
231346
231347 rc = sqlite3_step(pSorter->pStmt);
231348 if( rc==SQLITE_DONE ){
231349 rc = SQLITE_OK;
231350 CsrFlagSet(pCsr, FTS5CSR_EOF);
231351 }else if( rc==SQLITE_ROW ){
231352 const u8 *a;
231353 const u8 *aBlob;
231354 int nBlob;
231355 int i;
@@ -233334,11 +234692,11 @@
233334 int nArg, /* Number of args */
233335 sqlite3_value **apUnused /* Function arguments */
233336 ){
233337 assert( nArg==0 );
233338 UNUSED_PARAM2(nArg, apUnused);
233339 sqlite3_result_text(pCtx, "fts5: 2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec", -1, SQLITE_TRANSIENT);
233340 }
233341
233342 /*
233343 ** Return true if zName is the extension on one of the shadow tables used
233344 ** by this module.
233345
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.39.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.39.0"
456 #define SQLITE_VERSION_NUMBER 3039000
457 #define SQLITE_SOURCE_ID "2022-03-23 10:04:52 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -870,11 +870,11 @@
870 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
876
877 /*
878 ** CAPI3REF: Flags For File Open Operations
879 **
880 ** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
4154 **
4155 ** ^If the most recent error references a specific token in the input
4156 ** SQL, the sqlite3_error_offset() interface returns the byte offset
4157 ** of the start of that token. ^The byte offset returned by
4158 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159 ** ^If the most recent error does not reference a specific token in the input
4160 ** SQL, then the sqlite3_error_offset() function returns -1.
4161 **
4162 ** When the serialized [threading mode] is in use, it might be the
4163 ** case that a second error occurs on a separate thread in between
4164 ** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
4588 ** ^For example, an UPDATE statement might have a WHERE clause that
4589 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4590 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4591 ** read-only no-op if the table already exists, but
4592 ** sqlite3_stmt_readonly() still returns false for such a statement.
4593 **
4594 ** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4595 ** statement, then sqlite3_stmt_readonly(X) returns the same value as
4596 ** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
4597 */
4598 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4599
4600 /*
4601 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
4660 ** still make the distinction between protected and unprotected
4661 ** sqlite3_value objects even when not strictly required.
4662 **
4663 ** ^The sqlite3_value objects that are passed as parameters into the
4664 ** implementation of [application-defined SQL functions] are protected.
4665 ** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4666 ** are protected.
4667 ** ^The sqlite3_value object returned by
4668 ** [sqlite3_column_value()] is unprotected.
4669 ** Unprotected sqlite3_value objects may only be used as arguments
4670 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4671 ** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
5282 ** bytes in the string, not the number of characters.
5283 **
5284 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
5285 ** even empty strings, are always zero-terminated. ^The return
5286 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
5287 **
5288 ** ^Strings returned by sqlite3_column_text16() always have the endianness
5289 ** which is native to the platform, regardless of the text encoding set
5290 ** for the database.
5291 **
5292 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
5293 ** [unprotected sqlite3_value] object. In a multithreaded environment,
5294 ** an unprotected sqlite3_value object may only be used safely with
5295 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
5300 ** Hence, the sqlite3_column_value() interface
5301 ** is normally only useful within the implementation of
5302 ** [application-defined SQL functions] or [virtual tables], not within
5303 ** top-level application code.
5304 **
5305 ** These routines may attempt to convert the datatype of the result.
5306 ** ^For example, if the internal representation is FLOAT and a text result
5307 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5308 ** conversion automatically. ^(The following table details the conversions
5309 ** that are applied:
5310 **
@@ -5315,11 +5325,11 @@
5325 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5326 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5327 ** <tr><td> TEXT <td> BLOB <td> No change
5328 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5329 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5330 ** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
5331 ** </table>
5332 ** </blockquote>)^
5333 **
5334 ** Note that when type conversions occur, pointers returned by prior
5335 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
5897 **
5898 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5899 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5900 ** is a [protected sqlite3_value] object even if the input is not.
5901 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5902 ** memory allocation fails. ^If V is a [pointer value], then the result
5903 ** of sqlite3_value_dup(V) is a NULL value.
5904 **
5905 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5906 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5907 ** then sqlite3_value_free(V) is a harmless no-op.
5908 */
@@ -7435,28 +7446,60 @@
7446 /*
7447 ** CAPI3REF: Virtual Table Constraint Operator Codes
7448 **
7449 ** These macros define the allowed values for the
7450 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7451 ** an operator that is part of a constraint term in the WHERE clause of
7452 ** a query that uses a [virtual table].
7453 **
7454 ** ^The left-hand operand of the operator is given by the corresponding
7455 ** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7456 ** operand is the rowid.
7457 ** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7458 ** operators have no left-hand operand, and so for those operators the
7459 ** corresponding aConstraint[].iColumn is meaningless and should not be
7460 ** used.
7461 **
7462 ** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7463 ** value 255 are reserved to represent functions that are overloaded
7464 ** by the [xFindFunction|xFindFunction method] of the virtual table
7465 ** implementation.
7466 **
7467 ** The right-hand operands for each constraint might be accessible using
7468 ** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7469 ** operand is only available if it appears as a single constant literal
7470 ** in the input SQL. If the right-hand operand is another column or an
7471 ** expression (even a constant expression) or a parameter, then the
7472 ** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7473 ** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7474 ** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7475 ** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7476 ** always return SQLITE_NOTFOUND.
7477 **
7478 ** The collating sequence to be used for comparison can be found using
7479 ** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7480 ** tables, the collating sequence of constraints does not matter (for example
7481 ** because the constraints are numeric) and so the sqlite3_vtab_collation()
7482 ** interface is no commonly needed.
7483 */
7484 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7485 #define SQLITE_INDEX_CONSTRAINT_GT 4
7486 #define SQLITE_INDEX_CONSTRAINT_LE 8
7487 #define SQLITE_INDEX_CONSTRAINT_LT 16
7488 #define SQLITE_INDEX_CONSTRAINT_GE 32
7489 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7490 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7491 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7492 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7493 #define SQLITE_INDEX_CONSTRAINT_NE 68
7494 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7495 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7496 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7497 #define SQLITE_INDEX_CONSTRAINT_IS 72
7498 #define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7499 #define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7500 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7501
7502 /*
7503 ** CAPI3REF: Register A Virtual Table Implementation
7504 ** METHOD: sqlite3
7505 **
@@ -7481,11 +7524,11 @@
7524 ** ^The sqlite3_create_module()
7525 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7526 ** destructor.
7527 **
7528 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7529 ** NULL then no new module is created and any existing modules with the
7530 ** same name are dropped.
7531 **
7532 ** See also: [sqlite3_drop_modules()]
7533 */
7534 SQLITE_API int sqlite3_create_module(
@@ -9775,25 +9818,26 @@
9818 */
9819 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
9820
9821 /*
9822 ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
9823 ** METHOD: sqlite3_index_info
9824 **
9825 ** This function may only be called from within a call to the [xBestIndex]
9826 ** method of a [virtual table]. This function returns a pointer to a string
9827 ** that is the name of the appropriate collation sequence to use for text
9828 ** comparisons on the constraint identified by its arguments.
9829 **
9830 ** The first argument must be the pointer to the [sqlite3_index_info] object
9831 ** that is the first parameter to the xBestIndex() method. The second argument
9832 ** must be an index into the aConstraint[] array belonging to the
9833 ** sqlite3_index_info structure passed to xBestIndex.
9834 **
9835 ** Important:
9836 ** The first parameter must be the same pointer that is passed into the
9837 ** xBestMethod() method. The first parameter may not be a pointer to a
9838 ** different [sqlite3_index_info] object, even an exact copy.
9839 **
9840 ** The return value is computed as follows:
9841 **
9842 ** <ol>
9843 ** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9807,10 +9851,247 @@
9851 ** <li><p> Otherwise, "BINARY" is returned.
9852 ** </ol>
9853 */
9854 SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
9855
9856 /*
9857 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9858 ** METHOD: sqlite3_index_info
9859 **
9860 ** This API may only be used from within an [xBestIndex|xBestIndex method]
9861 ** of a [virtual table] implementation. The result of calling this
9862 ** interface from outside of xBestIndex() is undefined and probably harmful.
9863 **
9864 ** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9865 ** 3. The integer returned by sqlite3_vtab_distinct()
9866 ** gives the virtual table additional information about how the query
9867 ** planner wants the output to be ordered. As long as the virtual table
9868 ** can meet the ordering requirements of the query planner, it may set
9869 ** the "orderByConsumed" flag.
9870 **
9871 ** <ol><li value="0"><p>
9872 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9873 ** that the query planner needs the virtual table to return all rows in the
9874 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9875 ** [sqlite3_index_info] object. This is the default expectation. If the
9876 ** virtual table outputs all rows in sorted order, then it is always safe for
9877 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9878 ** the return value from sqlite3_vtab_distinct().
9879 ** <li value="1"><p>
9880 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9881 ** that the query planner does not need the rows to be returned in sorted order
9882 ** as long as all rows with the same values in all columns identified by the
9883 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
9884 ** is doing a GROUP BY.
9885 ** <li value="2"><p>
9886 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9887 ** that the query planner does not need the rows returned in any particular
9888 ** order, as long as rows with the same values in all "aOrderBy" columns
9889 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9890 ** combination of values in the columns identified by the "aOrderBy" field
9891 ** needs to be returned.)^ ^It is always ok for two or more rows with the same
9892 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9893 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9894 ** that have the same value for all columns identified by "aOrderBy".
9895 ** ^However omitting the extra rows is optional.
9896 ** This mode is used for a DISTINCT query.
9897 ** <li value="3"><p>
9898 ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9899 ** that the query planner needs only distinct rows but it does need the
9900 ** rows to be sorted.)^ ^The virtual table implementation is free to omit
9901 ** rows that are identical in all aOrderBy columns, if it wants to, but
9902 ** it is not required to omit any rows. This mode is used for queries
9903 ** that have both DISTINCT and ORDER BY clauses.
9904 ** </ol>
9905 **
9906 ** ^For the purposes of comparing virtual table output values to see if the
9907 ** values are same value for sorting purposes, two NULL values are considered
9908 ** to be the same. In other words, the comparison operator is "IS"
9909 ** (or "IS NOT DISTINCT FROM") and not "==".
9910 **
9911 ** If a virtual table implementation is unable to meet the requirements
9912 ** specified above, then it must not set the "orderByConsumed" flag in the
9913 ** [sqlite3_index_info] object or an incorrect answer may result.
9914 **
9915 ** ^A virtual table implementation is always free to return rows in any order
9916 ** it wants, as long as the "orderByConsumed" flag is not set. ^When the
9917 ** the "orderByConsumed" flag is unset, the query planner will add extra
9918 ** [bytecode] to ensure that the final results returned by the SQL query are
9919 ** ordered correctly. The use of the "orderByConsumed" flag and the
9920 ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful
9921 ** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed"
9922 ** flag might help queries against a virtual table to run faster. Being
9923 ** overly aggressive and setting the "orderByConsumed" flag when it is not
9924 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9925 ** results.
9926 */
9927 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9928
9929 /*
9930 ** CAPI3REF: Identify and handle IN constraints in xBestIndex
9931 **
9932 ** This interface may only be used from within an
9933 ** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9934 ** The result of invoking this interface from any other context is
9935 ** undefined and probably harmful.
9936 **
9937 ** ^(A constraint on a virtual table of the form
9938 ** "[IN operator|column IN (...)]" is
9939 ** communicated to the xBestIndex method as a
9940 ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9941 ** this constraint, it must set the corresponding
9942 ** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9943 ** the usual mode of handling IN operators, SQLite generates [bytecode]
9944 ** that invokes the [xFilter|xFilter() method] once for each value
9945 ** on the right-hand side of the IN operator.)^ Thus the virtual table
9946 ** only sees a single value from the right-hand side of the IN operator
9947 ** at a time.
9948 **
9949 ** In some cases, however, it would be advantageous for the virtual
9950 ** table to see all values on the right-hand of the IN operator all at
9951 ** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9952 **
9953 ** <ol>
9954 ** <li><p>
9955 ** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9956 ** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9957 ** is an [IN operator] that can be processed all at once. ^In other words,
9958 ** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9959 ** by which the virtual table can ask SQLite if all-at-once processing
9960 ** of the IN operator is even possible.
9961 **
9962 ** <li><p>
9963 ** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9964 ** to SQLite that the virtual table does or does not want to process
9965 ** the IN operator all-at-once, respectively. ^Thus when the third
9966 ** parameter (F) is non-negative, this interface is the mechanism by
9967 ** which the virtual table tells SQLite how it wants to process the
9968 ** IN operator.
9969 ** </ol>
9970 **
9971 ** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9972 ** within the same xBestIndex method call. ^For any given P,N pair,
9973 ** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9974 ** within the same xBestIndex call. ^If the interface returns true
9975 ** (non-zero), that means that the constraint is an IN operator
9976 ** that can be processed all-at-once. ^If the constraint is not an IN
9977 ** operator or cannot be processed all-at-once, then the interface returns
9978 ** false.
9979 **
9980 ** ^(All-at-once processing of the IN operator is selected if both of the
9981 ** following conditions are met:
9982 **
9983 ** <ol>
9984 ** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9985 ** integer. This is how the virtual table tells SQLite that it wants to
9986 ** use the N-th constraint.
9987 **
9988 ** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9989 ** non-negative had F>=1.
9990 ** </ol>)^
9991 **
9992 ** ^If either or both of the conditions above are false, then SQLite uses
9993 ** the traditional one-at-a-time processing strategy for the IN constraint.
9994 ** ^If both conditions are true, then the argvIndex-th parameter to the
9995 ** xFilter method will be an [sqlite3_value] that appears to be NULL,
9996 ** but which can be passed to [sqlite3_vtab_in_first()] and
9997 ** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9998 ** of the IN constraint.
9999 */
10000 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
10001
10002 /*
10003 ** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
10004 **
10005 ** These interfaces are only useful from within the
10006 ** [xFilter|xFilter() method] of a [virtual table] implementation.
10007 ** The result of invoking these interfaces from any other context
10008 ** is undefined and probably harmful.
10009 **
10010 ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
10011 ** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
10012 ** xFilter method which invokes these routines, and specifically
10013 ** a parameter that was previously selected for all-at-once IN constraint
10014 ** processing use the [sqlite3_vtab_in()] interface in the
10015 ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
10016 ** an xFilter argument that was selected for all-at-once IN constraint
10017 ** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
10018 ** exhibit some other undefined or harmful behavior.
10019 **
10020 ** ^(Use these routines to access all values on the right-hand side
10021 ** of the IN constraint using code like the following:
10022 **
10023 ** <blockquote><pre>
10024 ** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
10025 ** &nbsp; rc==SQLITE_OK && pVal
10026 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10027 ** &nbsp; ){
10028 ** &nbsp; // do something with pVal
10029 ** &nbsp; }
10030 ** &nbsp; if( rc!=SQLITE_OK ){
10031 ** &nbsp; // an error has occurred
10032 ** &nbsp; }
10033 ** </pre></blockquote>)^
10034 **
10035 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
10036 ** routines return SQLITE_OK and set *P to point to the first or next value
10037 ** on the RHS of the IN constraint. ^If there are no more values on the
10038 ** right hand side of the IN constraint, then *P is set to NULL and these
10039 ** routines return [SQLITE_DONE]. ^The return value might be
10040 ** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
10041 **
10042 ** The *ppOut values returned by these routines are only valid until the
10043 ** next call to either of these routines or until the end of the xFilter
10044 ** method from which these routines were called. If the virtual table
10045 ** implementation needs to retain the *ppOut values for longer, it must make
10046 ** copies. The *ppOut values are [protected sqlite3_value|protected].
10047 */
10048 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
10049 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
10050
10051 /*
10052 ** CAPI3REF: Constraint values in xBestIndex()
10053 ** METHOD: sqlite3_index_info
10054 **
10055 ** This API may only be used from within the [xBestIndex|xBestIndex method]
10056 ** of a [virtual table] implementation. The result of calling this interface
10057 ** from outside of an xBestIndex method are undefined and probably harmful.
10058 **
10059 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
10060 ** the [xBestIndex] method of a [virtual table] implementation, with P being
10061 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
10062 ** J being a 0-based index into P->aConstraint[], then this routine
10063 ** attempts to set *V to the value of the right-hand operand of
10064 ** that constraint if the right-hand operand is known. ^If the
10065 ** right-hand operand is not known, then *V is set to a NULL pointer.
10066 ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
10067 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
10068 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
10069 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
10070 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
10071 ** something goes wrong.
10072 **
10073 ** The sqlite3_vtab_rhs_value() interface is usually only successful if
10074 ** the right-hand operand of a constraint is a literal value in the original
10075 ** SQL statement. If the right-hand operand is an expression or a reference
10076 ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
10077 ** will probably return [SQLITE_NOTFOUND].
10078 **
10079 ** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
10080 ** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
10081 ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
10082 **
10083 ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
10084 ** and remains valid for the duration of the xBestIndex method call.
10085 ** ^When xBestIndex returns, the sqlite3_value object returned by
10086 ** sqlite3_vtab_rhs_value() is automatically deallocated.
10087 **
10088 ** The "_rhs_" in the name of this routine is an abbreviation for
10089 ** "Right-Hand Side".
10090 */
10091 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
10092
10093 /*
10094 ** CAPI3REF: Conflict resolution modes
10095 ** KEYWORDS: {conflict resolution mode}
10096 **
10097 ** These constants are returned by [sqlite3_vtab_on_conflict()] to
@@ -14246,11 +14527,11 @@
14527 ** one parameter that destructors normally want. So we have to introduce
14528 ** this magic value that the code knows to handle differently. Any
14529 ** pointer will work here as long as it is distinct from SQLITE_STATIC
14530 ** and SQLITE_TRANSIENT.
14531 */
14532 #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear)
14533
14534 /*
14535 ** When SQLITE_OMIT_WSD is defined, it means that the target platform does
14536 ** not support Writable Static Data (WSD) such as global and static variables.
14537 ** All variables must either be on the stack or dynamically allocated from
@@ -14374,14 +14655,15 @@
14655 #define BMS ((int)(sizeof(Bitmask)*8))
14656
14657 /*
14658 ** A bit in a Bitmask
14659 */
14660 #define MASKBIT(n) (((Bitmask)1)<<(n))
14661 #define MASKBIT64(n) (((u64)1)<<(n))
14662 #define MASKBIT32(n) (((unsigned int)1)<<(n))
14663 #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0)
14664 #define ALLBITS ((Bitmask)-1)
14665
14666 /* A VList object records a mapping between parameters/variables/wildcards
14667 ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
14668 ** variable number associated with that parameter. See the format description
14669 ** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14439,18 +14721,19 @@
14721 ** Handle type for pages.
14722 */
14723 typedef struct PgHdr DbPage;
14724
14725 /*
14726 ** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is
14727 ** reserved for working around a windows/posix incompatibility). It is
14728 ** used in the journal to signify that the remainder of the journal file
14729 ** is devoted to storing a super-journal name - there are no more pages to
14730 ** roll back. See comments for function writeSuperJournal() in pager.c
14731 ** for details.
14732 */
14733 #define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14734 #define PAGER_SJ_PGNO(x) ((x)->lckPgno)
14735
14736 /*
14737 ** Allowed values for the flags parameter to sqlite3PagerOpen().
14738 **
14739 ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15123,11 +15406,10 @@
15406 SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
15407 Table *pTab; /* Used when p4type is P4_TABLE */
15408 #ifdef SQLITE_ENABLE_CURSOR_HINTS
15409 Expr *pExpr; /* Used when p4type is P4_EXPR */
15410 #endif
 
15411 } p4;
15412 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
15413 char *zComment; /* Comment to improve readability */
15414 #endif
15415 #ifdef VDBE_PROFILE
@@ -15174,25 +15456,23 @@
15456 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
15457 #define P4_STATIC (-1) /* Pointer to a static string */
15458 #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
15459 #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
15460 #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15461 #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */
 
15462 /* Above do not own any resources. Must free those below */
15463 #define P4_FREE_IF_LE (-6)
15464 #define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */
15465 #define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */
15466 #define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */
15467 #define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */
15468 #define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */
15469 #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
15470 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
15471 #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
15472 #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
15473 #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
 
15474
15475 /* Error message codes for OP_Halt */
15476 #define P5_ConstraintNotNull 1
15477 #define P5_ConstraintUnique 2
15478 #define P5_ConstraintCheck 3
@@ -15233,46 +15513,46 @@
15513 /* Automatically generated. Do not edit */
15514 /* See the tool/mkopcodeh.tcl script for details */
15515 #define OP_Savepoint 0
15516 #define OP_AutoCommit 1
15517 #define OP_Transaction 2
15518 #define OP_Checkpoint 3
15519 #define OP_JournalMode 4
15520 #define OP_Vacuum 5
15521 #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15522 #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
15523 #define OP_Goto 8 /* jump */
15524 #define OP_Gosub 9 /* jump */
15525 #define OP_InitCoroutine 10 /* jump */
15526 #define OP_Yield 11 /* jump */
15527 #define OP_MustBeInt 12 /* jump */
15528 #define OP_Jump 13 /* jump */
15529 #define OP_Once 14 /* jump */
15530 #define OP_If 15 /* jump */
15531 #define OP_IfNot 16 /* jump */
15532 #define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15533 #define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15534 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15535 #define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */
15536 #define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */
15537 #define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */
15538 #define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */
15539 #define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15540 #define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */
15541 #define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */
15542 #define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */
15543 #define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */
15544 #define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */
15545 #define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */
15546 #define OP_Last 31 /* jump */
15547 #define OP_IfSmaller 32 /* jump */
15548 #define OP_SorterSort 33 /* jump */
15549 #define OP_Sort 34 /* jump */
15550 #define OP_Rewind 35 /* jump */
15551 #define OP_SorterNext 36 /* jump */
15552 #define OP_Prev 37 /* jump */
15553 #define OP_Next 38 /* jump */
15554 #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
15555 #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
15556 #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
15557 #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
15558 #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15301,41 +15581,41 @@
15581 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15582 #define OP_Return 67
15583 #define OP_EndCoroutine 68
15584 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15585 #define OP_Halt 70
15586 #define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587 #define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588 #define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589 #define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15590 #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15591 #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15592 #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15593 #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15594 #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
15595 #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15596 #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
15597 #define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */
15598 #define OP_FkCheck 83
15599 #define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */
15600 #define OP_CollSeq 85
15601 #define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */
15602 #define OP_RealAffinity 87
15603 #define OP_Cast 88 /* synopsis: affinity(r[P1]) */
15604 #define OP_Permutation 89
15605 #define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15606 #define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15607 #define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15608 #define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609 #define OP_Column 94 /* synopsis: r[P3]=PX */
15610 #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15611 #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15612 #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15613 #define OP_Count 98 /* synopsis: r[P2]=count() */
15614 #define OP_ReadCookie 99
15615 #define OP_SetCookie 100
15616 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */
15617 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15618 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15619 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15620 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15621 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15342,82 +15622,84 @@
15622 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15623 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15624 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15625 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15626 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15627 #define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */
15628 #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */
15629 #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15630 #define OP_OpenDup 115
15631 #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
15632 #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15633 #define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */
15634 #define OP_SorterOpen 119
15635 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15636 #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
15637 #define OP_Close 122
15638 #define OP_ColumnsUsed 123
15639 #define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */
15640 #define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */
15641 #define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */
15642 #define OP_NewRowid 127 /* synopsis: r[P2]=rowid */
15643 #define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */
15644 #define OP_RowCell 129
15645 #define OP_Delete 130
15646 #define OP_ResetCount 131
15647 #define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15648 #define OP_SorterData 133 /* synopsis: r[P2]=data */
15649 #define OP_RowData 134 /* synopsis: r[P2]=data */
15650 #define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15651 #define OP_NullRow 136
15652 #define OP_SeekEnd 137
15653 #define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15654 #define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15655 #define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
15656 #define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */
15657 #define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */
15658 #define OP_FinishSeek 143
15659 #define OP_Destroy 144
15660 #define OP_Clear 145
15661 #define OP_ResetSorter 146
15662 #define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15663 #define OP_SqlExec 148
15664 #define OP_ParseSchema 149
15665 #define OP_LoadAnalysis 150
15666 #define OP_DropTable 151
15667 #define OP_DropIndex 152
15668 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15669 #define OP_DropTrigger 154
15670 #define OP_IntegrityCk 155
15671 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */
15672 #define OP_Param 157
15673 #define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */
15674 #define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15675 #define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15676 #define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15677 #define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15678 #define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15679 #define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */
15680 #define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */
15681 #define OP_Expire 166
15682 #define OP_CursorLock 167
15683 #define OP_CursorUnlock 168
15684 #define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */
15685 #define OP_VBegin 170
15686 #define OP_VCreate 171
15687 #define OP_VDestroy 172
15688 #define OP_VOpen 173
15689 #define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15690 #define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15691 #define OP_VRename 176
15692 #define OP_Pagecount 177
15693 #define OP_MaxPgcnt 178
15694 #define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15695 #define OP_Trace 180
15696 #define OP_CursorHint 181
15697 #define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15698 #define OP_Noop 183
15699 #define OP_Explain 184
15700 #define OP_Abortable 185
15701
15702 /* Properties such as "out2" or "jump" that are specified in
15703 ** comments following the "case" for each opcode in the vdbe.c
15704 ** are encoded into bitvectors as follows:
15705 */
@@ -15426,34 +15708,34 @@
15708 #define OPFLG_IN2 0x04 /* in2: P2 is an input */
15709 #define OPFLG_IN3 0x08 /* in3: P3 is an input */
15710 #define OPFLG_OUT2 0x10 /* out2: P2 is an output */
15711 #define OPFLG_OUT3 0x20 /* out3: P3 is an output */
15712 #define OPFLG_INITIALIZER {\
15713 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
15714 /* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\
15715 /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\
15716 /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15717 /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15718 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15719 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15720 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15721 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722 /* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15723 /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15724 /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15725 /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
15726 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15727 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15728 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15729 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15730 /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15731 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15732 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15733 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15734 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15735 /* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15736 /* 184 */ 0x00, 0x00,}
15737
15738 /* The resolve3P2Values() routine is able to run faster if it knows
15739 ** the value of the largest JUMP opcode. The smaller the maximum
15740 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15741 ** generated this include file strives to group all JUMP opcodes
@@ -17507,10 +17789,15 @@
17789 ** b-tree.
17790 */
17791 struct UnpackedRecord {
17792 KeyInfo *pKeyInfo; /* Collation and sort-order information */
17793 Mem *aMem; /* Values */
17794 union {
17795 char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */
17796 i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
17797 } u;
17798 int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */
17799 u16 nField; /* Number of entries in apMem[] */
17800 i8 default_rc; /* Comparison result if keys are equal */
17801 u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
17802 i8 r1; /* Value to return if (lhs < rhs) */
17803 i8 r2; /* Value to return if (lhs > rhs) */
@@ -17814,11 +18101,14 @@
18101 ** TK_SELECT: 1st register of result vector */
18102 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18103 ** TK_VARIABLE: variable number (always >= 1).
18104 ** TK_SELECT_COLUMN: column of the result vector */
18105 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18106 union {
18107 int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18108 int iOfst; /* else: start of token from start of statement */
18109 } w;
18110 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18111 union {
18112 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
18113 ** for a column of an index on an expression */
18114 Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -18576,10 +18866,11 @@
18866 ** initialized as they will be set before being used. The boundary is
18867 ** determined by offsetof(Parse,aTempReg).
18868 **************************************************************************/
18869
18870 int aTempReg[8]; /* Holding area for temporary registers */
18871 Parse *pOuterParse; /* Outer Parse object when nested */
18872 Token sNameToken; /* Token with unqualified schema object name */
18873
18874 /************************************************************************
18875 ** Above is constant between recursions. Below is reset before and after
18876 ** each recursion. The boundary between these two regions is determined
@@ -18626,11 +18917,12 @@
18917 #define PARSE_MODE_UNMAP 3
18918
18919 /*
18920 ** Sizes and pointers of various parts of the Parse object.
18921 */
18922 #define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg))
18923 #define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/
18924 #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
18925 #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
18926 #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
18927
18928 /*
@@ -18921,10 +19213,11 @@
19213 #endif
19214 #ifndef SQLITE_UNTESTABLE
19215 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
19216 #endif
19217 int bLocaltimeFault; /* True to fail localtime() calls */
19218 int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
19219 int iOnceResetThreshold; /* When to reset OP_Once counters */
19220 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
19221 unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
19222 /* vvvv--- must be last ---vvv */
19223 #ifdef SQLITE_DEBUG
@@ -19125,11 +19418,11 @@
19418 Expr *pStart; /* Expression for "<expr> PRECEDING" */
19419 Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
19420 Window **ppThis; /* Pointer to this object in Select.pWin list */
19421 Window *pNextWin; /* Next window function belonging to this SELECT */
19422 Expr *pFilter; /* The FILTER expression */
19423 FuncDef *pWFunc; /* The function */
19424 int iEphCsr; /* Partition buffer or Peer buffer */
19425 int regAccum; /* Accumulator */
19426 int regResult; /* Interim result */
19427 int csrApp; /* Function cursor (used by min/max) */
19428 int regApp; /* Function register (also used by min/max) */
@@ -19566,11 +19859,12 @@
19859 #endif
19860 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
19861 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19862 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19863 Upsert*);
19864 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,
19865 ExprList*,Select*,u16,int);
19866 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
19867 SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
19868 SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
19869 SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
19870 SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -19966,11 +20260,11 @@
20260 void (*)(sqlite3_context*),
20261 void (*)(sqlite3_context*,int,sqlite3_value **),
20262 FuncDestructor *pDestructor
20263 );
20264 SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
20265 SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*);
20266 SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
20267 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
20268 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
20269
20270 SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
@@ -19979,10 +20273,11 @@
20273 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
20274 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
20275 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
20276 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
20277 SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
20278 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
20279
20280 SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
20281 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
20282
20283 #ifndef SQLITE_OMIT_SUBQUERY
@@ -20083,15 +20378,21 @@
20378 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
20379 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
20380 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
20381 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
20382 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20383
20384 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20385 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20386 && !defined(SQLITE_OMIT_VIRTUALTABLE)
20387 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20388 #endif
20389 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20390 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20391 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20392 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
20393 SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*);
20394 SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
20395 #ifdef SQLITE_ENABLE_NORMALIZE
20396 SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
20397 #endif
20398 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
@@ -20520,10 +20821,18 @@
20821
20822 #endif /* !defined(_OS_COMMON_H_) */
20823
20824 /************** End of os_common.h *******************************************/
20825 /************** Begin file ctime.c *******************************************/
20826 /* DO NOT EDIT!
20827 ** This file is automatically generated by the script in the canonical
20828 ** SQLite source tree at tool/mkctimec.tcl.
20829 **
20830 ** To modify this header, edit any of the various lists in that script
20831 ** which specify categories of generated conditionals in this file.
20832 */
20833
20834 /*
20835 ** 2010 February 23
20836 **
20837 ** The author disclaims copyright to this source code. In place of
20838 ** a legal notice, here is a blessing:
@@ -20568,13 +20877,10 @@
20877 ** only a handful of compile-time options, so most times this array is usually
20878 ** rather short and uses little memory space.
20879 */
20880 static const char * const sqlite3azCompileOpt[] = {
20881
 
 
 
20882 #ifdef SQLITE_32BIT_ROWID
20883 "32BIT_ROWID",
20884 #endif
20885 #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
20886 "4_BYTE_ALIGNED_MALLOC",
@@ -20701,13 +21007,10 @@
21007 "DISABLE_FTS4_DEFERRED",
21008 #endif
21009 #ifdef SQLITE_DISABLE_INTRINSIC
21010 "DISABLE_INTRINSIC",
21011 #endif
 
 
 
21012 #ifdef SQLITE_DISABLE_LFS
21013 "DISABLE_LFS",
21014 #endif
21015 #ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
21016 "DISABLE_PAGECACHE_OVERFLOW_STATS",
@@ -21104,10 +21407,13 @@
21407 #ifdef SQLITE_OMIT_INTEGRITY_CHECK
21408 "OMIT_INTEGRITY_CHECK",
21409 #endif
21410 #ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS
21411 "OMIT_INTROSPECTION_PRAGMAS",
21412 #endif
21413 #ifdef SQLITE_OMIT_JSON
21414 "OMIT_JSON",
21415 #endif
21416 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
21417 "OMIT_LIKE_OPTIMIZATION",
21418 #endif
21419 #ifdef SQLITE_OMIT_LOAD_EXTENSION
@@ -21293,14 +21599,12 @@
21599 "WIN32_MALLOC",
21600 #endif
21601 #ifdef SQLITE_ZERO_MALLOC
21602 "ZERO_MALLOC",
21603 #endif
21604
21605 } ;
 
 
21606
21607 SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
21608 *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
21609 return (const char**)sqlite3azCompileOpt;
21610 }
@@ -21595,13 +21899,17 @@
21899 #endif
21900 #ifndef SQLITE_UNTESTABLE
21901 0, /* xTestCallback */
21902 #endif
21903 0, /* bLocaltimeFault */
21904 0, /* xAltLocaltime */
21905 0x7ffffffe, /* iOnceResetThreshold */
21906 SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
21907 0, /* iPrngSeed */
21908 #ifdef SQLITE_DEBUG
21909 {0,0,0,0,0,0} /* aTune */
21910 #endif
21911 };
21912
21913 /*
21914 ** Hash table for global functions - functions common to all
21915 ** database connections. After initialization, this table is
@@ -21941,20 +22249,20 @@
22249 i64 i; /* Integer value used when MEM_Int is set in flags */
22250 int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
22251 const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
22252 FuncDef *pDef; /* Used only when flags==MEM_Agg */
22253 } u;
22254 char *z; /* String or BLOB value */
22255 int n; /* Number of characters in string value, excluding '\0' */
22256 u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
22257 u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
22258 u8 eSubtype; /* Subtype for this value */
 
 
22259 /* ShallowCopy only needs to copy the information above */
22260 sqlite3 *db; /* The associated database connection */
22261 int szMalloc; /* Size of the zMalloc allocation */
22262 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
22263 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
22264 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
22265 #ifdef SQLITE_DEBUG
22266 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
22267 u16 mScopyFlags; /* flags value immediately after the shallow copy */
22268 #endif
@@ -21962,15 +22270,47 @@
22270
22271 /*
22272 ** Size of struct Mem not including the Mem.zMalloc member or anything that
22273 ** follows.
22274 */
22275 #define MEMCELLSIZE offsetof(Mem,db)
22276
22277 /* One or more of the following flags are set to indicate the
22278 ** representations of the value stored in the Mem struct.
22279 **
22280 ** * MEM_Null An SQL NULL value
22281 **
22282 ** * MEM_Null|MEM_Zero An SQL NULL with the virtual table
22283 ** UPDATE no-change flag set
22284 **
22285 ** * MEM_Null|MEM_Term| An SQL NULL, but also contains a
22286 ** MEM_Subtype pointer accessible using
22287 ** sqlite3_value_pointer().
22288 **
22289 ** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal
22290 ** to other NULLs even using the IS operator.
22291 **
22292 ** * MEM_Str A string, stored in Mem.z with
22293 ** length Mem.n. Zero-terminated if
22294 ** MEM_Term is set. This flag is
22295 ** incompatible with MEM_Blob and
22296 ** MEM_Null, but can appear with MEM_Int,
22297 ** MEM_Real, and MEM_IntReal.
22298 **
22299 ** * MEM_Blob A blob, stored in Mem.z length Mem.n.
22300 ** Incompatible with MEM_Str, MEM_Null,
22301 ** MEM_Int, MEM_Real, and MEM_IntReal.
22302 **
22303 ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus
22304 ** MEM.u.i extra 0x00 bytes at the end.
22305 **
22306 ** * MEM_Int Integer stored in Mem.u.i.
22307 **
22308 ** * MEM_Real Real stored in Mem.u.r.
22309 **
22310 ** * MEM_IntReal Real stored as an integer in Mem.u.i.
22311 **
22312 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
22313 ** For a pointer type created using sqlite3_bind_pointer() or
22314 ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
22315 **
22316 ** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -21977,39 +22317,36 @@
22317 ** Usually this is encoded in the same unicode encoding as the main
22318 ** database (see below for exceptions). If the MEM_Term flag is also
22319 ** set, then the string is nul terminated. The MEM_Int and MEM_Real
22320 ** flags may coexist with the MEM_Str flag.
22321 */
22322 #define MEM_Undefined 0x0000 /* Value is undefined */
22323 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
22324 #define MEM_Str 0x0002 /* Value is a string */
22325 #define MEM_Int 0x0004 /* Value is an integer */
22326 #define MEM_Real 0x0008 /* Value is a real number */
22327 #define MEM_Blob 0x0010 /* Value is a BLOB */
22328 #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
22329 #define MEM_AffMask 0x003f /* Mask of affinity bits */
22330
22331 /* Extra bits that modify the meanings of the core datatypes above
22332 */
22333 #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
22334 /* 0x0080 // Available */
22335 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
 
 
 
 
 
 
 
 
22336 #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22337 #define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */
22338 #define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */
22339 #define MEM_TypeMask 0x0dbf /* Mask of type bits */
22340
22341 /* Bits that determine the storage for Mem.z for a string or blob or
22342 ** aggregate accumulator.
22343 */
22344 #define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */
22345 #define MEM_Static 0x2000 /* Mem.z points to a static string */
22346 #define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */
22347 #define MEM_Agg 0x8000 /* Mem.z points to an agg function context */
22348
22349 /* Return TRUE if Mem X contains dynamically allocated content - anything
22350 ** that needs to be deallocated to avoid a leak.
22351 */
22352 #define VdbeMemDynamic(X) \
@@ -22027,15 +22364,19 @@
22364 #define MemNullNochng(X) \
22365 (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
22366 && (X)->n==0 && (X)->u.nZero==0)
22367
22368 /*
22369 ** Return true if a memory cell has been initialized and is valid.
22370 ** is for use inside assert() statements only.
22371 **
22372 ** A Memory cell is initialized if at least one of the
22373 ** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits
22374 ** is set. It is "undefined" if all those bits are zero.
22375 */
22376 #ifdef SQLITE_DEBUG
22377 #define memIsValid(M) ((M)->flags & MEM_AffMask)!=0
22378 #endif
22379
22380 /*
22381 ** Each auxiliary data pointer stored by a user defined function
22382 ** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22215,18 +22556,36 @@
22556 Mem *aNew; /* Array of new.* values */
22557 Table *pTab; /* Schema object being upated */
22558 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
22559 };
22560
22561 /*
22562 ** An instance of this object is used to pass an vector of values into
22563 ** OP_VFilter, the xFilter method of a virtual table. The vector is the
22564 ** set of values on the right-hand side of an IN constraint.
22565 **
22566 ** The value as passed into xFilter is an sqlite3_value with a "pointer"
22567 ** type, such as is generated by sqlite3_result_pointer() and read by
22568 ** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
22569 ** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
22570 ** know how to use this object to step through all the values in the
22571 ** right operand of the IN constraint.
22572 */
22573 typedef struct ValueList ValueList;
22574 struct ValueList {
22575 BtCursor *pCsr; /* An ephemeral table holding all values */
22576 sqlite3_value *pOut; /* Register to hold each decoded output value */
22577 };
22578
22579 /*
22580 ** Function prototypes
22581 */
22582 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22583 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22584 void sqliteVdbePopStack(Vdbe*,int);
22585 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
22586 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
 
22587 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22588 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22589 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22590 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
22591 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22284,10 +22643,11 @@
22643 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
22644 SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
22645 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
22646 SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
22647 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
22648 SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p);
22649 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
22650 #ifndef SQLITE_OMIT_WINDOWFUNC
22651 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
22652 #endif
22653 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23251,12 +23611,14 @@
23611 ** The following routine implements the rough equivalent of localtime_r()
23612 ** using whatever operating-system specific localtime facility that
23613 ** is available. This routine returns 0 on success and
23614 ** non-zero on any kind of error.
23615 **
23616 ** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
23617 ** routine will always fail. If bLocaltimeFault is nonzero and
23618 ** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
23619 ** invoked in place of the OS-defined localtime() function.
23620 **
23621 ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
23622 ** library function localtime_r() is used to assist in the calculation of
23623 ** local time.
23624 */
@@ -23268,20 +23630,34 @@
23630 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
23631 #endif
23632 sqlite3_mutex_enter(mutex);
23633 pX = localtime(t);
23634 #ifndef SQLITE_UNTESTABLE
23635 if( sqlite3GlobalConfig.bLocaltimeFault ){
23636 if( sqlite3GlobalConfig.xAltLocaltime!=0
23637 && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
23638 ){
23639 pX = pTm;
23640 }else{
23641 pX = 0;
23642 }
23643 }
23644 #endif
23645 if( pX ) *pTm = *pX;
23646 #if SQLITE_THREADSAFE>0
23647 sqlite3_mutex_leave(mutex);
23648 #endif
23649 rc = pX==0;
23650 #else
23651 #ifndef SQLITE_UNTESTABLE
23652 if( sqlite3GlobalConfig.bLocaltimeFault ){
23653 if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
23654 return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
23655 }else{
23656 return 1;
23657 }
23658 }
23659 #endif
23660 #if HAVE_LOCALTIME_R
23661 rc = localtime_r(t, pTm)==0;
23662 #else
23663 rc = localtime_s(pTm, t);
@@ -23292,71 +23668,60 @@
23668 #endif /* SQLITE_OMIT_LOCALTIME */
23669
23670
23671 #ifndef SQLITE_OMIT_LOCALTIME
23672 /*
23673 ** Assuming the input DateTime is UTC, move it to its localtime equivalent.
 
 
 
 
 
23674 */
23675 static int toLocaltime(
23676 DateTime *p, /* Date at which to calculate offset */
23677 sqlite3_context *pCtx /* Write error here if one occurs */
 
23678 ){
 
23679 time_t t;
23680 struct tm sLocal;
23681 int iYearDiff;
23682
23683 /* Initialize the contents of sLocal to avoid a compiler warning. */
23684 memset(&sLocal, 0, sizeof(sLocal));
23685
23686 computeJD(p);
23687 if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
23688 || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
23689 ){
23690 /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
23691 ** works for years between 1970 and 2037. For dates outside this range,
23692 ** SQLite attempts to map the year into an equivalent year within this
23693 ** range, do the calculation, then map the year back.
23694 */
23695 DateTime x = *p;
23696 computeYMD_HMS(&x);
23697 iYearDiff = (2000 + x.Y%4) - x.Y;
23698 x.Y += iYearDiff;
23699 x.validJD = 0;
23700 computeJD(&x);
23701 t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23702 }else{
23703 iYearDiff = 0;
23704 t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
23705 }
 
 
 
23706 if( osLocaltime(&t, &sLocal) ){
23707 sqlite3_result_error(pCtx, "local time unavailable", -1);
23708 return SQLITE_ERROR;
23709 }
23710 p->Y = sLocal.tm_year + 1900 - iYearDiff;
23711 p->M = sLocal.tm_mon + 1;
23712 p->D = sLocal.tm_mday;
23713 p->h = sLocal.tm_hour;
23714 p->m = sLocal.tm_min;
23715 p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
23716 p->validYMD = 1;
23717 p->validHMS = 1;
23718 p->validJD = 0;
23719 p->rawS = 0;
23720 p->validTZ = 0;
23721 p->isError = 0;
23722 return SQLITE_OK;
 
 
 
23723 }
23724 #endif /* SQLITE_OMIT_LOCALTIME */
23725
23726 /*
23727 ** The following table defines various date transformations of the form
@@ -23406,11 +23771,12 @@
23771 */
23772 static int parseModifier(
23773 sqlite3_context *pCtx, /* Function context */
23774 const char *z, /* The text of the modifier */
23775 int n, /* Length of zMod in bytes */
23776 DateTime *p, /* The date/time value to be modified */
23777 int idx /* Parameter index of the modifier */
23778 ){
23779 int rc = 1;
23780 double r;
23781 switch(sqlite3UpperToLower[(u8)z[0]] ){
23782 case 'a': {
@@ -23419,14 +23785,17 @@
23785 **
23786 ** If rawS is available, then interpret as a julian day number, or
23787 ** a unix timestamp, depending on its magnitude.
23788 */
23789 if( sqlite3_stricmp(z, "auto")==0 ){
23790 if( idx>1 ) return 1; /* IMP: R-33611-57934 */
23791 if( !p->rawS || p->validJD ){
23792 rc = 0;
23793 p->rawS = 0;
23794 }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
23795 && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
23796 ){
23797 r = p->s*1000.0 + 210866760000000.0;
23798 clearYMD_HMS_TZ(p);
23799 p->iJD = (sqlite3_int64)(r + 0.5);
23800 p->validJD = 1;
23801 p->rawS = 0;
@@ -23443,10 +23812,11 @@
23812 ** is not the first modifier, or if the prior argument is not a numeric
23813 ** value in the allowed range of julian day numbers understood by
23814 ** SQLite (0..5373484.5) then the result will be NULL.
23815 */
23816 if( sqlite3_stricmp(z, "julianday")==0 ){
23817 if( idx>1 ) return 1; /* IMP: R-31176-64601 */
23818 if( p->validJD && p->rawS ){
23819 rc = 0;
23820 p->rawS = 0;
23821 }
23822 }
@@ -23458,13 +23828,11 @@
23828 **
23829 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
23830 ** show local time.
23831 */
23832 if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23833 rc = toLocaltime(p, pCtx);
 
 
23834 }
23835 break;
23836 }
23837 #endif
23838 case 'u': {
@@ -23473,10 +23841,11 @@
23841 **
23842 ** Treat the current value of p->s as the number of
23843 ** seconds since 1970. Convert to a real julian day number.
23844 */
23845 if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
23846 if( idx>1 ) return 1; /* IMP: R-49255-55373 */
23847 r = p->s*1000.0 + 210866760000000.0;
23848 if( r>=0.0 && r<464269060800000.0 ){
23849 clearYMD_HMS_TZ(p);
23850 p->iJD = (sqlite3_int64)(r + 0.5);
23851 p->validJD = 1;
@@ -23485,22 +23854,35 @@
23854 }
23855 }
23856 #ifndef SQLITE_OMIT_LOCALTIME
23857 else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
23858 if( p->tzSet==0 ){
23859 i64 iOrigJD; /* Original localtime */
23860 i64 iGuess; /* Guess at the corresponding utc time */
23861 int cnt = 0; /* Safety to prevent infinite loop */
23862 int iErr; /* Guess is off by this much */
23863
23864 computeJD(p);
23865 iGuess = iOrigJD = p->iJD;
23866 iErr = 0;
23867 do{
23868 DateTime new;
23869 memset(&new, 0, sizeof(new));
23870 iGuess -= iErr;
23871 new.iJD = iGuess;
23872 new.validJD = 1;
23873 rc = toLocaltime(&new, pCtx);
23874 if( rc ) return rc;
23875 computeJD(&new);
23876 iErr = new.iJD - iOrigJD;
23877 }while( iErr && cnt++<3 );
23878 memset(p, 0, sizeof(*p));
23879 p->iJD = iGuess;
23880 p->validJD = 1;
23881 p->tzSet = 1;
 
 
23882 }
23883 rc = SQLITE_OK;
23884 }
23885 #endif
23886 break;
23887 }
23888 case 'w': {
@@ -23686,11 +24068,11 @@
24068 }
24069 }
24070 for(i=1; i<argc; i++){
24071 z = sqlite3_value_text(argv[i]);
24072 n = sqlite3_value_bytes(argv[i]);
24073 if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
24074 }
24075 computeJD(p);
24076 if( p->isError || !validJulianDay(p->iJD) ) return 1;
24077 return 0;
24078 }
@@ -23746,15 +24128,42 @@
24128 int argc,
24129 sqlite3_value **argv
24130 ){
24131 DateTime x;
24132 if( isDate(context, argc, argv, &x)==0 ){
24133 int Y, s;
24134 char zBuf[24];
24135 computeYMD_HMS(&x);
24136 Y = x.Y;
24137 if( Y<0 ) Y = -Y;
24138 zBuf[1] = '0' + (Y/1000)%10;
24139 zBuf[2] = '0' + (Y/100)%10;
24140 zBuf[3] = '0' + (Y/10)%10;
24141 zBuf[4] = '0' + (Y)%10;
24142 zBuf[5] = '-';
24143 zBuf[6] = '0' + (x.M/10)%10;
24144 zBuf[7] = '0' + (x.M)%10;
24145 zBuf[8] = '-';
24146 zBuf[9] = '0' + (x.D/10)%10;
24147 zBuf[10] = '0' + (x.D)%10;
24148 zBuf[11] = ' ';
24149 zBuf[12] = '0' + (x.h/10)%10;
24150 zBuf[13] = '0' + (x.h)%10;
24151 zBuf[14] = ':';
24152 zBuf[15] = '0' + (x.m/10)%10;
24153 zBuf[16] = '0' + (x.m)%10;
24154 zBuf[17] = ':';
24155 s = (int)x.s;
24156 zBuf[18] = '0' + (s/10)%10;
24157 zBuf[19] = '0' + (s)%10;
24158 zBuf[20] = 0;
24159 if( x.Y<0 ){
24160 zBuf[0] = '-';
24161 sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
24162 }else{
24163 sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
24164 }
24165 }
24166 }
24167
24168 /*
24169 ** time( TIMESTRING, MOD, MOD, ...)
@@ -23766,14 +24175,24 @@
24175 int argc,
24176 sqlite3_value **argv
24177 ){
24178 DateTime x;
24179 if( isDate(context, argc, argv, &x)==0 ){
24180 int s;
24181 char zBuf[16];
24182 computeHMS(&x);
24183 zBuf[0] = '0' + (x.h/10)%10;
24184 zBuf[1] = '0' + (x.h)%10;
24185 zBuf[2] = ':';
24186 zBuf[3] = '0' + (x.m/10)%10;
24187 zBuf[4] = '0' + (x.m)%10;
24188 zBuf[5] = ':';
24189 s = (int)x.s;
24190 zBuf[6] = '0' + (s/10)%10;
24191 zBuf[7] = '0' + (s)%10;
24192 zBuf[8] = 0;
24193 sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
24194 }
24195 }
24196
24197 /*
24198 ** date( TIMESTRING, MOD, MOD, ...)
@@ -23785,14 +24204,32 @@
24204 int argc,
24205 sqlite3_value **argv
24206 ){
24207 DateTime x;
24208 if( isDate(context, argc, argv, &x)==0 ){
24209 int Y;
24210 char zBuf[16];
24211 computeYMD(&x);
24212 Y = x.Y;
24213 if( Y<0 ) Y = -Y;
24214 zBuf[1] = '0' + (Y/1000)%10;
24215 zBuf[2] = '0' + (Y/100)%10;
24216 zBuf[3] = '0' + (Y/10)%10;
24217 zBuf[4] = '0' + (Y)%10;
24218 zBuf[5] = '-';
24219 zBuf[6] = '0' + (x.M/10)%10;
24220 zBuf[7] = '0' + (x.M)%10;
24221 zBuf[8] = '-';
24222 zBuf[9] = '0' + (x.D/10)%10;
24223 zBuf[10] = '0' + (x.D)%10;
24224 zBuf[11] = 0;
24225 if( x.Y<0 ){
24226 zBuf[0] = '-';
24227 sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
24228 }else{
24229 sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
24230 }
24231 }
24232 }
24233
24234 /*
24235 ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -28956,22 +29393,31 @@
29393 /*
29394 ** Call this routine to record the fact that an OOM (out-of-memory) error
29395 ** has happened. This routine will set db->mallocFailed, and also
29396 ** temporarily disable the lookaside memory allocator and interrupt
29397 ** any running VDBEs.
29398 **
29399 ** Always return a NULL pointer so that this routine can be invoked using
29400 **
29401 ** return sqlite3OomFault(db);
29402 **
29403 ** and thereby avoid unnecessary stack frame allocations for the overwhelmingly
29404 ** common case where no OOM occurs.
29405 */
29406 SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){
29407 if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
29408 db->mallocFailed = 1;
29409 if( db->nVdbeExec>0 ){
29410 AtomicStore(&db->u1.isInterrupted, 1);
29411 }
29412 DisableLookaside;
29413 if( db->pParse ){
29414 sqlite3ErrorMsg(db->pParse, "out of memory");
29415 db->pParse->rc = SQLITE_NOMEM_BKPT;
29416 }
29417 }
29418 return 0;
29419 }
29420
29421 /*
29422 ** This routine reactivates the memory allocator and clears the
29423 ** db->mallocFailed flag as necessary.
@@ -29876,17 +30322,26 @@
30322 bufpt[j] = 0;
30323 length = j;
30324 goto adjust_width_for_utf8;
30325 }
30326 case etTOKEN: {
 
30327 if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
30328 if( flag_alternateform ){
30329 /* %#T means an Expr pointer that uses Expr.u.zToken */
30330 Expr *pExpr = va_arg(ap,Expr*);
30331 if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){
30332 sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken);
30333 sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr);
30334 }
30335 }else{
30336 /* %T means a Token pointer */
30337 Token *pToken = va_arg(ap, Token*);
30338 assert( bArgList==0 );
30339 if( pToken && pToken->n ){
30340 sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
30341 sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30342 }
30343 }
30344 length = width = 0;
30345 break;
30346 }
30347 case etSRCITEM: {
@@ -29960,10 +30415,22 @@
30415 zEnd = &zText[strlen(zText)];
30416 if( SQLITE_WITHIN(z,zText,zEnd) ){
30417 db->errByteOffset = (int)(z-zText);
30418 }
30419 }
30420
30421 /*
30422 ** If pExpr has a byte offset for the start of a token, record that as
30423 ** as the error offset.
30424 */
30425 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30426 while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
30427 pExpr = pExpr->pLeft;
30428 }
30429 if( pExpr==0 ) return;
30430 db->errByteOffset = pExpr->w.iOfst;
30431 }
30432
30433 /*
30434 ** Enlarge the memory allocation on a StrAccum object so that it is
30435 ** able to accept at least N more bytes of text.
30436 **
@@ -30423,11 +30890,11 @@
30890 memset(p, 0, sizeof(*p));
30891 }else{
30892 p->iLevel++;
30893 }
30894 assert( moreToFollow==0 || moreToFollow==1 );
30895 if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30896 return p;
30897 }
30898
30899 /*
30900 ** Finished with one layer of the tree
@@ -30447,11 +30914,11 @@
30914 int i;
30915 StrAccum acc;
30916 char zBuf[500];
30917 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
30918 if( p ){
30919 for(i=0; i<p->iLevel && i<(int)sizeof(p->bLine)-1; i++){
30920 sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
30921 }
30922 sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
30923 }
30924 if( zFormat!=0 ){
@@ -30777,11 +31244,11 @@
31244 ** Generate a human-readable explanation for a Window Function object
31245 */
31246 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
31247 pView = sqlite3TreeViewPush(pView, more);
31248 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
31249 pWin->pWFunc->zName, pWin->pWFunc->nArg);
31250 sqlite3TreeViewWindow(pView, pWin, 0);
31251 sqlite3TreeViewPop(pView);
31252 }
31253 #endif /* SQLITE_OMIT_WINDOWFUNC */
31254
@@ -30802,11 +31269,11 @@
31269 StrAccum x;
31270 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31271 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31272 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31273 if( ExprHasProperty(pExpr, EP_FromJoin) ){
31274 sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
31275 }
31276 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31277 sqlite3_str_appendf(&x, " DDL");
31278 }
31279 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -32356,17 +32823,23 @@
32823 */
32824 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
32825 char *zMsg;
32826 va_list ap;
32827 sqlite3 *db = pParse->db;
32828 assert( db!=0 );
32829 assert( db->pParse==pParse );
32830 db->errByteOffset = -2;
32831 va_start(ap, zFormat);
32832 zMsg = sqlite3VMPrintf(db, zFormat, ap);
32833 va_end(ap);
32834 if( db->errByteOffset<-1 ) db->errByteOffset = -1;
32835 if( db->suppressErr ){
32836 sqlite3DbFree(db, zMsg);
32837 if( db->mallocFailed ){
32838 pParse->nErr++;
32839 pParse->rc = SQLITE_NOMEM;
32840 }
32841 }else{
32842 pParse->nErr++;
32843 sqlite3DbFree(db, pParse->zErrMsg);
32844 pParse->zErrMsg = zMsg;
32845 pParse->rc = SQLITE_ERROR;
@@ -34164,46 +34637,46 @@
34637 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
34638 static const char *const azName[] = {
34639 /* 0 */ "Savepoint" OpHelp(""),
34640 /* 1 */ "AutoCommit" OpHelp(""),
34641 /* 2 */ "Transaction" OpHelp(""),
34642 /* 3 */ "Checkpoint" OpHelp(""),
34643 /* 4 */ "JournalMode" OpHelp(""),
34644 /* 5 */ "Vacuum" OpHelp(""),
34645 /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34646 /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34647 /* 8 */ "Goto" OpHelp(""),
34648 /* 9 */ "Gosub" OpHelp(""),
34649 /* 10 */ "InitCoroutine" OpHelp(""),
34650 /* 11 */ "Yield" OpHelp(""),
34651 /* 12 */ "MustBeInt" OpHelp(""),
34652 /* 13 */ "Jump" OpHelp(""),
34653 /* 14 */ "Once" OpHelp(""),
34654 /* 15 */ "If" OpHelp(""),
34655 /* 16 */ "IfNot" OpHelp(""),
34656 /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34657 /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34658 /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34659 /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34660 /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34661 /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34662 /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34663 /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34664 /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34665 /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34666 /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"),
34667 /* 28 */ "Found" OpHelp("key=r[P3@P4]"),
34668 /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34669 /* 30 */ "NotExists" OpHelp("intkey=r[P3]"),
34670 /* 31 */ "Last" OpHelp(""),
34671 /* 32 */ "IfSmaller" OpHelp(""),
34672 /* 33 */ "SorterSort" OpHelp(""),
34673 /* 34 */ "Sort" OpHelp(""),
34674 /* 35 */ "Rewind" OpHelp(""),
34675 /* 36 */ "SorterNext" OpHelp(""),
34676 /* 37 */ "Prev" OpHelp(""),
34677 /* 38 */ "Next" OpHelp(""),
34678 /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
34679 /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
34680 /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
34681 /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
34682 /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34232,41 +34705,41 @@
34705 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34706 /* 67 */ "Return" OpHelp(""),
34707 /* 68 */ "EndCoroutine" OpHelp(""),
34708 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34709 /* 70 */ "Halt" OpHelp(""),
34710 /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34711 /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34712 /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34713 /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34714 /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
34715 /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
34716 /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34717 /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34718 /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34719 /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34720 /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34721 /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34722 /* 83 */ "FkCheck" OpHelp(""),
34723 /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34724 /* 85 */ "CollSeq" OpHelp(""),
34725 /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34726 /* 87 */ "RealAffinity" OpHelp(""),
34727 /* 88 */ "Cast" OpHelp("affinity(r[P1])"),
34728 /* 89 */ "Permutation" OpHelp(""),
34729 /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34730 /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34731 /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34732 /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34733 /* 94 */ "Column" OpHelp("r[P3]=PX"),
34734 /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34735 /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34736 /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34737 /* 98 */ "Count" OpHelp("r[P2]=count()"),
34738 /* 99 */ "ReadCookie" OpHelp(""),
34739 /* 100 */ "SetCookie" OpHelp(""),
34740 /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34741 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
34742 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
34743 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
34744 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
34745 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34273,82 +34746,84 @@
34746 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
34747 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34748 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34749 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34750 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34751 /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34752 /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34753 /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34754 /* 115 */ "OpenDup" OpHelp(""),
34755 /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34756 /* 117 */ "String8" OpHelp("r[P2]='P4'"),
34757 /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34758 /* 119 */ "SorterOpen" OpHelp(""),
34759 /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34760 /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34761 /* 122 */ "Close" OpHelp(""),
34762 /* 123 */ "ColumnsUsed" OpHelp(""),
34763 /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34764 /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34765 /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34766 /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"),
34767 /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34768 /* 129 */ "RowCell" OpHelp(""),
34769 /* 130 */ "Delete" OpHelp(""),
34770 /* 131 */ "ResetCount" OpHelp(""),
34771 /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34772 /* 133 */ "SorterData" OpHelp("r[P2]=data"),
34773 /* 134 */ "RowData" OpHelp("r[P2]=data"),
34774 /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
34775 /* 136 */ "NullRow" OpHelp(""),
34776 /* 137 */ "SeekEnd" OpHelp(""),
34777 /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
34778 /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
34779 /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34780 /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34781 /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34782 /* 143 */ "FinishSeek" OpHelp(""),
34783 /* 144 */ "Destroy" OpHelp(""),
34784 /* 145 */ "Clear" OpHelp(""),
34785 /* 146 */ "ResetSorter" OpHelp(""),
34786 /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34787 /* 148 */ "SqlExec" OpHelp(""),
34788 /* 149 */ "ParseSchema" OpHelp(""),
34789 /* 150 */ "LoadAnalysis" OpHelp(""),
34790 /* 151 */ "DropTable" OpHelp(""),
34791 /* 152 */ "DropIndex" OpHelp(""),
34792 /* 153 */ "Real" OpHelp("r[P2]=P4"),
34793 /* 154 */ "DropTrigger" OpHelp(""),
34794 /* 155 */ "IntegrityCk" OpHelp(""),
34795 /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34796 /* 157 */ "Param" OpHelp(""),
34797 /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34798 /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34799 /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34800 /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34801 /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34802 /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34803 /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34804 /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34805 /* 166 */ "Expire" OpHelp(""),
34806 /* 167 */ "CursorLock" OpHelp(""),
34807 /* 168 */ "CursorUnlock" OpHelp(""),
34808 /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34809 /* 170 */ "VBegin" OpHelp(""),
34810 /* 171 */ "VCreate" OpHelp(""),
34811 /* 172 */ "VDestroy" OpHelp(""),
34812 /* 173 */ "VOpen" OpHelp(""),
34813 /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
34814 /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34815 /* 176 */ "VRename" OpHelp(""),
34816 /* 177 */ "Pagecount" OpHelp(""),
34817 /* 178 */ "MaxPgcnt" OpHelp(""),
34818 /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34819 /* 180 */ "Trace" OpHelp(""),
34820 /* 181 */ "CursorHint" OpHelp(""),
34821 /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34822 /* 183 */ "Noop" OpHelp(""),
34823 /* 184 */ "Explain" OpHelp(""),
34824 /* 185 */ "Abortable" OpHelp(""),
34825 };
34826 return azName[i];
34827 }
34828 #endif
34829
@@ -39264,15 +39739,21 @@
39739 int ofst, /* First lock to acquire or release */
39740 int n, /* Number of locks to acquire or release */
39741 int flags /* What to do with the lock */
39742 ){
39743 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39744 unixShm *p; /* The shared memory being locked */
39745 unixShmNode *pShmNode; /* The underlying file iNode */
39746 int rc = SQLITE_OK; /* Result code */
39747 u16 mask; /* Mask of locks to take or release */
39748 int *aLock;
39749
39750 p = pDbFd->pShm;
39751 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
39752 pShmNode = p->pShmNode;
39753 if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
39754 aLock = pShmNode->aLock;
39755
39756 assert( pShmNode==pDbFd->pInode->pShmNode );
39757 assert( pShmNode->pInode==pDbFd->pInode );
39758 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
39759 assert( n>=1 );
@@ -40365,24 +40846,27 @@
40846 ** "<path to db>-journalNN"
40847 ** "<path to db>-walNN"
40848 **
40849 ** where NN is a decimal number. The NN naming schemes are
40850 ** used by the test_multiplex.c module.
40851 **
40852 ** In normal operation, the journal file name will always contain
40853 ** a '-' character. However in 8+3 filename mode, or if a corrupt
40854 ** rollback journal specifies a super-journal with a goofy name, then
40855 ** the '-' might be missing or the '-' might be the first character in
40856 ** the filename. In that case, just return SQLITE_OK with *pMode==0.
40857 */
40858 nDb = sqlite3Strlen30(zPath) - 1;
40859 while( nDb>0 && zPath[nDb]!='.' ){
40860 if( zPath[nDb]=='-' ){
40861 memcpy(zDb, zPath, nDb);
40862 zDb[nDb] = '\0';
40863 rc = getFileMode(zDb, pMode, pUid, pGid);
40864 break;
40865 }
40866 nDb--;
40867 }
 
 
 
 
40868 }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
40869 *pMode = 0600;
40870 }else if( flags & SQLITE_OPEN_URI ){
40871 /* If this is a main database file and the file was opened using a URI
40872 ** filename, check for the "modeof" parameter. If present, interpret
@@ -46556,14 +47040,18 @@
47040 int flags /* What to do with the lock */
47041 ){
47042 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
47043 winShm *p = pDbFd->pShm; /* The shared memory being locked */
47044 winShm *pX; /* For looping over all siblings */
47045 winShmNode *pShmNode;
47046 int rc = SQLITE_OK; /* Result code */
47047 u16 mask; /* Mask of locks to take or release */
47048
47049 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
47050 pShmNode = p->pShmNode;
47051 if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
47052
47053 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
47054 assert( n>=1 );
47055 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
47056 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
47057 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53458,10 +53946,11 @@
53946 u16 nExtra; /* Add this many bytes to each in-memory page */
53947 i16 nReserve; /* Number of unused bytes at end of each page */
53948 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
53949 u32 sectorSize; /* Assumed sector size during rollback */
53950 Pgno mxPgno; /* Maximum allowed size of the database */
53951 Pgno lckPgno; /* Page number for the locking page */
53952 i64 pageSize; /* Number of bytes in a page */
53953 i64 journalSizeLimit; /* Size limit for persistent journal files */
53954 char *zFilename; /* Name of the database file */
53955 char *zJournal; /* Name of the journal file */
53956 int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54444,11 +54933,11 @@
54933 ** pPager at the current location. The super-journal name must be the last
54934 ** thing written to a journal file. If the pager is in full-sync mode, the
54935 ** journal file descriptor is advanced to the next sector boundary before
54936 ** anything is written. The format is:
54937 **
54938 ** + 4 bytes: PAGER_SJ_PGNO.
54939 ** + N bytes: super-journal filename in utf-8.
54940 ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
54941 ** + 4 bytes: super-journal name checksum.
54942 ** + 8 bytes: aJournalMagic[].
54943 **
@@ -54492,11 +54981,11 @@
54981 iHdrOff = pPager->journalOff;
54982
54983 /* Write the super-journal data to the end of the journal file. If
54984 ** an error occurs, return the error code to the caller.
54985 */
54986 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager))))
54987 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
54988 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
54989 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
54990 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
54991 iHdrOff+4+nSuper+8)))
@@ -55002,11 +55491,11 @@
55491 ** to the database file, then the IO error code is returned. If data
55492 ** is successfully read from the (sub-)journal file but appears to be
55493 ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
55494 ** two circumstances:
55495 **
55496 ** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
55497 ** * If the record is being rolled back from the main journal file
55498 ** and the checksum field does not match the record content.
55499 **
55500 ** Neither of these two scenarios are possible during a savepoint rollback.
55501 **
@@ -55062,11 +55551,11 @@
55551 /* Sanity checking on the page. This is more important that I originally
55552 ** thought. If a power failure occurs while the journal is being written,
55553 ** it could cause invalid data to be written into the journal. We need to
55554 ** detect this invalid data (with high probability) and ignore it.
55555 */
55556 if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){
55557 assert( !isSavepnt );
55558 return SQLITE_DONE;
55559 }
55560 if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
55561 return SQLITE_OK;
@@ -55621,10 +56110,13 @@
56110 rc = pager_truncate(pPager, mxPg);
56111 if( rc!=SQLITE_OK ){
56112 goto end_playback;
56113 }
56114 pPager->dbSize = mxPg;
56115 if( pPager->mxPgno<mxPg ){
56116 pPager->mxPgno = mxPg;
56117 }
56118 }
56119
56120 /* Copy original pages out of the journal and back into the
56121 ** database file and/or page cache.
56122 */
@@ -56517,10 +57009,11 @@
57009 if( rc==SQLITE_OK ){
57010 sqlite3PageFree(pPager->pTmpSpace);
57011 pPager->pTmpSpace = pNew;
57012 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
57013 pPager->pageSize = pageSize;
57014 pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1;
57015 }else{
57016 sqlite3PageFree(pNew);
57017 }
57018 }
57019
@@ -56723,11 +57216,10 @@
57216 ** rolled back or committed. It is not safe to call this function and
57217 ** then continue writing to the database.
57218 */
57219 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
57220 assert( pPager->dbSize>=nPage || CORRUPT_DB );
 
57221 assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
57222 pPager->dbSize = nPage;
57223
57224 /* At one point the code here called assertTruncateConstraint() to
57225 ** ensure that all pages being truncated away by this operation are,
@@ -58287,11 +58779,11 @@
58779
58780 noContent = (flags & PAGER_GET_NOCONTENT)!=0;
58781 if( pPg->pPager && !noContent ){
58782 /* In this case the pcache already contains an initialized copy of
58783 ** the page. Return without further ado. */
58784 assert( pgno!=PAGER_SJ_PGNO(pPager) );
58785 pPager->aStat[PAGER_STAT_HIT]++;
58786 return SQLITE_OK;
58787
58788 }else{
58789 /* The pager cache has created a new page. Its content needs to
@@ -58298,11 +58790,11 @@
58790 ** be initialized. But first some error checks:
58791 **
58792 ** (*) obsolete. Was: maximum page number is 2^31
58793 ** (2) Never try to fetch the locking page
58794 */
58795 if( pgno==PAGER_SJ_PGNO(pPager) ){
58796 rc = SQLITE_CORRUPT_BKPT;
58797 goto pager_acquire_err;
58798 }
58799
58800 pPg->pPager = pPager;
@@ -58697,11 +59189,11 @@
59189 i64 iOff = pPager->journalOff;
59190
59191 /* We should never write to the journal file the page that
59192 ** contains the database locks. The following assert verifies
59193 ** that we do not. */
59194 assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );
59195
59196 assert( pPager->journalHdr<=pPager->journalOff );
59197 pData2 = pPg->pData;
59198 cksum = pager_cksum(pPager, (u8*)pData2);
59199
@@ -58876,11 +59368,11 @@
59368
59369 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
59370 Pgno pg = pg1+ii;
59371 PgHdr *pPage;
59372 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
59373 if( pg!=PAGER_SJ_PGNO(pPager) ){
59374 rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
59375 if( rc==SQLITE_OK ){
59376 rc = pager_write(pPage);
59377 if( pPage->flags&PGHDR_NEED_SYNC ){
59378 needSync = 1;
@@ -59354,11 +59846,11 @@
59846 ** image was extended as part of the current transaction and then the
59847 ** last page in the db image moved to the free-list. In this case the
59848 ** last page is never written out to disk, leaving the database file
59849 ** undersized. Fix this now if it is the case. */
59850 if( pPager->dbSize>pPager->dbFileSize ){
59851 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager));
59852 assert( pPager->eState==PAGER_WRITER_DBMOD );
59853 rc = pager_truncate(pPager, nNew);
59854 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
59855 }
59856
@@ -60203,10 +60695,22 @@
60695 int eMode, /* Type of checkpoint */
60696 int *pnLog, /* OUT: Final number of frames in log */
60697 int *pnCkpt /* OUT: Final number of checkpointed frames */
60698 ){
60699 int rc = SQLITE_OK;
60700 if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){
60701 /* This only happens when a database file is zero bytes in size opened and
60702 ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint()
60703 ** is invoked without any intervening transactions. We need to start
60704 ** a transaction to initialize pWal. The PRAGMA table_list statement is
60705 ** used for this since it starts transactions on every database file,
60706 ** including all ATTACHed databases. This seems expensive for a single
60707 ** sqlite3_wal_checkpoint() call, but it happens very rarely.
60708 ** https://sqlite.org/forum/forumpost/fd0f19d229156939
60709 */
60710 sqlite3_exec(db, "PRAGMA table_list",0,0,0);
60711 }
60712 if( pPager->pWal ){
60713 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
60714 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
60715 pPager->pBusyHandlerArg,
60716 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -63102,11 +63606,13 @@
63606 rc = WAL_RETRY;
63607 goto begin_unreliable_shm_out;
63608 }
63609
63610 /* Allocate a buffer to read frames into */
63611 assert( (pWal->szPage & (pWal->szPage-1))==0 );
63612 assert( pWal->szPage>=512 && pWal->szPage<=65536 );
63613 szFrame = pWal->szPage + WAL_FRAME_HDRSIZE;
63614 aFrame = (u8 *)sqlite3_malloc64(szFrame);
63615 if( aFrame==0 ){
63616 rc = SQLITE_NOMEM_BKPT;
63617 goto begin_unreliable_shm_out;
63618 }
@@ -63116,11 +63622,11 @@
63622 ** wal file since the heap-memory wal-index was created. If so, the
63623 ** heap-memory wal-index is discarded and WAL_RETRY returned to
63624 ** the caller. */
63625 aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
63626 aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
63627 for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage);
63628 iOffset+szFrame<=szWal;
63629 iOffset+=szFrame
63630 ){
63631 u32 pgno; /* Database page number for frame */
63632 u32 nTruncate; /* dbsize field from frame header */
@@ -64967,11 +65473,13 @@
65473 u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
65474 ** non-overflow cell */
65475 u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
65476 BtShared *pBt; /* Pointer to BtShared that this page is part of */
65477 u8 *aData; /* Pointer to disk image of the page data */
65478 u8 *aDataEnd; /* One byte past the end of the entire page - not just
65479 ** the usable space, the entire page. Used to prevent
65480 ** corruption-induced buffer overflow. */
65481 u8 *aCellIdx; /* The cell index area */
65482 u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
65483 DbPage *pDbPage; /* Pager page handle */
65484 u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
65485 void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65272,11 +65780,11 @@
65780 #define CURSOR_FAULT 4
65781
65782 /*
65783 ** The database page the PENDING_BYTE occupies. This page is never used.
65784 */
65785 #define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1))
65786
65787 /*
65788 ** These macros define the location of the pointer-map entry for a
65789 ** database page. The first argument to each is the number of usable
65790 ** bytes on each page of the database (often 1024). The second is the
@@ -65913,11 +66421,11 @@
66421 if( isIndex ){
66422 HashElem *p;
66423 int bSeen = 0;
66424 for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
66425 Index *pIdx = (Index *)sqliteHashData(p);
66426 if( pIdx->tnum==iRoot ){
66427 if( bSeen ){
66428 /* Two or more indexes share the same root page. There must
66429 ** be imposter tables. So just return true. The assert is not
66430 ** useful in that case. */
66431 return 1;
@@ -66506,11 +67014,11 @@
67014 }
67015
67016 /*
67017 ** In this version of BtreeMoveto, pKey is a packed index record
67018 ** such as is generated by the OP_MakeRecord opcode. Unpack the
67019 ** record and then call sqlite3BtreeIndexMoveto() to do the work.
67020 */
67021 static int btreeMoveto(
67022 BtCursor *pCur, /* Cursor open on the btree to be searched */
67023 const void *pKey, /* Packed key if the btree is an index */
67024 i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67026,10 +67534,11 @@
67534 ** data area of the btree-page. The return number includes the cell
67535 ** data header and the local payload, but not any overflow page or
67536 ** the space used by the cell pointer.
67537 **
67538 ** cellSizePtrNoPayload() => table internal nodes
67539 ** cellSizePtrTableLeaf() => table leaf nodes
67540 ** cellSizePtr() => all index nodes & table leaf nodes
67541 */
67542 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
67543 u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
67544 u8 *pEnd; /* End mark for a varint */
@@ -67051,17 +67560,10 @@
67560 do{
67561 nSize = (nSize<<7) | (*++pIter & 0x7f);
67562 }while( *(pIter)>=0x80 && pIter<pEnd );
67563 }
67564 pIter++;
 
 
 
 
 
 
 
67565 testcase( nSize==pPage->maxLocal );
67566 testcase( nSize==(u32)pPage->maxLocal+1 );
67567 if( nSize<=pPage->maxLocal ){
67568 nSize += (u32)(pIter - pCell);
67569 if( nSize<4 ) nSize = 4;
@@ -67097,10 +67599,62 @@
67599 pEnd = pIter + 9;
67600 while( (*pIter++)&0x80 && pIter<pEnd );
67601 assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
67602 return (u16)(pIter - pCell);
67603 }
67604 static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){
67605 u8 *pIter = pCell; /* For looping over bytes of pCell */
67606 u8 *pEnd; /* End mark for a varint */
67607 u32 nSize; /* Size value to return */
67608
67609 #ifdef SQLITE_DEBUG
67610 /* The value returned by this function should always be the same as
67611 ** the (CellInfo.nSize) value found by doing a full parse of the
67612 ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
67613 ** this function verifies that this invariant is not violated. */
67614 CellInfo debuginfo;
67615 pPage->xParseCell(pPage, pCell, &debuginfo);
67616 #endif
67617
67618 nSize = *pIter;
67619 if( nSize>=0x80 ){
67620 pEnd = &pIter[8];
67621 nSize &= 0x7f;
67622 do{
67623 nSize = (nSize<<7) | (*++pIter & 0x7f);
67624 }while( *(pIter)>=0x80 && pIter<pEnd );
67625 }
67626 pIter++;
67627 /* pIter now points at the 64-bit integer key value, a variable length
67628 ** integer. The following block moves pIter to point at the first byte
67629 ** past the end of the key value. */
67630 if( (*pIter++)&0x80
67631 && (*pIter++)&0x80
67632 && (*pIter++)&0x80
67633 && (*pIter++)&0x80
67634 && (*pIter++)&0x80
67635 && (*pIter++)&0x80
67636 && (*pIter++)&0x80
67637 && (*pIter++)&0x80 ){ pIter++; }
67638 testcase( nSize==pPage->maxLocal );
67639 testcase( nSize==(u32)pPage->maxLocal+1 );
67640 if( nSize<=pPage->maxLocal ){
67641 nSize += (u32)(pIter - pCell);
67642 if( nSize<4 ) nSize = 4;
67643 }else{
67644 int minLocal = pPage->minLocal;
67645 nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
67646 testcase( nSize==pPage->maxLocal );
67647 testcase( nSize==(u32)pPage->maxLocal+1 );
67648 if( nSize>pPage->maxLocal ){
67649 nSize = minLocal;
67650 }
67651 nSize += 4 + (u16)(pIter - pCell);
67652 }
67653 assert( nSize==debuginfo.nSize || CORRUPT_DB );
67654 return (u16)nSize;
67655 }
67656
67657
67658 #ifdef SQLITE_DEBUG
67659 /* This variation on cellSizePtr() is used inside of assert() statements
67660 ** only. */
@@ -67110,11 +67664,11 @@
67664 #endif
67665
67666 #ifndef SQLITE_OMIT_AUTOVACUUM
67667 /*
67668 ** The cell pCell is currently part of page pSrc but will ultimately be part
67669 ** of pPage. (pSrc and pPage are often the same.) If pCell contains a
67670 ** pointer to an overflow page, insert an entry into the pointer-map for
67671 ** the overflow page that will be valid after pCell has been moved to pPage.
67672 */
67673 static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
67674 CellInfo info;
@@ -67285,21 +67839,23 @@
67839 */
67840 static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
67841 const int hdr = pPg->hdrOffset; /* Offset to page header */
67842 u8 * const aData = pPg->aData; /* Page data */
67843 int iAddr = hdr + 1; /* Address of ptr to pc */
67844 u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */
67845 int pc = get2byte(pTmp); /* Address of a free slot */
67846 int x; /* Excess size of the slot */
67847 int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
67848 int size; /* Size of the free slot */
67849
67850 assert( pc>0 );
67851 while( pc<=maxPC ){
67852 /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
67853 ** freeblock form a big-endian integer which is the size of the freeblock
67854 ** in bytes, including the 4-byte header. */
67855 pTmp = &aData[pc+2];
67856 size = get2byte(pTmp);
67857 if( (x = size - nByte)>=0 ){
67858 testcase( x==4 );
67859 testcase( x==3 );
67860 if( x<4 ){
67861 /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67320,11 +67876,12 @@
67876 put2byte(&aData[pc+2], x);
67877 }
67878 return &aData[pc + x];
67879 }
67880 iAddr = pc;
67881 pTmp = &aData[pc];
67882 pc = get2byte(pTmp);
67883 if( pc<=iAddr+size ){
67884 if( pc ){
67885 /* The next slot in the chain is not past the end of the current slot */
67886 *pRc = SQLITE_CORRUPT_PAGE(pPg);
67887 }
@@ -67354,10 +67911,11 @@
67911 static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
67912 const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
67913 u8 * const data = pPage->aData; /* Local cache of pPage->aData */
67914 int top; /* First byte of cell content area */
67915 int rc = SQLITE_OK; /* Integer return code */
67916 u8 *pTmp; /* Temp ptr into data[] */
67917 int gap; /* First byte of gap between cell pointers and cell content */
67918
67919 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67920 assert( pPage->pBt );
67921 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67372,11 +67930,12 @@
67930 /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
67931 ** and the reserved space is zero (the usual value for reserved space)
67932 ** then the cell content offset of an empty page wants to be 65536.
67933 ** However, that integer is too large to be stored in a 2-byte unsigned
67934 ** integer, so a value of 0 is used in its place. */
67935 pTmp = &data[hdr+5];
67936 top = get2byte(pTmp);
67937 assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
67938 if( gap>top ){
67939 if( top==0 && pPage->pBt->usableSize==65536 ){
67940 top = 65536;
67941 }else{
@@ -67454,10 +68013,11 @@
68013 u8 nFrag = 0; /* Reduction in fragmentation */
68014 u16 iOrigSize = iSize; /* Original value of iSize */
68015 u16 x; /* Offset to cell content area */
68016 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
68017 unsigned char *data = pPage->aData; /* Page content */
68018 u8 *pTmp; /* Temporary ptr into data[] */
68019
68020 assert( pPage->pBt!=0 );
68021 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
68022 assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
68023 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67481,11 +68041,11 @@
68041 iPtr = iFreeBlk;
68042 }
68043 if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
68044 return SQLITE_CORRUPT_PAGE(pPage);
68045 }
68046 assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB );
68047
68048 /* At this point:
68049 ** iFreeBlk: First freeblock after iStart, or zero if none
68050 ** iPtr: The address of a pointer to iFreeBlk
68051 **
@@ -67516,11 +68076,12 @@
68076 }
68077 }
68078 if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
68079 data[hdr+7] -= nFrag;
68080 }
68081 pTmp = &data[hdr+5];
68082 x = get2byte(pTmp);
68083 if( iStart<=x ){
68084 /* The new freeblock is at the beginning of the cell content area,
68085 ** so just extend the cell content area rather than create another
68086 ** freelist entry */
68087 if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67560,11 +68121,10 @@
68121 assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
68122 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
68123 pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
68124 flagByte &= ~PTF_LEAF;
68125 pPage->childPtrSize = 4-4*pPage->leaf;
 
68126 pBt = pPage->pBt;
68127 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
68128 /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
68129 ** interior table b-tree page. */
68130 assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67572,10 +68132,11 @@
68132 ** leaf table b-tree page. */
68133 assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
68134 pPage->intKey = 1;
68135 if( pPage->leaf ){
68136 pPage->intKeyLeaf = 1;
68137 pPage->xCellSize = cellSizePtrTableLeaf;
68138 pPage->xParseCell = btreeParseCellPtr;
68139 }else{
68140 pPage->intKeyLeaf = 0;
68141 pPage->xCellSize = cellSizePtrNoPayload;
68142 pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67589,16 +68150,21 @@
68150 /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
68151 ** leaf index b-tree page. */
68152 assert( (PTF_ZERODATA|PTF_LEAF)==10 );
68153 pPage->intKey = 0;
68154 pPage->intKeyLeaf = 0;
68155 pPage->xCellSize = cellSizePtr;
68156 pPage->xParseCell = btreeParseCellPtrIndex;
68157 pPage->maxLocal = pBt->maxLocal;
68158 pPage->minLocal = pBt->minLocal;
68159 }else{
68160 /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
68161 ** an error. */
68162 pPage->intKey = 0;
68163 pPage->intKeyLeaf = 0;
68164 pPage->xCellSize = cellSizePtr;
68165 pPage->xParseCell = btreeParseCellPtrIndex;
68166 return SQLITE_CORRUPT_PAGE(pPage);
68167 }
68168 pPage->max1bytePayload = pBt->max1bytePayload;
68169 return SQLITE_OK;
68170 }
@@ -67752,11 +68318,11 @@
68318 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
68319 pPage->maskPage = (u16)(pBt->pageSize - 1);
68320 pPage->nOverflow = 0;
68321 pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
68322 pPage->aCellIdx = data + pPage->childPtrSize + 8;
68323 pPage->aDataEnd = pPage->aData + pBt->pageSize;
68324 pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
68325 /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
68326 ** number of cells on the page. */
68327 pPage->nCell = get2byte(&data[3]);
68328 if( pPage->nCell>MX_CELL(pBt) ){
@@ -67787,11 +68353,11 @@
68353 unsigned char *data = pPage->aData;
68354 BtShared *pBt = pPage->pBt;
68355 u8 hdr = pPage->hdrOffset;
68356 u16 first;
68357
68358 assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB );
68359 assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
68360 assert( sqlite3PagerGetData(pPage->pDbPage) == data );
68361 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
68362 assert( sqlite3_mutex_held(pBt->mutex) );
68363 if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67803,11 +68369,11 @@
68369 data[hdr+7] = 0;
68370 put2byte(&data[hdr+5], pBt->usableSize);
68371 pPage->nFree = (u16)(pBt->usableSize - first);
68372 decodeFlags(pPage, flags);
68373 pPage->cellOffset = first;
68374 pPage->aDataEnd = &data[pBt->pageSize];
68375 pPage->aCellIdx = &data[first];
68376 pPage->aDataOfst = &data[pPage->childPtrSize];
68377 pPage->nOverflow = 0;
68378 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
68379 pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -67929,11 +68495,11 @@
68495 rc = btreeInitPage(*ppPage);
68496 if( rc!=SQLITE_OK ){
68497 goto getAndInitPage_error2;
68498 }
68499 }
68500 assert( (*ppPage)->pgno==pgno || CORRUPT_DB );
68501 assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
68502
68503 /* If obtaining a child page for a cursor, we must verify that the page is
68504 ** compatible with the root page. */
68505 if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -67948,11 +68514,13 @@
68514 if( pCur ){
68515 pCur->iPage--;
68516 pCur->pPage = pCur->apPage[pCur->iPage];
68517 }
68518 testcase( pgno==0 );
68519 assert( pgno!=0 || rc==SQLITE_CORRUPT
68520 || rc==SQLITE_IOERR_NOMEM
68521 || rc==SQLITE_NOMEM );
68522 return rc;
68523 }
68524
68525 /*
68526 ** Release a MemPage. This should be called once for each prior
@@ -68934,13 +69502,17 @@
69502 freeTempSpace(pBt);
69503 rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
69504 pageSize-usableSize);
69505 return rc;
69506 }
69507 if( nPage>nPageFile ){
69508 if( sqlite3WritableSchema(pBt->db)==0 ){
69509 rc = SQLITE_CORRUPT_BKPT;
69510 goto page1_init_failed;
69511 }else{
69512 nPage = nPageFile;
69513 }
69514 }
69515 /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
69516 ** be less than 480. In other words, if the page size is 512, then the
69517 ** reserved space size cannot exceed 32. */
69518 if( usableSize<480 ){
@@ -71012,11 +71584,11 @@
71584 }
71585 pCur->iPage = 0;
71586 pCur->curIntKey = pCur->pPage->intKey;
71587 }
71588 pRoot = pCur->pPage;
71589 assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB );
71590
71591 /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
71592 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
71593 ** NULL, the caller expects a table b-tree. If this is not the case,
71594 ** return an SQLITE_CORRUPT error.
@@ -71332,10 +71904,73 @@
71904 moveto_table_finish:
71905 pCur->info.nSize = 0;
71906 assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
71907 return rc;
71908 }
71909
71910 /*
71911 ** Compare the "idx"-th cell on the page the cursor pCur is currently
71912 ** pointing to to pIdxKey using xRecordCompare. Return negative or
71913 ** zero if the cell is less than or equal pIdxKey. Return positive
71914 ** if unknown.
71915 **
71916 ** Return value negative: Cell at pCur[idx] less than pIdxKey
71917 **
71918 ** Return value is zero: Cell at pCur[idx] equals pIdxKey
71919 **
71920 ** Return value positive: Nothing is known about the relationship
71921 ** of the cell at pCur[idx] and pIdxKey.
71922 **
71923 ** This routine is part of an optimization. It is always safe to return
71924 ** a positive value as that will cause the optimization to be skipped.
71925 */
71926 static int indexCellCompare(
71927 BtCursor *pCur,
71928 int idx,
71929 UnpackedRecord *pIdxKey,
71930 RecordCompare xRecordCompare
71931 ){
71932 MemPage *pPage = pCur->pPage;
71933 int c;
71934 int nCell; /* Size of the pCell cell in bytes */
71935 u8 *pCell = findCellPastPtr(pPage, idx);
71936
71937 nCell = pCell[0];
71938 if( nCell<=pPage->max1bytePayload ){
71939 /* This branch runs if the record-size field of the cell is a
71940 ** single byte varint and the record fits entirely on the main
71941 ** b-tree page. */
71942 testcase( pCell+nCell+1==pPage->aDataEnd );
71943 c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
71944 }else if( !(pCell[1] & 0x80)
71945 && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
71946 ){
71947 /* The record-size field is a 2 byte varint and the record
71948 ** fits entirely on the main b-tree page. */
71949 testcase( pCell+nCell+2==pPage->aDataEnd );
71950 c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
71951 }else{
71952 /* If the record extends into overflow pages, do not attempt
71953 ** the optimization. */
71954 c = 99;
71955 }
71956 return c;
71957 }
71958
71959 /*
71960 ** Return true (non-zero) if pCur is current pointing to the last
71961 ** page of a table.
71962 */
71963 static int cursorOnLastPage(BtCursor *pCur){
71964 int i;
71965 assert( pCur->eState==CURSOR_VALID );
71966 for(i=0; i<pCur->iPage; i++){
71967 MemPage *pPage = pCur->apPage[i];
71968 if( pCur->aiIdx[i]<pPage->nCell ) return 0;
71969 }
71970 return 1;
71971 }
71972
71973 /* Move the cursor so that it points to an entry in an index table
71974 ** near the key pIdxKey. Return a success code.
71975 **
71976 ** If an exact match is not found, then the cursor is always
@@ -71383,25 +72018,61 @@
72018 assert( pIdxKey->default_rc==1
72019 || pIdxKey->default_rc==0
72020 || pIdxKey->default_rc==-1
72021 );
72022
72023
72024 /* Check to see if we can skip a lot of work. Two cases:
72025 **
72026 ** (1) If the cursor is already pointing to the very last cell
72027 ** in the table and the pIdxKey search key is greater than or
72028 ** equal to that last cell, then no movement is required.
72029 **
72030 ** (2) If the cursor is on the last page of the table and the first
72031 ** cell on that last page is less than or equal to the pIdxKey
72032 ** search key, then we can start the search on the current page
72033 ** without needing to go back to root.
72034 */
72035 if( pCur->eState==CURSOR_VALID
72036 && pCur->pPage->leaf
72037 && cursorOnLastPage(pCur)
72038 ){
72039 int c;
72040 if( pCur->ix==pCur->pPage->nCell-1
72041 && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0
72042 && pIdxKey->errCode==SQLITE_OK
72043 ){
72044 *pRes = c;
72045 return SQLITE_OK; /* Cursor already pointing at the correct spot */
72046 }
72047 if( pCur->iPage>0
72048 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
72049 && pIdxKey->errCode==SQLITE_OK
72050 ){
72051 pCur->curFlags &= ~BTCF_ValidOvfl;
72052 goto bypass_moveto_root; /* Start search on the current page */
72053 }
72054 pIdxKey->errCode = SQLITE_OK;
72055 }
72056
72057 rc = moveToRoot(pCur);
72058 if( rc ){
72059 if( rc==SQLITE_EMPTY ){
72060 assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
72061 *pRes = -1;
72062 return SQLITE_OK;
72063 }
72064 return rc;
72065 }
72066
72067 bypass_moveto_root:
72068 assert( pCur->pPage );
72069 assert( pCur->pPage->isInit );
72070 assert( pCur->eState==CURSOR_VALID );
72071 assert( pCur->pPage->nCell > 0 );
72072 assert( pCur->curIntKey==0 );
72073 assert( pIdxKey!=0 );
72074 for(;;){
72075 int lwr, upr, idx, c;
72076 Pgno chldPg;
72077 MemPage *pPage = pCur->pPage;
72078 u8 *pCell; /* Pointer to current cell in pPage */
@@ -71411,11 +72082,11 @@
72082 ** not run. If this is not the root-page, then the moveToChild() routine
72083 ** would have already detected db corruption. Similarly, pPage must
72084 ** be the right kind (index or table) of b-tree page. Otherwise
72085 ** a moveToChild() or moveToRoot() call would have detected corruption. */
72086 assert( pPage->nCell>0 );
72087 assert( pPage->intKey==0 );
72088 lwr = 0;
72089 upr = pPage->nCell-1;
72090 idx = upr>>1; /* idx = (lwr+upr)/2; */
72091 for(;;){
72092 int nCell; /* Size of the pCell cell in bytes */
@@ -72106,11 +72777,11 @@
72777
72778 assert( sqlite3_mutex_held(pBt->mutex) );
72779 assert( CORRUPT_DB || iPage>1 );
72780 assert( !pMemPage || pMemPage->pgno==iPage );
72781
72782 if( iPage<2 || iPage>pBt->nPage ){
72783 return SQLITE_CORRUPT_BKPT;
72784 }
72785 if( pMemPage ){
72786 pPage = pMemPage;
72787 sqlite3PagerRef(pPage->pDbPage);
@@ -72541,10 +73212,16 @@
73212 data = pPage->aData;
73213 ptr = &pPage->aCellIdx[2*idx];
73214 assert( pPage->pBt->usableSize > (u32)(ptr-data) );
73215 pc = get2byte(ptr);
73216 hdr = pPage->hdrOffset;
73217 #if 0 /* Not required. Omit for efficiency */
73218 if( pc<hdr+pPage->nCell*2 ){
73219 *pRC = SQLITE_CORRUPT_BKPT;
73220 return;
73221 }
73222 #endif
73223 testcase( pc==(u32)get2byte(&data[hdr+5]) );
73224 testcase( pc+sz==pPage->pBt->usableSize );
73225 if( pc+sz > pPage->pBt->usableSize ){
73226 *pRC = SQLITE_CORRUPT_BKPT;
73227 return;
@@ -74504,11 +75181,11 @@
75181 ** For an index btree (used for indexes and WITHOUT ROWID tables), the
75182 ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
75183 ** pX.pData,nData,nZero fields must be zero.
75184 **
75185 ** If the seekResult parameter is non-zero, then a successful call to
75186 ** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
75187 ** been performed. In other words, if seekResult!=0 then the cursor
75188 ** is currently pointing to a cell that will be adjacent to the cell
75189 ** to be inserted. If seekResult<0 then pCur points to a cell that is
75190 ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
75191 ** that is larger than (pKey,nKey).
@@ -74522,11 +75199,11 @@
75199 */
75200 SQLITE_PRIVATE int sqlite3BtreeInsert(
75201 BtCursor *pCur, /* Insert data into the table of this cursor */
75202 const BtreePayload *pX, /* Content of the row to be inserted */
75203 int flags, /* True if this is likely an append */
75204 int seekResult /* Result of prior IndexMoveto() call */
75205 ){
75206 int rc;
75207 int loc = seekResult; /* -1: before desired location +1: after */
75208 int szNew = 0;
75209 int idx;
@@ -74537,28 +75214,10 @@
75214 unsigned char *newCell = 0;
75215
75216 assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
75217 assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
75218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75219 /* Save the positions of any other cursors open on this table.
75220 **
75221 ** In some cases, the call to btreeMoveto() below is a no-op. For
75222 ** example, when inserting data into a table with auto-generated integer
75223 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74579,10 +75238,33 @@
75238 ** set the flag, load the schema, and then unset the flag. */
75239 return SQLITE_CORRUPT_BKPT;
75240 }
75241 }
75242
75243 /* Ensure that the cursor is not in the CURSOR_FAULT state and that it
75244 ** points to a valid cell.
75245 */
75246 if( pCur->eState>=CURSOR_REQUIRESEEK ){
75247 testcase( pCur->eState==CURSOR_REQUIRESEEK );
75248 testcase( pCur->eState==CURSOR_FAULT );
75249 rc = moveToRoot(pCur);
75250 if( rc && rc!=SQLITE_EMPTY ) return rc;
75251 }
75252
75253 assert( cursorOwnsBtShared(pCur) );
75254 assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75255 && pBt->inTransaction==TRANS_WRITE
75256 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75257 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75258
75259 /* Assert that the caller has been consistent. If this cursor was opened
75260 ** expecting an index b-tree, then the caller should be inserting blob
75261 ** keys with no associated data. If the cursor was opened expecting an
75262 ** intkey table, the caller should be inserting integer keys with a
75263 ** blob of associated data. */
75264 assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75265
75266 if( pCur->pKeyInfo==0 ){
75267 assert( pX->pKey==0 );
75268 /* If this is an insert into a table b-tree, invalidate any incrblob
75269 ** cursors open on the row being replaced */
75270 if( p->hasIncrblobCur ){
@@ -74667,18 +75349,18 @@
75349 return btreeOverwriteCell(pCur, &x2);
75350 }
75351 }
75352 }
75353 assert( pCur->eState==CURSOR_VALID
75354 || (pCur->eState==CURSOR_INVALID && loc) );
 
75355
75356 pPage = pCur->pPage;
75357 assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
75358 assert( pPage->leaf || !pPage->intKey );
75359 if( pPage->nFree<0 ){
75360 if( NEVER(pCur->eState>CURSOR_INVALID) ){
75361 /* ^^^^^--- due to the moveToRoot() call above */
75362 rc = SQLITE_CORRUPT_BKPT;
75363 }else{
75364 rc = btreeComputeFreeSpace(pPage);
75365 }
75366 if( rc ) return rc;
@@ -74955,16 +75637,20 @@
75637 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
75638 assert( pCur->curFlags & BTCF_WriteFlag );
75639 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75640 assert( !hasReadConflicts(p, pCur->pgnoRoot) );
75641 assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
75642 if( pCur->eState!=CURSOR_VALID ){
75643 if( pCur->eState>=CURSOR_REQUIRESEEK ){
75644 rc = btreeRestoreCursorPosition(pCur);
75645 assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75646 if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75647 }else{
75648 return SQLITE_CORRUPT_BKPT;
75649 }
75650 }
75651 assert( pCur->eState==CURSOR_VALID );
75652
75653 iCellDepth = pCur->iPage;
75654 iCellIdx = pCur->ix;
75655 pPage = pCur->pPage;
75656 if( pPage->nCell<=iCellIdx ){
@@ -74992,11 +75678,12 @@
75678 ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
75679 */
75680 bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
75681 if( bPreserve ){
75682 if( !pPage->leaf
75683 || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) >
75684 (int)(pBt->usableSize*2/3)
75685 || pPage->nCell==1 /* See dbfuzz001.test for a test case */
75686 ){
75687 /* A b-tree rebalance will be required after deleting this entry.
75688 ** Save the cursor key. */
75689 rc = saveCursorKey(pCur);
@@ -75311,11 +75998,11 @@
75998 return SQLITE_CORRUPT_BKPT;
75999 }
76000 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
76001 if( rc ) return rc;
76002 if( (pBt->openFlags & BTREE_SINGLE)==0
76003 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
76004 ){
76005 rc = SQLITE_CORRUPT_BKPT;
76006 goto cleardatabasepage_out;
76007 }
76008 hdr = pPage->hdrOffset;
@@ -76691,18 +77378,17 @@
77378 int i = sqlite3FindDbName(pDb, zDb);
77379
77380 if( i==1 ){
77381 Parse sParse;
77382 int rc = 0;
77383 sqlite3ParseObjectInit(&sParse,pDb);
 
77384 if( sqlite3OpenTempDatabase(&sParse) ){
77385 sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
77386 rc = SQLITE_ERROR;
77387 }
77388 sqlite3DbFree(pErrorDb, sParse.zErrMsg);
77389 sqlite3ParseObjectReset(&sParse);
77390 if( rc ){
77391 return 0;
77392 }
77393 }
77394
@@ -77934,10 +78620,18 @@
78620 assert( sqlite3VdbeCheckMemInvariants(p) );
78621 if( VdbeMemDynamic(p) || p->szMalloc ){
78622 vdbeMemClear(p);
78623 }
78624 }
78625
78626 /* Like sqlite3VdbeMemRelease() but faster for cases where we
78627 ** know in advance that the Mem is not MEM_Dyn or MEM_Agg.
78628 */
78629 SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){
78630 assert( !VdbeMemDynamic(p) );
78631 if( p->szMalloc ) vdbeMemClear(p);
78632 }
78633
78634 /*
78635 ** Convert a 64-bit IEEE double into a 64-bit signed integer.
78636 ** If the double is out of range of a 64-bit signed integer then
78637 ** return the closest available 64-bit signed integer.
@@ -78296,10 +78990,11 @@
78990 void *pPtr,
78991 const char *zPType,
78992 void (*xDestructor)(void*)
78993 ){
78994 assert( pMem->flags==MEM_Null );
78995 vdbeMemClear(pMem);
78996 pMem->u.zPType = zPType ? zPType : "";
78997 pMem->z = pPtr;
78998 pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
78999 pMem->eSubtype = 'p';
79000 pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78910,15 +79605,11 @@
79605 const char *zNeg = "";
79606 int rc = SQLITE_OK;
79607
79608 assert( pExpr!=0 );
79609 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
 
79610 if( op==TK_REGISTER ) op = pExpr->op2;
 
 
 
79611
79612 /* Compressed expressions only appear when parsing the DEFAULT clause
79613 ** on a table column definition, and hence only when pCtx==0. This
79614 ** check ensures that an EP_TokenOnly expression is never passed down
79615 ** into valueFromFunction(). */
@@ -79029,11 +79720,11 @@
79720 *ppVal = pVal;
79721 return rc;
79722
79723 no_mem:
79724 #ifdef SQLITE_ENABLE_STAT4
79725 if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) )
79726 #endif
79727 sqlite3OomFault(db);
79728 sqlite3DbFree(db, zVal);
79729 assert( *ppVal==0 );
79730 #ifdef SQLITE_ENABLE_STAT4
@@ -79509,11 +80200,11 @@
80200 if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
80201 sqlite3OomFault(p->db);
80202 return SQLITE_NOMEM;
80203 }
80204
80205 assert( nOp<=(int)(1024/sizeof(Op)) );
80206 assert( nNew>=(v->nOpAlloc+nOp) );
80207 pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
80208 if( pNew ){
80209 p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
80210 v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -80111,11 +80802,11 @@
80802 ** and store that value in *pMaxFuncArgs.
80803 **
80804 ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
80805 ** indicate what the prepared statement actually does.
80806 **
80807 ** (4) (discontinued)
80808 **
80809 ** (5) Reclaim the memory allocated for storing labels.
80810 **
80811 ** This routine will only function correctly if the mkopcodeh.tcl generator
80812 ** script numbers the opcodes correctly. Changes to this routine must be
@@ -80157,29 +80848,10 @@
80848 case OP_JournalMode: {
80849 p->readOnly = 0;
80850 p->bIsReader = 1;
80851 break;
80852 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80853 #ifndef SQLITE_OMIT_VIRTUALTABLE
80854 case OP_VUpdate: {
80855 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
80856 break;
80857 }
@@ -80459,11 +81131,10 @@
81131 break;
81132 }
81133 case P4_REAL:
81134 case P4_INT64:
81135 case P4_DYNAMIC:
 
81136 case P4_INTARRAY: {
81137 sqlite3DbFree(db, p4);
81138 break;
81139 }
81140 case P4_KEYINFO: {
@@ -80707,12 +81378,11 @@
81378 ** makes the code easier to read during debugging. None of this happens
81379 ** in a production build.
81380 */
81381 static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
81382 assert( p->nOp>0 || p->aOp==0 );
81383 assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 );
 
81384 if( p->nOp ){
81385 assert( p->aOp );
81386 sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
81387 p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
81388 }
@@ -81057,14 +81727,10 @@
81727 }
81728 case P4_SUBPROGRAM: {
81729 zP4 = "program";
81730 break;
81731 }
 
 
 
 
81732 case P4_TABLE: {
81733 zP4 = pOp->p4.pTab->zName;
81734 break;
81735 }
81736 default: {
@@ -81192,25 +81858,44 @@
81858 }
81859 #endif
81860
81861 /*
81862 ** Initialize an array of N Mem element.
81863 **
81864 ** This is a high-runner, so only those fields that really do need to
81865 ** be initialized are set. The Mem structure is organized so that
81866 ** the fields that get initialized are nearby and hopefully on the same
81867 ** cache line.
81868 **
81869 ** Mem.flags = flags
81870 ** Mem.db = db
81871 ** Mem.szMalloc = 0
81872 **
81873 ** All other fields of Mem can safely remain uninitialized for now. They
81874 ** will be initialized before use.
81875 */
81876 static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81877 if( N>0 ){
81878 do{
81879 p->flags = flags;
81880 p->db = db;
81881 p->szMalloc = 0;
81882 #ifdef SQLITE_DEBUG
81883 p->pScopyFrom = 0;
81884 #endif
81885 p++;
81886 }while( (--N)>0 );
81887 }
81888 }
81889
81890 /*
81891 ** Release auxiliary memory held in an array of N Mem elements.
81892 **
81893 ** After this routine returns, all Mem elements in the array will still
81894 ** be valid. Those Mem elements that were not holding auxiliary resources
81895 ** will be unchanged. Mem elements which had something freed will be
81896 ** set to MEM_Undefined.
81897 */
81898 static void releaseMemArray(Mem *p, int N){
81899 if( p && N ){
81900 Mem *pEnd = &p[N];
81901 sqlite3 *db = p->db;
@@ -81239,16 +81924,21 @@
81924 testcase( p->flags & MEM_Agg );
81925 testcase( p->flags & MEM_Dyn );
81926 if( p->flags&(MEM_Agg|MEM_Dyn) ){
81927 testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
81928 sqlite3VdbeMemRelease(p);
81929 p->flags = MEM_Undefined;
81930 }else if( p->szMalloc ){
81931 sqlite3DbFreeNN(db, p->zMalloc);
81932 p->szMalloc = 0;
81933 p->flags = MEM_Undefined;
81934 }
81935 #ifdef SQLITE_DEBUG
81936 else{
81937 p->flags = MEM_Undefined;
81938 }
81939 #endif
81940 }while( (++p)<pEnd );
81941 }
81942 }
81943
81944 #ifdef SQLITE_DEBUG
@@ -82324,11 +83014,11 @@
83014 || (!deferred && p->nFkConstraint>0)
83015 ){
83016 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
83017 p->errorAction = OE_Abort;
83018 sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
83019 return SQLITE_CONSTRAINT_FOREIGNKEY;
83020 }
83021 return SQLITE_OK;
83022 }
83023 #endif
83024
@@ -82579,10 +83269,11 @@
83269 db->bBenignMalloc--;
83270 }else if( db->pErr ){
83271 sqlite3ValueSetNull(db->pErr);
83272 }
83273 db->errCode = rc;
83274 db->errByteOffset = -1;
83275 return rc;
83276 }
83277
83278 #ifdef SQLITE_ENABLE_SQLLOG
83279 /*
@@ -82858,11 +83549,11 @@
83549 ** pointed to was deleted out from under it. Or maybe the btree was
83550 ** rebalanced. Whatever the cause, try to restore "p" to the place it
83551 ** is supposed to be pointing. If the row was deleted out from under the
83552 ** cursor, set the cursor to point to a NULL row.
83553 */
83554 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){
83555 int isDifferentRow, rc;
83556 assert( p->eCurType==CURTYPE_BTREE );
83557 assert( p->uc.pCursor!=0 );
83558 assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
83559 rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82876,43 +83567,11 @@
83567 ** if need be. Return any I/O error from the restore operation.
83568 */
83569 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
83570 assert( p->eCurType==CURTYPE_BTREE );
83571 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83572 return sqlite3VdbeHandleMovedCursor(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83573 }
83574 return SQLITE_OK;
83575 }
83576
83577 /*
@@ -83570,12 +84229,12 @@
84229 if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
84230 rc = 0;
84231 }else{
84232 rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
84233 }
84234 sqlite3VdbeMemReleaseMalloc(&c1);
84235 sqlite3VdbeMemReleaseMalloc(&c2);
84236 return rc;
84237 }
84238 }
84239
84240 /*
@@ -84095,11 +84754,12 @@
84754
84755 default:
84756 return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
84757 }
84758
84759 assert( pPKey2->u.i == pPKey2->aMem[0].u.i );
84760 v = pPKey2->u.i;
84761 if( v>lhs ){
84762 res = pPKey2->r1;
84763 }else if( v<lhs ){
84764 res = pPKey2->r2;
84765 }else if( pPKey2->nField>1 ){
@@ -84130,16 +84790,22 @@
84790 const u8 *aKey1 = (const u8*)pKey1;
84791 int serial_type;
84792 int res;
84793
84794 assert( pPKey2->aMem[0].flags & MEM_Str );
84795 assert( pPKey2->aMem[0].n == pPKey2->n );
84796 assert( pPKey2->aMem[0].z == pPKey2->u.z );
84797 vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84798 serial_type = (signed char)(aKey1[1]);
84799
84800 vrcs_restart:
 
84801 if( serial_type<12 ){
84802 if( serial_type<0 ){
84803 sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84804 if( serial_type>=12 ) goto vrcs_restart;
84805 assert( CORRUPT_DB );
84806 }
84807 res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
84808 }else if( !(serial_type & 0x01) ){
84809 res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
84810 }else{
84811 int nCmp;
@@ -84149,19 +84815,19 @@
84815 nStr = (serial_type-12) / 2;
84816 if( (szHdr + nStr) > nKey1 ){
84817 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
84818 return 0; /* Corruption */
84819 }
84820 nCmp = MIN( pPKey2->n, nStr );
84821 res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp);
84822
84823 if( res>0 ){
84824 res = pPKey2->r2;
84825 }else if( res<0 ){
84826 res = pPKey2->r1;
84827 }else{
84828 res = nStr - pPKey2->n;
84829 if( res==0 ){
84830 if( pPKey2->nField>1 ){
84831 res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
84832 }else{
84833 res = pPKey2->default_rc;
@@ -84212,19 +84878,22 @@
84878 }else{
84879 p->r1 = -1;
84880 p->r2 = 1;
84881 }
84882 if( (flags & MEM_Int) ){
84883 p->u.i = p->aMem[0].u.i;
84884 return vdbeRecordCompareInt;
84885 }
84886 testcase( flags & MEM_Real );
84887 testcase( flags & MEM_Null );
84888 testcase( flags & MEM_Blob );
84889 if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
84890 && p->pKeyInfo->aColl[0]==0
84891 ){
84892 assert( flags & MEM_Str );
84893 p->u.z = p->aMem[0].z;
84894 p->n = p->aMem[0].n;
84895 return vdbeRecordCompareString;
84896 }
84897 }
84898
84899 return sqlite3VdbeRecordCompare;
@@ -84293,18 +84962,18 @@
84962 }
84963
84964 /* Fetch the integer off the end of the index record */
84965 sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
84966 *rowid = v.u.i;
84967 sqlite3VdbeMemReleaseMalloc(&m);
84968 return SQLITE_OK;
84969
84970 /* Jump here if database corruption is detected after m has been
84971 ** allocated. Free the m object and return SQLITE_CORRUPT. */
84972 idx_rowid_corruption:
84973 testcase( m.szMalloc!=0 );
84974 sqlite3VdbeMemReleaseMalloc(&m);
84975 return SQLITE_CORRUPT_BKPT;
84976 }
84977
84978 /*
84979 ** Compare the key of the index entry that cursor pC is pointing to against
@@ -84342,11 +85011,11 @@
85011 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
85012 if( rc ){
85013 return rc;
85014 }
85015 *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
85016 sqlite3VdbeMemReleaseMalloc(&m);
85017 return SQLITE_OK;
85018 }
85019
85020 /*
85021 ** This routine sets the value to be returned by subsequent calls to
@@ -84509,11 +85178,11 @@
85178 static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
85179 if( p ){
85180 int i;
85181 for(i=0; i<nField; i++){
85182 Mem *pMem = &p->aMem[i];
85183 if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem);
85184 }
85185 sqlite3DbFreeNN(db, p);
85186 }
85187 }
85188 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -84936,10 +85605,13 @@
85605 pNew->flags |= MEM_Ephem;
85606 if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
85607 sqlite3ValueFree(pNew);
85608 pNew = 0;
85609 }
85610 }else if( pNew->flags & MEM_Null ){
85611 /* Do not duplicate pointer values */
85612 pNew->flags &= ~(MEM_Term|MEM_Subtype);
85613 }
85614 return pNew;
85615 }
85616
85617 /* Destroy an sqlite3_value object previously obtained from
@@ -85436,10 +86108,74 @@
86108 */
86109 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
86110 assert( p );
86111 return sqlite3_value_nochange(p->pOut);
86112 }
86113
86114 /*
86115 ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
86116 ** sqlite3_vtab_in_next() (if bNext!=0).
86117 */
86118 static int valueFromValueList(
86119 sqlite3_value *pVal, /* Pointer to the ValueList object */
86120 sqlite3_value **ppOut, /* Store the next value from the list here */
86121 int bNext /* 1 for _next(). 0 for _first() */
86122 ){
86123 int rc;
86124 ValueList *pRhs;
86125
86126 *ppOut = 0;
86127 if( pVal==0 ) return SQLITE_MISUSE;
86128 pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
86129 if( pRhs==0 ) return SQLITE_MISUSE;
86130 if( bNext ){
86131 rc = sqlite3BtreeNext(pRhs->pCsr, 0);
86132 }else{
86133 int dummy = 0;
86134 rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy);
86135 assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) );
86136 if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE;
86137 }
86138 if( rc==SQLITE_OK ){
86139 u32 sz; /* Size of current row in bytes */
86140 Mem sMem; /* Raw content of current row */
86141 memset(&sMem, 0, sizeof(sMem));
86142 sz = sqlite3BtreePayloadSize(pRhs->pCsr);
86143 rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem);
86144 if( rc==SQLITE_OK ){
86145 u8 *zBuf = (u8*)sMem.z;
86146 u32 iSerial;
86147 sqlite3_value *pOut = pRhs->pOut;
86148 int iOff = 1 + getVarint32(&zBuf[1], iSerial);
86149 sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut);
86150 pOut->enc = ENC(pOut->db);
86151 if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){
86152 rc = SQLITE_NOMEM;
86153 }else{
86154 *ppOut = pOut;
86155 }
86156 }
86157 sqlite3VdbeMemRelease(&sMem);
86158 }
86159 return rc;
86160 }
86161
86162 /*
86163 ** Set the iterator value pVal to point to the first value in the set.
86164 ** Set (*ppOut) to point to this value before returning.
86165 */
86166 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){
86167 return valueFromValueList(pVal, ppOut, 0);
86168 }
86169
86170 /*
86171 ** Set the iterator value pVal to point to the next value in the set.
86172 ** Set (*ppOut) to point to this value before returning.
86173 */
86174 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){
86175 return valueFromValueList(pVal, ppOut, 1);
86176 }
86177
86178 /*
86179 ** Return the current time for a statement. If the current time
86180 ** is requested more than once within the same run of a single prepared
86181 ** statement, the exact same time is returned for each invocation regardless
@@ -85631,19 +86367,19 @@
86367 #if defined(SQLITE_DEBUG) && defined(__GNUC__)
86368 __attribute__((aligned(8)))
86369 #endif
86370 = {
86371 /* .u = */ {0},
86372 /* .z = */ (char*)0,
86373 /* .n = */ (int)0,
86374 /* .flags = */ (u16)MEM_Null,
86375 /* .enc = */ (u8)0,
86376 /* .eSubtype = */ (u8)0,
86377 /* .db = */ (sqlite3*)0,
 
 
86378 /* .szMalloc = */ (int)0,
86379 /* .uTemp = */ (u32)0,
86380 /* .zMalloc = */ (char*)0,
86381 /* .xDel = */ (void(*)(void*))0,
86382 #ifdef SQLITE_DEBUG
86383 /* .pScopyFrom = */ (Mem*)0,
86384 /* .mScopyFlags= */ 0,
86385 #endif
@@ -86121,11 +86857,14 @@
86857 case SQLITE_INTEGER: {
86858 rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
86859 break;
86860 }
86861 case SQLITE_FLOAT: {
86862 assert( pValue->flags & (MEM_Real|MEM_IntReal) );
86863 rc = sqlite3_bind_double(pStmt, i,
86864 (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i
86865 );
86866 break;
86867 }
86868 case SQLITE_BLOB: {
86869 if( pValue->flags & MEM_Zero ){
86870 rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -87537,11 +88276,10 @@
88276 */
88277 static u64 filterHash(const Mem *aMem, const Op *pOp){
88278 int i, mx;
88279 u64 h = 0;
88280
 
88281 assert( pOp->p4type==P4_INT32 );
88282 for(i=pOp->p3, mx=i+pOp->p4.i; i<mx; i++){
88283 const Mem *p = &aMem[i];
88284 if( p->flags & (MEM_Int|MEM_IntReal) ){
88285 h += p->u.i;
@@ -87852,14 +88590,18 @@
88590 jump_to_p2:
88591 pOp = &aOp[pOp->p2 - 1];
88592 break;
88593 }
88594
88595 /* Opcode: Return P1 * P3 * *
88596 **
88597 ** Jump to the next instruction after the address in register P1. After
88598 ** the jump, register P1 becomes undefined.
88599 **
88600 ** P3 is not used by the byte-code engine. However, the code generator
88601 ** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88602 ** one.
88603 */
88604 case OP_Return: { /* in1 */
88605 pIn1 = &aMem[pOp->p1];
88606 assert( pIn1->flags==MEM_Int );
88607 pOp = &aOp[pIn1->u.i];
@@ -88043,15 +88785,26 @@
88785 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
88786 }
88787 goto vdbe_return;
88788 }
88789
88790 /* Opcode: BeginSubrtn P1 P2 * * *
88791 ** Synopsis: r[P2]=P1
88792 **
88793 ** Mark the beginning of a subroutine by loading the integer value P1
88794 ** into register r[P2]. The P2 register is used to store the return
88795 ** address of the subroutine call.
88796 **
88797 ** This opcode is identical to OP_Integer. It has a different name
88798 ** only to make the byte code easier to read and verify.
88799 */
88800 /* Opcode: Integer P1 P2 * * *
88801 ** Synopsis: r[P2]=P1
88802 **
88803 ** The 32-bit integer value P1 is written into register P2.
88804 */
88805 case OP_BeginSubrtn:
88806 case OP_Integer: { /* out2 */
88807 pOut = out2Prerelease(p, pOp);
88808 pOut->u.i = pOp->p1;
88809 break;
88810 }
@@ -89020,11 +89773,11 @@
89773 testcase( pIn1->flags & MEM_Real );
89774 testcase( pIn1->flags & MEM_IntReal );
89775 sqlite3VdbeMemStringify(pIn1, encoding, 1);
89776 testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
89777 flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
89778 if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str;
89779 }
89780 if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
89781 testcase( pIn3->flags & MEM_Int );
89782 testcase( pIn3->flags & MEM_Real );
89783 testcase( pIn3->flags & MEM_IntReal );
@@ -89488,14 +90241,22 @@
90241 case OP_Offset: { /* out3 */
90242 VdbeCursor *pC; /* The VDBE cursor */
90243 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90244 pC = p->apCsr[pOp->p1];
90245 pOut = &p->aMem[pOp->p3];
90246 if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
90247 sqlite3VdbeMemSetNull(pOut);
90248 }else{
90249 if( pC->deferredMoveto ){
90250 rc = sqlite3VdbeFinishMoveto(pC);
90251 if( rc ) goto abort_due_to_error;
90252 }
90253 if( sqlite3BtreeEof(pC->uc.pCursor) ){
90254 sqlite3VdbeMemSetNull(pOut);
90255 }else{
90256 sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90257 }
90258 }
90259 break;
90260 }
90261 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
90262
@@ -89520,11 +90281,11 @@
90281 ** skipped for length() and all content loading can be skipped for typeof().
90282 */
90283 case OP_Column: {
90284 u32 p2; /* column number to retrieve */
90285 VdbeCursor *pC; /* The VDBE cursor */
90286 BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
90287 u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
90288 int len; /* The length of the serialized data for the column */
90289 int i; /* Loop counter */
90290 Mem *pDest; /* Where to write the extracted value */
90291 Mem sMem; /* For storing the record being decoded */
@@ -89534,23 +90295,15 @@
90295 u64 offset64; /* 64-bit offset */
90296 u32 t; /* A type code from the record header */
90297 Mem *pReg; /* PseudoTable input register */
90298
90299 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90300 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
90301 pC = p->apCsr[pOp->p1];
 
90302 p2 = (u32)pOp->p2;
90303
90304 op_column_restart:
 
 
 
 
 
 
 
 
90305 assert( pC!=0 );
90306 assert( p2<(u32)pC->nField );
90307 aOffset = pC->aOffset;
90308 assert( aOffset==pC->aType+pC->nField );
90309 assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89567,30 +90320,43 @@
90320 assert( pReg->flags & MEM_Blob );
90321 assert( memIsValid(pReg) );
90322 pC->payloadSize = pC->szRow = pReg->n;
90323 pC->aRow = (u8*)pReg->z;
90324 }else{
90325 pDest = &aMem[pOp->p3];
90326 memAboutToChange(p, pDest);
90327 sqlite3VdbeMemSetNull(pDest);
90328 goto op_column_out;
90329 }
90330 }else{
90331 pCrsr = pC->uc.pCursor;
90332 if( pC->deferredMoveto ){
90333 u32 iMap;
90334 assert( !pC->isEphemeral );
90335 if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
90336 pC = pC->pAltCursor;
90337 p2 = iMap - 1;
90338 goto op_column_restart;
90339 }
90340 rc = sqlite3VdbeFinishMoveto(pC);
90341 if( rc ) goto abort_due_to_error;
90342 }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
90343 rc = sqlite3VdbeHandleMovedCursor(pC);
90344 if( rc ) goto abort_due_to_error;
90345 goto op_column_restart;
90346 }
90347 assert( pC->eCurType==CURTYPE_BTREE );
90348 assert( pCrsr );
90349 assert( sqlite3BtreeCursorIsValid(pCrsr) );
90350 pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
90351 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
90352 assert( pC->szRow<=pC->payloadSize );
90353 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
 
 
 
90354 }
90355 pC->cacheStatus = p->cacheCtr;
90356 pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
90357 pC->nHdrParsed = 0;
 
90358
90359 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
90360 /* pC->aRow does not have to hold the entire row, but it does at least
90361 ** need to cover the header of the record. If pC->aRow does not contain
90362 ** the complete header, then set it to zero, forcing the header to be
@@ -89627,10 +90393,14 @@
90393 zData = pC->aRow;
90394 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
90395 testcase( aOffset[0]==0 );
90396 goto op_column_read_header;
90397 }
90398 }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){
90399 rc = sqlite3VdbeHandleMovedCursor(pC);
90400 if( rc ) goto abort_due_to_error;
90401 goto op_column_restart;
90402 }
90403
90404 /* Make sure at least the first p2+1 entries of the header have been
90405 ** parsed and valid information is in aOffset[] and pC->aType[].
90406 */
@@ -89695,10 +90465,12 @@
90465 /* If after trying to extract new entries from the header, nHdrParsed is
90466 ** still not up to p2, that means that the record has fewer than p2
90467 ** columns. So the result will be either the default value or a NULL.
90468 */
90469 if( pC->nHdrParsed<=p2 ){
90470 pDest = &aMem[pOp->p3];
90471 memAboutToChange(p, pDest);
90472 if( pOp->p4type==P4_MEM ){
90473 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
90474 }else{
90475 sqlite3VdbeMemSetNull(pDest);
90476 }
@@ -89712,10 +90484,12 @@
90484 ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
90485 ** all valid.
90486 */
90487 assert( p2<pC->nHdrParsed );
90488 assert( rc==SQLITE_OK );
90489 pDest = &aMem[pOp->p3];
90490 memAboutToChange(p, pDest);
90491 assert( sqlite3VdbeCheckMemInvariants(pDest) );
90492 if( VdbeMemDynamic(pDest) ){
90493 sqlite3VdbeMemSetNull(pDest);
90494 }
90495 assert( t==pC->aType[p2] );
@@ -89732,10 +90506,11 @@
90506 */
90507 static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
90508 pDest->n = len = (t-12)/2;
90509 pDest->enc = encoding;
90510 if( pDest->szMalloc < len+2 ){
90511 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
90512 pDest->flags = MEM_Null;
90513 if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
90514 }else{
90515 pDest->z = pDest->zMalloc;
90516 }
@@ -89764,10 +90539,11 @@
90539 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
90540 ** and it begins with a bunch of zeros.
90541 */
90542 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
90543 }else{
90544 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
90545 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
90546 if( rc!=SQLITE_OK ) goto abort_due_to_error;
90547 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
90548 pDest->flags &= ~MEM_Ephem;
90549 }
@@ -89846,10 +90622,12 @@
90622 case COLTYPE_TEXT: {
90623 if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error;
90624 break;
90625 }
90626 case COLTYPE_REAL: {
90627 testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real );
90628 testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal );
90629 if( pIn1->flags & MEM_Int ){
90630 /* When applying REAL affinity, if the result is still an MEM_Int
90631 ** that will fit in 6 bytes, then change the type to MEM_IntReal
90632 ** so that we keep the high-resolution integer value but know that
90633 ** the type really wants to be REAL. */
@@ -89863,11 +90641,11 @@
90641 }else{
90642 pIn1->u.r = (double)pIn1->u.i;
90643 pIn1->flags |= MEM_Real;
90644 pIn1->flags &= ~MEM_Int;
90645 }
90646 }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){
90647 goto vdbe_type_error;
90648 }
90649 break;
90650 }
90651 default: {
@@ -89974,11 +90752,10 @@
90752 u32 serial_type; /* Type field */
90753 Mem *pData0; /* First field to be combined into the record */
90754 Mem *pLast; /* Last field of the record */
90755 int nField; /* Number of fields in the record */
90756 char *zAffinity; /* The affinity string for the record */
 
90757 u32 len; /* Length of a field */
90758 u8 *zHdr; /* Where to write next byte of the header */
90759 u8 *zPayload; /* Where to write next byte of the payload */
90760
90761 /* Assuming the record contains N fields, the record format looks
@@ -90003,11 +90780,10 @@
90780 zAffinity = pOp->p4.z;
90781 assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
90782 pData0 = &aMem[nField];
90783 nField = pOp->p2;
90784 pLast = &pData0[nField-1];
 
90785
90786 /* Identify the output register */
90787 assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
90788 pOut = &aMem[pOp->p3];
90789 memAboutToChange(p, pOut);
@@ -90102,14 +90878,14 @@
90878 }
90879 nHdr++;
90880 testcase( uu==127 ); testcase( uu==128 );
90881 testcase( uu==32767 ); testcase( uu==32768 );
90882 testcase( uu==8388607 ); testcase( uu==8388608 );
90883 testcase( uu==2147483647 ); testcase( uu==2147483648LL );
90884 testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
90885 if( uu<=127 ){
90886 if( (i&1)==i && p->minWriteFileFormat>=4 ){
90887 pRec->uTemp = 8+(u32)uu;
90888 }else{
90889 nData++;
90890 pRec->uTemp = 1;
90891 }
@@ -92568,10 +93344,14 @@
93344 /* Opcode: NullRow P1 * * * *
93345 **
93346 ** Move the cursor P1 to a null row. Any OP_Column operations
93347 ** that occur while the cursor is on the null row will always
93348 ** write a NULL.
93349 **
93350 ** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93351 ** just reset the cache for that cursor. This causes the row of
93352 ** content held by the pseudo-cursor to be reparsed.
93353 */
93354 case OP_NullRow: {
93355 VdbeCursor *pC;
93356
93357 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92747,11 +93527,11 @@
93527 VdbeBranchTaken(res!=0,2);
93528 if( res ) goto jump_to_p2;
93529 break;
93530 }
93531
93532 /* Opcode: Next P1 P2 P3 * P5
93533 **
93534 ** Advance cursor P1 so that it points to the next key/data pair in its
93535 ** table or index. If there are no more key/value pairs then fall through
93536 ** to the following instruction. But if the cursor advance was successful,
93537 ** jump immediately to P2.
@@ -92766,19 +93546,16 @@
93546 ** The P3 value is a hint to the btree implementation. If P3==1, that
93547 ** means P1 is an SQL index and that this instruction could have been
93548 ** omitted if that index had been unique. P3 is usually 0. P3 is
93549 ** always either 0 or 1.
93550 **
 
 
 
93551 ** If P5 is positive and the jump is taken, then event counter
93552 ** number P5-1 in the prepared statement is incremented.
93553 **
93554 ** See also: Prev
93555 */
93556 /* Opcode: Prev P1 P2 P3 * P5
93557 **
93558 ** Back up cursor P1 so that it points to the previous key/data pair in its
93559 ** table or index. If there is no previous key/value pairs then fall through
93560 ** to the following instruction. But if the cursor backup was successful,
93561 ** jump immediately to P2.
@@ -92794,13 +93571,10 @@
93571 ** The P3 value is a hint to the btree implementation. If P3==1, that
93572 ** means P1 is an SQL index and that this instruction could have been
93573 ** omitted if that index had been unique. P3 is usually 0. P3 is
93574 ** always either 0 or 1.
93575 **
 
 
 
93576 ** If P5 is positive and the jump is taken, then event counter
93577 ** number P5-1 in the prepared statement is incremented.
93578 */
93579 /* Opcode: SorterNext P1 P2 * * P5
93580 **
@@ -92814,34 +93588,37 @@
93588
93589 pC = p->apCsr[pOp->p1];
93590 assert( isSorter(pC) );
93591 rc = sqlite3VdbeSorterNext(db, pC);
93592 goto next_tail;
93593
93594 case OP_Prev: /* jump */
93595 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93596 assert( pOp->p5<ArraySize(p->aCounter) );
93597 pC = p->apCsr[pOp->p1];
93598 assert( pC!=0 );
93599 assert( pC->deferredMoveto==0 );
93600 assert( pC->eCurType==CURTYPE_BTREE );
93601 assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
93602 || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
93603 || pC->seekOp==OP_NullRow);
93604 rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
93605 goto next_tail;
93606
93607 case OP_Next: /* jump */
93608 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93609 assert( pOp->p5<ArraySize(p->aCounter) );
93610 pC = p->apCsr[pOp->p1];
93611 assert( pC!=0 );
93612 assert( pC->deferredMoveto==0 );
93613 assert( pC->eCurType==CURTYPE_BTREE );
93614 assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
 
 
 
 
 
 
93615 || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
93616 || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
93617 || pC->seekOp==OP_IfNoHope);
93618 rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3);
 
 
 
93619
 
93620 next_tail:
93621 pC->cacheStatus = CACHE_STALE;
93622 VdbeBranchTaken(rc==SQLITE_OK,2);
93623 if( rc==SQLITE_OK ){
93624 pC->nullRow = 0;
@@ -93055,10 +93832,11 @@
93832 assert( pTabCur->uc.pCursor!=0 );
93833 assert( pTabCur->isTable );
93834 pTabCur->nullRow = 0;
93835 pTabCur->movetoTarget = rowid;
93836 pTabCur->deferredMoveto = 1;
93837 pTabCur->cacheStatus = CACHE_STALE;
93838 assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
93839 assert( !pTabCur->isEphemeral );
93840 pTabCur->ub.aAltMap = pOp->p4.ai;
93841 assert( !pC->isEphemeral );
93842 pTabCur->pAltCursor = pC;
@@ -93189,11 +93967,11 @@
93967 }
93968 sqlite3VdbeMemInit(&m, db, 0);
93969 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
93970 if( rc ) goto abort_due_to_error;
93971 res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
93972 sqlite3VdbeMemReleaseMalloc(&m);
93973 }
93974 /* End of inlined sqlite3VdbeIdxKeyCompare() */
93975
93976 assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
93977 if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94592,10 +95370,38 @@
95370 goto no_mem;
95371 }
95372 break;
95373 }
95374 #endif /* SQLITE_OMIT_VIRTUALTABLE */
95375
95376 #ifndef SQLITE_OMIT_VIRTUALTABLE
95377 /* Opcode: VInitIn P1 P2 P3 * *
95378 ** Synopsis: r[P2]=ValueList(P1,P3)
95379 **
95380 ** Set register P2 to be a pointer to a ValueList object for cursor P1
95381 ** with cache register P3 and output register P3+1. This ValueList object
95382 ** can be used as the first argument to sqlite3_vtab_in_first() and
95383 ** sqlite3_vtab_in_next() to extract all of the values stored in the P1
95384 ** cursor. Register P3 is used to hold the values returned by
95385 ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
95386 */
95387 case OP_VInitIn: { /* out2 */
95388 VdbeCursor *pC; /* The cursor containing the RHS values */
95389 ValueList *pRhs; /* New ValueList object to put in reg[P2] */
95390
95391 pC = p->apCsr[pOp->p1];
95392 pRhs = sqlite3_malloc64( sizeof(*pRhs) );
95393 if( pRhs==0 ) goto no_mem;
95394 pRhs->pCsr = pC->uc.pCursor;
95395 pRhs->pOut = &aMem[pOp->p3];
95396 pOut = out2Prerelease(p, pOp);
95397 pOut->flags = MEM_Null;
95398 sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
95399 break;
95400 }
95401 #endif /* SQLITE_OMIT_VIRTUALTABLE */
95402
95403
95404 #ifndef SQLITE_OMIT_VIRTUALTABLE
95405 /* Opcode: VFilter P1 P2 P3 P4 *
95406 ** Synopsis: iplan=r[P3] zplan='P4'
95407 **
@@ -95579,14 +96385,13 @@
96385 wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
96386
96387 sqlite3_mutex_enter(db->mutex);
96388
96389 pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
96390 while(1){
96391 sqlite3ParseObjectInit(&sParse,db);
96392 if( !pBlob ) goto blob_open_out;
 
96393 sqlite3DbFree(db, zErr);
96394 zErr = 0;
96395
96396 sqlite3BtreeEnterAll(db);
96397 pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
@@ -95759,11 +96564,13 @@
96564 sqlite3BtreeLeaveAll(db);
96565 if( db->mallocFailed ){
96566 goto blob_open_out;
96567 }
96568 rc = blobSeekToRow(pBlob, iRow, &zErr);
96569 if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break;
96570 sqlite3ParseObjectReset(&sParse);
96571 }
96572
96573 blob_open_out:
96574 if( rc==SQLITE_OK && db->mallocFailed==0 ){
96575 *ppBlob = (sqlite3_blob *)pBlob;
96576 }else{
@@ -95770,11 +96577,11 @@
96577 if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
96578 sqlite3DbFree(db, pBlob);
96579 }
96580 sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
96581 sqlite3DbFree(db, zErr);
96582 sqlite3ParseObjectReset(&sParse);
96583 rc = sqlite3ApiExit(db, rc);
96584 sqlite3_mutex_leave(db->mutex);
96585 return rc;
96586 }
96587
@@ -99319,10 +100126,13 @@
100126 }
100127 return rc;
100128 }
100129
100130
100131 /* Forward reference */
100132 static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size);
100133
100134 /*
100135 ** Write data to the file.
100136 */
100137 static int memjrnlWrite(
100138 sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99349,26 +100159,24 @@
100159 /* An in-memory journal file should only ever be appended to. Random
100160 ** access writes are not required. The only exception to this is when
100161 ** the in-memory journal is being used by a connection using the
100162 ** atomic-write optimization. In this case the first 28 bytes of the
100163 ** journal file may be written as part of committing the transaction. */
100164 assert( iOfst<=p->endpoint.iOffset );
100165 if( iOfst>0 && iOfst!=p->endpoint.iOffset ){
100166 memjrnlTruncate(pJfd, iOfst);
100167 }
100168 if( iOfst==0 && p->pFirst ){
100169 assert( p->nChunkSize>iAmt );
100170 memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
100171 }else{
 
 
 
 
100172 while( nWrite>0 ){
100173 FileChunk *pChunk = p->endpoint.pChunk;
100174 int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
100175 int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
100176
100177 assert( pChunk!=0 || iChunkOffset==0 );
100178 if( iChunkOffset==0 ){
100179 /* New chunk is required to extend the file. */
100180 FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
100181 if( !pNew ){
100182 return SQLITE_IOERR_NOMEM_BKPT;
@@ -99379,14 +100187,15 @@
100187 pChunk->pNext = pNew;
100188 }else{
100189 assert( !p->pFirst );
100190 p->pFirst = pNew;
100191 }
100192 pChunk = p->endpoint.pChunk = pNew;
100193 }
100194
100195 assert( pChunk!=0 );
100196 memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace);
100197 zWrite += iSpace;
100198 nWrite -= iSpace;
100199 p->endpoint.iOffset += iSpace;
100200 }
100201 }
@@ -100460,10 +101269,11 @@
101269 }else if( zTab ){
101270 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
101271 }else{
101272 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
101273 }
101274 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101275 pParse->checkSchema = 1;
101276 pTopNC->nNcErr++;
101277 }
101278
101279 /* If a column from a table in pSrcList is referenced, then record
@@ -100568,11 +101378,12 @@
101378 */
101379 static void notValidImpl(
101380 Parse *pParse, /* Leave error message here */
101381 NameContext *pNC, /* The name context */
101382 const char *zMsg, /* Type of error */
101383 Expr *pExpr, /* Invalidate this expression on error */
101384 Expr *pError /* Associate error with this expression */
101385 ){
101386 const char *zIn = "partial index WHERE clauses";
101387 if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
101388 #ifndef SQLITE_OMIT_CHECK
101389 else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100580,14 +101391,15 @@
101391 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
101392 else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
101393 #endif
101394 sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
101395 if( pExpr ) pExpr->op = TK_NULL;
101396 sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
101397 }
101398 #define sqlite3ResolveNotValid(P,N,M,X,E,R) \
101399 assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
101400 if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R);
101401
101402 /*
101403 ** Expression p should encode a floating point value between 1.0 and 0.0.
101404 ** Return 1024 times this value. Or return -1 if p is not a floating point
101405 ** value between 1.0 and 0.0.
@@ -100718,11 +101530,11 @@
101530 }else{
101531 Expr *pLeft = pExpr->pLeft;
101532 testcase( pNC->ncFlags & NC_IdxExpr );
101533 testcase( pNC->ncFlags & NC_GenCol );
101534 sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
101535 NC_IdxExpr|NC_GenCol, 0, pExpr);
101536 pRight = pExpr->pRight;
101537 if( pRight->op==TK_ID ){
101538 zDb = 0;
101539 }else{
101540 assert( pRight->op==TK_DOT );
@@ -100749,21 +101561,19 @@
101561 ExprList *pList = pExpr->x.pList; /* The argument list */
101562 int n = pList ? pList->nExpr : 0; /* Number of arguments */
101563 int no_such_func = 0; /* True if no such function exists */
101564 int wrong_num_args = 0; /* True if wrong number of arguments */
101565 int is_agg = 0; /* True if is an aggregate function */
 
101566 const char *zId; /* The function name. */
101567 FuncDef *pDef; /* Information about the function */
101568 u8 enc = ENC(pParse->db); /* The database encoding */
101569 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
101570 #ifndef SQLITE_OMIT_WINDOWFUNC
101571 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
101572 #endif
101573 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
101574 zId = pExpr->u.zToken;
 
101575 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
101576 if( pDef==0 ){
101577 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
101578 if( pDef==0 ){
101579 no_such_func = 1;
@@ -100776,12 +101586,12 @@
101586 ExprSetProperty(pExpr, EP_Unlikely);
101587 if( n==2 ){
101588 pExpr->iTable = exprProbability(pList->a[1].pExpr);
101589 if( pExpr->iTable<0 ){
101590 sqlite3ErrorMsg(pParse,
101591 "second argument to %#T() must be a "
101592 "constant between 0.0 and 1.0", pExpr);
101593 pNC->nNcErr++;
101594 }
101595 }else{
101596 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
101597 ** equivalent to likelihood(X, 0.0625).
@@ -100798,12 +101608,12 @@
101608 #ifndef SQLITE_OMIT_AUTHORIZATION
101609 {
101610 int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
101611 if( auth!=SQLITE_OK ){
101612 if( auth==SQLITE_DENY ){
101613 sqlite3ErrorMsg(pParse, "not authorized to use function: %#T",
101614 pExpr);
101615 pNC->nNcErr++;
101616 }
101617 pExpr->op = TK_NULL;
101618 return WRC_Prune;
101619 }
@@ -100822,11 +101632,11 @@
101632 ** sqlite_version() that might change over time cannot be used
101633 ** in an index or generated column. Curiously, they can be used
101634 ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
101635 ** all this. */
101636 sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
101637 NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
101638 }else{
101639 assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
101640 pExpr->op2 = pNC->ncFlags & NC_SelfRef;
101641 if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
101642 }
@@ -100835,11 +101645,11 @@
101645 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
101646 ){
101647 /* Internal-use-only functions are disallowed unless the
101648 ** SQL is being compiled using sqlite3NestedParse() or
101649 ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
101650 ** used to activate internal functions for testing purposes */
101651 no_such_func = 1;
101652 pDef = 0;
101653 }else
101654 if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
101655 && !IN_RENAME_OBJECT
@@ -100854,11 +101664,11 @@
101664 || (pDef->xValue==0 && pDef->xInverse==0)
101665 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
101666 );
101667 if( pDef && pDef->xValue==0 && pWin ){
101668 sqlite3ErrorMsg(pParse,
101669 "%#T() may not be used as a window function", pExpr
101670 );
101671 pNC->nNcErr++;
101672 }else if(
101673 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
101674 || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100868,38 +101678,38 @@
101678 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
101679 zType = "window";
101680 }else{
101681 zType = "aggregate";
101682 }
101683 sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr);
101684 pNC->nNcErr++;
101685 is_agg = 0;
101686 }
101687 #else
101688 if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
101689 sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr);
101690 pNC->nNcErr++;
101691 is_agg = 0;
101692 }
101693 #endif
101694 else if( no_such_func && pParse->db->init.busy==0
101695 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
101696 && pParse->explain==0
101697 #endif
101698 ){
101699 sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
101700 pNC->nNcErr++;
101701 }else if( wrong_num_args ){
101702 sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()",
101703 pExpr);
101704 pNC->nNcErr++;
101705 }
101706 #ifndef SQLITE_OMIT_WINDOWFUNC
101707 else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
101708 sqlite3ErrorMsg(pParse,
101709 "FILTER may not be used with non-aggregate %#T()",
101710 pExpr
101711 );
101712 pNC->nNcErr++;
101713 }
101714 #endif
101715 if( is_agg ){
@@ -100980,11 +101790,11 @@
101790 testcase( pNC->ncFlags & NC_IsCheck );
101791 testcase( pNC->ncFlags & NC_PartIdx );
101792 testcase( pNC->ncFlags & NC_IdxExpr );
101793 testcase( pNC->ncFlags & NC_GenCol );
101794 if( pNC->ncFlags & NC_SelfRef ){
101795 notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
101796 }else{
101797 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
101798 }
101799 assert( pNC->nRef>=nRef );
101800 if( nRef!=pNC->nRef ){
@@ -100998,11 +101808,11 @@
101808 testcase( pNC->ncFlags & NC_IsCheck );
101809 testcase( pNC->ncFlags & NC_PartIdx );
101810 testcase( pNC->ncFlags & NC_IdxExpr );
101811 testcase( pNC->ncFlags & NC_GenCol );
101812 sqlite3ResolveNotValid(pParse, pNC, "parameters",
101813 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr);
101814 break;
101815 }
101816 case TK_IS:
101817 case TK_ISNOT: {
101818 Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101050,15 +101860,17 @@
101860 testcase( pExpr->op==TK_GE );
101861 testcase( pExpr->op==TK_IS );
101862 testcase( pExpr->op==TK_ISNOT );
101863 testcase( pExpr->op==TK_BETWEEN );
101864 sqlite3ErrorMsg(pParse, "row value misused");
101865 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101866 }
101867 break;
101868 }
101869 }
101870 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
101871 return pParse->nErr ? WRC_Abort : WRC_Continue;
101872 }
101873
101874 /*
101875 ** pEList is a list of expressions which are really the result set of the
101876 ** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
@@ -101162,15 +101974,17 @@
101974 */
101975 static void resolveOutOfRangeError(
101976 Parse *pParse, /* The error context into which to write the error */
101977 const char *zType, /* "ORDER" or "GROUP" */
101978 int i, /* The index (1-based) of the term out of range */
101979 int mx, /* Largest permissible value of i */
101980 Expr *pError /* Associate the error with the expression */
101981 ){
101982 sqlite3ErrorMsg(pParse,
101983 "%r %s BY term out of range - should be "
101984 "between 1 and %d", i, zType, mx);
101985 sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
101986 }
101987
101988 /*
101989 ** Analyze the ORDER BY clause in a compound SELECT statement. Modify
101990 ** each term of the ORDER BY clause is a constant integer between 1
@@ -101222,11 +102036,11 @@
102036 if( pItem->done ) continue;
102037 pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
102038 if( NEVER(pE==0) ) continue;
102039 if( sqlite3ExprIsInteger(pE, &iCol) ){
102040 if( iCol<=0 || iCol>pEList->nExpr ){
102041 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
102042 return 1;
102043 }
102044 }else{
102045 iCol = resolveAsName(pParse, pEList, pE);
102046 if( iCol==0 ){
@@ -101318,11 +102132,11 @@
102132 pEList = pSelect->pEList;
102133 assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
102134 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
102135 if( pItem->u.x.iOrderByCol ){
102136 if( pItem->u.x.iOrderByCol>pEList->nExpr ){
102137 resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0);
102138 return 1;
102139 }
102140 resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
102141 }
102142 }
@@ -101410,11 +102224,11 @@
102224 if( sqlite3ExprIsInteger(pE2, &iCol) ){
102225 /* The ORDER BY term is an integer constant. Again, set the column
102226 ** number so that sqlite3ResolveOrderGroupBy() will convert the
102227 ** order-by term to a copy of the result-set expression */
102228 if( iCol<1 || iCol>0xffff ){
102229 resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2);
102230 return 1;
102231 }
102232 pItem->u.x.iOrderByCol = (u16)iCol;
102233 continue;
102234 }
@@ -101468,11 +102282,11 @@
102282 ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and
102283 ** this routine in the correct order.
102284 */
102285 if( (p->selFlags & SF_Expanded)==0 ){
102286 sqlite3SelectPrep(pParse, p, pOuterNC);
102287 return pParse->nErr ? WRC_Abort : WRC_Prune;
102288 }
102289
102290 isCompound = p->pPrior!=0;
102291 nCompound = 0;
102292 pLeftmost = p;
@@ -101516,11 +102330,12 @@
102330 const char *zSavedContext = pParse->zAuthContext;
102331
102332 if( pItem->zName ) pParse->zAuthContext = pItem->zName;
102333 sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
102334 pParse->zAuthContext = zSavedContext;
102335 if( pParse->nErr ) return WRC_Abort;
102336 assert( db->mallocFailed==0 );
102337
102338 /* If the number of references to the outer context changed when
102339 ** expressions in the sub-select were resolved, the sub-select
102340 ** is correlated. It is not required to check the refcount on any
102341 ** but the innermost outer context object, as lookupName() increments
@@ -102662,13 +103477,12 @@
103477 **
103478 ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
103479 ** if appropriate.
103480 */
103481 static void exprSetHeight(Expr *p){
103482 int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
103483 if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
 
103484 if( ExprUseXSelect(p) ){
103485 heightOfSelect(p->x.pSelect, &nHeight);
103486 }else if( p->x.pList ){
103487 heightOfExprList(p->x.pList, &nHeight);
103488 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -102963,10 +103777,11 @@
103777 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
103778 if( pNew==0 ){
103779 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
103780 return 0;
103781 }
103782 pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
103783 if( pList
103784 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
103785 && !pParse->nested
103786 ){
103787 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103006,11 +103821,11 @@
103821 ** (2) not tagged with SQLITE_INNOCUOUS (which means it
103822 ** is tagged with SQLITE_FUNC_UNSAFE) and
103823 ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103824 ** that the schema is possibly tainted).
103825 */
103826 sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
103827 }
103828 }
103829 }
103830
103831 /*
@@ -103062,10 +103877,11 @@
103877 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103878 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103879 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103880 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103881 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
103882 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103883 return;
103884 }
103885 x = (ynVar)i;
103886 if( x>pParse->nVar ){
103887 pParse->nVar = (int)x;
@@ -103089,10 +103905,11 @@
103905 }
103906 }
103907 pExpr->iColumn = x;
103908 if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103909 sqlite3ErrorMsg(pParse, "too many SQL variables");
103910 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103911 }
103912 }
103913
103914 /*
103915 ** Recursively delete an expression tree.
@@ -104696,12 +105513,11 @@
105513 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
105514 Expr *pRhs = pEList->a[i].pExpr;
105515 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
105516 int j;
105517
105518 assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
 
105519 for(j=0; j<nExpr; j++){
105520 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
105521 assert( pIdx->azColl[j] );
105522 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
105523 continue;
@@ -104932,12 +105748,11 @@
105748 assert( !ExprUseYWin(pExpr) );
105749 ExprSetProperty(pExpr, EP_Subrtn);
105750 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
105751 pExpr->y.sub.regReturn = ++pParse->nMem;
105752 pExpr->y.sub.iAddr =
105753 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
 
105754
105755 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
105756 }
105757
105758 /* Check to see if this is a vector IN operator */
@@ -105035,10 +105850,11 @@
105850 ** disable the test that was generated above that makes sure
105851 ** this code only executes once. Because for a non-constant
105852 ** expression we need to rerun this code each time.
105853 */
105854 if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
105855 sqlite3VdbeChangeToNoop(v, addrOnce-1);
105856 sqlite3VdbeChangeToNoop(v, addrOnce);
105857 ExprClearProperty(pExpr, EP_Subrtn);
105858 addrOnce = 0;
105859 }
105860
@@ -105055,11 +105871,14 @@
105871 }
105872 if( addrOnce ){
105873 sqlite3VdbeJumpHere(v, addrOnce);
105874 /* Subroutine return */
105875 assert( ExprUseYSub(pExpr) );
105876 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105877 || pParse->nErr );
105878 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105879 pExpr->y.sub.iAddr-1);
105880 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105881 sqlite3ClearTempRegCache(pParse);
105882 }
105883 }
105884 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105110,13 +105929,11 @@
105929 assert( !ExprUseYWin(pExpr) );
105930 assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105931 ExprSetProperty(pExpr, EP_Subrtn);
105932 pExpr->y.sub.regReturn = ++pParse->nMem;
105933 pExpr->y.sub.iAddr =
105934 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
 
 
105935
105936 /* The evaluation of the EXISTS/SELECT must be repeated every time it
105937 ** is encountered if any of the following is true:
105938 **
105939 ** * The right-hand side is a correlated subquery
@@ -105173,14 +105990,12 @@
105990 pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
105991 pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
105992 }
105993 pSel->iLimit = 0;
105994 if( sqlite3Select(pParse, pSel, &dest) ){
105995 pExpr->op2 = pExpr->op;
105996 pExpr->op = TK_ERROR;
 
 
105997 return 0;
105998 }
105999 pExpr->iTable = rReg = dest.iSDParm;
106000 ExprSetVVAProperty(pExpr, EP_NoReduce);
106001 if( addrOnce ){
@@ -105187,11 +106002,14 @@
106002 sqlite3VdbeJumpHere(v, addrOnce);
106003 }
106004
106005 /* Subroutine return */
106006 assert( ExprUseYSub(pExpr) );
106007 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106008 || pParse->nErr );
106009 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106010 pExpr->y.sub.iAddr-1);
106011 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
106012 sqlite3ClearTempRegCache(pParse);
106013 return rReg;
106014 }
106015 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105393,14 +106211,13 @@
106211 if( destIfNull==destIfFalse ){
106212 destStep2 = destIfFalse;
106213 }else{
106214 destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
106215 }
 
106216 for(i=0; i<nVector; i++){
106217 Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
106218 if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
106219 if( sqlite3ExprCanBeNull(p) ){
106220 sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
106221 VdbeCoverage(v);
106222 }
106223 }
@@ -105534,15 +106351,16 @@
106351 const char *z = pExpr->u.zToken;
106352 assert( z!=0 );
106353 c = sqlite3DecOrHexToI64(z, &value);
106354 if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
106355 #ifdef SQLITE_OMIT_FLOATING_POINT
106356 sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
106357 #else
106358 #ifndef SQLITE_OMIT_HEX_INTEGER
106359 if( sqlite3_strnicmp(z,"0x",2)==0 ){
106360 sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
106361 negFlag?"-":"",pExpr);
106362 }else
106363 #endif
106364 {
106365 codeReal(v, z, negFlag, iMem);
106366 }
@@ -106214,11 +107032,11 @@
107032 if( pInfo==0
107033 || NEVER(pExpr->iAgg<0)
107034 || NEVER(pExpr->iAgg>=pInfo->nFunc)
107035 ){
107036 assert( !ExprHasProperty(pExpr, EP_IntValue) );
107037 sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
107038 }else{
107039 return pInfo->aFunc[pExpr->iAgg].iMem;
107040 }
107041 break;
107042 }
@@ -106255,11 +107073,11 @@
107073 if( pDef==0 && pParse->explain ){
107074 pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
107075 }
107076 #endif
107077 if( pDef==0 || pDef->xFinalize!=0 ){
107078 sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
107079 break;
107080 }
107081 if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
107082 assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
107083 assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -108571,11 +109389,13 @@
109389 sqlite3 *db; /* The database connection; */
109390 Vdbe *v; /* The prepared statement under construction */
109391 int r1; /* Temporary registers */
109392
109393 db = pParse->db;
109394 assert( db->pParse==pParse );
109395 if( pParse->nErr ) return;
109396 assert( db->mallocFailed==0 );
109397 pNew = pParse->pNewTable;
109398 assert( pNew );
109399
109400 assert( sqlite3BtreeHoldsAllMutexes(db) );
109401 iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
@@ -108697,11 +109517,11 @@
109517 sqlite3NestedParse(pParse,
109518 "SELECT CASE WHEN quick_check GLOB 'CHECK*'"
109519 " THEN raise(ABORT,'CHECK constraint failed')"
109520 " ELSE raise(ABORT,'NOT NULL constraint failed')"
109521 " END"
109522 " FROM pragma_quick_check(%Q,%Q)"
109523 " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'",
109524 zTab, zDb
109525 );
109526 }
109527 }
@@ -108876,11 +109696,11 @@
109696 if( !zOld ) goto exit_rename_column;
109697 for(iCol=0; iCol<pTab->nCol; iCol++){
109698 if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
109699 }
109700 if( iCol==pTab->nCol ){
109701 sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
109702 goto exit_rename_column;
109703 }
109704
109705 /* Ensure the schema contains no double-quoted strings */
109706 renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -108982,11 +109802,13 @@
109802 **
109803 ** Technically, as x no longer points into a valid object or to the byte
109804 ** following a valid object, it may not be used in comparison operations.
109805 */
109806 static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
109807 assert( pParse==pParse->db->pParse );
109808 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
109809 if( pParse->nErr==0 ){
109810 const RenameToken *p;
109811 u8 i = 0;
109812 for(p=pParse->pRename; p; p=p->pNext){
109813 if( p->p ){
109814 assert( p->p!=pPtr );
@@ -109304,16 +110126,16 @@
110126 ){
110127 const char *zT = (const char*)sqlite3_value_text(pType);
110128 const char *zN = (const char*)sqlite3_value_text(pObject);
110129 char *zErr;
110130
110131 zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",
110132 zT, zN, (zWhen[0] ? " " : ""), zWhen,
110133 pParse->zErrMsg
110134 );
110135 sqlite3_result_error(pCtx, zErr, -1);
110136 sqlite3DbFree(pParse->db, zErr);
110137 }
110138
110139 /*
110140 ** For each name in the the expression-list pEList (i.e. each
110141 ** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109374,23 +110196,25 @@
110196 const char *zSql, /* SQL to parse */
110197 int bTemp /* True if SQL is from temp schema */
110198 ){
110199 int rc;
110200
110201 sqlite3ParseObjectInit(p, db);
110202 if( zSql==0 ){
110203 return SQLITE_NOMEM;
110204 }
110205 if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){
110206 return SQLITE_CORRUPT_BKPT;
110207 }
110208 db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
 
 
 
 
 
110209 p->eParseMode = PARSE_MODE_RENAME;
110210 p->db = db;
110211 p->nQueryLoop = 1;
110212 rc = sqlite3RunParser(p, zSql);
110213 if( db->mallocFailed ) rc = SQLITE_NOMEM;
110214 if( rc==SQLITE_OK
110215 && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
110216 ){
110217 rc = SQLITE_CORRUPT_BKPT;
110218 }
110219
110220 #ifdef SQLITE_DEBUG
@@ -109664,17 +110488,17 @@
110488 sqlite3FreeIndex(db, pIdx);
110489 }
110490 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
110491 sqlite3DbFree(db, pParse->zErrMsg);
110492 renameTokenFree(db, pParse->pRename);
110493 sqlite3ParseObjectReset(pParse);
110494 }
110495
110496 /*
110497 ** SQL function:
110498 **
110499 ** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
110500 **
110501 ** 0. zSql: SQL statement to rewrite
110502 ** 1. type: Type of object ("table", "view" etc.)
110503 ** 2. object: Name of object
110504 ** 3. Database: Database name (e.g. "main")
@@ -109688,11 +110512,12 @@
110512 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
110513 ** into zNew. The name should be quoted if bQuote is true.
110514 **
110515 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
110516 ** It is only accessible to SQL created using sqlite3NestedParse(). It is
110517 ** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
110518 ** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
110519 */
110520 static void renameColumnFunc(
110521 sqlite3_context *context,
110522 int NotUsed,
110523 sqlite3_value **argv
@@ -109837,11 +110662,13 @@
110662 assert( rc==SQLITE_OK );
110663 rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
110664
110665 renameColumnFunc_done:
110666 if( rc!=SQLITE_OK ){
110667 if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110668 sqlite3_result_value(context, argv[0]);
110669 }else if( sParse.zErrMsg ){
110670 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110671 }else{
110672 sqlite3_result_error_code(context, rc);
110673 }
110674 }
@@ -110036,11 +110863,13 @@
110863
110864 if( rc==SQLITE_OK ){
110865 rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110866 }
110867 if( rc!=SQLITE_OK ){
110868 if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110869 sqlite3_result_value(context, argv[3]);
110870 }else if( sParse.zErrMsg ){
110871 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110872 }else{
110873 sqlite3_result_error_code(context, rc);
110874 }
110875 }
@@ -110061,14 +110890,14 @@
110890 renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110891 }
110892 return WRC_Continue;
110893 }
110894
110895 /* SQL function: sqlite_rename_quotefix(DB,SQL)
110896 **
110897 ** Rewrite the DDL statement "SQL" so that any string literals that use
110898 ** double-quotes use single quotes instead.
110899 **
110900 ** Two arguments must be passed:
110901 **
110902 ** 0: Database name ("main", "temp" etc.).
110903 ** 1: SQL statement to edit.
@@ -110083,10 +110912,14 @@
110912 ** );
110913 **
110914 ** returns the string:
110915 **
110916 ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
110917 **
110918 ** If there is a error in the input SQL, then raise an error, except
110919 ** if PRAGMA writable_schema=ON, then just return the input string
110920 ** unmodified following an error.
110921 */
110922 static void renameQuotefixFunc(
110923 sqlite3_context *context,
110924 int NotUsed,
110925 sqlite3_value **argv
@@ -110157,11 +110990,15 @@
110990 rc = renameEditSql(context, &sCtx, zInput, 0, 0);
110991 }
110992 renameTokenFree(db, sCtx.pList);
110993 }
110994 if( rc!=SQLITE_OK ){
110995 if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){
110996 sqlite3_result_value(context, argv[1]);
110997 }else{
110998 sqlite3_result_error_code(context, rc);
110999 }
111000 }
111001 renameParseCleanup(&sParse);
111002 }
111003
111004 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110169,11 +111006,12 @@
111006 #endif
111007
111008 sqlite3BtreeLeaveAll(db);
111009 }
111010
111011 /* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
111012 **
111013 ** An SQL user function that checks that there are no parse or symbol
111014 ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
111015 ** After an ALTER TABLE .. RENAME operation is performed and the schema
111016 ** reloaded, this function is called on each SQL statement in the schema
111017 ** to ensure that it is still usable.
@@ -110184,15 +111022,17 @@
111022 ** 3: Object name.
111023 ** 4: True if object is from temp schema.
111024 ** 5: "when" part of error message.
111025 ** 6: True to disable the DQS quirk when parsing SQL.
111026 **
111027 ** The return value is computed as follows:
 
111028 **
111029 ** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
111030 ** then raise the error.
111031 ** B. Else if a trigger is created and the the table that the trigger is
111032 ** attached to is in database zDb, then return 1.
111033 ** C. Otherwise return NULL.
111034 */
111035 static void renameTableTest(
111036 sqlite3_context *context,
111037 int NotUsed,
111038 sqlite3_value **argv
@@ -110233,16 +111073,20 @@
111073 rc = renameResolveTrigger(&sParse);
111074 }
111075 if( rc==SQLITE_OK ){
111076 int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
111077 int i2 = sqlite3FindDbName(db, zDb);
111078 if( i1==i2 ){
111079 /* Handle output case B */
111080 sqlite3_result_int(context, 1);
111081 }
111082 }
111083 }
111084 }
111085
111086 if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
111087 /* Output case A */
111088 renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
111089 }
111090 renameParseCleanup(&sParse);
111091 }
111092
@@ -110354,11 +111198,11 @@
111198 assert( db->mallocFailed );
111199 goto exit_drop_column;
111200 }
111201 iCol = sqlite3ColumnIndex(pTab, zCol);
111202 if( iCol<0 ){
111203 sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName);
111204 goto exit_drop_column;
111205 }
111206
111207 /* Do not allow the user to drop a PRIMARY KEY column or a column
111208 ** constrained by a UNIQUE constraint. */
@@ -110378,10 +111222,16 @@
111222
111223 /* Edit the sqlite_schema table */
111224 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
111225 assert( iDb>=0 );
111226 zDb = db->aDb[iDb].zDbSName;
111227 #ifndef SQLITE_OMIT_AUTHORIZATION
111228 /* Invoke the authorization callback. */
111229 if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){
111230 goto exit_drop_column;
111231 }
111232 #endif
111233 renameTestSchema(pParse, zDb, iDb==1, "", 0);
111234 renameFixQuotes(pParse, zDb, iDb==1);
111235 sqlite3NestedParse(pParse,
111236 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
111237 "sql = sqlite_drop_column(%d, sql, %d) "
@@ -111501,11 +112351,11 @@
112351 if( pStat1==0 ) return;
112352 pStat1->zName = (char*)&pStat1[1];
112353 memcpy(pStat1->zName, "sqlite_stat1", 13);
112354 pStat1->nCol = 3;
112355 pStat1->iPKey = -1;
112356 sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
112357 }
112358 #endif
112359
112360 /* Establish a read-lock on the table at the shared-cache level.
112361 ** Open a read-only cursor on the table. Also allocate a cursor number
@@ -112765,11 +113615,11 @@
113615 ){
113616 goto attach_end;
113617 }
113618
113619 #ifndef SQLITE_OMIT_AUTHORIZATION
113620 if( ALWAYS(pAuthArg) ){
113621 char *zAuthArg;
113622 if( pAuthArg->op==TK_STRING ){
113623 assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
113624 zAuthArg = pAuthArg->u.zToken;
113625 }else{
@@ -113426,15 +114276,17 @@
114276 sqlite3 *db;
114277 Vdbe *v;
114278
114279 assert( pParse->pToplevel==0 );
114280 db = pParse->db;
114281 assert( db->pParse==pParse );
114282 if( pParse->nested ) return;
114283 if( pParse->nErr ){
114284 if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM;
114285 return;
114286 }
114287 assert( db->mallocFailed==0 );
114288
114289 /* Begin by generating some termination code at the end of the
114290 ** vdbe program
114291 */
114292 v = pParse->pVdbe;
@@ -113563,11 +114415,13 @@
114415 }
114416 }
114417
114418 /* Get the VDBE program ready for execution
114419 */
114420 assert( v!=0 || pParse->nErr );
114421 assert( db->mallocFailed==0 || pParse->nErr );
114422 if( pParse->nErr==0 ){
114423 /* A minimum of one cursor is required if autoincrement is used
114424 * See ticket [a696379c1f08866] */
114425 assert( pParse->pAinc==0 || pParse->nTab>0 );
114426 sqlite3VdbeMakeReady(v, pParse);
114427 pParse->rc = SQLITE_DONE;
@@ -113612,10 +114466,12 @@
114466 pParse->nested++;
114467 memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
114468 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
114469 db->mDbFlags |= DBFLAG_PreferBuiltin;
114470 sqlite3RunParser(pParse, zSql);
114471 sqlite3DbFree(db, pParse->zErrMsg);
114472 pParse->zErrMsg = 0;
114473 db->mDbFlags = savedDbFlags;
114474 sqlite3DbFree(db, zSql);
114475 memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
114476 pParse->nested--;
114477 }
@@ -114572,11 +115428,12 @@
115428 goto begin_table_error;
115429 }
115430 pTable = sqlite3FindTable(db, zName, zDb);
115431 if( pTable ){
115432 if( !noErr ){
115433 sqlite3ErrorMsg(pParse, "%s %T already exists",
115434 (IsView(pTable)? "view" : "table"), pName);
115435 }else{
115436 assert( !db->init.busy || CORRUPT_DB );
115437 sqlite3CodeVerifySchema(pParse, iDb);
115438 sqlite3ForceNotReadOnly(pParse);
115439 }
@@ -115667,14 +116524,15 @@
116524 pList->a[0].sortFlags = pParse->iPkSortOrder;
116525 assert( pParse->pNewTable==pTab );
116526 pTab->iPKey = -1;
116527 sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
116528 SQLITE_IDXTYPE_PRIMARYKEY);
116529 if( pParse->nErr ){
116530 pTab->tabFlags &= ~TF_WithoutRowid;
116531 return;
116532 }
116533 assert( db->mallocFailed==0 );
116534 pPk = sqlite3PrimaryKeyIndex(pTab);
116535 assert( pPk->nKeyCol==1 );
116536 }else{
116537 pPk = sqlite3PrimaryKeyIndex(pTab);
116538 assert( pPk!=0 );
@@ -116101,10 +116959,15 @@
116959 int regRec; /* A record to be insert into the new table */
116960 int regRowid; /* Rowid of the next row to insert */
116961 int addrInsLoop; /* Top of the loop for inserting rows */
116962 Table *pSelTab; /* A table that describes the SELECT results */
116963
116964 if( IN_SPECIAL_PARSE ){
116965 pParse->rc = SQLITE_ERROR;
116966 pParse->nErr++;
116967 return;
116968 }
116969 regYield = ++pParse->nMem;
116970 regRec = ++pParse->nMem;
116971 regRowid = ++pParse->nMem;
116972 assert(pParse->nTab==1);
116973 sqlite3MayAbort(pParse);
@@ -116411,14 +117274,14 @@
117274 ** normally holds CHECK constraints on an ordinary table, but for
117275 ** a VIEW it holds the list of column names.
117276 */
117277 sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
117278 &pTable->nCol, &pTable->aCol);
117279 if( pParse->nErr==0
 
117280 && pTable->nCol==pSel->pEList->nExpr
117281 ){
117282 assert( db->mallocFailed==0 );
117283 sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
117284 SQLITE_AFF_NONE);
117285 }
117286 }else{
117287 /* CREATE VIEW name AS... without an argument list. Construct
@@ -117033,11 +117896,11 @@
117896 tnum = (Pgno)memRootPage;
117897 }else{
117898 tnum = pIndex->tnum;
117899 }
117900 pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
117901 assert( pKey!=0 || pParse->nErr );
117902
117903 /* Open the sorter cursor if we are to use one. */
117904 iSorter = pParse->nTab++;
117905 sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
117906 sqlite3KeyInfoRef(pKey), P4_KEYINFO);
@@ -117197,13 +118060,15 @@
118060 int nExtra = 0; /* Space allocated for zExtra[] */
118061 int nExtraCol; /* Number of extra columns needed */
118062 char *zExtra = 0; /* Extra space after the Index object */
118063 Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
118064
118065 assert( db->pParse==pParse );
118066 if( pParse->nErr ){
118067 goto exit_create_index;
118068 }
118069 assert( db->mallocFailed==0 );
118070 if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
118071 goto exit_create_index;
118072 }
118073 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
118074 goto exit_create_index;
@@ -117263,11 +118128,10 @@
118128 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
118129 }
118130 pDb = &db->aDb[iDb];
118131
118132 assert( pTab!=0 );
 
118133 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
118134 && db->init.busy==0
118135 && pTblName!=0
118136 #if SQLITE_USER_AUTHENTICATION
118137 && sqlite3UserAuthTable(pTab->zName)==0
@@ -117827,14 +118691,14 @@
118691 Index *pIndex;
118692 Vdbe *v;
118693 sqlite3 *db = pParse->db;
118694 int iDb;
118695
 
118696 if( db->mallocFailed ){
118697 goto exit_drop_index;
118698 }
118699 assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
118700 assert( pName->nSrc==1 );
118701 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
118702 goto exit_drop_index;
118703 }
118704 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
@@ -119746,13 +120610,15 @@
120610 Trigger *pTrigger; /* List of table triggers, if required */
120611 #endif
120612
120613 memset(&sContext, 0, sizeof(sContext));
120614 db = pParse->db;
120615 assert( db->pParse==pParse );
120616 if( pParse->nErr ){
120617 goto delete_from_cleanup;
120618 }
120619 assert( db->mallocFailed==0 );
120620 assert( pTabList->nSrc==1 );
120621
120622
120623 /* Locate the table which we want to delete. This table has to be
120624 ** put in an SrcList structure because some of the subroutines we
@@ -119929,11 +120795,11 @@
120795 **
120796 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
120797 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
120798 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
120799 */
120800 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
120801 if( pWInfo==0 ) goto delete_from_cleanup;
120802 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
120803 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
120804 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
120805 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120542,10 +121408,11 @@
121408 static void subtypeFunc(
121409 sqlite3_context *context,
121410 int argc,
121411 sqlite3_value **argv
121412 ){
121413 UNUSED_PARAMETER(argc);
121414 sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
121415 }
121416
121417 /*
121418 ** Implementation of the length() function
@@ -121555,12 +122422,13 @@
122422 UNUSED_PARAMETER(argc);
122423 sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
122424 sqlite3QuoteValue(&str,argv[0]);
122425 sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
122426 SQLITE_DYNAMIC);
122427 if( str.accError!=SQLITE_OK ){
122428 sqlite3_result_null(context);
122429 sqlite3_result_error_code(context, str.accError);
122430 }
122431 }
122432
122433 /*
122434 ** The unicode() function. Return the integer unicode code-point value
@@ -122675,12 +123543,12 @@
123543 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
123544 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123545 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123546 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123547 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
123548 {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
123549 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
123550 #endif
123551 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
123552 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
123553 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
123554 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123472,11 +124340,11 @@
124340
124341 /* Create VDBE to loop through the entries in pSrc that match the WHERE
124342 ** clause. For each row found, increment either the deferred or immediate
124343 ** foreign key constraint counter. */
124344 if( pParse->nErr==0 ){
124345 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0);
124346 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
124347 if( pWInfo ){
124348 sqlite3WhereEnd(pWInfo);
124349 }
124350 }
@@ -124480,11 +125348,11 @@
125348 sqlite3OomFault(db);
125349 return;
125350 }
125351
125352 for(i=j=0; i<pTab->nCol; i++){
125353 assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
125354 if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
125355 zColAff[j++] = pTab->aCol[i].affinity;
125356 }
125357 }
125358 do{
@@ -125014,13 +125882,15 @@
125882 Trigger *pTrigger; /* List of triggers on pTab, if required */
125883 int tmask; /* Mask of trigger times */
125884 #endif
125885
125886 db = pParse->db;
125887 assert( db->pParse==pParse );
125888 if( pParse->nErr ){
125889 goto insert_cleanup;
125890 }
125891 assert( db->mallocFailed==0 );
125892 dest.iSDParm = 0; /* Suppress a harmless compiler warning */
125893
125894 /* If the Select object is really just a simple VALUES() list with a
125895 ** single row (the common case) then keep that one row of values
125896 ** and discard the other (unused) parts of the pSelect object
@@ -125092,11 +125962,15 @@
125962 ** Then special optimizations can be applied that make the transfer
125963 ** very fast and which reduce fragmentation of indices.
125964 **
125965 ** This is the 2nd template.
125966 */
125967 if( pColumn==0
125968 && pSelect!=0
125969 && pTrigger==0
125970 && xferOptimization(pParse, pTab, pSelect, onError, iDb)
125971 ){
125972 assert( !pTrigger );
125973 assert( pList==0 );
125974 goto insert_end;
125975 }
125976 #endif /* SQLITE_OMIT_XFER_OPT */
@@ -125192,11 +126066,13 @@
126066 sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
126067 dest.iSdst = bIdListInOrder ? regData : 0;
126068 dest.nSdst = pTab->nCol;
126069 rc = sqlite3Select(pParse, pSelect, &dest);
126070 regFromSelect = dest.iSdst;
126071 assert( db->pParse==pParse );
126072 if( rc || pParse->nErr ) goto insert_cleanup;
126073 assert( db->mallocFailed==0 );
126074 sqlite3VdbeEndCoroutine(v, regYield);
126075 sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
126076 assert( pSelect->pEList );
126077 nColumn = pSelect->pEList->nExpr;
126078
@@ -126573,11 +127449,11 @@
127449 }
127450 }
127451 if( isUpdate ){
127452 /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
127453 ** table, only conflict if the new PRIMARY KEY values are actually
127454 ** different from the old. See TH3 withoutrowid04.test.
127455 **
127456 ** For a UNIQUE index, only conflict if the PRIMARY KEY values
127457 ** of the matched index row are different from the original PRIMARY
127458 ** KEY values of this row before the update. */
127459 int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127061,22 +127937,17 @@
127937 Vdbe *v; /* The VDBE we are building */
127938 int regAutoinc; /* Memory register used by AUTOINC */
127939 int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127940 int regData, regRowid; /* Registers holding data and rowid */
127941
127942 assert( pSelect!=0 );
 
 
127943 if( pParse->pWith || pSelect->pWith ){
127944 /* Do not attempt to process this query if there are an WITH clauses
127945 ** attached to it. Proceeding may generate a false "no such table: xxx"
127946 ** error if pSelect reads from a CTE named "xxx". */
127947 return 0;
127948 }
 
 
 
127949 #ifndef SQLITE_OMIT_VIRTUALTABLE
127950 if( IsVirtual(pDest) ){
127951 return 0; /* tab1 must not be a virtual table */
127952 }
127953 #endif
@@ -127937,10 +128808,20 @@
128808 int (*autovacuum_pages)(sqlite3*,
128809 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
128810 void*, void(*)(void*));
128811 /* Version 3.38.0 and later */
128812 int (*error_offset)(sqlite3*);
128813 int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
128814 int (*vtab_distinct)(sqlite3_index_info*);
128815 int (*vtab_in)(sqlite3_index_info*,int,int);
128816 int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
128817 int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
128818 /* Version 3.39.0 and later */
128819 int (*deserialize)(sqlite3*,const char*,unsigned char*,
128820 sqlite3_int64,sqlite3_int64,unsigned);
128821 unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
128822 unsigned int);
128823 };
128824
128825 /*
128826 ** This is the function signature used for all extension entry points. It
128827 ** is also defined in the file "loadext.c".
@@ -128250,10 +129131,19 @@
129131 #define sqlite3_total_changes64 sqlite3_api->total_changes64
129132 /* Version 3.37.0 and later */
129133 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
129134 /* Version 3.38.0 and later */
129135 #define sqlite3_error_offset sqlite3_api->error_offset
129136 #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
129137 #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
129138 #define sqlite3_vtab_in sqlite3_api->vtab_in
129139 #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
129140 #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
129141 #ifndef SQLITE_OMIT_DESERIALIZE
129142 #define sqlite3_deserialize sqlite3_api->deserialize
129143 #define sqlite3_serialize sqlite3_api->serialize
129144 #endif
129145 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
129146
129147 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
129148 /* This case when the file really is being compiled as a loadable
129149 ** extension */
@@ -128741,10 +129631,23 @@
129631 sqlite3_total_changes64,
129632 /* Version 3.37.0 and later */
129633 sqlite3_autovacuum_pages,
129634 /* Version 3.38.0 and later */
129635 sqlite3_error_offset,
129636 sqlite3_vtab_rhs_value,
129637 sqlite3_vtab_distinct,
129638 sqlite3_vtab_in,
129639 sqlite3_vtab_in_first,
129640 sqlite3_vtab_in_next,
129641 /* Version 3.39.0 and later */
129642 #ifndef SQLITE_OMIT_DESERIALIZE
129643 sqlite3_deserialize,
129644 sqlite3_serialize
129645 #else
129646 0,
129647 0
129648 #endif
129649 };
129650
129651 /* True if x is the directory separator character
129652 */
129653 #if SQLITE_OS_WIN
@@ -129411,11 +130314,11 @@
130314 /* iArg: */ BTREE_DATA_VERSION },
130315 #endif
130316 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
130317 {/* zName: */ "database_list",
130318 /* ePragTyp: */ PragTyp_DATABASE_LIST,
130319 /* ePragFlg: */ PragFlg_Result0,
130320 /* ColNames: */ 47, 3,
130321 /* iArg: */ 0 },
130322 #endif
130323 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
130324 {/* zName: */ "default_cache_size",
@@ -130099,19 +131002,20 @@
131002 Vdbe *v, /* The prepared statement being created */
131003 FuncDef *p, /* A particular function definition */
131004 int isBuiltin, /* True if this is a built-in function */
131005 int showInternFuncs /* True if showing internal functions */
131006 ){
131007 u32 mask =
131008 SQLITE_DETERMINISTIC |
131009 SQLITE_DIRECTONLY |
131010 SQLITE_SUBTYPE |
131011 SQLITE_INNOCUOUS |
131012 SQLITE_FUNC_INTERNAL
131013 ;
131014 if( showInternFuncs ) mask = 0xffffffff;
131015 for(; p; p=p->pNext){
131016 const char *zType;
 
 
 
 
 
 
 
131017 static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
131018
131019 assert( SQLITE_FUNC_ENCMASK==0x3 );
131020 assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
131021 assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -131042,10 +131946,14 @@
131946 sqlite3_stmt *pDummy = 0;
131947 (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
131948 (void)sqlite3_finalize(pDummy);
131949 sqlite3DbFree(db, zSql);
131950 }
131951 if( db->mallocFailed ){
131952 sqlite3ErrorMsg(db->pParse, "out of memory");
131953 db->pParse->rc = SQLITE_NOMEM_BKPT;
131954 }
131955 pHash = &db->aDb[ii].pSchema->tblHash;
131956 break;
131957 }
131958 }
131959 }
@@ -133078,12 +133986,14 @@
133986 }
133987
133988 /*
133989 ** Free all memory allocations in the pParse object
133990 */
133991 SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){
133992 sqlite3 *db = pParse->db;
133993 assert( db!=0 );
133994 assert( db->pParse==pParse );
133995 assert( pParse->nested==0 );
133996 #ifndef SQLITE_OMIT_SHARED_CACHE
133997 sqlite3DbFree(db, pParse->aTableLock);
133998 #endif
133999 while( pParse->pCleanup ){
@@ -133094,15 +134004,16 @@
134004 }
134005 sqlite3DbFree(db, pParse->aLabel);
134006 if( pParse->pConstExpr ){
134007 sqlite3ExprListDelete(db, pParse->pConstExpr);
134008 }
134009 assert( db->lookaside.bDisable >= pParse->disableLookaside );
134010 db->lookaside.bDisable -= pParse->disableLookaside;
134011 db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
134012 assert( pParse->db->pParse==pParse );
134013 db->pParse = pParse->pOuterParse;
134014 pParse->db = 0;
134015 pParse->disableLookaside = 0;
134016 }
134017
134018 /*
134019 ** Add a new cleanup operation to a Parser. The cleanup should happen when
@@ -133111,11 +134022,11 @@
134022 **
134023 ** Use this mechanism for uncommon cleanups. There is a higher setup
134024 ** cost for this mechansim (an extra malloc), so it should not be used
134025 ** for common cleanups that happen on most calls. But for less
134026 ** common cleanups, we save a single NULL-pointer comparison in
134027 ** sqlite3ParseObjectReset(), which reduces the total CPU cycle count.
134028 **
134029 ** If a memory allocation error occurs, then the cleanup happens immediately.
134030 ** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
134031 ** pParse->earlyCleanup flag is set in that case. Calling code show verify
134032 ** that test cases exist for which this happens, to guard against possible
@@ -133150,10 +134061,29 @@
134061 pParse->earlyCleanup = 1;
134062 #endif
134063 }
134064 return pPtr;
134065 }
134066
134067 /*
134068 ** Turn bulk memory into a valid Parse object and link that Parse object
134069 ** into database connection db.
134070 **
134071 ** Call sqlite3ParseObjectReset() to undo this operation.
134072 **
134073 ** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which
134074 ** is generated by Lemon.
134075 */
134076 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){
134077 memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ);
134078 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
134079 assert( db->pParse!=pParse );
134080 pParse->pOuterParse = db->pParse;
134081 db->pParse = pParse;
134082 pParse->db = db;
134083 if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory");
134084 }
134085
134086 /*
134087 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
134088 */
134089 static int sqlite3Prepare(
@@ -133167,15 +134097,19 @@
134097 ){
134098 int rc = SQLITE_OK; /* Result code */
134099 int i; /* Loop counter */
134100 Parse sParse; /* Parsing context */
134101
134102 /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */
134103 memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
134104 memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
134105 sParse.pOuterParse = db->pParse;
134106 db->pParse = &sParse;
134107 sParse.db = db;
134108 sParse.pReprepare = pReprepare;
134109 assert( ppStmt && *ppStmt==0 );
134110 if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
134111 assert( sqlite3_mutex_held(db->mutex) );
134112
134113 /* For a long-term use prepared statement avoid the use of
134114 ** lookaside memory.
134115 */
@@ -133224,11 +134158,10 @@
134158 }
134159 }
134160
134161 sqlite3VtabUnlockList(db);
134162
 
134163 if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
134164 char *zSqlCopy;
134165 int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
134166 testcase( nBytes==mxLen );
134167 testcase( nBytes==mxLen+1 );
@@ -133291,11 +134224,11 @@
134224 sqlite3DbFree(db, pT);
134225 }
134226
134227 end_prepare:
134228
134229 sqlite3ParseObjectReset(&sParse);
134230 return rc;
134231 }
134232 static int sqlite3LockAndPrepare(
134233 sqlite3 *db, /* Database handle. */
134234 const char *zSql, /* UTF-8 encoded SQL statement. */
@@ -133563,11 +134496,11 @@
134496 ** how to process the DISTINCT keyword, to simplify passing that information
134497 ** into the selectInnerLoop() routine.
134498 */
134499 typedef struct DistinctCtx DistinctCtx;
134500 struct DistinctCtx {
134501 u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */
134502 u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
134503 int tabTnct; /* Ephemeral table used for DISTINCT processing */
134504 int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
134505 };
134506
@@ -133896,29 +134829,29 @@
134829 ** sqlite3PExpr(). */
134830 if( pEq && isOuterJoin ){
134831 ExprSetProperty(pEq, EP_FromJoin);
134832 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134833 ExprSetVVAProperty(pEq, EP_NoReduce);
134834 pEq->w.iRightJoinTable = pE2->iTable;
134835 }
134836 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134837 }
134838
134839 /*
134840 ** Set the EP_FromJoin property on all terms of the given expression.
134841 ** And set the Expr.w.iRightJoinTable to iTable for every term in the
134842 ** expression.
134843 **
134844 ** The EP_FromJoin property is used on terms of an expression to tell
134845 ** the LEFT OUTER JOIN processing logic that this term is part of the
134846 ** join restriction specified in the ON or USING clause and not a part
134847 ** of the more general WHERE clause. These terms are moved over to the
134848 ** WHERE clause during join processing but we need to remember that they
134849 ** originated in the ON or USING clause.
134850 **
134851 ** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134852 ** expression depends on table w.iRightJoinTable even if that table is not
134853 ** explicitly mentioned in the expression. That information is needed
134854 ** for cases like this:
134855 **
134856 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134857 **
@@ -133932,11 +134865,11 @@
134865 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
134866 while( p ){
134867 ExprSetProperty(p, EP_FromJoin);
134868 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134869 ExprSetVVAProperty(p, EP_NoReduce);
134870 p->w.iRightJoinTable = iTable;
134871 if( p->op==TK_FUNCTION ){
134872 assert( ExprUseXList(p) );
134873 if( p->x.pList ){
134874 int i;
134875 for(i=0; i<p->x.pList->nExpr; i++){
@@ -133948,19 +134881,19 @@
134881 p = p->pRight;
134882 }
134883 }
134884
134885 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134886 ** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
134887 ** an ordinary term that omits the EP_FromJoin mark.
134888 **
134889 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134890 */
134891 static void unsetJoinExpr(Expr *p, int iTable){
134892 while( p ){
134893 if( ExprHasProperty(p, EP_FromJoin)
134894 && (iTable<0 || p->w.iRightJoinTable==iTable) ){
134895 ExprClearProperty(p, EP_FromJoin);
134896 }
134897 if( p->op==TK_COLUMN && p->iTable==iTable ){
134898 ExprClearProperty(p, EP_CanBeNull);
134899 }
@@ -134946,11 +135879,11 @@
135879 p->enc = ENC(db);
135880 p->db = db;
135881 p->nRef = 1;
135882 memset(&p[1], 0, nExtra);
135883 }else{
135884 return (KeyInfo*)sqlite3OomFault(db);
135885 }
135886 return p;
135887 }
135888
135889 /*
@@ -135117,10 +136050,13 @@
136050 }
136051 #endif
136052
136053 iTab = pSort->iECursor;
136054 if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
136055 if( eDest==SRT_Mem && p->iOffset ){
136056 sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst);
136057 }
136058 regRowid = 0;
136059 regRow = pDest->iSdst;
136060 }else{
136061 regRowid = sqlite3GetTempReg(pParse);
136062 if( eDest==SRT_EphemTab || eDest==SRT_Table ){
@@ -136162,11 +137098,11 @@
137098 ** (3) There is no ORDER BY clause
137099 **
137100 ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
137101 ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
137102 ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
137103 ** Since the limit is exactly 1, we only need to evaluate the left-most VALUES.
137104 */
137105 static int multiSelectValues(
137106 Parse *pParse, /* Parsing context */
137107 Select *p, /* The right-most of SELECTs to be coded */
137108 SelectDest *pDest /* What to do with query results */
@@ -136975,10 +137911,11 @@
137911 }else{
137912 pSplit = p;
137913 for(i=2; i<nSelect; i+=2){ pSplit = pSplit->pPrior; }
137914 }
137915 pPrior = pSplit->pPrior;
137916 assert( pPrior!=0 );
137917 pSplit->pPrior = 0;
137918 pPrior->pNext = 0;
137919 assert( p->pOrderBy == pOrderBy );
137920 assert( pOrderBy!=0 || db->mallocFailed );
137921 pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
@@ -137186,13 +138123,13 @@
138123 SubstContext *pSubst, /* Description of the substitution */
138124 Expr *pExpr /* Expr in which substitution occurs */
138125 ){
138126 if( pExpr==0 ) return 0;
138127 if( ExprHasProperty(pExpr, EP_FromJoin)
138128 && pExpr->w.iRightJoinTable==pSubst->iTable
138129 ){
138130 pExpr->w.iRightJoinTable = pSubst->iNewTable;
138131 }
138132 if( pExpr->op==TK_COLUMN
138133 && pExpr->iTable==pSubst->iTable
138134 && !ExprHasProperty(pExpr, EP_FixedCol)
138135 ){
@@ -137227,11 +138164,11 @@
138164 }
138165 if( pSubst->isLeftJoin ){
138166 ExprSetProperty(pNew, EP_CanBeNull);
138167 }
138168 if( ExprHasProperty(pExpr,EP_FromJoin) ){
138169 sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
138170 }
138171 sqlite3ExprDelete(db, pExpr);
138172 pExpr = pNew;
138173
138174 /* Ensure that the expression now has an implicit collation sequence,
@@ -137392,11 +138329,11 @@
138329 int op = pExpr->op;
138330 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
138331 renumberCursorDoMapping(pWalker, &pExpr->iTable);
138332 }
138333 if( ExprHasProperty(pExpr, EP_FromJoin) ){
138334 renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
138335 }
138336 return WRC_Continue;
138337 }
138338
138339 /*
@@ -138402,15 +139339,17 @@
139339 iCursor, isLeftJoin);
139340 pWhere = pWhere->pLeft;
139341 }
139342 if( isLeftJoin
139343 && (ExprHasProperty(pWhere,EP_FromJoin)==0
139344 || pWhere->w.iRightJoinTable!=iCursor)
139345 ){
139346 return 0; /* restriction (4) */
139347 }
139348 if( ExprHasProperty(pWhere,EP_FromJoin)
139349 && pWhere->w.iRightJoinTable!=iCursor
139350 ){
139351 return 0; /* restriction (5) */
139352 }
139353 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
139354 nChng++;
139355 pSubq->selFlags |= SF_PushDown;
@@ -139126,11 +140065,12 @@
140065 }
140066 }
140067
140068 /* Process NATURAL keywords, and ON and USING clauses of joins.
140069 */
140070 assert( db->mallocFailed==0 || pParse->nErr!=0 );
140071 if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
140072 return WRC_Abort;
140073 }
140074
140075 /* For every "*" that occurs in the column list, insert the names of
140076 ** all columns in all tables. And for every TABLE.* insert the names
@@ -139423,16 +140363,17 @@
140363 Parse *pParse, /* The parser context */
140364 Select *p, /* The SELECT statement being coded. */
140365 NameContext *pOuterNC /* Name context for container */
140366 ){
140367 assert( p!=0 || pParse->db->mallocFailed );
140368 assert( pParse->db->pParse==pParse );
140369 if( pParse->db->mallocFailed ) return;
140370 if( p->selFlags & SF_HasTypeInfo ) return;
140371 sqlite3SelectExpand(pParse, p);
140372 if( pParse->nErr ) return;
140373 sqlite3ResolveSelectNames(pParse, p, pOuterNC);
140374 if( pParse->nErr ) return;
140375 sqlite3SelectAddTypeInfo(pParse, p);
140376 }
140377
140378 /*
140379 ** Reset the aggregate accumulator.
@@ -139445,12 +140386,14 @@
140386 static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
140387 Vdbe *v = pParse->pVdbe;
140388 int i;
140389 struct AggInfo_func *pFunc;
140390 int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
140391 assert( pParse->db->pParse==pParse );
140392 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
140393 if( nReg==0 ) return;
140394 if( pParse->nErr ) return;
140395 #ifdef SQLITE_DEBUG
140396 /* Verify that all AggInfo registers are within the range specified by
140397 ** AggInfo.mnReg..AggInfo.mxReg */
140398 assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
140399 for(i=0; i<pAggInfo->nColumn; i++){
@@ -139869,14 +140812,16 @@
140812 sqlite3 *db; /* The database connection */
140813 ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
140814 u8 minMaxFlag; /* Flag for min/max queries */
140815
140816 db = pParse->db;
140817 assert( pParse==db->pParse );
140818 v = sqlite3GetVdbe(pParse);
140819 if( p==0 || pParse->nErr ){
140820 return 1;
140821 }
140822 assert( db->mallocFailed==0 );
140823 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
140824 #if SELECTTRACE_ENABLED
140825 SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
140826 if( sqlite3SelectTrace & 0x100 ){
140827 sqlite3TreeViewSelect(0, p, 0);
@@ -139907,13 +140852,14 @@
140852 }
140853 p->selFlags &= ~SF_Distinct;
140854 p->selFlags |= SF_NoopOrderBy;
140855 }
140856 sqlite3SelectPrep(pParse, p, 0);
140857 if( pParse->nErr ){
140858 goto select_end;
140859 }
140860 assert( db->mallocFailed==0 );
140861 assert( p->pEList!=0 );
140862 #if SELECTTRACE_ENABLED
140863 if( sqlite3SelectTrace & 0x104 ){
140864 SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
140865 sqlite3TreeViewSelect(0, p, 0);
@@ -139953,11 +140899,11 @@
140899 sqlite3GenerateColumnNames(pParse, p);
140900 }
140901
140902 #ifndef SQLITE_OMIT_WINDOWFUNC
140903 if( sqlite3WindowRewrite(pParse, p) ){
140904 assert( pParse->nErr );
140905 goto select_end;
140906 }
140907 #if SELECTTRACE_ENABLED
140908 if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
140909 SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
@@ -140350,10 +141296,11 @@
141296 p->selFlags |= SF_Aggregate;
141297 /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
141298 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
141299 ** original setting of the SF_Distinct flag, not the current setting */
141300 assert( sDistinct.isTnct );
141301 sDistinct.isTnct = 2;
141302
141303 #if SELECTTRACE_ENABLED
141304 if( sqlite3SelectTrace & 0x400 ){
141305 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
141306 sqlite3TreeViewSelect(0, p, 0);
@@ -140429,11 +141376,11 @@
141376
141377
141378 /* Begin the database scan. */
141379 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141380 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
141381 p->pEList, p, wctrlFlags, p->nSelectRow);
141382 if( pWInfo==0 ) goto select_end;
141383 if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
141384 p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
141385 }
141386 if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140693,11 +141640,12 @@
141640 ** in the right order to begin with.
141641 */
141642 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
141643 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141644 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
141645 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
141646 | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
141647 );
141648 if( pWInfo==0 ){
141649 sqlite3ExprListDelete(db, pDistinct);
141650 goto select_end;
141651 }
@@ -140875,11 +141823,11 @@
141823 resetAccumulator(pParse, pAggInfo);
141824 sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
141825 VdbeComment((v, "indicate accumulator empty"));
141826 sqlite3VdbeAddOp1(v, OP_Return, regReset);
141827
141828 if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
141829 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
141830 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
141831 }
141832 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
141833 else {
@@ -140991,11 +141939,11 @@
141939 assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
141940 assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
141941
141942 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141943 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
141944 pDistinct, 0, minMaxFlag|distFlag, 0);
141945 if( pWInfo==0 ){
141946 goto select_end;
141947 }
141948 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
141949 eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141048,11 +141996,11 @@
141996 /* Control jumps to here if an error is encountered above, or upon
141997 ** successful coding of the SELECT.
141998 */
141999 select_end:
142000 assert( db->mallocFailed==0 || db->mallocFailed==1 );
142001 assert( db->mallocFailed==0 || pParse->nErr!=0 );
142002 sqlite3ExprListDelete(db, pMinMaxOrderBy);
142003 #ifdef SQLITE_DEBUG
142004 if( pAggInfo && !db->mallocFailed ){
142005 for(i=0; i<pAggInfo->nColumn; i++){
142006 Expr *pExpr = pAggInfo->aCol[i].pCExpr;
@@ -141349,15 +142297,14 @@
142297 && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
142298 && pTrig->pTabSchema!=pTmpSchema
142299 ){
142300 pTrig->pNext = pList;
142301 pList = pTrig;
142302 }else if( pTrig->op==TK_RETURNING ){
142303 #ifndef SQLITE_OMIT_VIRTUALTABLE
142304 assert( pParse->db->pVtabCtx==0 );
142305 #endif
 
142306 assert( pParse->bReturning );
142307 assert( &(pParse->u1.pReturning->retTrig) == pTrig );
142308 pTrig->table = pTab->zName;
142309 pTrig->pTabSchema = pTab->pSchema;
142310 pTrig->pNext = pList;
@@ -141728,10 +142675,11 @@
142675 const char *zEnd /* End of SQL text */
142676 ){
142677 sqlite3 *db = pParse->db;
142678 TriggerStep *pTriggerStep;
142679
142680 if( pParse->nErr ) return 0;
142681 pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
142682 if( pTriggerStep ){
142683 char *z = (char*)&pTriggerStep[1];
142684 memcpy(z, pName->z, pName->n);
142685 sqlite3Dequote(z);
@@ -142200,10 +143148,11 @@
143148 Select sSelect;
143149 SrcList sFrom;
143150
143151 assert( v!=0 );
143152 assert( pParse->bReturning );
143153 assert( db->pParse==pParse );
143154 pReturning = pParse->u1.pReturning;
143155 assert( pTrigger == &(pReturning->retTrig) );
143156 memset(&sSelect, 0, sizeof(sSelect));
143157 memset(&sFrom, 0, sizeof(sFrom));
143158 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
@@ -142210,11 +143159,12 @@
143159 sSelect.pSrc = &sFrom;
143160 sFrom.nSrc = 1;
143161 sFrom.a[0].pTab = pTab;
143162 sFrom.a[0].iCursor = -1;
143163 sqlite3SelectPrep(pParse, &sSelect, 0);
143164 if( pParse->nErr==0 ){
143165 assert( db->mallocFailed==0 );
143166 sqlite3GenerateColumnNames(pParse, &sSelect);
143167 }
143168 sqlite3ExprListDelete(db, sSelect.pEList);
143169 pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
143170 if( !db->mallocFailed ){
@@ -142228,11 +143178,11 @@
143178 sNC.uNC.iBaseReg = regIn;
143179 sNC.ncFlags = NC_UBaseReg;
143180 pParse->eTriggerOp = pTrigger->op;
143181 pParse->pTriggerTab = pTab;
143182 if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK
143183 && ALWAYS(!db->mallocFailed)
143184 ){
143185 int i;
143186 int nCol = pNew->nExpr;
143187 int reg = pParse->nMem+1;
143188 pParse->nMem += nCol+2;
@@ -142392,12 +143342,12 @@
143342 TriggerPrg *pPrg; /* Value to return */
143343 Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
143344 Vdbe *v; /* Temporary VM */
143345 NameContext sNC; /* Name context for sub-vdbe */
143346 SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
 
143347 int iEndTrigger = 0; /* Label to jump to if WHEN is false */
143348 Parse sSubParse; /* Parse context for sub-vdbe */
143349
143350 assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
143351 assert( pTop->pVdbe );
143352
143353 /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
@@ -142415,23 +143365,21 @@
143365 pPrg->aColmask[0] = 0xffffffff;
143366 pPrg->aColmask[1] = 0xffffffff;
143367
143368 /* Allocate and populate a new Parse context to use for coding the
143369 ** trigger sub-program. */
143370 sqlite3ParseObjectInit(&sSubParse, db);
 
143371 memset(&sNC, 0, sizeof(sNC));
143372 sNC.pParse = &sSubParse;
143373 sSubParse.pTriggerTab = pTab;
143374 sSubParse.pToplevel = pTop;
143375 sSubParse.zAuthContext = pTrigger->zName;
143376 sSubParse.eTriggerOp = pTrigger->op;
143377 sSubParse.nQueryLoop = pParse->nQueryLoop;
143378 sSubParse.disableVtab = pParse->disableVtab;
143379
143380 v = sqlite3GetVdbe(&sSubParse);
 
143381 if( v ){
143382 VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
143383 pTrigger->zName, onErrorText(orconf),
143384 (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
143385 (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
@@ -142453,42 +143401,43 @@
143401 if( pTrigger->pWhen ){
143402 pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
143403 if( db->mallocFailed==0
143404 && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
143405 ){
143406 iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse);
143407 sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
143408 }
143409 sqlite3ExprDelete(db, pWhen);
143410 }
143411
143412 /* Code the trigger program into the sub-vdbe. */
143413 codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf);
143414
143415 /* Insert an OP_Halt at the end of the sub-program. */
143416 if( iEndTrigger ){
143417 sqlite3VdbeResolveLabel(v, iEndTrigger);
143418 }
143419 sqlite3VdbeAddOp0(v, OP_Halt);
143420 VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
143421 transferParseError(pParse, &sSubParse);
143422
143423 if( pParse->nErr==0 ){
143424 assert( db->mallocFailed==0 );
143425 pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
143426 }
143427 pProgram->nMem = sSubParse.nMem;
143428 pProgram->nCsr = sSubParse.nTab;
143429 pProgram->token = (void *)pTrigger;
143430 pPrg->aColmask[0] = sSubParse.oldmask;
143431 pPrg->aColmask[1] = sSubParse.newmask;
143432 sqlite3VdbeDelete(v);
143433 }else{
143434 transferParseError(pParse, &sSubParse);
143435 }
143436
143437 assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg );
143438 sqlite3ParseObjectReset(&sSubParse);
 
 
143439 return pPrg;
143440 }
143441
143442 /*
143443 ** Return a pointer to a TriggerPrg object containing the sub-program for
@@ -142517,10 +143466,11 @@
143466 );
143467
143468 /* If an existing TriggerPrg could not be located, create a new one. */
143469 if( !pPrg ){
143470 pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
143471 pParse->db->errByteOffset = -1;
143472 }
143473
143474 return pPrg;
143475 }
143476
@@ -142539,11 +143489,11 @@
143489 int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
143490 ){
143491 Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
143492 TriggerPrg *pPrg;
143493 pPrg = getRowTrigger(pParse, p, pTab, orconf);
143494 assert( pPrg || pParse->nErr );
143495
143496 /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
143497 ** is a pointer to the sub-vdbe containing the trigger program. */
143498 if( pPrg ){
143499 int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
@@ -143057,13 +144007,15 @@
144007 int regRowSet = 0; /* Rowset of rows to be updated */
144008 int regKey = 0; /* composite PRIMARY KEY value */
144009
144010 memset(&sContext, 0, sizeof(sContext));
144011 db = pParse->db;
144012 assert( db->pParse==pParse );
144013 if( pParse->nErr ){
144014 goto update_cleanup;
144015 }
144016 assert( db->mallocFailed==0 );
144017
144018 /* Locate the table which we want to update.
144019 */
144020 pTab = sqlite3SrcListLookup(pParse, pTabList);
144021 if( pTab==0 ) goto update_cleanup;
@@ -143431,11 +144383,11 @@
144383 ** or index, causing a single-pass approach to malfunction. */
144384 flags = WHERE_ONEPASS_DESIRED;
144385 if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
144386 flags |= WHERE_ONEPASS_MULTIROW;
144387 }
144388 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
144389 if( pWInfo==0 ) goto update_cleanup;
144390
144391 /* A one-pass strategy that might update more than one row may not
144392 ** be used if any column of the index used for the scan is being
144393 ** updated. Otherwise, if there is an index on "b", statements like
@@ -143953,11 +144905,13 @@
144905 }else{
144906 regRec = ++pParse->nMem;
144907 regRowid = ++pParse->nMem;
144908
144909 /* Start scanning the virtual table */
144910 pWInfo = sqlite3WhereBegin(
144911 pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0
144912 );
144913 if( pWInfo==0 ) return;
144914
144915 /* Populate the argument registers. */
144916 for(i=0; i<pTab->nCol; i++){
144917 assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145598,13 +146552,13 @@
146552 return SQLITE_MISUSE_BKPT;
146553 }
146554 pTab = pCtx->pTab;
146555 assert( IsVirtual(pTab) );
146556
146557 sqlite3ParseObjectInit(&sParse, db);
146558 sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
146559 sParse.disableTriggers = 1;
146560 /* We should never be able to reach this point while loading the
146561 ** schema. Nevertheless, defend against that (turn off db->init.busy)
146562 ** in case a bug arises. */
146563 assert( db->init.busy==0 );
146564 initBusy = db->init.busy;
@@ -145654,11 +146608,11 @@
146608
146609 if( sParse.pVdbe ){
146610 sqlite3VdbeFinalize(sParse.pVdbe);
146611 }
146612 sqlite3DeleteTable(db, sParse.pNewTable);
146613 sqlite3ParseObjectReset(&sParse);
146614 db->init.busy = initBusy;
146615
146616 assert( (rc&0xff)==rc );
146617 rc = sqlite3ApiExit(db, rc);
146618 sqlite3_mutex_leave(db->mutex);
@@ -146265,14 +147219,16 @@
147219 u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
147220 Index *pIndex; /* Index used, or NULL */
147221 } btree;
147222 struct { /* Information for virtual tables */
147223 int idxNum; /* Index number */
147224 u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
147225 u32 bOmitOffset : 1; /* True to let virtual table handle offset */
147226 i8 isOrdered; /* True if satisfies ORDER BY */
147227 u16 omitMask; /* Terms that may be omitted */
147228 char *idxStr; /* Index identifier string */
147229 u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
147230 } vtab;
147231 } u;
147232 u32 wsFlags; /* WHERE_* flags describing the plan */
147233 u16 nLTerm; /* Number of entries in aLTerm[] */
147234 u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146425,10 +147381,11 @@
147381 #ifdef SQLITE_ENABLE_STAT4
147382 # define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
147383 #else
147384 # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
147385 #endif
147386 #define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
147387
147388 /*
147389 ** An instance of the WhereScan object is used as an iterator for locating
147390 ** terms in the WHERE clause that are useful to the query planner.
147391 */
@@ -146528,11 +147485,10 @@
147485 ** to construct WhereLoop objects for a particular query.
147486 */
147487 struct WhereLoopBuilder {
147488 WhereInfo *pWInfo; /* Information about this WHERE */
147489 WhereClause *pWC; /* WHERE clause terms */
 
147490 WhereLoop *pNew; /* Template WhereLoop */
147491 WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
147492 #ifdef SQLITE_ENABLE_STAT4
147493 UnpackedRecord *pRec; /* Probe for stat4 (if required) */
147494 int nRecValid; /* Number of valid fields currently in pRec */
@@ -146596,10 +147552,13 @@
147552 Parse *pParse; /* Parsing and code generating context */
147553 SrcList *pTabList; /* List of tables in the join */
147554 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
147555 ExprList *pResultSet; /* Result set of the query */
147556 Expr *pWhere; /* The complete WHERE clause */
147557 #ifndef SQLITE_OMIT_VIRTUALTABLE
147558 Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */
147559 #endif
147560 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
147561 int iContinue; /* Jump here to continue with next record */
147562 int iBreak; /* Jump here to break out of the loop */
147563 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
147564 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146681,10 +147640,11 @@
147640
147641 /* whereexpr.c: */
147642 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
147643 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
147644 SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
147645 SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*);
147646 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
147647 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
147648 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
147649 SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
147650 SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146751,10 +147711,11 @@
147711 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
147712 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
147713 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
147714 #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
147715 #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
147716 #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
147717
147718 #endif /* !defined(SQLITE_WHEREINT_H) */
147719
147720 /************** End of whereInt.h ********************************************/
147721 /************** Continuing where we left off in wherecode.c ******************/
@@ -147529,10 +148490,11 @@
148490 sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
148491 VdbeCoverageIf(v, bRev==0);
148492 VdbeCoverageIf(v, bRev!=0);
148493 VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
148494 j = sqlite3VdbeAddOp0(v, OP_Goto);
148495 assert( pLevel->addrSkip==0 );
148496 pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
148497 iIdxCur, 0, regBase, nSkip);
148498 VdbeCoverageIf(v, bRev==0);
148499 VdbeCoverageIf(v, bRev!=0);
148500 sqlite3VdbeJumpHere(v, j);
@@ -147561,10 +148523,13 @@
148523 regBase = r1;
148524 }else{
148525 sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
148526 }
148527 }
148528 }
148529 for(j=nSkip; j<nEq; j++){
148530 pTerm = pLoop->aLTerm[j];
148531 if( pTerm->eOperator & WO_IN ){
148532 if( pTerm->pExpr->flags & EP_xIsSelect ){
148533 /* No affinity ever needs to be (or should be) applied to a value
148534 ** from the RHS of an "? IN (SELECT ...)" expression. The
148535 ** sqlite3FindInIndex() routine has already ensured that the
@@ -147575,11 +148540,12 @@
148540 Expr *pRight = pTerm->pExpr->pRight;
148541 if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
148542 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
148543 VdbeCoverage(v);
148544 }
148545 if( pParse->nErr==0 ){
148546 assert( pParse->db->mallocFailed==0 );
148547 if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
148548 zAff[j] = SQLITE_AFF_BLOB;
148549 }
148550 if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
148551 zAff[j] = SQLITE_AFF_BLOB;
@@ -147795,11 +148761,11 @@
148761 ** are also excluded. See codeCursorHintIsOrFunction() for details.
148762 */
148763 if( pTabItem->fg.jointype & JT_LEFT ){
148764 Expr *pExpr = pTerm->pExpr;
148765 if( !ExprHasProperty(pExpr, EP_FromJoin)
148766 || pExpr->w.iRightJoinTable!=pTabItem->iCursor
148767 ){
148768 sWalker.eCode = 0;
148769 sWalker.xExprCallback = codeCursorHintIsOrFunction;
148770 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
148771 if( sWalker.eCode ) continue;
@@ -147850,18 +148816,26 @@
148816 ** rowid stored in register iRowid.
148817 **
148818 ** Normally, this is just:
148819 **
148820 ** OP_DeferredSeek $iCur $iRowid
148821 **
148822 ** Which causes a seek on $iCur to the row with rowid $iRowid.
148823 **
148824 ** However, if the scan currently being coded is a branch of an OR-loop and
148825 ** the statement currently being coded is a SELECT, then additional information
148826 ** is added that might allow OP_Column to omit the seek and instead do its
148827 ** lookup on the index, thus avoiding an expensive seek operation. To
148828 ** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur
148829 ** and P4 is set to an array of integers containing one entry for each column
148830 ** in the table. For each table column, if the column is the i'th
148831 ** column of the index, then the corresponding array entry is set to (i+1).
148832 ** If the column does not appear in the index at all, the array entry is set
148833 ** to 0. The OP_Column opcode can check this array to see if the column it
148834 ** wants is in the index and if it is, it will substitute the index cursor
148835 ** and column number and continue with those new values, rather than seeking
148836 ** the table cursor.
148837 */
148838 static void codeDeferredSeek(
148839 WhereInfo *pWInfo, /* Where clause context */
148840 Index *pIdx, /* Index scan is using */
148841 int iCur, /* Cursor for IPK b-tree */
@@ -148122,10 +149096,11 @@
149096 ){
149097 while( ++iLevel < pWInfo->nLevel ){
149098 WhereLevel *pLevel = &pWInfo->a[iLevel];
149099 WhereLoop *pLoop = pLevel->pWLoop;
149100 if( pLevel->regFilter==0 ) continue;
149101 if( pLevel->pWLoop->nSkip ) continue;
149102 /* ,--- Because sqlite3ConstructBloomFilter() has will not have set
149103 ** vvvvv--' pLevel->regFilter if this were true. */
149104 if( NEVER(pLoop->prereq & notReady) ) continue;
149105 if( pLoop->wsFlags & WHERE_IPK ){
149106 WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148256,24 +149231,39 @@
149231 ** to access the data.
149232 */
149233 int iReg; /* P3 Value for OP_VFilter */
149234 int addrNotFound;
149235 int nConstraint = pLoop->nLTerm;
 
149236
149237 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
149238 addrNotFound = pLevel->addrBrk;
149239 for(j=0; j<nConstraint; j++){
149240 int iTarget = iReg+j+2;
149241 pTerm = pLoop->aLTerm[j];
149242 if( NEVER(pTerm==0) ) continue;
149243 if( pTerm->eOperator & WO_IN ){
149244 if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){
149245 int iTab = pParse->nTab++;
149246 int iCache = ++pParse->nMem;
149247 sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab);
149248 sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache);
149249 }else{
149250 codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
149251 addrNotFound = pLevel->addrNxt;
149252 }
149253 }else{
149254 Expr *pRight = pTerm->pExpr->pRight;
149255 codeExprOrVector(pParse, pRight, iTarget, 1);
149256 if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
149257 && pLoop->u.vtab.bOmitOffset
149258 ){
149259 assert( pTerm->eOperator==WO_AUX );
149260 assert( pWInfo->pLimit!=0 );
149261 assert( pWInfo->pLimit->iOffset>0 );
149262 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
149263 VdbeComment((v,"Zero OFFSET counter"));
149264 }
149265 }
149266 }
149267 sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
149268 sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
149269 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148286,61 +149276,71 @@
149276 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
149277 pLevel->p1 = iCur;
149278 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
149279 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
149280 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
149281
149282 for(j=0; j<nConstraint; j++){
 
 
 
 
149283 pTerm = pLoop->aLTerm[j];
 
149284 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
149285 disableTerm(pLevel, pTerm);
149286 continue;
149287 }
149288 if( (pTerm->eOperator & WO_IN)!=0
149289 && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0
149290 && !db->mallocFailed
149291 ){
149292 Expr *pCompare; /* The comparison operator */
149293 Expr *pRight; /* RHS of the comparison */
149294 VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
149295 int iIn; /* IN loop corresponding to the j-th constraint */
149296
149297 /* Reload the constraint value into reg[iReg+j+2]. The same value
149298 ** was loaded into the same register prior to the OP_VFilter, but
149299 ** the xFilter implementation might have changed the datatype or
149300 ** encoding of the value in the register, so it *must* be reloaded.
149301 */
149302 for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){
 
149303 pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
149304 if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2)
149305 || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2)
149306 ){
149307 testcase( pOp->opcode==OP_Rowid );
149308 sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149309 break;
149310 }
149311 }
149312
149313 /* Generate code that will continue to the next row if
149314 ** the IN constraint is not satisfied
149315 */
149316 pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
149317 if( !db->mallocFailed ){
149318 int iFld = pTerm->u.x.iField;
149319 Expr *pLeft = pTerm->pExpr->pLeft;
149320 assert( pLeft!=0 );
149321 if( iFld>0 ){
149322 assert( pLeft->op==TK_VECTOR );
149323 assert( ExprUseXList(pLeft) );
149324 assert( iFld<=pLeft->x.pList->nExpr );
149325 pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr;
149326 }else{
149327 pCompare->pLeft = pLeft;
149328 }
149329 pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
149330 if( pRight ){
149331 pRight->iTable = iReg+j+2;
149332 sqlite3ExprIfFalse(
149333 pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
149334 );
149335 }
149336 pCompare->pLeft = 0;
 
149337 }
149338 sqlite3ExprDelete(db, pCompare);
149339 }
149340 }
149341
149342 /* These registers need to be preserved in case there is an IN operator
149343 ** loop. So we could deallocate the registers here (and potentially
149344 ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
149345 ** simpler and safer to simply not reuse the registers.
149346 **
@@ -149028,11 +150028,11 @@
150028 regRowid = ++pParse->nMem;
150029 }
150030 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
150031
150032 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
150033 ** Then for every term xN, evaluate as the subexpression: xN AND y
150034 ** That way, terms in y that are factored into the disjunction will
150035 ** be picked up by the recursive calls to sqlite3WhereBegin() below.
150036 **
150037 ** Actually, each subexpression is converted to "xN AND w" where w is
150038 ** the "interesting" terms of z - terms that did not originate in the
@@ -149040,21 +150040,38 @@
150040 ** indices.
150041 **
150042 ** This optimization also only applies if the (x1 OR x2 OR ...) term
150043 ** is not contained in the ON clause of a LEFT JOIN.
150044 ** See ticket http://www.sqlite.org/src/info/f2369304e4
150045 **
150046 ** 2022-02-04: Do not push down slices of a row-value comparison.
150047 ** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
150048 ** the initialization of the right-hand operand of the vector comparison
150049 ** might not occur, or might occur only in an OR branch that is not
150050 ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
150051 **
150052 ** 2022-03-03: Do not push down expressions that involve subqueries.
150053 ** The subquery might get coded as a subroutine. Any table-references
150054 ** in the subquery might be resolved to index-references for the index on
150055 ** the OR branch in which the subroutine is coded. But if the subroutine
150056 ** is invoked from a different OR branch that uses a different index, such
150057 ** index-references will not work. tag-20220303a
150058 ** https://sqlite.org/forum/forumpost/36937b197273d403
150059 */
150060 if( pWC->nTerm>1 ){
150061 int iTerm;
150062 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
150063 Expr *pExpr = pWC->a[iTerm].pExpr;
150064 if( &pWC->a[iTerm] == pTerm ) continue;
150065 testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
150066 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
150067 testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
150068 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
150069 continue;
150070 }
150071 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
150072 if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */
150073 pExpr = sqlite3ExprDup(db, pExpr, 0);
150074 pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
150075 }
150076 if( pAndExpr ){
150077 /* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149091,13 +150108,13 @@
150108 pOrExpr = pAndExpr;
150109 }
150110 /* Loop through table entries that match term pOrTerm. */
150111 ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
150112 WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
150113 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
150114 WHERE_OR_SUBCLAUSE, iCovCur);
150115 assert( pSubWInfo || pParse->nErr );
150116 if( pSubWInfo ){
150117 WhereLoop *pSubLoop;
150118 int addrExplain = sqlite3WhereExplainOneScan(
150119 pParse, pOrTab, &pSubWInfo->a[0], 0
150120 );
@@ -149831,11 +150848,11 @@
150848 void *pNotUsed;
150849 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
150850 assert( pVtab!=0 );
150851 assert( pVtab->pModule!=0 );
150852 assert( !ExprHasProperty(pExpr, EP_IntValue) );
150853 pMod = (sqlite3_module *)pVtab->pModule;
150854 if( pMod->xFindFunction!=0 ){
150855 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
150856 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
150857 *peOp2 = i;
150858 *ppRight = pList->a[1].pExpr;
@@ -149875,11 +150892,11 @@
150892 ** a join, then transfer the appropriate markings over to derived.
150893 */
150894 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150895 if( pDerived ){
150896 pDerived->flags |= pBase->flags & EP_FromJoin;
150897 pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
150898 }
150899 }
150900
150901 /*
150902 ** Mark term iChild as being a child of term iParent
@@ -150520,11 +151537,11 @@
151537 abort();
151538 }
151539 #endif
151540
151541 if( ExprHasProperty(pExpr, EP_FromJoin) ){
151542 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
151543 prereqAll |= x;
151544 extraRight = x-1; /* ON clause terms may not be used with an index
151545 ** on left table of a LEFT JOIN. Ticket #3015 */
151546 if( (prereqAll>>1)>=x ){
151547 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150788,11 +151805,14 @@
151805 ** new terms for each component comparison - "a = ?" and "b = ?". The
151806 ** new terms completely replace the original vector comparison, which is
151807 ** no longer used.
151808 **
151809 ** This is only required if at least one side of the comparison operation
151810 ** is not a sub-select.
151811 **
151812 ** tag-20220128a
151813 */
151814 if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
151815 && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
151816 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
151817 && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
151818 || (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150805,11 +151825,11 @@
151825 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
151826 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
151827
151828 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
151829 transferJoinMarkings(pNew, pExpr);
151830 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
151831 exprAnalyze(pSrc, pWC, idxNew);
151832 }
151833 pTerm = &pWC->a[idxTerm];
151834 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
151835 pTerm->eOperator = 0;
@@ -150835,11 +151855,11 @@
151855 && pWC->op==TK_AND
151856 ){
151857 int i;
151858 for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
151859 int idxNew;
151860 idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
151861 pWC->a[idxNew].u.x.iField = i+1;
151862 exprAnalyze(pSrc, pWC, idxNew);
151863 markTermAsChild(pWC, idxNew, idxTerm);
151864 }
151865 }
@@ -150868,11 +151888,11 @@
151888 Expr *pNewExpr;
151889 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151890 0, sqlite3ExprDup(db, pRight, 0));
151891 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151892 ExprSetProperty(pNewExpr, EP_FromJoin);
151893 pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
151894 }
151895 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151896 testcase( idxNew==0 );
151897 pNewTerm = &pWC->a[idxNew];
151898 pNewTerm->prereqRight = prereqExpr;
@@ -150930,10 +151950,117 @@
151950 }else{
151951 sqlite3WhereSplit(pWC, pE2->pLeft, op);
151952 sqlite3WhereSplit(pWC, pE2->pRight, op);
151953 }
151954 }
151955
151956 /*
151957 ** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or
151958 ** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the
151959 ** where-clause passed as the first argument. The value for the term
151960 ** is found in register iReg.
151961 **
151962 ** In the common case where the value is a simple integer
151963 ** (example: "LIMIT 5 OFFSET 10") then the expression codes as a
151964 ** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value().
151965 ** If not, then it codes as a TK_REGISTER expression.
151966 */
151967 static void whereAddLimitExpr(
151968 WhereClause *pWC, /* Add the constraint to this WHERE clause */
151969 int iReg, /* Register that will hold value of the limit/offset */
151970 Expr *pExpr, /* Expression that defines the limit/offset */
151971 int iCsr, /* Cursor to which the constraint applies */
151972 int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */
151973 ){
151974 Parse *pParse = pWC->pWInfo->pParse;
151975 sqlite3 *db = pParse->db;
151976 Expr *pNew;
151977 int iVal = 0;
151978
151979 if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
151980 Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
151981 if( pVal==0 ) return;
151982 ExprSetProperty(pVal, EP_IntValue);
151983 pVal->u.iValue = iVal;
151984 pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
151985 }else{
151986 Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
151987 if( pVal==0 ) return;
151988 pVal->iTable = iReg;
151989 pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
151990 }
151991 if( pNew ){
151992 WhereTerm *pTerm;
151993 int idx;
151994 idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL);
151995 pTerm = &pWC->a[idx];
151996 pTerm->leftCursor = iCsr;
151997 pTerm->eOperator = WO_AUX;
151998 pTerm->eMatchOp = eMatchOp;
151999 }
152000 }
152001
152002 /*
152003 ** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the
152004 ** SELECT statement passed as the second argument. These terms are only
152005 ** added if:
152006 **
152007 ** 1. The SELECT statement has a LIMIT clause, and
152008 ** 2. The SELECT statement is not an aggregate or DISTINCT query, and
152009 ** 3. The SELECT statement has exactly one object in its from clause, and
152010 ** that object is a virtual table, and
152011 ** 4. There are no terms in the WHERE clause that will not be passed
152012 ** to the virtual table xBestIndex method.
152013 ** 5. The ORDER BY clause, if any, will be made available to the xBestIndex
152014 ** method.
152015 **
152016 ** LIMIT and OFFSET terms are ignored by most of the planner code. They
152017 ** exist only so that they may be passed to the xBestIndex method of the
152018 ** single virtual table in the FROM clause of the SELECT.
152019 */
152020 SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
152021 assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) );
152022 if( (p && p->pLimit) /* 1 */
152023 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
152024 && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
152025 ){
152026 ExprList *pOrderBy = p->pOrderBy;
152027 int iCsr = p->pSrc->a[0].iCursor;
152028 int ii;
152029
152030 /* Check condition (4). Return early if it is not met. */
152031 for(ii=0; ii<pWC->nTerm; ii++){
152032 if( pWC->a[ii].wtFlags & TERM_CODED ){
152033 /* This term is a vector operation that has been decomposed into
152034 ** other, subsequent terms. It can be ignored. See tag-20220128a */
152035 assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
152036 assert( pWC->a[ii].eOperator==0 );
152037 continue;
152038 }
152039 if( pWC->a[ii].leftCursor!=iCsr ) return;
152040 }
152041
152042 /* Check condition (5). Return early if it is not met. */
152043 if( pOrderBy ){
152044 for(ii=0; ii<pOrderBy->nExpr; ii++){
152045 Expr *pExpr = pOrderBy->a[ii].pExpr;
152046 if( pExpr->op!=TK_COLUMN ) return;
152047 if( pExpr->iTable!=iCsr ) return;
152048 if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
152049 }
152050 }
152051
152052 /* All conditions are met. Add the terms to the where-clause object. */
152053 assert( p->pLimit->op==TK_LIMIT );
152054 whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
152055 iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
152056 if( p->iOffset>0 ){
152057 whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
152058 iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
152059 }
152060 }
152061 }
152062
152063 /*
152064 ** Initialize a preallocated WhereClause structure.
152065 */
152066 SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -150966,10 +152093,11 @@
152093 for(i=pWC->nBase; i<pWC->nTerm; i++){
152094 assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
152095 }
152096 #endif
152097 while(1){
152098 assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
152099 if( a->wtFlags & TERM_DYNAMIC ){
152100 sqlite3ExprDelete(db, a->pExpr);
152101 }
152102 if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
152103 if( a->wtFlags & TERM_ORINFO ){
@@ -151123,10 +152251,11 @@
152251 if( pColRef==0 ) return;
152252 pColRef->iTable = pItem->iCursor;
152253 pColRef->iColumn = k++;
152254 assert( ExprUseYTab(pColRef) );
152255 pColRef->y.pTab = pTab;
152256 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
152257 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
152258 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
152259 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
152260 if( pItem->fg.jointype & JT_LEFT ){
152261 sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151167,12 +152296,18 @@
152296 ** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
152297 ** agree on the structure, all will be well.
152298 */
152299 typedef struct HiddenIndexInfo HiddenIndexInfo;
152300 struct HiddenIndexInfo {
152301 WhereClause *pWC; /* The Where clause being analyzed */
152302 Parse *pParse; /* The parsing context */
152303 int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
152304 u32 mIn; /* Mask of terms that are <col> IN (...) */
152305 u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */
152306 sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
152307 ** because extra space is allocated to hold up
152308 ** to nTerm such values */
152309 };
152310
152311 /* Forward declaration of methods */
152312 static int whereLoopResize(sqlite3*, WhereLoop*, int);
152313
@@ -152209,11 +153344,14 @@
153344 VdbeCoverage(v);
153345 sqlite3VdbeJumpHere(v, addrTop);
153346 pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
153347 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
153348 while( ++iLevel < pWInfo->nLevel ){
153349 const SrcItem *pTabItem;
153350 pLevel = &pWInfo->a[iLevel];
153351 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153352 if( pTabItem->fg.jointype & JT_LEFT ) continue;
153353 pLoop = pLevel->pWLoop;
153354 if( NEVER(pLoop==0) ) continue;
153355 if( pLoop->prereq & notReady ) continue;
153356 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
153357 ==WHERE_BLOOMFILTER
@@ -152232,31 +153370,33 @@
153370
153371 #ifndef SQLITE_OMIT_VIRTUALTABLE
153372 /*
153373 ** Allocate and populate an sqlite3_index_info structure. It is the
153374 ** responsibility of the caller to eventually release the structure
153375 ** by passing the pointer returned by this function to freeIndexInfo().
153376 */
153377 static sqlite3_index_info *allocateIndexInfo(
153378 WhereInfo *pWInfo, /* The WHERE clause */
153379 WhereClause *pWC, /* The WHERE clause being analyzed */
153380 Bitmask mUnusable, /* Ignore terms with these prereqs */
153381 SrcItem *pSrc, /* The FROM clause term that is the vtab */
 
153382 u16 *pmNoOmit /* Mask of terms not to omit */
153383 ){
153384 int i, j;
153385 int nTerm;
153386 Parse *pParse = pWInfo->pParse;
153387 struct sqlite3_index_constraint *pIdxCons;
153388 struct sqlite3_index_orderby *pIdxOrderBy;
153389 struct sqlite3_index_constraint_usage *pUsage;
153390 struct HiddenIndexInfo *pHidden;
153391 WhereTerm *pTerm;
153392 int nOrderBy;
153393 sqlite3_index_info *pIdxInfo;
153394 u16 mNoOmit = 0;
153395 const Table *pTab;
153396 int eDistinct = 0;
153397 ExprList *pOrderBy = pWInfo->pOrderBy;
153398
153399 assert( pSrc!=0 );
153400 pTab = pSrc->pTab;
153401 assert( pTab!=0 );
153402 assert( IsVirtual(pTab) );
@@ -152274,10 +153414,11 @@
153414 testcase( pTerm->eOperator & WO_ISNULL );
153415 testcase( pTerm->eOperator & WO_IS );
153416 testcase( pTerm->eOperator & WO_ALL );
153417 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
153418 if( pTerm->wtFlags & TERM_VNULL ) continue;
153419
153420 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153421 assert( pTerm->u.x.leftColumn>=XN_ROWID );
153422 assert( pTerm->u.x.leftColumn<pTab->nCol );
153423
153424 /* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152335,40 +153476,53 @@
153476 }
153477
153478 /* No matches cause a break out of the loop */
153479 break;
153480 }
153481 if( i==n ){
153482 nOrderBy = n;
153483 if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
153484 eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
153485 }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
153486 eDistinct = 1;
153487 }
153488 }
153489 }
153490
153491 /* Allocate the sqlite3_index_info structure
153492 */
153493 pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
153494 + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
153495 + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden)
153496 + sizeof(sqlite3_value*)*nTerm );
153497 if( pIdxInfo==0 ){
153498 sqlite3ErrorMsg(pParse, "out of memory");
153499 return 0;
153500 }
153501 pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
153502 pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm];
153503 pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
153504 pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
153505 pIdxInfo->aConstraint = pIdxCons;
153506 pIdxInfo->aOrderBy = pIdxOrderBy;
153507 pIdxInfo->aConstraintUsage = pUsage;
153508 pHidden->pWC = pWC;
153509 pHidden->pParse = pParse;
153510 pHidden->eDistinct = eDistinct;
153511 pHidden->mIn = 0;
153512 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
153513 u16 op;
153514 if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
153515 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
153516 pIdxCons[j].iTermOffset = i;
153517 op = pTerm->eOperator & WO_ALL;
153518 if( op==WO_IN ){
153519 if( (pTerm->wtFlags & TERM_SLICE)==0 ){
153520 pHidden->mIn |= SMASKBIT32(j);
153521 }
153522 op = WO_EQ;
153523 }
153524 if( op==WO_AUX ){
153525 pIdxCons[j].op = pTerm->eMatchOp;
153526 }else if( op & (WO_ISNULL|WO_IS) ){
153527 if( op==WO_ISNULL ){
153528 pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152414,10 +153568,28 @@
153568 pIdxInfo->nOrderBy = j;
153569
153570 *pmNoOmit = mNoOmit;
153571 return pIdxInfo;
153572 }
153573
153574 /*
153575 ** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
153576 ** and possibly modified by xBestIndex methods.
153577 */
153578 static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
153579 HiddenIndexInfo *pHidden;
153580 int i;
153581 assert( pIdxInfo!=0 );
153582 pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
153583 assert( pHidden->pParse!=0 );
153584 assert( pHidden->pParse->db==db );
153585 for(i=0; i<pIdxInfo->nConstraint; i++){
153586 sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */
153587 pHidden->aRhs[i] = 0;
153588 }
153589 sqlite3DbFree(db, pIdxInfo);
153590 }
153591
153592 /*
153593 ** The table object reference passed as the second argument to this function
153594 ** must represent a virtual table. This function invokes the xBestIndex()
153595 ** method of the virtual table with the sqlite3_index_info object that
@@ -152436,11 +153608,13 @@
153608 static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
153609 sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
153610 int rc;
153611
153612 whereTraceIndexInfoInputs(p);
153613 pParse->db->nSchemaLock++;
153614 rc = pVtab->pModule->xBestIndex(pVtab, p);
153615 pParse->db->nSchemaLock--;
153616 whereTraceIndexInfoOutputs(p);
153617
153618 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
153619 if( rc==SQLITE_NOMEM ){
153620 sqlite3OomFault(pParse->db);
@@ -154265,11 +155439,11 @@
155439 }
155440 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
155441 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
155442 Expr *pExpr;
155443 pExpr = pTerm->pExpr;
155444 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
155445 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
155446 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
155447 && (pTerm->wtFlags & TERM_VNULL)==0
155448 ){
155449 return 1;
@@ -154566,10 +155740,19 @@
155740 }
155741 return rc;
155742 }
155743
155744 #ifndef SQLITE_OMIT_VIRTUALTABLE
155745
155746 /*
155747 ** Return true if pTerm is a virtual table LIMIT or OFFSET term.
155748 */
155749 static int isLimitTerm(WhereTerm *pTerm){
155750 assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
155751 return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
155752 && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
155753 }
155754
155755 /*
155756 ** Argument pIdxInfo is already populated with all constraints that may
155757 ** be used by the virtual table identified by pBuilder->pNew->iTab. This
155758 ** function marks a subset of those constraints usable, invokes the
@@ -154594,13 +155777,15 @@
155777 Bitmask mPrereq, /* Mask of tables that must be used. */
155778 Bitmask mUsable, /* Mask of usable tables */
155779 u16 mExclude, /* Exclude terms using these operators */
155780 sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
155781 u16 mNoOmit, /* Do not omit these constraints */
155782 int *pbIn, /* OUT: True if plan uses an IN(...) op */
155783 int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */
155784 ){
155785 WhereClause *pWC = pBuilder->pWC;
155786 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155787 struct sqlite3_index_constraint *pIdxCons;
155788 struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
155789 int i;
155790 int mxTerm;
155791 int rc = SQLITE_OK;
@@ -154619,10 +155804,11 @@
155804 for(i=0; i<nConstraint; i++, pIdxCons++){
155805 WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
155806 pIdxCons->usable = 0;
155807 if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
155808 && (pTerm->eOperator & mExclude)==0
155809 && (pbRetryLimit || !isLimitTerm(pTerm))
155810 ){
155811 pIdxCons->usable = 1;
155812 }
155813 }
155814
@@ -154634,10 +155820,11 @@
155820 pIdxInfo->orderByConsumed = 0;
155821 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
155822 pIdxInfo->estimatedRows = 25;
155823 pIdxInfo->idxFlags = 0;
155824 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
155825 pHidden->mHandleIn = 0;
155826
155827 /* Invoke the virtual table xBestIndex() method */
155828 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
155829 if( rc ){
155830 if( rc==SQLITE_CONSTRAINT ){
@@ -154651,12 +155838,12 @@
155838 return rc;
155839 }
155840
155841 mxTerm = -1;
155842 assert( pNew->nLSlot>=nConstraint );
155843 memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
155844 memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
155845 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
155846 for(i=0; i<nConstraint; i++, pIdxCons++){
155847 int iTerm;
155848 if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
155849 WhereTerm *pTerm;
@@ -154686,21 +155873,41 @@
155873 testcase( i!=iTerm );
155874 pNew->u.vtab.omitMask |= 1<<iTerm;
155875 }else{
155876 testcase( i!=iTerm );
155877 }
155878 if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
155879 pNew->u.vtab.bOmitOffset = 1;
155880 }
155881 }
155882 if( SMASKBIT32(i) & pHidden->mHandleIn ){
155883 pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm);
155884 }else if( (pTerm->eOperator & WO_IN)!=0 ){
155885 /* A virtual table that is constrained by an IN clause may not
155886 ** consume the ORDER BY clause because (1) the order of IN terms
155887 ** is not necessarily related to the order of output terms and
155888 ** (2) Multiple outputs from a single IN value will not merge
155889 ** together. */
155890 pIdxInfo->orderByConsumed = 0;
155891 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
155892 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
155893 }
155894
155895 if( isLimitTerm(pTerm) && *pbIn ){
155896 /* If there is an IN(...) term handled as an == (separate call to
155897 ** xFilter for each value on the RHS of the IN) and a LIMIT or
155898 ** OFFSET term handled as well, the plan is unusable. Set output
155899 ** variable *pbRetryLimit to true to tell the caller to retry with
155900 ** LIMIT and OFFSET disabled. */
155901 if( pIdxInfo->needToFreeIdxStr ){
155902 sqlite3_free(pIdxInfo->idxStr);
155903 pIdxInfo->idxStr = 0;
155904 pIdxInfo->needToFreeIdxStr = 0;
155905 }
155906 *pbRetryLimit = 1;
155907 return SQLITE_OK;
155908 }
155909 }
155910 }
155911
155912 pNew->nLTerm = mxTerm+1;
155913 for(i=0; i<=mxTerm; i++){
@@ -154770,10 +155977,90 @@
155977 zRet = (pC ? pC->zName : sqlite3StrBINARY);
155978 }
155979 return zRet;
155980 }
155981
155982 /*
155983 ** Return true if constraint iCons is really an IN(...) constraint, or
155984 ** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
155985 ** or clear (if bHandle==0) the flag to handle it using an iterator.
155986 */
155987 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){
155988 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155989 u32 m = SMASKBIT32(iCons);
155990 if( m & pHidden->mIn ){
155991 if( bHandle==0 ){
155992 pHidden->mHandleIn &= ~m;
155993 }else if( bHandle>0 ){
155994 pHidden->mHandleIn |= m;
155995 }
155996 return 1;
155997 }
155998 return 0;
155999 }
156000
156001 /*
156002 ** This interface is callable from within the xBestIndex callback only.
156003 **
156004 ** If possible, set (*ppVal) to point to an object containing the value
156005 ** on the right-hand-side of constraint iCons.
156006 */
156007 SQLITE_API int sqlite3_vtab_rhs_value(
156008 sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */
156009 int iCons, /* Constraint for which RHS is wanted */
156010 sqlite3_value **ppVal /* Write value extracted here */
156011 ){
156012 HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1];
156013 sqlite3_value *pVal = 0;
156014 int rc = SQLITE_OK;
156015 if( iCons<0 || iCons>=pIdxInfo->nConstraint ){
156016 rc = SQLITE_MISUSE; /* EV: R-30545-25046 */
156017 }else{
156018 if( pH->aRhs[iCons]==0 ){
156019 WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset];
156020 rc = sqlite3ValueFromExpr(
156021 pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db),
156022 SQLITE_AFF_BLOB, &pH->aRhs[iCons]
156023 );
156024 testcase( rc!=SQLITE_OK );
156025 }
156026 pVal = pH->aRhs[iCons];
156027 }
156028 *ppVal = pVal;
156029
156030 if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */
156031 rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */
156032 }
156033
156034 return rc;
156035 }
156036
156037 /*
156038 ** Return true if ORDER BY clause may be handled as DISTINCT.
156039 */
156040 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
156041 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156042 assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 );
156043 return pHidden->eDistinct;
156044 }
156045
156046 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156047 && !defined(SQLITE_OMIT_VIRTUALTABLE)
156048 /*
156049 ** Cause the prepared statement that is associated with a call to
156050 ** xBestIndex to open write transactions on all attached schemas.
156051 ** This is used by the (built-in) sqlite_dbpage virtual table.
156052 */
156053 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
156054 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156055 Parse *pParse = pHidden->pParse;
156056 int nDb = pParse->db->nDb;
156057 int i;
156058 for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
156059 }
156060 #endif
156061
156062 /*
156063 ** Add all WhereLoop objects for a table of the join identified by
156064 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
156065 **
156066 ** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
@@ -154811,35 +156098,43 @@
156098 int nConstraint; /* Number of constraints in p */
156099 int bIn; /* True if plan uses IN(...) operator */
156100 WhereLoop *pNew;
156101 Bitmask mBest; /* Tables used by best possible plan */
156102 u16 mNoOmit;
156103 int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */
156104
156105 assert( (mPrereq & mUnusable)==0 );
156106 pWInfo = pBuilder->pWInfo;
156107 pParse = pWInfo->pParse;
156108 pWC = pBuilder->pWC;
156109 pNew = pBuilder->pNew;
156110 pSrc = &pWInfo->pTabList->a[pNew->iTab];
156111 assert( IsVirtual(pSrc->pTab) );
156112 p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
 
156113 if( p==0 ) return SQLITE_NOMEM_BKPT;
156114 pNew->rSetup = 0;
156115 pNew->wsFlags = WHERE_VIRTUALTABLE;
156116 pNew->nLTerm = 0;
156117 pNew->u.vtab.needFree = 0;
156118 nConstraint = p->nConstraint;
156119 if( whereLoopResize(pParse->db, pNew, nConstraint) ){
156120 freeIndexInfo(pParse->db, p);
156121 return SQLITE_NOMEM_BKPT;
156122 }
156123
156124 /* First call xBestIndex() with all constraints usable. */
156125 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
156126 WHERETRACE(0x40, (" VirtualOne: all usable\n"));
156127 rc = whereLoopAddVirtualOne(
156128 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
156129 );
156130 if( bRetry ){
156131 assert( rc==SQLITE_OK );
156132 rc = whereLoopAddVirtualOne(
156133 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0
156134 );
156135 }
156136
156137 /* If the call to xBestIndex() with all terms enabled produced a plan
156138 ** that does not require any source tables (IOW: a plan with mBest==0)
156139 ** and does not use an IN(...) operator, then there is no point in making
156140 ** any further calls to xBestIndex() since they will all return the same
@@ -154853,11 +156148,11 @@
156148 /* If the plan produced by the earlier call uses an IN(...) term, call
156149 ** xBestIndex again, this time with IN(...) terms disabled. */
156150 if( bIn ){
156151 WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
156152 rc = whereLoopAddVirtualOne(
156153 pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
156154 assert( bIn==0 );
156155 mBestNoIn = pNew->prereq & ~mPrereq;
156156 if( mBestNoIn==0 ){
156157 seenZero = 1;
156158 seenZeroNoIN = 1;
@@ -154880,11 +156175,11 @@
156175 if( mNext==ALLBITS ) break;
156176 if( mNext==mBest || mNext==mBestNoIn ) continue;
156177 WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
156178 (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
156179 rc = whereLoopAddVirtualOne(
156180 pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
156181 if( pNew->prereq==mPrereq ){
156182 seenZero = 1;
156183 if( bIn==0 ) seenZeroNoIN = 1;
156184 }
156185 }
@@ -154893,26 +156188,26 @@
156188 ** that requires no source tables at all (i.e. one guaranteed to be
156189 ** usable), make a call here with all source tables disabled */
156190 if( rc==SQLITE_OK && seenZero==0 ){
156191 WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
156192 rc = whereLoopAddVirtualOne(
156193 pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
156194 if( bIn==0 ) seenZeroNoIN = 1;
156195 }
156196
156197 /* If the calls to xBestIndex() have so far failed to find a plan
156198 ** that requires no source tables at all and does not use an IN(...)
156199 ** operator, make a final call to obtain one here. */
156200 if( rc==SQLITE_OK && seenZeroNoIN==0 ){
156201 WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
156202 rc = whereLoopAddVirtualOne(
156203 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
156204 }
156205 }
156206
156207 if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
156208 freeIndexInfo(pParse->db, p);
156209 WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
156210 return rc;
156211 }
156212 #endif /* SQLITE_OMIT_VIRTUALTABLE */
156213
@@ -154952,11 +156247,10 @@
156247 WhereTerm *pOrTerm;
156248 int once = 1;
156249 int i, j;
156250
156251 sSubBuild = *pBuilder;
 
156252 sSubBuild.pOrSet = &sCur;
156253
156254 WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
156255 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
156256 if( (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -155202,11 +156496,13 @@
156496 if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
156497 }else{
156498 pLoop = pLast;
156499 }
156500 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
156501 if( pLoop->u.vtab.isOrdered
156502 && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
156503 ){
156504 obSat = obDone;
156505 }
156506 break;
156507 }else if( wctrlFlags & WHERE_DISTINCTBY ){
156508 pLoop->u.btree.nDistinctCol = 0;
@@ -155469,11 +156765,11 @@
156765 **
156766 ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
156767 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
156768 */
156769 SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
156770 assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) );
156771 assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
156772 return pWInfo->sorted;
156773 }
156774
156775 #ifdef WHERETRACE_ENABLED
@@ -155870,16 +157166,16 @@
157166 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
157167 }
157168 }
157169 pWInfo->bOrderedInnerLoop = 0;
157170 if( pWInfo->pOrderBy ){
157171 pWInfo->nOBSat = pFrom->isOrdered;
157172 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
157173 if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
157174 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
157175 }
157176 }else{
 
157177 pWInfo->revMask = pFrom->revLoop;
157178 if( pWInfo->nOBSat<=0 ){
157179 pWInfo->nOBSat = 0;
157180 if( nLoop>0 ){
157181 u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156138,11 +157434,11 @@
157434 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
157435 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
157436 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
157437 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
157438 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
157439 || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
157440 ){
157441 break;
157442 }
157443 }
157444 }
@@ -156310,10 +157606,11 @@
157606 Parse *pParse, /* The parser context */
157607 SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
157608 Expr *pWhere, /* The WHERE clause */
157609 ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
157610 ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
157611 Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */
157612 u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
157613 int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
157614 ** If WHERE_USE_LIMIT, then the limit amount */
157615 ){
157616 int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156344,11 +157641,10 @@
157641 memset(&sWLB, 0, sizeof(sWLB));
157642
157643 /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
157644 testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
157645 if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
 
157646
157647 /* The number of tables in the FROM clause is limited by the number of
157648 ** bits in a Bitmask
157649 */
157650 testcase( pTabList->nSrc==BMS );
@@ -156387,10 +157683,13 @@
157683 pWInfo->nLevel = nTabList;
157684 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
157685 pWInfo->wctrlFlags = wctrlFlags;
157686 pWInfo->iLimit = iAuxArg;
157687 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
157688 #ifndef SQLITE_OMIT_VIRTUALTABLE
157689 pWInfo->pLimit = pLimit;
157690 #endif
157691 memset(&pWInfo->nOBSat, 0,
157692 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
157693 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
157694 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
157695 pMaskSet = &pWInfo->sMaskSet;
@@ -156455,10 +157754,11 @@
157754 #endif
157755 }
157756
157757 /* Analyze all of the subexpressions. */
157758 sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
157759 sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
157760 if( db->mallocFailed ) goto whereBeginError;
157761
157762 /* Special case: WHERE terms that do not refer to any tables in the join
157763 ** (constant expressions). Evaluate each such term, and jump over all the
157764 ** generated code if the result is not true.
@@ -156554,13 +157854,14 @@
157854 }
157855 }
157856 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
157857 pWInfo->revMask = ALLBITS;
157858 }
157859 if( pParse->nErr ){
157860 goto whereBeginError;
157861 }
157862 assert( db->mallocFailed==0 );
157863 #ifdef WHERETRACE_ENABLED
157864 if( sqlite3WhereTrace ){
157865 sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
157866 if( pWInfo->nOBSat>0 ){
157867 sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
@@ -156700,10 +158001,11 @@
158001 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
158002 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
158003 if( pWInfo->eOnePass==ONEPASS_OFF
158004 && pTab->nCol<BMS
158005 && (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
158006 && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0
158007 ){
158008 /* If we know that only a prefix of the record will be used,
158009 ** it is advantageous to reduce the "column count" field in
158010 ** the P4 operand of the OP_OpenRead/Write opcode. */
158011 Bitmask b = pTabItem->colUsed;
@@ -156860,10 +158162,30 @@
158162 if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
158163 sqlite3VdbePrintOp(0, pc, pOp);
158164 }
158165 #endif
158166
158167 #ifdef SQLITE_DEBUG
158168 /*
158169 ** Return true if cursor iCur is opened by instruction k of the
158170 ** bytecode. Used inside of assert() only.
158171 */
158172 static int cursorIsOpen(Vdbe *v, int iCur, int k){
158173 while( k>=0 ){
158174 VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
158175 if( pOp->p1!=iCur ) continue;
158176 if( pOp->opcode==OP_Close ) return 0;
158177 if( pOp->opcode==OP_OpenRead ) return 1;
158178 if( pOp->opcode==OP_OpenWrite ) return 1;
158179 if( pOp->opcode==OP_OpenDup ) return 1;
158180 if( pOp->opcode==OP_OpenAutoindex ) return 1;
158181 if( pOp->opcode==OP_OpenEphemeral ) return 1;
158182 }
158183 return 0;
158184 }
158185 #endif /* SQLITE_DEBUG */
158186
158187 /*
158188 ** Generate the end of the WHERE loop. See comments on
158189 ** sqlite3WhereBegin() for additional information.
158190 */
158191 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157112,10 +158434,15 @@
158434 || pOp->opcode==OP_Offset
158435 #endif
158436 ){
158437 int x = pOp->p2;
158438 assert( pIdx->pTable==pTab );
158439 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158440 if( pOp->opcode==OP_Offset ){
158441 /* Do not need to translate the column number */
158442 }else
158443 #endif
158444 if( !HasRowid(pTab) ){
158445 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
158446 x = pPk->aiColumn[x];
158447 assert( x>=0 );
158448 }else{
@@ -157125,13 +158452,26 @@
158452 x = sqlite3TableColumnToIndex(pIdx, x);
158453 if( x>=0 ){
158454 pOp->p2 = x;
158455 pOp->p1 = pLevel->iIdxCur;
158456 OpcodeRewriteTrace(db, k, pOp);
158457 }else{
158458 /* Unable to translate the table reference into an index
158459 ** reference. Verify that this is harmless - that the
158460 ** table being referenced really is open.
158461 */
158462 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158463 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158464 || cursorIsOpen(v,pOp->p1,k)
158465 || pOp->opcode==OP_Offset
158466 );
158467 #else
158468 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158469 || cursorIsOpen(v,pOp->p1,k)
158470 );
158471 #endif
158472 }
 
 
158473 }else if( pOp->opcode==OP_Rowid ){
158474 pOp->p1 = pLevel->iIdxCur;
158475 pOp->opcode = OP_IdxRowid;
158476 OpcodeRewriteTrace(db, k, pOp);
158477 }else if( pOp->opcode==OP_IfNullRow ){
@@ -157882,11 +159222,11 @@
159222 break;
159223 }
159224 }
159225 }
159226 }
159227 pWin->pWFunc = pFunc;
159228 }
159229
159230 /*
159231 ** Context object passed through sqlite3WalkExprList() to
159232 ** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158115,11 +159455,15 @@
159455 ** are invoked in the correct order as described under "SELECT REWRITING"
159456 ** at the top of this file.
159457 */
159458 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
159459 int rc = SQLITE_OK;
159460 if( p->pWin
159461 && p->pPrior==0
159462 && ALWAYS((p->selFlags & SF_WinRewrite)==0)
159463 && ALWAYS(!IN_RENAME_OBJECT)
159464 ){
159465 Vdbe *v = sqlite3GetVdbe(pParse);
159466 sqlite3 *db = pParse->db;
159467 Select *pSub = 0; /* The subquery */
159468 SrcList *pSrc = p->pSrc;
159469 Expr *pWhere = p->pWhere;
@@ -158190,12 +159534,13 @@
159534 ** window function - one for the accumulator, another for interim
159535 ** results. */
159536 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159537 ExprList *pArgs;
159538 assert( ExprUseXList(pWin->pOwner) );
159539 assert( pWin->pWFunc!=0 );
159540 pArgs = pWin->pOwner->x.pList;
159541 if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
159542 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
159543 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
159544 pWin->bExprArgs = 1;
159545 }else{
159546 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158264,16 +159609,11 @@
159609 ** there could still be references to that table embedded in the
159610 ** result-set or ORDER BY clause of the SELECT statement p. */
159611 sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
159612 }
159613
159614 assert( rc==SQLITE_OK || pParse->nErr!=0 );
 
 
 
 
 
159615 return rc;
159616 }
159617
159618 /*
159619 ** Unlink the Window object from the Select to which it is attached,
@@ -158578,11 +159918,11 @@
159918 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
159919 return;
159920 }
159921
159922 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159923 FuncDef *p = pWin->pWFunc;
159924 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
159925 /* The inline versions of min() and max() require a single ephemeral
159926 ** table and 3 registers. The registers are used as follows:
159927 **
159928 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158595,11 +159935,11 @@
159935 pList = pWin->pOwner->x.pList;
159936 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
159937 pWin->csrApp = pParse->nTab++;
159938 pWin->regApp = pParse->nMem+1;
159939 pParse->nMem += 3;
159940 if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
159941 assert( pKeyInfo->aSortFlags[0]==0 );
159942 pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
159943 }
159944 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
159945 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -158818,11 +160158,11 @@
160158 ){
160159 Parse *pParse = p->pParse;
160160 Vdbe *v = sqlite3GetVdbe(pParse);
160161 Window *pWin;
160162 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160163 FuncDef *pFunc = pWin->pWFunc;
160164 int regArg;
160165 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
160166 int i;
160167
160168 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -158932,11 +160272,11 @@
160272 Vdbe *v = sqlite3GetVdbe(pParse);
160273 Window *pWin;
160274
160275 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160276 if( pMWin->regStartRowid==0
160277 && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
160278 && (pWin->eStart!=TK_UNBOUNDED)
160279 ){
160280 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
160281 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
160282 VdbeCoverage(v);
@@ -158946,16 +160286,16 @@
160286 assert( pMWin->regStartRowid==0 );
160287 }else{
160288 int nArg = windowArgCount(pWin);
160289 if( bFin ){
160290 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
160291 sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
160292 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
160293 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
160294 }else{
160295 sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
160296 sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
160297 }
160298 }
160299 }
160300 }
160301
@@ -159080,11 +160420,11 @@
160420 }else{
160421 Parse *pParse = p->pParse;
160422 Window *pWin;
160423
160424 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160425 FuncDef *pFunc = pWin->pWFunc;
160426 assert( ExprUseXList(pWin->pOwner) );
160427 if( pFunc->zName==nth_valueName
160428 || pFunc->zName==first_valueName
160429 ){
160430 int csr = pWin->csrApp;
@@ -159152,11 +160492,11 @@
160492 Vdbe *v = sqlite3GetVdbe(pParse);
160493 int regArg;
160494 int nArg = 0;
160495 Window *pWin;
160496 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160497 FuncDef *pFunc = pWin->pWFunc;
160498 assert( pWin->regAccum );
160499 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
160500 nArg = MAX(nArg, windowArgCount(pWin));
160501 if( pMWin->regStartRowid==0 ){
160502 if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159182,11 +160522,11 @@
160522 */
160523 static int windowCacheFrame(Window *pMWin){
160524 Window *pWin;
160525 if( pMWin->regStartRowid ) return 1;
160526 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160527 FuncDef *pFunc = pWin->pWFunc;
160528 if( (pFunc->zName==nth_valueName)
160529 || (pFunc->zName==first_valueName)
160530 || (pFunc->zName==leadName)
160531 || (pFunc->zName==lagName)
160532 ){
@@ -159540,11 +160880,11 @@
160880 pNew = sqlite3DbMallocZero(db, sizeof(Window));
160881 if( pNew ){
160882 pNew->zName = sqlite3DbStrDup(db, p->zName);
160883 pNew->zBase = sqlite3DbStrDup(db, p->zBase);
160884 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
160885 pNew->pWFunc = p->pWFunc;
160886 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
160887 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
160888 pNew->eFrmType = p->eFrmType;
160889 pNew->eEnd = p->eEnd;
160890 pNew->eStart = p->eStart;
@@ -160417,14 +161757,11 @@
161757 }
161758 return pSelect;
161759 }
161760
161761
161762 /* Construct a new Expr object from a single token */
 
 
 
161763 static Expr *tokenExpr(Parse *pParse, int op, Token t){
161764 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
161765 if( p ){
161766 /* memset(p, 0, sizeof(Expr)); */
161767 p->op = (u8)op;
@@ -160440,10 +161777,11 @@
161777 p->iTable = 0;
161778 p->iColumn = 0;
161779 p->u.zToken = (char*)&p[1];
161780 memcpy(p->u.zToken, t.z, t.n);
161781 p->u.zToken[t.n] = 0;
161782 p->w.iOfst = (int)(t.z - pParse->zTail);
161783 if( sqlite3Isquote(p->u.zToken[0]) ){
161784 sqlite3DequoteExpr(p);
161785 }
161786 #if SQLITE_MAX_EXPR_DEPTH>0
161787 p->nHeight = 1;
@@ -164251,11 +165589,11 @@
165589 }
165590 break;
165591 case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
165592 {
165593 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
165594 Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
165595 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
165596 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
165597 }
165598 break;
165599 case 103: /* as ::= AS nm */
@@ -164536,29 +165874,24 @@
165874 case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
165875 {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
165876 break;
165877 case 180: /* expr ::= nm DOT nm */
165878 {
165879 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165880 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
 
 
 
 
165881 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
165882 }
165883 yymsp[-2].minor.yy528 = yylhsminor.yy528;
165884 break;
165885 case 181: /* expr ::= nm DOT nm DOT nm */
165886 {
165887 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
165888 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165889 Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
165890 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
165891 if( IN_RENAME_OBJECT ){
165892 sqlite3RenameTokenRemap(pParse, 0, temp1);
 
165893 }
165894 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
165895 }
165896 yymsp[-4].minor.yy528 = yylhsminor.yy528;
165897 break;
@@ -164567,10 +165900,11 @@
165900 {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
165901 break;
165902 case 184: /* term ::= INTEGER */
165903 {
165904 yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
165905 if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
165906 }
165907 yymsp[0].minor.yy528 = yylhsminor.yy528;
165908 break;
165909 case 185: /* expr ::= VARIABLE */
165910 {
@@ -166811,11 +168145,14 @@
168145 }else if( tokenType==TK_FILTER ){
168146 assert( n==6 );
168147 tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
168148 #endif /* SQLITE_OMIT_WINDOWFUNC */
168149 }else{
168150 Token x;
168151 x.z = zSql;
168152 x.n = n;
168153 sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
168154 break;
168155 }
168156 }
168157 pParse->sLastToken.z = zSql;
168158 pParse->sLastToken.n = n;
@@ -171422,16 +172759,20 @@
172759 ** is called immediately after installing the new callback and the return
172760 ** value from sqlite3FaultSim(0) becomes the return from
172761 ** sqlite3_test_control().
172762 */
172763 case SQLITE_TESTCTRL_FAULT_INSTALL: {
172764 /* A bug in MSVC prevents it from understanding pointers to functions
172765 ** types in the second argument to va_arg(). Work around the problem
172766 ** using a typedef.
172767 ** http://support.microsoft.com/kb/47961 <-- dead hyperlink
172768 ** Search at http://web.archive.org/ to find the 2015-03-16 archive
172769 ** of the link above to see the original text.
172770 ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
172771 */
172772 typedef int(*sqlite3FaultFuncType)(int);
172773 sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
172774 rc = sqlite3FaultSim(0);
172775 break;
172776 }
172777
172778 /*
@@ -171554,17 +172895,31 @@
172895 sqlite3 *db = va_arg(ap, sqlite3*);
172896 db->dbOptFlags = va_arg(ap, u32);
172897 break;
172898 }
172899
172900 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
172901 **
172902 ** If parameter onoff is 1, subsequent calls to localtime() fail.
172903 ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
172904 ** processing.
172905 **
172906 ** xAlt arguments are void pointers, but they really want to be:
172907 **
172908 ** int xAlt(const time_t*, struct tm*);
172909 **
172910 ** xAlt should write results in to struct tm object of its 2nd argument
172911 ** and return zero on success, or return non-zero on failure.
172912 */
172913 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
172914 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
172915 if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
172916 typedef int(*sqlite3LocaltimeType)(const void*,void*);
172917 sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
172918 }else{
172919 sqlite3GlobalConfig.xAltLocaltime = 0;
172920 }
172921 break;
172922 }
172923
172924 /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
172925 **
@@ -171762,14 +173117,16 @@
173117 ** Test access for the LogEst conversion routines.
173118 */
173119 case SQLITE_TESTCTRL_LOGEST: {
173120 double rIn = va_arg(ap, double);
173121 LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
173122 int *pI1 = va_arg(ap,int*);
173123 u64 *pU64 = va_arg(ap,u64*);
173124 int *pI2 = va_arg(ap,int*);
173125 *pI1 = rLogEst;
173126 *pU64 = sqlite3LogEstToInt(rLogEst);
173127 *pI2 = sqlite3LogEst(*pU64);
173128 break;
173129 }
173130
173131
173132 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193696,11 +195053,11 @@
195053 u32 iRoot;
195054 JsonNode *pTarget;
195055 if( pPatch->eType!=JSON_OBJECT ){
195056 return pPatch;
195057 }
195058 assert( iTarget<pParse->nNode );
195059 pTarget = &pParse->aNode[iTarget];
195060 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
195061 if( pTarget->eType!=JSON_OBJECT ){
195062 jsonRemoveAllNulls(pPatch);
195063 return pPatch;
@@ -193955,12 +195312,12 @@
195312 sqlite3_result_error_nomem(ctx);
195313 goto jsonSetDone;
195314 }else if( x.nErr ){
195315 goto jsonSetDone;
195316 }else if( pNode && (bApnd || bIsSet) ){
195317 testcase( pNode->eU!=0 && pNode->eU!=1 );
195318 assert( pNode->eU!=3 && pNode->eU!=5 );
195319 VVA( pNode->eU = 4 );
195320 pNode->jnFlags |= (u8)JNODE_REPLACE;
195321 pNode->u.iReplace = i + 1;
195322 }
195323 }
@@ -194737,11 +196094,11 @@
196094 sqlite3_module *pModule;
196095 } aMod[] = {
196096 { "json_each", &jsonEachModule },
196097 { "json_tree", &jsonTreeModule },
196098 };
196099 unsigned int i;
196100 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
196101 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
196102 }
196103 return rc;
196104 }
@@ -208991,10 +210348,11 @@
210348 && pIdxInfo->aOrderBy[0].iColumn<=0
210349 && pIdxInfo->aOrderBy[0].desc==0
210350 ){
210351 pIdxInfo->orderByConsumed = 1;
210352 }
210353 sqlite3VtabWriteAll(pIdxInfo);
210354 return SQLITE_OK;
210355 }
210356
210357 /*
210358 ** Open a new dbpagevfs cursor.
@@ -209168,11 +210526,11 @@
210526 if( iDb<0 ){
210527 zErr = "no such schema";
210528 goto update_fail;
210529 }
210530 pBt = pTab->db->aDb[iDb].pBt;
210531 if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
210532 zErr = "bad page number";
210533 goto update_fail;
210534 }
210535 szPage = sqlite3BtreeGetPageSize(pBt);
210536 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231345,11 +232703,11 @@
232703 int rc;
232704
232705 rc = sqlite3_step(pSorter->pStmt);
232706 if( rc==SQLITE_DONE ){
232707 rc = SQLITE_OK;
232708 CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
232709 }else if( rc==SQLITE_ROW ){
232710 const u8 *a;
232711 const u8 *aBlob;
232712 int nBlob;
232713 int i;
@@ -233334,11 +234692,11 @@
234692 int nArg, /* Number of args */
234693 sqlite3_value **apUnused /* Function arguments */
234694 ){
234695 assert( nArg==0 );
234696 UNUSED_PARAM2(nArg, apUnused);
234697 sqlite3_result_text(pCtx, "fts5: 2022-03-14 20:31:57 387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e", -1, SQLITE_TRANSIENT);
234698 }
234699
234700 /*
234701 ** Return true if zName is the extension on one of the shadow tables used
234702 ** by this module.
234703
+308 -27
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144144
**
145145
** See also: [sqlite3_libversion()],
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149
-#define SQLITE_VERSION "3.38.0"
150
-#define SQLITE_VERSION_NUMBER 3038000
151
-#define SQLITE_SOURCE_ID "2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec"
149
+#define SQLITE_VERSION "3.39.0"
150
+#define SQLITE_VERSION_NUMBER 3039000
151
+#define SQLITE_SOURCE_ID "2022-03-23 10:04:52 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -564,11 +564,11 @@
564564
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565565
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566566
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567567
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568568
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569
-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
569
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
570570
571571
/*
572572
** CAPI3REF: Flags For File Open Operations
573573
**
574574
** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
38483848
**
38493849
** ^If the most recent error references a specific token in the input
38503850
** SQL, the sqlite3_error_offset() interface returns the byte offset
38513851
** of the start of that token. ^The byte offset returned by
38523852
** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853
-** ^If the most error does not reference a specific token in the input
3853
+** ^If the most recent error does not reference a specific token in the input
38543854
** SQL, then the sqlite3_error_offset() function returns -1.
38553855
**
38563856
** When the serialized [threading mode] is in use, it might be the
38573857
** case that a second error occurs on a separate thread in between
38583858
** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
42824282
** ^For example, an UPDATE statement might have a WHERE clause that
42834283
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
42844284
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
42854285
** read-only no-op if the table already exists, but
42864286
** sqlite3_stmt_readonly() still returns false for such a statement.
4287
+**
4288
+** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4289
+** statement, then sqlite3_stmt_readonly(X) returns the same value as
4290
+** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
42874291
*/
42884292
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
42894293
42904294
/*
42914295
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
43504354
** still make the distinction between protected and unprotected
43514355
** sqlite3_value objects even when not strictly required.
43524356
**
43534357
** ^The sqlite3_value objects that are passed as parameters into the
43544358
** implementation of [application-defined SQL functions] are protected.
4359
+** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4360
+** are protected.
43554361
** ^The sqlite3_value object returned by
43564362
** [sqlite3_column_value()] is unprotected.
43574363
** Unprotected sqlite3_value objects may only be used as arguments
43584364
** to [sqlite3_result_value()], [sqlite3_bind_value()], and
43594365
** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
49704976
** bytes in the string, not the number of characters.
49714977
**
49724978
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
49734979
** even empty strings, are always zero-terminated. ^The return
49744980
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4981
+**
4982
+** ^Strings returned by sqlite3_column_text16() always have the endianness
4983
+** which is native to the platform, regardless of the text encoding set
4984
+** for the database.
49754985
**
49764986
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
49774987
** [unprotected sqlite3_value] object. In a multithreaded environment,
49784988
** an unprotected sqlite3_value object may only be used safely with
49794989
** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
49844994
** Hence, the sqlite3_column_value() interface
49854995
** is normally only useful within the implementation of
49864996
** [application-defined SQL functions] or [virtual tables], not within
49874997
** top-level application code.
49884998
**
4989
-** The these routines may attempt to convert the datatype of the result.
4999
+** These routines may attempt to convert the datatype of the result.
49905000
** ^For example, if the internal representation is FLOAT and a text result
49915001
** is requested, [sqlite3_snprintf()] is used internally to perform the
49925002
** conversion automatically. ^(The following table details the conversions
49935003
** that are applied:
49945004
**
@@ -5009,11 +5019,11 @@
50095019
** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
50105020
** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
50115021
** <tr><td> TEXT <td> BLOB <td> No change
50125022
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
50135023
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5014
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5024
+** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
50155025
** </table>
50165026
** </blockquote>)^
50175027
**
50185028
** Note that when type conversions occur, pointers returned by prior
50195029
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
55815591
**
55825592
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
55835593
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
55845594
** is a [protected sqlite3_value] object even if the input is not.
55855595
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5586
-** memory allocation fails.
5596
+** memory allocation fails. ^If V is a [pointer value], then the result
5597
+** of sqlite3_value_dup(V) is a NULL value.
55875598
**
55885599
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
55895600
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
55905601
** then sqlite3_value_free(V) is a harmless no-op.
55915602
*/
@@ -7129,28 +7140,60 @@
71297140
/*
71307141
** CAPI3REF: Virtual Table Constraint Operator Codes
71317142
**
71327143
** These macros define the allowed values for the
71337144
** [sqlite3_index_info].aConstraint[].op field. Each value represents
7134
-** an operator that is part of a constraint term in the wHERE clause of
7145
+** an operator that is part of a constraint term in the WHERE clause of
71357146
** a query that uses a [virtual table].
7147
+**
7148
+** ^The left-hand operand of the operator is given by the corresponding
7149
+** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7150
+** operand is the rowid.
7151
+** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7152
+** operators have no left-hand operand, and so for those operators the
7153
+** corresponding aConstraint[].iColumn is meaningless and should not be
7154
+** used.
7155
+**
7156
+** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7157
+** value 255 are reserved to represent functions that are overloaded
7158
+** by the [xFindFunction|xFindFunction method] of the virtual table
7159
+** implementation.
7160
+**
7161
+** The right-hand operands for each constraint might be accessible using
7162
+** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7163
+** operand is only available if it appears as a single constant literal
7164
+** in the input SQL. If the right-hand operand is another column or an
7165
+** expression (even a constant expression) or a parameter, then the
7166
+** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7167
+** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7168
+** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7169
+** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7170
+** always return SQLITE_NOTFOUND.
7171
+**
7172
+** The collating sequence to be used for comparison can be found using
7173
+** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7174
+** tables, the collating sequence of constraints does not matter (for example
7175
+** because the constraints are numeric) and so the sqlite3_vtab_collation()
7176
+** interface is no commonly needed.
71367177
*/
7137
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
7138
-#define SQLITE_INDEX_CONSTRAINT_GT 4
7139
-#define SQLITE_INDEX_CONSTRAINT_LE 8
7140
-#define SQLITE_INDEX_CONSTRAINT_LT 16
7141
-#define SQLITE_INDEX_CONSTRAINT_GE 32
7142
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7143
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7144
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7145
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7146
-#define SQLITE_INDEX_CONSTRAINT_NE 68
7147
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7148
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7149
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7150
-#define SQLITE_INDEX_CONSTRAINT_IS 72
7151
-#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7178
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
7179
+#define SQLITE_INDEX_CONSTRAINT_GT 4
7180
+#define SQLITE_INDEX_CONSTRAINT_LE 8
7181
+#define SQLITE_INDEX_CONSTRAINT_LT 16
7182
+#define SQLITE_INDEX_CONSTRAINT_GE 32
7183
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7184
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7185
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7186
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7187
+#define SQLITE_INDEX_CONSTRAINT_NE 68
7188
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7189
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7190
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7191
+#define SQLITE_INDEX_CONSTRAINT_IS 72
7192
+#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7193
+#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7194
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
71527195
71537196
/*
71547197
** CAPI3REF: Register A Virtual Table Implementation
71557198
** METHOD: sqlite3
71567199
**
@@ -7175,11 +7218,11 @@
71757218
** ^The sqlite3_create_module()
71767219
** interface is equivalent to sqlite3_create_module_v2() with a NULL
71777220
** destructor.
71787221
**
71797222
** ^If the third parameter (the pointer to the sqlite3_module object) is
7180
-** NULL then no new module is create and any existing modules with the
7223
+** NULL then no new module is created and any existing modules with the
71817224
** same name are dropped.
71827225
**
71837226
** See also: [sqlite3_drop_modules()]
71847227
*/
71857228
SQLITE_API int sqlite3_create_module(
@@ -9469,25 +9512,26 @@
94699512
*/
94709513
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
94719514
94729515
/*
94739516
** CAPI3REF: Determine The Collation For a Virtual Table Constraint
9517
+** METHOD: sqlite3_index_info
94749518
**
94759519
** This function may only be called from within a call to the [xBestIndex]
94769520
** method of a [virtual table]. This function returns a pointer to a string
94779521
** that is the name of the appropriate collation sequence to use for text
94789522
** comparisons on the constraint identified by its arguments.
94799523
**
9480
-** The first argument must be the pointer to the sqlite3_index_info object
9524
+** The first argument must be the pointer to the [sqlite3_index_info] object
94819525
** that is the first parameter to the xBestIndex() method. The second argument
94829526
** must be an index into the aConstraint[] array belonging to the
94839527
** sqlite3_index_info structure passed to xBestIndex.
94849528
**
94859529
** Important:
94869530
** The first parameter must be the same pointer that is passed into the
94879531
** xBestMethod() method. The first parameter may not be a pointer to a
9488
-** different sqlite3_index_info object, even an exact copy.
9532
+** different [sqlite3_index_info] object, even an exact copy.
94899533
**
94909534
** The return value is computed as follows:
94919535
**
94929536
** <ol>
94939537
** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9501,10 +9545,247 @@
95019545
** <li><p> Otherwise, "BINARY" is returned.
95029546
** </ol>
95039547
*/
95049548
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
95059549
9550
+/*
9551
+** CAPI3REF: Determine if a virtual table query is DISTINCT
9552
+** METHOD: sqlite3_index_info
9553
+**
9554
+** This API may only be used from within an [xBestIndex|xBestIndex method]
9555
+** of a [virtual table] implementation. The result of calling this
9556
+** interface from outside of xBestIndex() is undefined and probably harmful.
9557
+**
9558
+** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9559
+** 3. The integer returned by sqlite3_vtab_distinct()
9560
+** gives the virtual table additional information about how the query
9561
+** planner wants the output to be ordered. As long as the virtual table
9562
+** can meet the ordering requirements of the query planner, it may set
9563
+** the "orderByConsumed" flag.
9564
+**
9565
+** <ol><li value="0"><p>
9566
+** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9567
+** that the query planner needs the virtual table to return all rows in the
9568
+** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9569
+** [sqlite3_index_info] object. This is the default expectation. If the
9570
+** virtual table outputs all rows in sorted order, then it is always safe for
9571
+** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9572
+** the return value from sqlite3_vtab_distinct().
9573
+** <li value="1"><p>
9574
+** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9575
+** that the query planner does not need the rows to be returned in sorted order
9576
+** as long as all rows with the same values in all columns identified by the
9577
+** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
9578
+** is doing a GROUP BY.
9579
+** <li value="2"><p>
9580
+** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9581
+** that the query planner does not need the rows returned in any particular
9582
+** order, as long as rows with the same values in all "aOrderBy" columns
9583
+** are adjacent.)^ ^(Furthermore, only a single row for each particular
9584
+** combination of values in the columns identified by the "aOrderBy" field
9585
+** needs to be returned.)^ ^It is always ok for two or more rows with the same
9586
+** values in all "aOrderBy" columns to be returned, as long as all such rows
9587
+** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9588
+** that have the same value for all columns identified by "aOrderBy".
9589
+** ^However omitting the extra rows is optional.
9590
+** This mode is used for a DISTINCT query.
9591
+** <li value="3"><p>
9592
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9593
+** that the query planner needs only distinct rows but it does need the
9594
+** rows to be sorted.)^ ^The virtual table implementation is free to omit
9595
+** rows that are identical in all aOrderBy columns, if it wants to, but
9596
+** it is not required to omit any rows. This mode is used for queries
9597
+** that have both DISTINCT and ORDER BY clauses.
9598
+** </ol>
9599
+**
9600
+** ^For the purposes of comparing virtual table output values to see if the
9601
+** values are same value for sorting purposes, two NULL values are considered
9602
+** to be the same. In other words, the comparison operator is "IS"
9603
+** (or "IS NOT DISTINCT FROM") and not "==".
9604
+**
9605
+** If a virtual table implementation is unable to meet the requirements
9606
+** specified above, then it must not set the "orderByConsumed" flag in the
9607
+** [sqlite3_index_info] object or an incorrect answer may result.
9608
+**
9609
+** ^A virtual table implementation is always free to return rows in any order
9610
+** it wants, as long as the "orderByConsumed" flag is not set. ^When the
9611
+** the "orderByConsumed" flag is unset, the query planner will add extra
9612
+** [bytecode] to ensure that the final results returned by the SQL query are
9613
+** ordered correctly. The use of the "orderByConsumed" flag and the
9614
+** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful
9615
+** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed"
9616
+** flag might help queries against a virtual table to run faster. Being
9617
+** overly aggressive and setting the "orderByConsumed" flag when it is not
9618
+** valid to do so, on the other hand, might cause SQLite to return incorrect
9619
+** results.
9620
+*/
9621
+SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9622
+
9623
+/*
9624
+** CAPI3REF: Identify and handle IN constraints in xBestIndex
9625
+**
9626
+** This interface may only be used from within an
9627
+** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9628
+** The result of invoking this interface from any other context is
9629
+** undefined and probably harmful.
9630
+**
9631
+** ^(A constraint on a virtual table of the form
9632
+** "[IN operator|column IN (...)]" is
9633
+** communicated to the xBestIndex method as a
9634
+** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9635
+** this constraint, it must set the corresponding
9636
+** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9637
+** the usual mode of handling IN operators, SQLite generates [bytecode]
9638
+** that invokes the [xFilter|xFilter() method] once for each value
9639
+** on the right-hand side of the IN operator.)^ Thus the virtual table
9640
+** only sees a single value from the right-hand side of the IN operator
9641
+** at a time.
9642
+**
9643
+** In some cases, however, it would be advantageous for the virtual
9644
+** table to see all values on the right-hand of the IN operator all at
9645
+** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9646
+**
9647
+** <ol>
9648
+** <li><p>
9649
+** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9650
+** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9651
+** is an [IN operator] that can be processed all at once. ^In other words,
9652
+** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9653
+** by which the virtual table can ask SQLite if all-at-once processing
9654
+** of the IN operator is even possible.
9655
+**
9656
+** <li><p>
9657
+** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9658
+** to SQLite that the virtual table does or does not want to process
9659
+** the IN operator all-at-once, respectively. ^Thus when the third
9660
+** parameter (F) is non-negative, this interface is the mechanism by
9661
+** which the virtual table tells SQLite how it wants to process the
9662
+** IN operator.
9663
+** </ol>
9664
+**
9665
+** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9666
+** within the same xBestIndex method call. ^For any given P,N pair,
9667
+** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9668
+** within the same xBestIndex call. ^If the interface returns true
9669
+** (non-zero), that means that the constraint is an IN operator
9670
+** that can be processed all-at-once. ^If the constraint is not an IN
9671
+** operator or cannot be processed all-at-once, then the interface returns
9672
+** false.
9673
+**
9674
+** ^(All-at-once processing of the IN operator is selected if both of the
9675
+** following conditions are met:
9676
+**
9677
+** <ol>
9678
+** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9679
+** integer. This is how the virtual table tells SQLite that it wants to
9680
+** use the N-th constraint.
9681
+**
9682
+** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9683
+** non-negative had F>=1.
9684
+** </ol>)^
9685
+**
9686
+** ^If either or both of the conditions above are false, then SQLite uses
9687
+** the traditional one-at-a-time processing strategy for the IN constraint.
9688
+** ^If both conditions are true, then the argvIndex-th parameter to the
9689
+** xFilter method will be an [sqlite3_value] that appears to be NULL,
9690
+** but which can be passed to [sqlite3_vtab_in_first()] and
9691
+** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9692
+** of the IN constraint.
9693
+*/
9694
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
9695
+
9696
+/*
9697
+** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
9698
+**
9699
+** These interfaces are only useful from within the
9700
+** [xFilter|xFilter() method] of a [virtual table] implementation.
9701
+** The result of invoking these interfaces from any other context
9702
+** is undefined and probably harmful.
9703
+**
9704
+** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
9705
+** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
9706
+** xFilter method which invokes these routines, and specifically
9707
+** a parameter that was previously selected for all-at-once IN constraint
9708
+** processing use the [sqlite3_vtab_in()] interface in the
9709
+** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
9710
+** an xFilter argument that was selected for all-at-once IN constraint
9711
+** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
9712
+** exhibit some other undefined or harmful behavior.
9713
+**
9714
+** ^(Use these routines to access all values on the right-hand side
9715
+** of the IN constraint using code like the following:
9716
+**
9717
+** <blockquote><pre>
9718
+** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
9719
+** &nbsp; rc==SQLITE_OK && pVal
9720
+** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
9721
+** &nbsp; ){
9722
+** &nbsp; // do something with pVal
9723
+** &nbsp; }
9724
+** &nbsp; if( rc!=SQLITE_OK ){
9725
+** &nbsp; // an error has occurred
9726
+** &nbsp; }
9727
+** </pre></blockquote>)^
9728
+**
9729
+** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
9730
+** routines return SQLITE_OK and set *P to point to the first or next value
9731
+** on the RHS of the IN constraint. ^If there are no more values on the
9732
+** right hand side of the IN constraint, then *P is set to NULL and these
9733
+** routines return [SQLITE_DONE]. ^The return value might be
9734
+** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
9735
+**
9736
+** The *ppOut values returned by these routines are only valid until the
9737
+** next call to either of these routines or until the end of the xFilter
9738
+** method from which these routines were called. If the virtual table
9739
+** implementation needs to retain the *ppOut values for longer, it must make
9740
+** copies. The *ppOut values are [protected sqlite3_value|protected].
9741
+*/
9742
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
9743
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
9744
+
9745
+/*
9746
+** CAPI3REF: Constraint values in xBestIndex()
9747
+** METHOD: sqlite3_index_info
9748
+**
9749
+** This API may only be used from within the [xBestIndex|xBestIndex method]
9750
+** of a [virtual table] implementation. The result of calling this interface
9751
+** from outside of an xBestIndex method are undefined and probably harmful.
9752
+**
9753
+** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
9754
+** the [xBestIndex] method of a [virtual table] implementation, with P being
9755
+** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
9756
+** J being a 0-based index into P->aConstraint[], then this routine
9757
+** attempts to set *V to the value of the right-hand operand of
9758
+** that constraint if the right-hand operand is known. ^If the
9759
+** right-hand operand is not known, then *V is set to a NULL pointer.
9760
+** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9761
+** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
9762
+** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
9763
+** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
9764
+** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
9765
+** something goes wrong.
9766
+**
9767
+** The sqlite3_vtab_rhs_value() interface is usually only successful if
9768
+** the right-hand operand of a constraint is a literal value in the original
9769
+** SQL statement. If the right-hand operand is an expression or a reference
9770
+** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
9771
+** will probably return [SQLITE_NOTFOUND].
9772
+**
9773
+** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
9774
+** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
9775
+** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
9776
+**
9777
+** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
9778
+** and remains valid for the duration of the xBestIndex method call.
9779
+** ^When xBestIndex returns, the sqlite3_value object returned by
9780
+** sqlite3_vtab_rhs_value() is automatically deallocated.
9781
+**
9782
+** The "_rhs_" in the name of this routine is an abbreviation for
9783
+** "Right-Hand Side".
9784
+*/
9785
+SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
9786
+
95069787
/*
95079788
** CAPI3REF: Conflict resolution modes
95089789
** KEYWORDS: {conflict resolution mode}
95099790
**
95109791
** These constants are returned by [sqlite3_vtab_on_conflict()] to
95119792
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.38.0"
150 #define SQLITE_VERSION_NUMBER 3038000
151 #define SQLITE_SOURCE_ID "2022-01-12 00:28:12 adebb9d7478d092f16fb0ef7d5246ce152b166479d6f949110b5878b89ea2cec"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -564,11 +564,11 @@
564 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
570
571 /*
572 ** CAPI3REF: Flags For File Open Operations
573 **
574 ** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
3848 **
3849 ** ^If the most recent error references a specific token in the input
3850 ** SQL, the sqlite3_error_offset() interface returns the byte offset
3851 ** of the start of that token. ^The byte offset returned by
3852 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853 ** ^If the most error does not reference a specific token in the input
3854 ** SQL, then the sqlite3_error_offset() function returns -1.
3855 **
3856 ** When the serialized [threading mode] is in use, it might be the
3857 ** case that a second error occurs on a separate thread in between
3858 ** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
4282 ** ^For example, an UPDATE statement might have a WHERE clause that
4283 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4284 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4285 ** read-only no-op if the table already exists, but
4286 ** sqlite3_stmt_readonly() still returns false for such a statement.
 
 
 
 
4287 */
4288 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4289
4290 /*
4291 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
4350 ** still make the distinction between protected and unprotected
4351 ** sqlite3_value objects even when not strictly required.
4352 **
4353 ** ^The sqlite3_value objects that are passed as parameters into the
4354 ** implementation of [application-defined SQL functions] are protected.
 
 
4355 ** ^The sqlite3_value object returned by
4356 ** [sqlite3_column_value()] is unprotected.
4357 ** Unprotected sqlite3_value objects may only be used as arguments
4358 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4359 ** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
4970 ** bytes in the string, not the number of characters.
4971 **
4972 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4973 ** even empty strings, are always zero-terminated. ^The return
4974 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
 
 
 
 
4975 **
4976 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4977 ** [unprotected sqlite3_value] object. In a multithreaded environment,
4978 ** an unprotected sqlite3_value object may only be used safely with
4979 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
4984 ** Hence, the sqlite3_column_value() interface
4985 ** is normally only useful within the implementation of
4986 ** [application-defined SQL functions] or [virtual tables], not within
4987 ** top-level application code.
4988 **
4989 ** The these routines may attempt to convert the datatype of the result.
4990 ** ^For example, if the internal representation is FLOAT and a text result
4991 ** is requested, [sqlite3_snprintf()] is used internally to perform the
4992 ** conversion automatically. ^(The following table details the conversions
4993 ** that are applied:
4994 **
@@ -5009,11 +5019,11 @@
5009 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5010 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5011 ** <tr><td> TEXT <td> BLOB <td> No change
5012 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5013 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5014 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5015 ** </table>
5016 ** </blockquote>)^
5017 **
5018 ** Note that when type conversions occur, pointers returned by prior
5019 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
5581 **
5582 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5583 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5584 ** is a [protected sqlite3_value] object even if the input is not.
5585 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5586 ** memory allocation fails.
 
5587 **
5588 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5589 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5590 ** then sqlite3_value_free(V) is a harmless no-op.
5591 */
@@ -7129,28 +7140,60 @@
7129 /*
7130 ** CAPI3REF: Virtual Table Constraint Operator Codes
7131 **
7132 ** These macros define the allowed values for the
7133 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7134 ** an operator that is part of a constraint term in the wHERE clause of
7135 ** a query that uses a [virtual table].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7136 */
7137 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7138 #define SQLITE_INDEX_CONSTRAINT_GT 4
7139 #define SQLITE_INDEX_CONSTRAINT_LE 8
7140 #define SQLITE_INDEX_CONSTRAINT_LT 16
7141 #define SQLITE_INDEX_CONSTRAINT_GE 32
7142 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7143 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7144 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7145 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7146 #define SQLITE_INDEX_CONSTRAINT_NE 68
7147 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7148 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7149 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7150 #define SQLITE_INDEX_CONSTRAINT_IS 72
7151 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
 
 
7152
7153 /*
7154 ** CAPI3REF: Register A Virtual Table Implementation
7155 ** METHOD: sqlite3
7156 **
@@ -7175,11 +7218,11 @@
7175 ** ^The sqlite3_create_module()
7176 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7177 ** destructor.
7178 **
7179 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7180 ** NULL then no new module is create and any existing modules with the
7181 ** same name are dropped.
7182 **
7183 ** See also: [sqlite3_drop_modules()]
7184 */
7185 SQLITE_API int sqlite3_create_module(
@@ -9469,25 +9512,26 @@
9469 */
9470 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
9471
9472 /*
9473 ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
 
9474 **
9475 ** This function may only be called from within a call to the [xBestIndex]
9476 ** method of a [virtual table]. This function returns a pointer to a string
9477 ** that is the name of the appropriate collation sequence to use for text
9478 ** comparisons on the constraint identified by its arguments.
9479 **
9480 ** The first argument must be the pointer to the sqlite3_index_info object
9481 ** that is the first parameter to the xBestIndex() method. The second argument
9482 ** must be an index into the aConstraint[] array belonging to the
9483 ** sqlite3_index_info structure passed to xBestIndex.
9484 **
9485 ** Important:
9486 ** The first parameter must be the same pointer that is passed into the
9487 ** xBestMethod() method. The first parameter may not be a pointer to a
9488 ** different sqlite3_index_info object, even an exact copy.
9489 **
9490 ** The return value is computed as follows:
9491 **
9492 ** <ol>
9493 ** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9501,10 +9545,247 @@
9501 ** <li><p> Otherwise, "BINARY" is returned.
9502 ** </ol>
9503 */
9504 SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
9505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9506 /*
9507 ** CAPI3REF: Conflict resolution modes
9508 ** KEYWORDS: {conflict resolution mode}
9509 **
9510 ** These constants are returned by [sqlite3_vtab_on_conflict()] to
9511
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.39.0"
150 #define SQLITE_VERSION_NUMBER 3039000
151 #define SQLITE_SOURCE_ID "2022-03-23 10:04:52 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -564,11 +564,11 @@
564 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
570
571 /*
572 ** CAPI3REF: Flags For File Open Operations
573 **
574 ** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
3848 **
3849 ** ^If the most recent error references a specific token in the input
3850 ** SQL, the sqlite3_error_offset() interface returns the byte offset
3851 ** of the start of that token. ^The byte offset returned by
3852 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853 ** ^If the most recent error does not reference a specific token in the input
3854 ** SQL, then the sqlite3_error_offset() function returns -1.
3855 **
3856 ** When the serialized [threading mode] is in use, it might be the
3857 ** case that a second error occurs on a separate thread in between
3858 ** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
4282 ** ^For example, an UPDATE statement might have a WHERE clause that
4283 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4284 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4285 ** read-only no-op if the table already exists, but
4286 ** sqlite3_stmt_readonly() still returns false for such a statement.
4287 **
4288 ** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4289 ** statement, then sqlite3_stmt_readonly(X) returns the same value as
4290 ** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
4291 */
4292 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4293
4294 /*
4295 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
4354 ** still make the distinction between protected and unprotected
4355 ** sqlite3_value objects even when not strictly required.
4356 **
4357 ** ^The sqlite3_value objects that are passed as parameters into the
4358 ** implementation of [application-defined SQL functions] are protected.
4359 ** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4360 ** are protected.
4361 ** ^The sqlite3_value object returned by
4362 ** [sqlite3_column_value()] is unprotected.
4363 ** Unprotected sqlite3_value objects may only be used as arguments
4364 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4365 ** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
4976 ** bytes in the string, not the number of characters.
4977 **
4978 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4979 ** even empty strings, are always zero-terminated. ^The return
4980 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4981 **
4982 ** ^Strings returned by sqlite3_column_text16() always have the endianness
4983 ** which is native to the platform, regardless of the text encoding set
4984 ** for the database.
4985 **
4986 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4987 ** [unprotected sqlite3_value] object. In a multithreaded environment,
4988 ** an unprotected sqlite3_value object may only be used safely with
4989 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
4994 ** Hence, the sqlite3_column_value() interface
4995 ** is normally only useful within the implementation of
4996 ** [application-defined SQL functions] or [virtual tables], not within
4997 ** top-level application code.
4998 **
4999 ** These routines may attempt to convert the datatype of the result.
5000 ** ^For example, if the internal representation is FLOAT and a text result
5001 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5002 ** conversion automatically. ^(The following table details the conversions
5003 ** that are applied:
5004 **
@@ -5009,11 +5019,11 @@
5019 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5020 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5021 ** <tr><td> TEXT <td> BLOB <td> No change
5022 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5023 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5024 ** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
5025 ** </table>
5026 ** </blockquote>)^
5027 **
5028 ** Note that when type conversions occur, pointers returned by prior
5029 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
5591 **
5592 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5593 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5594 ** is a [protected sqlite3_value] object even if the input is not.
5595 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5596 ** memory allocation fails. ^If V is a [pointer value], then the result
5597 ** of sqlite3_value_dup(V) is a NULL value.
5598 **
5599 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5600 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5601 ** then sqlite3_value_free(V) is a harmless no-op.
5602 */
@@ -7129,28 +7140,60 @@
7140 /*
7141 ** CAPI3REF: Virtual Table Constraint Operator Codes
7142 **
7143 ** These macros define the allowed values for the
7144 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7145 ** an operator that is part of a constraint term in the WHERE clause of
7146 ** a query that uses a [virtual table].
7147 **
7148 ** ^The left-hand operand of the operator is given by the corresponding
7149 ** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7150 ** operand is the rowid.
7151 ** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7152 ** operators have no left-hand operand, and so for those operators the
7153 ** corresponding aConstraint[].iColumn is meaningless and should not be
7154 ** used.
7155 **
7156 ** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7157 ** value 255 are reserved to represent functions that are overloaded
7158 ** by the [xFindFunction|xFindFunction method] of the virtual table
7159 ** implementation.
7160 **
7161 ** The right-hand operands for each constraint might be accessible using
7162 ** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7163 ** operand is only available if it appears as a single constant literal
7164 ** in the input SQL. If the right-hand operand is another column or an
7165 ** expression (even a constant expression) or a parameter, then the
7166 ** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7167 ** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7168 ** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7169 ** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7170 ** always return SQLITE_NOTFOUND.
7171 **
7172 ** The collating sequence to be used for comparison can be found using
7173 ** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7174 ** tables, the collating sequence of constraints does not matter (for example
7175 ** because the constraints are numeric) and so the sqlite3_vtab_collation()
7176 ** interface is no commonly needed.
7177 */
7178 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7179 #define SQLITE_INDEX_CONSTRAINT_GT 4
7180 #define SQLITE_INDEX_CONSTRAINT_LE 8
7181 #define SQLITE_INDEX_CONSTRAINT_LT 16
7182 #define SQLITE_INDEX_CONSTRAINT_GE 32
7183 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7184 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7185 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7186 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7187 #define SQLITE_INDEX_CONSTRAINT_NE 68
7188 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7189 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7190 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7191 #define SQLITE_INDEX_CONSTRAINT_IS 72
7192 #define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7193 #define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7194 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7195
7196 /*
7197 ** CAPI3REF: Register A Virtual Table Implementation
7198 ** METHOD: sqlite3
7199 **
@@ -7175,11 +7218,11 @@
7218 ** ^The sqlite3_create_module()
7219 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7220 ** destructor.
7221 **
7222 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7223 ** NULL then no new module is created and any existing modules with the
7224 ** same name are dropped.
7225 **
7226 ** See also: [sqlite3_drop_modules()]
7227 */
7228 SQLITE_API int sqlite3_create_module(
@@ -9469,25 +9512,26 @@
9512 */
9513 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
9514
9515 /*
9516 ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
9517 ** METHOD: sqlite3_index_info
9518 **
9519 ** This function may only be called from within a call to the [xBestIndex]
9520 ** method of a [virtual table]. This function returns a pointer to a string
9521 ** that is the name of the appropriate collation sequence to use for text
9522 ** comparisons on the constraint identified by its arguments.
9523 **
9524 ** The first argument must be the pointer to the [sqlite3_index_info] object
9525 ** that is the first parameter to the xBestIndex() method. The second argument
9526 ** must be an index into the aConstraint[] array belonging to the
9527 ** sqlite3_index_info structure passed to xBestIndex.
9528 **
9529 ** Important:
9530 ** The first parameter must be the same pointer that is passed into the
9531 ** xBestMethod() method. The first parameter may not be a pointer to a
9532 ** different [sqlite3_index_info] object, even an exact copy.
9533 **
9534 ** The return value is computed as follows:
9535 **
9536 ** <ol>
9537 ** <li><p> If the constraint comes from a WHERE clause expression that contains
@@ -9501,10 +9545,247 @@
9545 ** <li><p> Otherwise, "BINARY" is returned.
9546 ** </ol>
9547 */
9548 SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
9549
9550 /*
9551 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9552 ** METHOD: sqlite3_index_info
9553 **
9554 ** This API may only be used from within an [xBestIndex|xBestIndex method]
9555 ** of a [virtual table] implementation. The result of calling this
9556 ** interface from outside of xBestIndex() is undefined and probably harmful.
9557 **
9558 ** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9559 ** 3. The integer returned by sqlite3_vtab_distinct()
9560 ** gives the virtual table additional information about how the query
9561 ** planner wants the output to be ordered. As long as the virtual table
9562 ** can meet the ordering requirements of the query planner, it may set
9563 ** the "orderByConsumed" flag.
9564 **
9565 ** <ol><li value="0"><p>
9566 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9567 ** that the query planner needs the virtual table to return all rows in the
9568 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9569 ** [sqlite3_index_info] object. This is the default expectation. If the
9570 ** virtual table outputs all rows in sorted order, then it is always safe for
9571 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9572 ** the return value from sqlite3_vtab_distinct().
9573 ** <li value="1"><p>
9574 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9575 ** that the query planner does not need the rows to be returned in sorted order
9576 ** as long as all rows with the same values in all columns identified by the
9577 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
9578 ** is doing a GROUP BY.
9579 ** <li value="2"><p>
9580 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9581 ** that the query planner does not need the rows returned in any particular
9582 ** order, as long as rows with the same values in all "aOrderBy" columns
9583 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9584 ** combination of values in the columns identified by the "aOrderBy" field
9585 ** needs to be returned.)^ ^It is always ok for two or more rows with the same
9586 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9587 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9588 ** that have the same value for all columns identified by "aOrderBy".
9589 ** ^However omitting the extra rows is optional.
9590 ** This mode is used for a DISTINCT query.
9591 ** <li value="3"><p>
9592 ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9593 ** that the query planner needs only distinct rows but it does need the
9594 ** rows to be sorted.)^ ^The virtual table implementation is free to omit
9595 ** rows that are identical in all aOrderBy columns, if it wants to, but
9596 ** it is not required to omit any rows. This mode is used for queries
9597 ** that have both DISTINCT and ORDER BY clauses.
9598 ** </ol>
9599 **
9600 ** ^For the purposes of comparing virtual table output values to see if the
9601 ** values are same value for sorting purposes, two NULL values are considered
9602 ** to be the same. In other words, the comparison operator is "IS"
9603 ** (or "IS NOT DISTINCT FROM") and not "==".
9604 **
9605 ** If a virtual table implementation is unable to meet the requirements
9606 ** specified above, then it must not set the "orderByConsumed" flag in the
9607 ** [sqlite3_index_info] object or an incorrect answer may result.
9608 **
9609 ** ^A virtual table implementation is always free to return rows in any order
9610 ** it wants, as long as the "orderByConsumed" flag is not set. ^When the
9611 ** the "orderByConsumed" flag is unset, the query planner will add extra
9612 ** [bytecode] to ensure that the final results returned by the SQL query are
9613 ** ordered correctly. The use of the "orderByConsumed" flag and the
9614 ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful
9615 ** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed"
9616 ** flag might help queries against a virtual table to run faster. Being
9617 ** overly aggressive and setting the "orderByConsumed" flag when it is not
9618 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9619 ** results.
9620 */
9621 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9622
9623 /*
9624 ** CAPI3REF: Identify and handle IN constraints in xBestIndex
9625 **
9626 ** This interface may only be used from within an
9627 ** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9628 ** The result of invoking this interface from any other context is
9629 ** undefined and probably harmful.
9630 **
9631 ** ^(A constraint on a virtual table of the form
9632 ** "[IN operator|column IN (...)]" is
9633 ** communicated to the xBestIndex method as a
9634 ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9635 ** this constraint, it must set the corresponding
9636 ** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9637 ** the usual mode of handling IN operators, SQLite generates [bytecode]
9638 ** that invokes the [xFilter|xFilter() method] once for each value
9639 ** on the right-hand side of the IN operator.)^ Thus the virtual table
9640 ** only sees a single value from the right-hand side of the IN operator
9641 ** at a time.
9642 **
9643 ** In some cases, however, it would be advantageous for the virtual
9644 ** table to see all values on the right-hand of the IN operator all at
9645 ** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9646 **
9647 ** <ol>
9648 ** <li><p>
9649 ** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9650 ** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9651 ** is an [IN operator] that can be processed all at once. ^In other words,
9652 ** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9653 ** by which the virtual table can ask SQLite if all-at-once processing
9654 ** of the IN operator is even possible.
9655 **
9656 ** <li><p>
9657 ** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9658 ** to SQLite that the virtual table does or does not want to process
9659 ** the IN operator all-at-once, respectively. ^Thus when the third
9660 ** parameter (F) is non-negative, this interface is the mechanism by
9661 ** which the virtual table tells SQLite how it wants to process the
9662 ** IN operator.
9663 ** </ol>
9664 **
9665 ** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9666 ** within the same xBestIndex method call. ^For any given P,N pair,
9667 ** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9668 ** within the same xBestIndex call. ^If the interface returns true
9669 ** (non-zero), that means that the constraint is an IN operator
9670 ** that can be processed all-at-once. ^If the constraint is not an IN
9671 ** operator or cannot be processed all-at-once, then the interface returns
9672 ** false.
9673 **
9674 ** ^(All-at-once processing of the IN operator is selected if both of the
9675 ** following conditions are met:
9676 **
9677 ** <ol>
9678 ** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9679 ** integer. This is how the virtual table tells SQLite that it wants to
9680 ** use the N-th constraint.
9681 **
9682 ** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9683 ** non-negative had F>=1.
9684 ** </ol>)^
9685 **
9686 ** ^If either or both of the conditions above are false, then SQLite uses
9687 ** the traditional one-at-a-time processing strategy for the IN constraint.
9688 ** ^If both conditions are true, then the argvIndex-th parameter to the
9689 ** xFilter method will be an [sqlite3_value] that appears to be NULL,
9690 ** but which can be passed to [sqlite3_vtab_in_first()] and
9691 ** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9692 ** of the IN constraint.
9693 */
9694 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
9695
9696 /*
9697 ** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
9698 **
9699 ** These interfaces are only useful from within the
9700 ** [xFilter|xFilter() method] of a [virtual table] implementation.
9701 ** The result of invoking these interfaces from any other context
9702 ** is undefined and probably harmful.
9703 **
9704 ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
9705 ** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
9706 ** xFilter method which invokes these routines, and specifically
9707 ** a parameter that was previously selected for all-at-once IN constraint
9708 ** processing use the [sqlite3_vtab_in()] interface in the
9709 ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
9710 ** an xFilter argument that was selected for all-at-once IN constraint
9711 ** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
9712 ** exhibit some other undefined or harmful behavior.
9713 **
9714 ** ^(Use these routines to access all values on the right-hand side
9715 ** of the IN constraint using code like the following:
9716 **
9717 ** <blockquote><pre>
9718 ** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
9719 ** &nbsp; rc==SQLITE_OK && pVal
9720 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
9721 ** &nbsp; ){
9722 ** &nbsp; // do something with pVal
9723 ** &nbsp; }
9724 ** &nbsp; if( rc!=SQLITE_OK ){
9725 ** &nbsp; // an error has occurred
9726 ** &nbsp; }
9727 ** </pre></blockquote>)^
9728 **
9729 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
9730 ** routines return SQLITE_OK and set *P to point to the first or next value
9731 ** on the RHS of the IN constraint. ^If there are no more values on the
9732 ** right hand side of the IN constraint, then *P is set to NULL and these
9733 ** routines return [SQLITE_DONE]. ^The return value might be
9734 ** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
9735 **
9736 ** The *ppOut values returned by these routines are only valid until the
9737 ** next call to either of these routines or until the end of the xFilter
9738 ** method from which these routines were called. If the virtual table
9739 ** implementation needs to retain the *ppOut values for longer, it must make
9740 ** copies. The *ppOut values are [protected sqlite3_value|protected].
9741 */
9742 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
9743 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
9744
9745 /*
9746 ** CAPI3REF: Constraint values in xBestIndex()
9747 ** METHOD: sqlite3_index_info
9748 **
9749 ** This API may only be used from within the [xBestIndex|xBestIndex method]
9750 ** of a [virtual table] implementation. The result of calling this interface
9751 ** from outside of an xBestIndex method are undefined and probably harmful.
9752 **
9753 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
9754 ** the [xBestIndex] method of a [virtual table] implementation, with P being
9755 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
9756 ** J being a 0-based index into P->aConstraint[], then this routine
9757 ** attempts to set *V to the value of the right-hand operand of
9758 ** that constraint if the right-hand operand is known. ^If the
9759 ** right-hand operand is not known, then *V is set to a NULL pointer.
9760 ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9761 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
9762 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
9763 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
9764 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
9765 ** something goes wrong.
9766 **
9767 ** The sqlite3_vtab_rhs_value() interface is usually only successful if
9768 ** the right-hand operand of a constraint is a literal value in the original
9769 ** SQL statement. If the right-hand operand is an expression or a reference
9770 ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
9771 ** will probably return [SQLITE_NOTFOUND].
9772 **
9773 ** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
9774 ** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
9775 ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
9776 **
9777 ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
9778 ** and remains valid for the duration of the xBestIndex method call.
9779 ** ^When xBestIndex returns, the sqlite3_value object returned by
9780 ** sqlite3_vtab_rhs_value() is automatically deallocated.
9781 **
9782 ** The "_rhs_" in the name of this routine is an abbreviation for
9783 ** "Right-Hand Side".
9784 */
9785 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
9786
9787 /*
9788 ** CAPI3REF: Conflict resolution modes
9789 ** KEYWORDS: {conflict resolution mode}
9790 **
9791 ** These constants are returned by [sqlite3_vtab_on_conflict()] to
9792
+4 -4
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314314
entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315315
"ecmd", "sendmail -ti", 0);
316316
@ <p>When the send method is "pipe to a command", this is the command
317317
@ that is run. Email messages are piped into the standard input of this
318318
@ command. The command is expected to extract the sender address,
319
- @ recepient addresses, and subject from the header of the piped email
319
+ @ recipient addresses, and subject from the header of the piped email
320320
@ text. (Property: "email-send-command")</p>
321321
322322
entry_attribute("Store Emails In This Database", 60, "email-send-db",
323323
"esdb", "", 0);
324324
@ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816816
}
817817
818818
/*
819819
** Send a single email message.
820820
**
821
-** The recepient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
821
+** The recipient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822822
** in the header. Likewise, the header must contains a "Subject:" line.
823823
** The header might also include fields like "Message-Id:" or
824824
** "In-Reply-To:".
825825
**
826826
** This routine will add fields to the header as follows:
@@ -1531,11 +1531,11 @@
15311531
if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
15321532
if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
15331533
if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
15341534
}
15351535
@ <p>To receive email notifications for changes to this
1536
- @ repository, fill out the form below and press "Submit" button.</p>
1536
+ @ repository, fill out the form below and press the "Submit" button.</p>
15371537
form_begin(0, "%R/subscribe");
15381538
@ <table class="subscribe">
15391539
@ <tr>
15401540
@ <td class="form_label">Email&nbsp;Address:</td>
15411541
@ <td><input type="text" name="e" value="%h(PD("e",""))" size="30"></td>
@@ -2325,11 +2325,11 @@
23252325
sqlite3_int64 iMtime = db_column_int64(&q, 6);
23262326
double rAge = (iNow - iMtime)/86400.0;
23272327
int uid = db_column_int(&q, 8);
23282328
const char *zUname = db_column_text(&q, 3);
23292329
sqlite3_int64 iContact = db_column_int64(&q, 9);
2330
- double rContact = (iNow/86400) - iContact;
2330
+ double rContact = (iNow/86400.0) - iContact;
23312331
@ <tr>
23322332
@ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
23332333
@ %h(db_column_text(&q,1))</a></td>
23342334
@ <td>%h(db_column_text(&q,2))</td>
23352335
@ <td>%s(db_column_int(&q,5)?"digest":"")</td>
23362336
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314 entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315 "ecmd", "sendmail -ti", 0);
316 @ <p>When the send method is "pipe to a command", this is the command
317 @ that is run. Email messages are piped into the standard input of this
318 @ command. The command is expected to extract the sender address,
319 @ recepient addresses, and subject from the header of the piped email
320 @ text. (Property: "email-send-command")</p>
321
322 entry_attribute("Store Emails In This Database", 60, "email-send-db",
323 "esdb", "", 0);
324 @ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816 }
817
818 /*
819 ** Send a single email message.
820 **
821 ** The recepient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822 ** in the header. Likewise, the header must contains a "Subject:" line.
823 ** The header might also include fields like "Message-Id:" or
824 ** "In-Reply-To:".
825 **
826 ** This routine will add fields to the header as follows:
@@ -1531,11 +1531,11 @@
1531 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
1532 if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
1533 if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
1534 }
1535 @ <p>To receive email notifications for changes to this
1536 @ repository, fill out the form below and press "Submit" button.</p>
1537 form_begin(0, "%R/subscribe");
1538 @ <table class="subscribe">
1539 @ <tr>
1540 @ <td class="form_label">Email&nbsp;Address:</td>
1541 @ <td><input type="text" name="e" value="%h(PD("e",""))" size="30"></td>
@@ -2325,11 +2325,11 @@
2325 sqlite3_int64 iMtime = db_column_int64(&q, 6);
2326 double rAge = (iNow - iMtime)/86400.0;
2327 int uid = db_column_int(&q, 8);
2328 const char *zUname = db_column_text(&q, 3);
2329 sqlite3_int64 iContact = db_column_int64(&q, 9);
2330 double rContact = (iNow/86400) - iContact;
2331 @ <tr>
2332 @ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
2333 @ %h(db_column_text(&q,1))</a></td>
2334 @ <td>%h(db_column_text(&q,2))</td>
2335 @ <td>%s(db_column_int(&q,5)?"digest":"")</td>
2336
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314 entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315 "ecmd", "sendmail -ti", 0);
316 @ <p>When the send method is "pipe to a command", this is the command
317 @ that is run. Email messages are piped into the standard input of this
318 @ command. The command is expected to extract the sender address,
319 @ recipient addresses, and subject from the header of the piped email
320 @ text. (Property: "email-send-command")</p>
321
322 entry_attribute("Store Emails In This Database", 60, "email-send-db",
323 "esdb", "", 0);
324 @ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816 }
817
818 /*
819 ** Send a single email message.
820 **
821 ** The recipient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822 ** in the header. Likewise, the header must contains a "Subject:" line.
823 ** The header might also include fields like "Message-Id:" or
824 ** "In-Reply-To:".
825 **
826 ** This routine will add fields to the header as follows:
@@ -1531,11 +1531,11 @@
1531 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
1532 if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
1533 if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
1534 }
1535 @ <p>To receive email notifications for changes to this
1536 @ repository, fill out the form below and press the "Submit" button.</p>
1537 form_begin(0, "%R/subscribe");
1538 @ <table class="subscribe">
1539 @ <tr>
1540 @ <td class="form_label">Email&nbsp;Address:</td>
1541 @ <td><input type="text" name="e" value="%h(PD("e",""))" size="30"></td>
@@ -2325,11 +2325,11 @@
2325 sqlite3_int64 iMtime = db_column_int64(&q, 6);
2326 double rAge = (iNow - iMtime)/86400.0;
2327 int uid = db_column_int(&q, 8);
2328 const char *zUname = db_column_text(&q, 3);
2329 sqlite3_int64 iContact = db_column_int64(&q, 9);
2330 double rContact = (iNow/86400.0) - iContact;
2331 @ <tr>
2332 @ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
2333 @ %h(db_column_text(&q,1))</a></td>
2334 @ <td>%h(db_column_text(&q,2))</td>
2335 @ <td>%s(db_column_int(&q,5)?"digest":"")</td>
2336
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238238
i-1, zDesc+1
239239
);
240240
if( rid==0 ) break;
241241
blob_appendf(&log, "%d", rid);
242242
zDesc += i;
243
+ while( zDesc[0]=='-' ) zDesc++;
243244
}
244245
}else{
245246
zLog = db_lget("bisect-log","");
246247
blob_init(&log, zLog, -1);
247248
}
@@ -327,10 +328,11 @@
327328
cPrefix = 'n';
328329
rid = -rid;
329330
}
330331
}
331332
zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
333
+ if( blob_size(&link)>0 ) blob_append(&link, "-", 1);
332334
blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
333335
}
334336
zResult = mprintf("%s", blob_str(&link));
335337
blob_reset(&link);
336338
blob_reset(&log);
337339
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238 i-1, zDesc+1
239 );
240 if( rid==0 ) break;
241 blob_appendf(&log, "%d", rid);
242 zDesc += i;
 
243 }
244 }else{
245 zLog = db_lget("bisect-log","");
246 blob_init(&log, zLog, -1);
247 }
@@ -327,10 +328,11 @@
327 cPrefix = 'n';
328 rid = -rid;
329 }
330 }
331 zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
 
332 blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
333 }
334 zResult = mprintf("%s", blob_str(&link));
335 blob_reset(&link);
336 blob_reset(&log);
337
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238 i-1, zDesc+1
239 );
240 if( rid==0 ) break;
241 blob_appendf(&log, "%d", rid);
242 zDesc += i;
243 while( zDesc[0]=='-' ) zDesc++;
244 }
245 }else{
246 zLog = db_lget("bisect-log","");
247 blob_init(&log, zLog, -1);
248 }
@@ -327,10 +328,11 @@
328 cPrefix = 'n';
329 rid = -rid;
330 }
331 }
332 zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
333 if( blob_size(&link)>0 ) blob_append(&link, "-", 1);
334 blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
335 }
336 zResult = mprintf("%s", blob_str(&link));
337 blob_reset(&link);
338 blob_reset(&log);
339
+3 -3
--- src/blob.c
+++ src/blob.c
@@ -164,11 +164,11 @@
164164
pBlob->aData = 0;
165165
pBlob->nAlloc = 0;
166166
pBlob->nUsed = 0;
167167
pBlob->iCursor = 0;
168168
pBlob->blobFlags = 0;
169
- }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
169
+ }else if( newSize>pBlob->nAlloc || newSize+4000<pBlob->nAlloc ){
170170
char *pNew = fossil_realloc(pBlob->aData, newSize);
171171
pBlob->aData = pNew;
172172
pBlob->nAlloc = newSize;
173173
if( pBlob->nUsed>pBlob->nAlloc ){
174174
pBlob->nUsed = pBlob->nAlloc;
@@ -595,12 +595,12 @@
595595
** builds.
596596
*/
597597
void blob_reserve(Blob *pBlob, unsigned int newSize){
598598
if(newSize>=0x7fff0000 ){
599599
blob_panic();
600
- }else if(newSize>pBlob->nUsed){
601
- pBlob->xRealloc(pBlob, newSize);
600
+ }else if(newSize>pBlob->nAlloc){
601
+ pBlob->xRealloc(pBlob, newSize+1);
602602
pBlob->aData[newSize] = 0;
603603
}
604604
}
605605
606606
/*
607607
--- src/blob.c
+++ src/blob.c
@@ -164,11 +164,11 @@
164 pBlob->aData = 0;
165 pBlob->nAlloc = 0;
166 pBlob->nUsed = 0;
167 pBlob->iCursor = 0;
168 pBlob->blobFlags = 0;
169 }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
170 char *pNew = fossil_realloc(pBlob->aData, newSize);
171 pBlob->aData = pNew;
172 pBlob->nAlloc = newSize;
173 if( pBlob->nUsed>pBlob->nAlloc ){
174 pBlob->nUsed = pBlob->nAlloc;
@@ -595,12 +595,12 @@
595 ** builds.
596 */
597 void blob_reserve(Blob *pBlob, unsigned int newSize){
598 if(newSize>=0x7fff0000 ){
599 blob_panic();
600 }else if(newSize>pBlob->nUsed){
601 pBlob->xRealloc(pBlob, newSize);
602 pBlob->aData[newSize] = 0;
603 }
604 }
605
606 /*
607
--- src/blob.c
+++ src/blob.c
@@ -164,11 +164,11 @@
164 pBlob->aData = 0;
165 pBlob->nAlloc = 0;
166 pBlob->nUsed = 0;
167 pBlob->iCursor = 0;
168 pBlob->blobFlags = 0;
169 }else if( newSize>pBlob->nAlloc || newSize+4000<pBlob->nAlloc ){
170 char *pNew = fossil_realloc(pBlob->aData, newSize);
171 pBlob->aData = pNew;
172 pBlob->nAlloc = newSize;
173 if( pBlob->nUsed>pBlob->nAlloc ){
174 pBlob->nUsed = pBlob->nAlloc;
@@ -595,12 +595,12 @@
595 ** builds.
596 */
597 void blob_reserve(Blob *pBlob, unsigned int newSize){
598 if(newSize>=0x7fff0000 ){
599 blob_panic();
600 }else if(newSize>pBlob->nAlloc){
601 pBlob->xRealloc(pBlob, newSize+1);
602 pBlob->aData[newSize] = 0;
603 }
604 }
605
606 /*
607
+5 -4
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330330
** directory.
331331
*/
332332
mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333333
if( mxLen<12 ) mxLen = 12;
334334
mxLen += (mxLen+9)/10;
335
- db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
335
+ db_prepare(&q,
336
+ "SELECT x, u FROM localfiles ORDER BY x COLLATE uintnocase /*scan*/");
336337
@ <div class="columns files" style="columns: %d(mxLen)ex auto">
337338
@ <ul class="browser">
338339
while( db_step(&q)==SQLITE_ROW ){
339340
const char *zFN;
340341
zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
368369
*/
369370
db_prepare(&q,
370371
"SELECT x, u FROM localfiles"
371372
" WHERE x COLLATE nocase IN"
372373
" ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
373
- " 'readme.html') ORDER BY x LIMIT 1;"
374
+ " 'readme.html') ORDER BY x COLLATE uintnocase LIMIT 1;"
374375
);
375376
if( db_step(&q)==SQLITE_ROW ){
376377
const char *zName = db_column_text(&q,0);
377378
const char *zUuid = db_column_text(&q,1);
378379
if( zUuid ){
@@ -790,11 +791,11 @@
790791
db_prepare(&q,
791792
"SELECT filename.name, blob.uuid, fileage.mtime\n"
792793
" FROM fileage, filename, blob\n"
793794
" WHERE filename.fnid=fileage.fnid\n"
794795
" AND blob.rid=fileage.fid\n"
795
- " ORDER BY filename.name COLLATE nocase;"
796
+ " ORDER BY filename.name COLLATE uintnocase;"
796797
);
797798
while( db_step(&q)==SQLITE_ROW ){
798799
const char *zFile = db_column_text(&q,0);
799800
const char *zUuid = db_column_text(&q,1);
800801
double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
813814
" (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
814815
" (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
815816
" max(event.mtime)\n"
816817
" FROM mlink JOIN event ON event.objid=mlink.mid\n"
817818
" GROUP BY mlink.fnid\n"
818
- " ORDER BY 1 COLLATE nocase;");
819
+ " ORDER BY 1 COLLATE uintnocase;");
819820
while( db_step(&q)==SQLITE_ROW ){
820821
const char *zName = db_column_text(&q, 0);
821822
const char *zUuid = db_column_text(&q,1);
822823
double mtime = db_column_double(&q,2);
823824
if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
824825
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330 ** directory.
331 */
332 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333 if( mxLen<12 ) mxLen = 12;
334 mxLen += (mxLen+9)/10;
335 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
 
336 @ <div class="columns files" style="columns: %d(mxLen)ex auto">
337 @ <ul class="browser">
338 while( db_step(&q)==SQLITE_ROW ){
339 const char *zFN;
340 zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
368 */
369 db_prepare(&q,
370 "SELECT x, u FROM localfiles"
371 " WHERE x COLLATE nocase IN"
372 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
373 " 'readme.html') ORDER BY x LIMIT 1;"
374 );
375 if( db_step(&q)==SQLITE_ROW ){
376 const char *zName = db_column_text(&q,0);
377 const char *zUuid = db_column_text(&q,1);
378 if( zUuid ){
@@ -790,11 +791,11 @@
790 db_prepare(&q,
791 "SELECT filename.name, blob.uuid, fileage.mtime\n"
792 " FROM fileage, filename, blob\n"
793 " WHERE filename.fnid=fileage.fnid\n"
794 " AND blob.rid=fileage.fid\n"
795 " ORDER BY filename.name COLLATE nocase;"
796 );
797 while( db_step(&q)==SQLITE_ROW ){
798 const char *zFile = db_column_text(&q,0);
799 const char *zUuid = db_column_text(&q,1);
800 double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
813 " (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
814 " (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
815 " max(event.mtime)\n"
816 " FROM mlink JOIN event ON event.objid=mlink.mid\n"
817 " GROUP BY mlink.fnid\n"
818 " ORDER BY 1 COLLATE nocase;");
819 while( db_step(&q)==SQLITE_ROW ){
820 const char *zName = db_column_text(&q, 0);
821 const char *zUuid = db_column_text(&q,1);
822 double mtime = db_column_double(&q,2);
823 if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
824
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330 ** directory.
331 */
332 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333 if( mxLen<12 ) mxLen = 12;
334 mxLen += (mxLen+9)/10;
335 db_prepare(&q,
336 "SELECT x, u FROM localfiles ORDER BY x COLLATE uintnocase /*scan*/");
337 @ <div class="columns files" style="columns: %d(mxLen)ex auto">
338 @ <ul class="browser">
339 while( db_step(&q)==SQLITE_ROW ){
340 const char *zFN;
341 zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
369 */
370 db_prepare(&q,
371 "SELECT x, u FROM localfiles"
372 " WHERE x COLLATE nocase IN"
373 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
374 " 'readme.html') ORDER BY x COLLATE uintnocase LIMIT 1;"
375 );
376 if( db_step(&q)==SQLITE_ROW ){
377 const char *zName = db_column_text(&q,0);
378 const char *zUuid = db_column_text(&q,1);
379 if( zUuid ){
@@ -790,11 +791,11 @@
791 db_prepare(&q,
792 "SELECT filename.name, blob.uuid, fileage.mtime\n"
793 " FROM fileage, filename, blob\n"
794 " WHERE filename.fnid=fileage.fnid\n"
795 " AND blob.rid=fileage.fid\n"
796 " ORDER BY filename.name COLLATE uintnocase;"
797 );
798 while( db_step(&q)==SQLITE_ROW ){
799 const char *zFile = db_column_text(&q,0);
800 const char *zUuid = db_column_text(&q,1);
801 double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
814 " (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
815 " (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
816 " max(event.mtime)\n"
817 " FROM mlink JOIN event ON event.objid=mlink.mid\n"
818 " GROUP BY mlink.fnid\n"
819 " ORDER BY 1 COLLATE uintnocase;");
820 while( db_step(&q)==SQLITE_ROW ){
821 const char *zName = db_column_text(&q, 0);
822 const char *zUuid = db_column_text(&q,1);
823 double mtime = db_column_double(&q,2);
824 if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
825
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275275
{ 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276276
"Mod-Tkt", "Moderate tickets" },
277277
{ 'r', CAPCLASS_TKT, 0,
278278
"Read-Tkt", "View tickets" },
279279
{ 's', CAPCLASS_SUPER, 0,
280
- "Superuser", "Setup and configure the respository" },
280
+ "Superuser", "Setup and configure the repository" },
281281
{ 't', CAPCLASS_TKT, 0,
282282
"Reports", "Create new ticket report formats" },
283283
{ 'u', CAPCLASS_OTHER, 0,
284284
"Reader", "Inherit all the capabilities of the \"reader\" user" },
285285
{ 'v', CAPCLASS_OTHER, 0,
286286
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276 "Mod-Tkt", "Moderate tickets" },
277 { 'r', CAPCLASS_TKT, 0,
278 "Read-Tkt", "View tickets" },
279 { 's', CAPCLASS_SUPER, 0,
280 "Superuser", "Setup and configure the respository" },
281 { 't', CAPCLASS_TKT, 0,
282 "Reports", "Create new ticket report formats" },
283 { 'u', CAPCLASS_OTHER, 0,
284 "Reader", "Inherit all the capabilities of the \"reader\" user" },
285 { 'v', CAPCLASS_OTHER, 0,
286
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276 "Mod-Tkt", "Moderate tickets" },
277 { 'r', CAPCLASS_TKT, 0,
278 "Read-Tkt", "View tickets" },
279 { 's', CAPCLASS_SUPER, 0,
280 "Superuser", "Setup and configure the repository" },
281 { 't', CAPCLASS_TKT, 0,
282 "Reports", "Create new ticket report formats" },
283 { 'u', CAPCLASS_OTHER, 0,
284 "Reader", "Inherit all the capabilities of the \"reader\" user" },
285 { 'v', CAPCLASS_OTHER, 0,
286
+46 -93
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364364
}
365365
366366
/* Works like fread():
367367
**
368368
** Read as many as bytes of content as we can, up to a maximum of nmemb
369
-** bytes. Return the number of bytes read. Return -1 if there is no
369
+** bytes. Return the number of bytes read. Return 0 if there is no
370370
** further input or if an I/O error occurs.
371371
*/
372372
size_t cgi_fread(void *ptr, size_t nmemb){
373373
if( !g.httpUseSSL ){
374374
return fread(ptr, 1, nmemb, g.httpIn);
375375
}
376376
#ifdef FOSSIL_ENABLE_SSL
377
- return ssl_read_server(g.httpSSLConn, ptr, nmemb);
377
+ return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378378
#else
379379
fossil_fatal("SSL not available");
380380
#endif
381381
}
382382
@@ -1061,71 +1061,23 @@
10611061
}
10621062
10631063
10641064
#ifdef FOSSIL_ENABLE_JSON
10651065
/*
1066
-** Internal helper for cson_data_source_FILE_n().
1067
-*/
1068
-typedef struct CgiPostReadState_ {
1069
- FILE * fh;
1070
- unsigned int len;
1071
- unsigned int pos;
1072
-} CgiPostReadState;
1073
-
1074
-/*
1075
-** cson_data_source_f() impl which reads only up to
1076
-** a specified amount of data from its input FILE.
1077
-** state MUST be a full populated (CgiPostReadState*).
1078
-*/
1079
-static int cson_data_source_FILE_n( void * state,
1080
- void * dest,
1081
- unsigned int * n ){
1082
- if( ! state || !dest || !n ) return cson_rc.ArgError;
1083
- else {
1084
- CgiPostReadState * st = (CgiPostReadState *)state;
1085
- if( st->pos >= st->len ){
1086
- *n = 0;
1087
- return 0;
1088
- }else if( !*n || ((st->pos + *n) > st->len) ){
1089
- return cson_rc.RangeError;
1090
- }else{
1091
- unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh );
1092
- if( ! rsz ){
1093
- *n = rsz;
1094
- return feof(st->fh) ? 0 : cson_rc.IOError;
1095
- }else{
1096
- *n = rsz;
1097
- st->pos += *n;
1098
- return 0;
1099
- }
1100
- }
1101
- }
1102
-}
1103
-
1104
-/*
1105
-** Reads a JSON object from the first contentLen bytes of zIn. On
1106
-** g.json.post is updated to hold the content. On error a
1107
-** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is
1108
-** called (in HTTP mode exit code 0 is used).
1109
-**
1110
-** If contentLen is 0 then the whole file is read.
1111
-*/
1112
-void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){
1113
- cson_value * jv = NULL;
1114
- int rc;
1115
- CgiPostReadState state;
1116
- cson_parse_opt popt = cson_parse_opt_empty;
1066
+** Reads a JSON object from the given blob, which is assumed to have
1067
+** been populated by the caller from stdin, the SSL API, or a file, as
1068
+** appropriate for the particular use case. On success g.json.post is
1069
+** updated to hold the content. On error a FSL_JSON_E_INVALID_REQUEST
1070
+** response is output and fossil_exit() is called (in HTTP mode exit
1071
+** code 0 is used).
1072
+*/
1073
+void cgi_parse_POST_JSON( Blob * pIn ){
1074
+ cson_value * jv = NULL;
11171075
cson_parse_info pinfo = cson_parse_info_empty;
11181076
assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1119
- popt.maxDepth = 15;
1120
- state.fh = zIn;
1121
- state.len = contentLen;
1122
- state.pos = 0;
1123
- rc = cson_parse( &jv,
1124
- contentLen ? cson_data_source_FILE_n : cson_data_source_FILE,
1125
- contentLen ? (void *)&state : (void *)zIn, &popt, &pinfo );
1126
- if(rc){
1077
+ jv = cson_parse_Blob(pIn, &pinfo);
1078
+ if( jv==NULL ){
11271079
goto invalidRequest;
11281080
}else{
11291081
json_gc_add( "POST.JSON", jv );
11301082
g.json.post.v = jv;
11311083
g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
11401092
char * msg = mprintf("JSON parse error at line %u, column %u, "
11411093
"byte offset %u: %s",
11421094
pinfo.line, pinfo.col, pinfo.length,
11431095
cson_rc_string(pinfo.errorCode));
11441096
json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1145
- free(msg);
1097
+ fossil_free(msg);
11461098
}else if(jv && !g.json.post.o){
11471099
json_err( FSL_JSON_E_INVALID_REQUEST,
11481100
"Request envelope must be a JSON Object (not array).", 1 );
11491101
}else{ /* generic error message */
11501102
json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
12221174
**
12231175
** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
12241176
**
12251177
** REQUEST_URI == SCRIPT_NAME + PATH_INFO
12261178
**
1179
+** Or if QUERY_STRING is not empty:
1180
+**
1181
+** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING
1182
+**
12271183
** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
12281184
** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
12291185
** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
12301186
** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
12311187
** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
12401196
** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
12411197
** PATH_INFO when it is empty.
12421198
**
12431199
** CGI Parameter quick reference:
12441200
**
1245
-** REQUEST_URI
1246
-** _____________|____________
1247
-** / \
1248
-** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1249
-** \________________/\____/\____________________/ \_/
1250
-** | | | |
1251
-** HTTP_HOST | PATH_INFO QUERY_STRING
1252
-** SCRIPT_NAME
1201
+** REQUEST_URI
1202
+** _____________|________________
1203
+** / \
1204
+** https://fossil-scm.org/forum/info/12736b30c072551a?t=c
1205
+** \___/ \____________/\____/\____________________/ \_/
1206
+** | | | | |
1207
+** | HTTP_HOST | PATH_INFO QUERY_STRING
1208
+** | |
1209
+** REQUEST_SCHEMA SCRIPT_NAME
1210
+**
12531211
*/
12541212
void cgi_init(void){
12551213
char *z;
12561214
const char *zType;
12571215
char *zSemi;
@@ -1270,20 +1228,18 @@
12701228
cgi_destination(CGI_BODY);
12711229
12721230
/* We must have SCRIPT_NAME. If the web server did not supply it, try
12731231
** to compute it from REQUEST_URI and PATH_INFO. */
12741232
if( zScriptName==0 ){
1275
- size_t nRU, nPI;
12761233
if( zRequestUri==0 || zPathInfo==0 ){
12771234
malformed_request("missing SCRIPT_NAME"); /* Does not return */
12781235
}
1279
- nRU = strlen(zRequestUri);
1280
- nPI = strlen(zPathInfo);
1281
- if( nRU<nPI ){
1282
- malformed_request("PATH_INFO is longer than REQUEST_URI");
1236
+ z = strstr(zRequestUri,zPathInfo);
1237
+ if( z==0 ){
1238
+ malformed_request("PATH_INFO not found in REQUEST_URI");
12831239
}
1284
- zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
1240
+ zScriptName = fossil_strndup(zRequestUri,(int)(z-zRequestUri));
12851241
cgi_set_parameter("SCRIPT_NAME", zScriptName);
12861242
}
12871243
12881244
#ifdef _WIN32
12891245
/* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
12991255
cgi_replace_parameter("PATH_INFO", zPathInfo);
13001256
}
13011257
#endif
13021258
if( zRequestUri==0 ){
13031259
const char *z = zPathInfo;
1260
+ const char *zQS = cgi_parameter("QUERY_STRING",0);
13041261
if( zPathInfo==0 ){
13051262
malformed_request("missing PATH_INFO and/or REQUEST_URI");
13061263
}
13071264
if( z[0]=='/' ) z++;
1308
- zRequestUri = mprintf("%s/%s", zScriptName, z);
1265
+ if( zQS && zQS[0] ){
1266
+ zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS);
1267
+ }else{
1268
+ zRequestUri = mprintf("%s/%s", zScriptName, z);
1269
+ }
13091270
cgi_set_parameter("REQUEST_URI", zRequestUri);
13101271
}
13111272
if( zPathInfo==0 ){
13121273
int i, j;
13131274
for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
13621323
}else{
13631324
g.zContentType = zType;
13641325
}
13651326
blob_zero(&g.cgiIn);
13661327
if( len>0 && zType ){
1328
+ if( blob_read_from_cgi(&g.cgiIn, len)<len ){
1329
+ char *zMsg = mprintf("CGI content-length mismatch: Wanted %d bytes"
1330
+ " but got only %d\n", len, blob_size(&g.cgiIn));
1331
+ malformed_request(zMsg);
1332
+ }
13671333
if( fossil_strcmp(zType, "application/x-fossil")==0 ){
1368
- if( blob_read_from_cgi(&g.cgiIn, len)!=len ){
1369
- malformed_request("CGI content-length mismatch");
1370
- }
13711334
blob_uncompress(&g.cgiIn, &g.cgiIn);
13721335
}
13731336
#ifdef FOSSIL_ENABLE_JSON
1374
- else if( noJson==0 && g.json.isJsonMode!=0
1375
- && json_can_consume_content_type(zType)!=0 ){
1376
- assert( !g.httpUseSSL );
1377
- cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
1378
- /*
1379
- Potential TODOs:
1380
-
1381
- 1) If parsing fails, immediately return an error response
1382
- without dispatching the ostensibly-upcoming JSON API.
1383
- */
1337
+ if( noJson==0 && g.json.isJsonMode!=0
1338
+ && json_can_consume_content_type(zType)!=0 ){
1339
+ cgi_parse_POST_JSON(&g.cgiIn);
13841340
cgi_set_content_type(json_guess_content_type());
13851341
}
13861342
#endif /* FOSSIL_ENABLE_JSON */
1387
- else{
1388
- blob_read_from_cgi(&g.cgiIn, len);
1389
- }
13901343
}
13911344
}
13921345
13931346
/*
13941347
** Decode POST parameter information in the cgiIn content, if any.
13951348
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return -1 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
@@ -1061,71 +1061,23 @@
1061 }
1062
1063
1064 #ifdef FOSSIL_ENABLE_JSON
1065 /*
1066 ** Internal helper for cson_data_source_FILE_n().
1067 */
1068 typedef struct CgiPostReadState_ {
1069 FILE * fh;
1070 unsigned int len;
1071 unsigned int pos;
1072 } CgiPostReadState;
1073
1074 /*
1075 ** cson_data_source_f() impl which reads only up to
1076 ** a specified amount of data from its input FILE.
1077 ** state MUST be a full populated (CgiPostReadState*).
1078 */
1079 static int cson_data_source_FILE_n( void * state,
1080 void * dest,
1081 unsigned int * n ){
1082 if( ! state || !dest || !n ) return cson_rc.ArgError;
1083 else {
1084 CgiPostReadState * st = (CgiPostReadState *)state;
1085 if( st->pos >= st->len ){
1086 *n = 0;
1087 return 0;
1088 }else if( !*n || ((st->pos + *n) > st->len) ){
1089 return cson_rc.RangeError;
1090 }else{
1091 unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh );
1092 if( ! rsz ){
1093 *n = rsz;
1094 return feof(st->fh) ? 0 : cson_rc.IOError;
1095 }else{
1096 *n = rsz;
1097 st->pos += *n;
1098 return 0;
1099 }
1100 }
1101 }
1102 }
1103
1104 /*
1105 ** Reads a JSON object from the first contentLen bytes of zIn. On
1106 ** g.json.post is updated to hold the content. On error a
1107 ** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is
1108 ** called (in HTTP mode exit code 0 is used).
1109 **
1110 ** If contentLen is 0 then the whole file is read.
1111 */
1112 void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){
1113 cson_value * jv = NULL;
1114 int rc;
1115 CgiPostReadState state;
1116 cson_parse_opt popt = cson_parse_opt_empty;
1117 cson_parse_info pinfo = cson_parse_info_empty;
1118 assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1119 popt.maxDepth = 15;
1120 state.fh = zIn;
1121 state.len = contentLen;
1122 state.pos = 0;
1123 rc = cson_parse( &jv,
1124 contentLen ? cson_data_source_FILE_n : cson_data_source_FILE,
1125 contentLen ? (void *)&state : (void *)zIn, &popt, &pinfo );
1126 if(rc){
1127 goto invalidRequest;
1128 }else{
1129 json_gc_add( "POST.JSON", jv );
1130 g.json.post.v = jv;
1131 g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
1140 char * msg = mprintf("JSON parse error at line %u, column %u, "
1141 "byte offset %u: %s",
1142 pinfo.line, pinfo.col, pinfo.length,
1143 cson_rc_string(pinfo.errorCode));
1144 json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1145 free(msg);
1146 }else if(jv && !g.json.post.o){
1147 json_err( FSL_JSON_E_INVALID_REQUEST,
1148 "Request envelope must be a JSON Object (not array).", 1 );
1149 }else{ /* generic error message */
1150 json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
1222 **
1223 ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
1224 **
1225 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO
1226 **
 
 
 
 
1227 ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
1228 ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
1229 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1230 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1231 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
1240 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1241 ** PATH_INFO when it is empty.
1242 **
1243 ** CGI Parameter quick reference:
1244 **
1245 ** REQUEST_URI
1246 ** _____________|____________
1247 ** / \
1248 ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1249 ** \________________/\____/\____________________/ \_/
1250 ** | | | |
1251 ** HTTP_HOST | PATH_INFO QUERY_STRING
1252 ** SCRIPT_NAME
 
 
1253 */
1254 void cgi_init(void){
1255 char *z;
1256 const char *zType;
1257 char *zSemi;
@@ -1270,20 +1228,18 @@
1270 cgi_destination(CGI_BODY);
1271
1272 /* We must have SCRIPT_NAME. If the web server did not supply it, try
1273 ** to compute it from REQUEST_URI and PATH_INFO. */
1274 if( zScriptName==0 ){
1275 size_t nRU, nPI;
1276 if( zRequestUri==0 || zPathInfo==0 ){
1277 malformed_request("missing SCRIPT_NAME"); /* Does not return */
1278 }
1279 nRU = strlen(zRequestUri);
1280 nPI = strlen(zPathInfo);
1281 if( nRU<nPI ){
1282 malformed_request("PATH_INFO is longer than REQUEST_URI");
1283 }
1284 zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
1285 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1286 }
1287
1288 #ifdef _WIN32
1289 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
1299 cgi_replace_parameter("PATH_INFO", zPathInfo);
1300 }
1301 #endif
1302 if( zRequestUri==0 ){
1303 const char *z = zPathInfo;
 
1304 if( zPathInfo==0 ){
1305 malformed_request("missing PATH_INFO and/or REQUEST_URI");
1306 }
1307 if( z[0]=='/' ) z++;
1308 zRequestUri = mprintf("%s/%s", zScriptName, z);
 
 
 
 
1309 cgi_set_parameter("REQUEST_URI", zRequestUri);
1310 }
1311 if( zPathInfo==0 ){
1312 int i, j;
1313 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
1362 }else{
1363 g.zContentType = zType;
1364 }
1365 blob_zero(&g.cgiIn);
1366 if( len>0 && zType ){
 
 
 
 
 
1367 if( fossil_strcmp(zType, "application/x-fossil")==0 ){
1368 if( blob_read_from_cgi(&g.cgiIn, len)!=len ){
1369 malformed_request("CGI content-length mismatch");
1370 }
1371 blob_uncompress(&g.cgiIn, &g.cgiIn);
1372 }
1373 #ifdef FOSSIL_ENABLE_JSON
1374 else if( noJson==0 && g.json.isJsonMode!=0
1375 && json_can_consume_content_type(zType)!=0 ){
1376 assert( !g.httpUseSSL );
1377 cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
1378 /*
1379 Potential TODOs:
1380
1381 1) If parsing fails, immediately return an error response
1382 without dispatching the ostensibly-upcoming JSON API.
1383 */
1384 cgi_set_content_type(json_guess_content_type());
1385 }
1386 #endif /* FOSSIL_ENABLE_JSON */
1387 else{
1388 blob_read_from_cgi(&g.cgiIn, len);
1389 }
1390 }
1391 }
1392
1393 /*
1394 ** Decode POST parameter information in the cgiIn content, if any.
1395
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return 0 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
@@ -1061,71 +1061,23 @@
1061 }
1062
1063
1064 #ifdef FOSSIL_ENABLE_JSON
1065 /*
1066 ** Reads a JSON object from the given blob, which is assumed to have
1067 ** been populated by the caller from stdin, the SSL API, or a file, as
1068 ** appropriate for the particular use case. On success g.json.post is
1069 ** updated to hold the content. On error a FSL_JSON_E_INVALID_REQUEST
1070 ** response is output and fossil_exit() is called (in HTTP mode exit
1071 ** code 0 is used).
1072 */
1073 void cgi_parse_POST_JSON( Blob * pIn ){
1074 cson_value * jv = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1075 cson_parse_info pinfo = cson_parse_info_empty;
1076 assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1077 jv = cson_parse_Blob(pIn, &pinfo);
1078 if( jv==NULL ){
 
 
 
 
 
 
1079 goto invalidRequest;
1080 }else{
1081 json_gc_add( "POST.JSON", jv );
1082 g.json.post.v = jv;
1083 g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
1092 char * msg = mprintf("JSON parse error at line %u, column %u, "
1093 "byte offset %u: %s",
1094 pinfo.line, pinfo.col, pinfo.length,
1095 cson_rc_string(pinfo.errorCode));
1096 json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1097 fossil_free(msg);
1098 }else if(jv && !g.json.post.o){
1099 json_err( FSL_JSON_E_INVALID_REQUEST,
1100 "Request envelope must be a JSON Object (not array).", 1 );
1101 }else{ /* generic error message */
1102 json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
1174 **
1175 ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
1176 **
1177 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO
1178 **
1179 ** Or if QUERY_STRING is not empty:
1180 **
1181 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING
1182 **
1183 ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
1184 ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
1185 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1186 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1187 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
1196 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1197 ** PATH_INFO when it is empty.
1198 **
1199 ** CGI Parameter quick reference:
1200 **
1201 ** REQUEST_URI
1202 ** _____________|________________
1203 ** / \
1204 ** https://fossil-scm.org/forum/info/12736b30c072551a?t=c
1205 ** \___/ \____________/\____/\____________________/ \_/
1206 ** | | | | |
1207 ** | HTTP_HOST | PATH_INFO QUERY_STRING
1208 ** | |
1209 ** REQUEST_SCHEMA SCRIPT_NAME
1210 **
1211 */
1212 void cgi_init(void){
1213 char *z;
1214 const char *zType;
1215 char *zSemi;
@@ -1270,20 +1228,18 @@
1228 cgi_destination(CGI_BODY);
1229
1230 /* We must have SCRIPT_NAME. If the web server did not supply it, try
1231 ** to compute it from REQUEST_URI and PATH_INFO. */
1232 if( zScriptName==0 ){
 
1233 if( zRequestUri==0 || zPathInfo==0 ){
1234 malformed_request("missing SCRIPT_NAME"); /* Does not return */
1235 }
1236 z = strstr(zRequestUri,zPathInfo);
1237 if( z==0 ){
1238 malformed_request("PATH_INFO not found in REQUEST_URI");
 
1239 }
1240 zScriptName = fossil_strndup(zRequestUri,(int)(z-zRequestUri));
1241 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1242 }
1243
1244 #ifdef _WIN32
1245 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
1255 cgi_replace_parameter("PATH_INFO", zPathInfo);
1256 }
1257 #endif
1258 if( zRequestUri==0 ){
1259 const char *z = zPathInfo;
1260 const char *zQS = cgi_parameter("QUERY_STRING",0);
1261 if( zPathInfo==0 ){
1262 malformed_request("missing PATH_INFO and/or REQUEST_URI");
1263 }
1264 if( z[0]=='/' ) z++;
1265 if( zQS && zQS[0] ){
1266 zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS);
1267 }else{
1268 zRequestUri = mprintf("%s/%s", zScriptName, z);
1269 }
1270 cgi_set_parameter("REQUEST_URI", zRequestUri);
1271 }
1272 if( zPathInfo==0 ){
1273 int i, j;
1274 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
1323 }else{
1324 g.zContentType = zType;
1325 }
1326 blob_zero(&g.cgiIn);
1327 if( len>0 && zType ){
1328 if( blob_read_from_cgi(&g.cgiIn, len)<len ){
1329 char *zMsg = mprintf("CGI content-length mismatch: Wanted %d bytes"
1330 " but got only %d\n", len, blob_size(&g.cgiIn));
1331 malformed_request(zMsg);
1332 }
1333 if( fossil_strcmp(zType, "application/x-fossil")==0 ){
 
 
 
1334 blob_uncompress(&g.cgiIn, &g.cgiIn);
1335 }
1336 #ifdef FOSSIL_ENABLE_JSON
1337 if( noJson==0 && g.json.isJsonMode!=0
1338 && json_can_consume_content_type(zType)!=0 ){
1339 cgi_parse_POST_JSON(&g.cgiIn);
 
 
 
 
 
 
 
1340 cgi_set_content_type(json_guess_content_type());
1341 }
1342 #endif /* FOSSIL_ENABLE_JSON */
 
 
 
1343 }
1344 }
1345
1346 /*
1347 ** Decode POST parameter information in the cgiIn content, if any.
1348
+125 -3
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484484
** needs to take care to inject them at the end of the history rather
485485
** than the same place new messages go.
486486
**
487487
** If "before" is provided, "name" is ignored.
488488
**
489
+** If "raw" is provided, the "xmsg" text is sent back as-is, in
490
+** markdown format, rather than being HTML-ized. This is not used or
491
+** supported by fossil's own chat client but is intended for 3rd-party
492
+** clients. (Specifically, for Brad Harder's curses-based client.)
493
+**
489494
** The reply from this webpage is JSON that describes the new content.
490495
** Format of the json:
491496
**
492497
** | {
493498
** | "msgs":[
@@ -543,10 +548,11 @@
543548
const int iDelay = 1000; /* Delay until next poll (milliseconds) */
544549
int nDelay; /* Maximum delay.*/
545550
int msgid = atoi(PD("name","0"));
546551
const int msgBefore = atoi(PD("before","0"));
547552
int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
553
+ const int bRaw = P("raw")!=0;
548554
Blob sql = empty_blob;
549555
Stmt q1;
550556
nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
551557
login_check_credentials();
552558
if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
620626
blob_appendf(&json, "null,");
621627
}
622628
blob_appendf(&json, "\"uclr\":%!j,",
623629
user_color(zFrom ? zFrom : "nobody"));
624630
625
- zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
626
- blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
627
- fossil_free(zMsg);
631
+ if(bRaw){
632
+ blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
633
+ }else{
634
+ zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
635
+ blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
636
+ fossil_free(zMsg);
637
+ }
628638
629639
if( nByte==0 ){
630640
blob_appendf(&json, "\"fsize\":0");
631641
}else{
632642
blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
806816
" VALUES(julianday('now'), %Q, %d);\n"
807817
"COMMIT;",
808818
mdel, g.zLogin, mdel
809819
);
810820
}
821
+
822
+/*
823
+** WEBPAGE: chat-backup hidden
824
+**
825
+** Download an SQLite database containing all chat content with a
826
+** message-id larger than the "msgid" query parameter. Setup
827
+** privilege is required to use this URL.
828
+**
829
+** This is used to implement the "fossil chat pull" command.
830
+*/
831
+void chat_backup_webpage(void){
832
+ int msgid;
833
+ unsigned char *pDb = 0;
834
+ sqlite3_int64 szDb = 0;
835
+ Blob chatDb;
836
+ login_check_credentials();
837
+ if( !g.perm.Setup ) return;
838
+ msgid = atoi(PD("msgid","0"));
839
+ db_multi_exec(
840
+ "ATTACH ':memory:' AS mem1;\n"
841
+ "PRAGMA mem1.page_size=512;\n"
842
+ "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
843
+ msgid
844
+ );
845
+ pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
846
+ if( pDb==0 ){
847
+ fossil_fatal("Out of memory");
848
+ }
849
+ blob_init(&chatDb, (const char*)pDb, (int)szDb);
850
+ cgi_set_content_type("application/x-sqlite3");
851
+ cgi_set_content(&chatDb);
852
+}
811853
812854
/*
813855
** COMMAND: chat
814856
**
815857
** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
829871
** the response is to bring up a web-browser window to the chatroom
830872
** on the default system web-browser. You can accomplish the same by
831873
** typing the appropriate URL into the web-browser yourself. This
832874
** command is merely a convenience for command-line oriented people.
833875
**
876
+** > fossil chat pull
877
+**
878
+** Copy chat content from the server down into the local clone,
879
+** as a backup or archive. Setup privilege is required on the server.
880
+**
881
+** --all Download all chat content. Normally only
882
+** previously undownloaded content is retrieved.
883
+** --debug Additional debugging output.
884
+** --out DATABASE Store CHAT table in separate database file
885
+** DATABASE rather that adding to local clone
886
+** --unsafe Allow the use of unencrypted http://
887
+**
834888
** > fossil chat send [ARGUMENTS]
835889
**
836890
** This command sends a new message to the chatroom. The message
837891
** to be sent is determined by arguments as follows:
838892
**
@@ -972,12 +1026,80 @@
9721026
fossil_print("ERROR: %s\n", blob_str(&down));
9731027
}
9741028
fossil_fatal("unable to send the chat message");
9751029
}
9761030
blob_reset(&down);
1031
+ }else if( strcmp(g.argv[2],"pull")==0 ){
1032
+ /* Pull the CHAT table from the default server down into the repository
1033
+ ** here on the local side */
1034
+ int allowUnsafe = find_option("unsafe",0,0)!=0;
1035
+ int bDebug = find_option("debug",0,0)!=0;
1036
+ const char *zOut = find_option("out",0,1);
1037
+ int bAll = find_option("all",0,0)!=0;
1038
+ int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1039
+ int msgid;
1040
+ Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1041
+ char *zObs;
1042
+ const char *zPw;
1043
+ Blob up, down;
1044
+ int nChat;
1045
+ int rc;
1046
+ verify_all_options();
1047
+ chat_create_tables();
1048
+ msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1049
+ if( !g.url.isHttps && !allowUnsafe ){
1050
+ fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1051
+ }
1052
+ blob_init(&reqUri, g.url.path, -1);
1053
+ blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1054
+ if( g.url.user && g.url.user[0] ){
1055
+ zObs = obscure(g.url.user);
1056
+ blob_appendf(&reqUri, "&resid=%t", zObs);
1057
+ fossil_free(zObs);
1058
+ }
1059
+ zPw = g.url.passwd;
1060
+ if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1061
+ if( zPw && zPw[0] ){
1062
+ zObs = obscure(zPw);
1063
+ blob_appendf(&reqUri, "&token=%t", zObs);
1064
+ fossil_free(zObs);
1065
+ }
1066
+ g.url.path = blob_str(&reqUri);
1067
+ if( bDebug ){
1068
+ fossil_print("REQUEST_URI: %s\n", g.url.path);
1069
+ mFlags &= ~HTTP_QUIET;
1070
+ mFlags |= HTTP_VERBOSE;
1071
+ }
1072
+ blob_init(&up, 0, 0);
1073
+ blob_init(&down, 0, 0);
1074
+ http_exchange(&up, &down, mFlags, 4, 0);
1075
+ if( zOut ){
1076
+ blob_write_to_file(&down, zOut);
1077
+ fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1078
+ }else{
1079
+ db_multi_exec("ATTACH ':memory:' AS chatbu;");
1080
+ if( g.fSqlTrace ){
1081
+ fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1082
+ blob_size(&down));
1083
+ }
1084
+ rc = sqlite3_deserialize(g.db, "chatbu",
1085
+ (unsigned char*)blob_buffer(&down),
1086
+ blob_size(&down), blob_size(&down), 0);
1087
+ if( rc ){
1088
+ fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1089
+ }
1090
+ nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1091
+ fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1092
+ db_multi_exec(
1093
+ "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1094
+ "fname,fmime,mdel,file)"
1095
+ " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1096
+ " FROM chatbu.chat;"
1097
+ );
1098
+ }
9771099
}else if( strcmp(g.argv[2],"url")==0 ){
9781100
/* Show the URL to access chat. */
9791101
fossil_print("%s/chat\n", zUrl);
9801102
}else{
9811103
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
9821104
}
9831105
}
9841106
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484 ** needs to take care to inject them at the end of the history rather
485 ** than the same place new messages go.
486 **
487 ** If "before" is provided, "name" is ignored.
488 **
 
 
 
 
 
489 ** The reply from this webpage is JSON that describes the new content.
490 ** Format of the json:
491 **
492 ** | {
493 ** | "msgs":[
@@ -543,10 +548,11 @@
543 const int iDelay = 1000; /* Delay until next poll (milliseconds) */
544 int nDelay; /* Maximum delay.*/
545 int msgid = atoi(PD("name","0"));
546 const int msgBefore = atoi(PD("before","0"));
547 int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
 
548 Blob sql = empty_blob;
549 Stmt q1;
550 nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
551 login_check_credentials();
552 if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
620 blob_appendf(&json, "null,");
621 }
622 blob_appendf(&json, "\"uclr\":%!j,",
623 user_color(zFrom ? zFrom : "nobody"));
624
625 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
626 blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
627 fossil_free(zMsg);
 
 
 
 
628
629 if( nByte==0 ){
630 blob_appendf(&json, "\"fsize\":0");
631 }else{
632 blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
806 " VALUES(julianday('now'), %Q, %d);\n"
807 "COMMIT;",
808 mdel, g.zLogin, mdel
809 );
810 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
812 /*
813 ** COMMAND: chat
814 **
815 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
829 ** the response is to bring up a web-browser window to the chatroom
830 ** on the default system web-browser. You can accomplish the same by
831 ** typing the appropriate URL into the web-browser yourself. This
832 ** command is merely a convenience for command-line oriented people.
833 **
 
 
 
 
 
 
 
 
 
 
 
 
834 ** > fossil chat send [ARGUMENTS]
835 **
836 ** This command sends a new message to the chatroom. The message
837 ** to be sent is determined by arguments as follows:
838 **
@@ -972,12 +1026,80 @@
972 fossil_print("ERROR: %s\n", blob_str(&down));
973 }
974 fossil_fatal("unable to send the chat message");
975 }
976 blob_reset(&down);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977 }else if( strcmp(g.argv[2],"url")==0 ){
978 /* Show the URL to access chat. */
979 fossil_print("%s/chat\n", zUrl);
980 }else{
981 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
982 }
983 }
984
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484 ** needs to take care to inject them at the end of the history rather
485 ** than the same place new messages go.
486 **
487 ** If "before" is provided, "name" is ignored.
488 **
489 ** If "raw" is provided, the "xmsg" text is sent back as-is, in
490 ** markdown format, rather than being HTML-ized. This is not used or
491 ** supported by fossil's own chat client but is intended for 3rd-party
492 ** clients. (Specifically, for Brad Harder's curses-based client.)
493 **
494 ** The reply from this webpage is JSON that describes the new content.
495 ** Format of the json:
496 **
497 ** | {
498 ** | "msgs":[
@@ -543,10 +548,11 @@
548 const int iDelay = 1000; /* Delay until next poll (milliseconds) */
549 int nDelay; /* Maximum delay.*/
550 int msgid = atoi(PD("name","0"));
551 const int msgBefore = atoi(PD("before","0"));
552 int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
553 const int bRaw = P("raw")!=0;
554 Blob sql = empty_blob;
555 Stmt q1;
556 nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
557 login_check_credentials();
558 if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
626 blob_appendf(&json, "null,");
627 }
628 blob_appendf(&json, "\"uclr\":%!j,",
629 user_color(zFrom ? zFrom : "nobody"));
630
631 if(bRaw){
632 blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
633 }else{
634 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
635 blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
636 fossil_free(zMsg);
637 }
638
639 if( nByte==0 ){
640 blob_appendf(&json, "\"fsize\":0");
641 }else{
642 blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
816 " VALUES(julianday('now'), %Q, %d);\n"
817 "COMMIT;",
818 mdel, g.zLogin, mdel
819 );
820 }
821
822 /*
823 ** WEBPAGE: chat-backup hidden
824 **
825 ** Download an SQLite database containing all chat content with a
826 ** message-id larger than the "msgid" query parameter. Setup
827 ** privilege is required to use this URL.
828 **
829 ** This is used to implement the "fossil chat pull" command.
830 */
831 void chat_backup_webpage(void){
832 int msgid;
833 unsigned char *pDb = 0;
834 sqlite3_int64 szDb = 0;
835 Blob chatDb;
836 login_check_credentials();
837 if( !g.perm.Setup ) return;
838 msgid = atoi(PD("msgid","0"));
839 db_multi_exec(
840 "ATTACH ':memory:' AS mem1;\n"
841 "PRAGMA mem1.page_size=512;\n"
842 "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
843 msgid
844 );
845 pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
846 if( pDb==0 ){
847 fossil_fatal("Out of memory");
848 }
849 blob_init(&chatDb, (const char*)pDb, (int)szDb);
850 cgi_set_content_type("application/x-sqlite3");
851 cgi_set_content(&chatDb);
852 }
853
854 /*
855 ** COMMAND: chat
856 **
857 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
871 ** the response is to bring up a web-browser window to the chatroom
872 ** on the default system web-browser. You can accomplish the same by
873 ** typing the appropriate URL into the web-browser yourself. This
874 ** command is merely a convenience for command-line oriented people.
875 **
876 ** > fossil chat pull
877 **
878 ** Copy chat content from the server down into the local clone,
879 ** as a backup or archive. Setup privilege is required on the server.
880 **
881 ** --all Download all chat content. Normally only
882 ** previously undownloaded content is retrieved.
883 ** --debug Additional debugging output.
884 ** --out DATABASE Store CHAT table in separate database file
885 ** DATABASE rather that adding to local clone
886 ** --unsafe Allow the use of unencrypted http://
887 **
888 ** > fossil chat send [ARGUMENTS]
889 **
890 ** This command sends a new message to the chatroom. The message
891 ** to be sent is determined by arguments as follows:
892 **
@@ -972,12 +1026,80 @@
1026 fossil_print("ERROR: %s\n", blob_str(&down));
1027 }
1028 fossil_fatal("unable to send the chat message");
1029 }
1030 blob_reset(&down);
1031 }else if( strcmp(g.argv[2],"pull")==0 ){
1032 /* Pull the CHAT table from the default server down into the repository
1033 ** here on the local side */
1034 int allowUnsafe = find_option("unsafe",0,0)!=0;
1035 int bDebug = find_option("debug",0,0)!=0;
1036 const char *zOut = find_option("out",0,1);
1037 int bAll = find_option("all",0,0)!=0;
1038 int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1039 int msgid;
1040 Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1041 char *zObs;
1042 const char *zPw;
1043 Blob up, down;
1044 int nChat;
1045 int rc;
1046 verify_all_options();
1047 chat_create_tables();
1048 msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1049 if( !g.url.isHttps && !allowUnsafe ){
1050 fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1051 }
1052 blob_init(&reqUri, g.url.path, -1);
1053 blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1054 if( g.url.user && g.url.user[0] ){
1055 zObs = obscure(g.url.user);
1056 blob_appendf(&reqUri, "&resid=%t", zObs);
1057 fossil_free(zObs);
1058 }
1059 zPw = g.url.passwd;
1060 if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1061 if( zPw && zPw[0] ){
1062 zObs = obscure(zPw);
1063 blob_appendf(&reqUri, "&token=%t", zObs);
1064 fossil_free(zObs);
1065 }
1066 g.url.path = blob_str(&reqUri);
1067 if( bDebug ){
1068 fossil_print("REQUEST_URI: %s\n", g.url.path);
1069 mFlags &= ~HTTP_QUIET;
1070 mFlags |= HTTP_VERBOSE;
1071 }
1072 blob_init(&up, 0, 0);
1073 blob_init(&down, 0, 0);
1074 http_exchange(&up, &down, mFlags, 4, 0);
1075 if( zOut ){
1076 blob_write_to_file(&down, zOut);
1077 fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1078 }else{
1079 db_multi_exec("ATTACH ':memory:' AS chatbu;");
1080 if( g.fSqlTrace ){
1081 fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1082 blob_size(&down));
1083 }
1084 rc = sqlite3_deserialize(g.db, "chatbu",
1085 (unsigned char*)blob_buffer(&down),
1086 blob_size(&down), blob_size(&down), 0);
1087 if( rc ){
1088 fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1089 }
1090 nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1091 fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1092 db_multi_exec(
1093 "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1094 "fname,fmime,mdel,file)"
1095 " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1096 " FROM chatbu.chat;"
1097 );
1098 }
1099 }else if( strcmp(g.argv[2],"url")==0 ){
1100 /* Show the URL to access chat. */
1101 fossil_print("%s/chat\n", zUrl);
1102 }else{
1103 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
1104 }
1105 }
1106
+125 -3
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484484
** needs to take care to inject them at the end of the history rather
485485
** than the same place new messages go.
486486
**
487487
** If "before" is provided, "name" is ignored.
488488
**
489
+** If "raw" is provided, the "xmsg" text is sent back as-is, in
490
+** markdown format, rather than being HTML-ized. This is not used or
491
+** supported by fossil's own chat client but is intended for 3rd-party
492
+** clients. (Specifically, for Brad Harder's curses-based client.)
493
+**
489494
** The reply from this webpage is JSON that describes the new content.
490495
** Format of the json:
491496
**
492497
** | {
493498
** | "msgs":[
@@ -543,10 +548,11 @@
543548
const int iDelay = 1000; /* Delay until next poll (milliseconds) */
544549
int nDelay; /* Maximum delay.*/
545550
int msgid = atoi(PD("name","0"));
546551
const int msgBefore = atoi(PD("before","0"));
547552
int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
553
+ const int bRaw = P("raw")!=0;
548554
Blob sql = empty_blob;
549555
Stmt q1;
550556
nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
551557
login_check_credentials();
552558
if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
620626
blob_appendf(&json, "null,");
621627
}
622628
blob_appendf(&json, "\"uclr\":%!j,",
623629
user_color(zFrom ? zFrom : "nobody"));
624630
625
- zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
626
- blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
627
- fossil_free(zMsg);
631
+ if(bRaw){
632
+ blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
633
+ }else{
634
+ zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
635
+ blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
636
+ fossil_free(zMsg);
637
+ }
628638
629639
if( nByte==0 ){
630640
blob_appendf(&json, "\"fsize\":0");
631641
}else{
632642
blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
806816
" VALUES(julianday('now'), %Q, %d);\n"
807817
"COMMIT;",
808818
mdel, g.zLogin, mdel
809819
);
810820
}
821
+
822
+/*
823
+** WEBPAGE: chat-backup hidden
824
+**
825
+** Download an SQLite database containing all chat content with a
826
+** message-id larger than the "msgid" query parameter. Setup
827
+** privilege is required to use this URL.
828
+**
829
+** This is used to implement the "fossil chat pull" command.
830
+*/
831
+void chat_backup_webpage(void){
832
+ int msgid;
833
+ unsigned char *pDb = 0;
834
+ sqlite3_int64 szDb = 0;
835
+ Blob chatDb;
836
+ login_check_credentials();
837
+ if( !g.perm.Setup ) return;
838
+ msgid = atoi(PD("msgid","0"));
839
+ db_multi_exec(
840
+ "ATTACH ':memory:' AS mem1;\n"
841
+ "PRAGMA mem1.page_size=512;\n"
842
+ "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
843
+ msgid
844
+ );
845
+ pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
846
+ if( pDb==0 ){
847
+ fossil_fatal("Out of memory");
848
+ }
849
+ blob_init(&chatDb, (const char*)pDb, (int)szDb);
850
+ cgi_set_content_type("application/x-sqlite3");
851
+ cgi_set_content(&chatDb);
852
+}
811853
812854
/*
813855
** COMMAND: chat
814856
**
815857
** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
829871
** the response is to bring up a web-browser window to the chatroom
830872
** on the default system web-browser. You can accomplish the same by
831873
** typing the appropriate URL into the web-browser yourself. This
832874
** command is merely a convenience for command-line oriented people.
833875
**
876
+** > fossil chat pull
877
+**
878
+** Copy chat content from the server down into the local clone,
879
+** as a backup or archive. Setup privilege is required on the server.
880
+**
881
+** --all Download all chat content. Normally only
882
+** previously undownloaded content is retrieved.
883
+** --debug Additional debugging output.
884
+** --out DATABASE Store CHAT table in separate database file
885
+** DATABASE rather that adding to local clone
886
+** --unsafe Allow the use of unencrypted http://
887
+**
834888
** > fossil chat send [ARGUMENTS]
835889
**
836890
** This command sends a new message to the chatroom. The message
837891
** to be sent is determined by arguments as follows:
838892
**
@@ -972,12 +1026,80 @@
9721026
fossil_print("ERROR: %s\n", blob_str(&down));
9731027
}
9741028
fossil_fatal("unable to send the chat message");
9751029
}
9761030
blob_reset(&down);
1031
+ }else if( strcmp(g.argv[2],"pull")==0 ){
1032
+ /* Pull the CHAT table from the default server down into the repository
1033
+ ** here on the local side */
1034
+ int allowUnsafe = find_option("unsafe",0,0)!=0;
1035
+ int bDebug = find_option("debug",0,0)!=0;
1036
+ const char *zOut = find_option("out",0,1);
1037
+ int bAll = find_option("all",0,0)!=0;
1038
+ int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1039
+ int msgid;
1040
+ Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1041
+ char *zObs;
1042
+ const char *zPw;
1043
+ Blob up, down;
1044
+ int nChat;
1045
+ int rc;
1046
+ verify_all_options();
1047
+ chat_create_tables();
1048
+ msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1049
+ if( !g.url.isHttps && !allowUnsafe ){
1050
+ fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1051
+ }
1052
+ blob_init(&reqUri, g.url.path, -1);
1053
+ blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1054
+ if( g.url.user && g.url.user[0] ){
1055
+ zObs = obscure(g.url.user);
1056
+ blob_appendf(&reqUri, "&resid=%t", zObs);
1057
+ fossil_free(zObs);
1058
+ }
1059
+ zPw = g.url.passwd;
1060
+ if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1061
+ if( zPw && zPw[0] ){
1062
+ zObs = obscure(zPw);
1063
+ blob_appendf(&reqUri, "&token=%t", zObs);
1064
+ fossil_free(zObs);
1065
+ }
1066
+ g.url.path = blob_str(&reqUri);
1067
+ if( bDebug ){
1068
+ fossil_print("REQUEST_URI: %s\n", g.url.path);
1069
+ mFlags &= ~HTTP_QUIET;
1070
+ mFlags |= HTTP_VERBOSE;
1071
+ }
1072
+ blob_init(&up, 0, 0);
1073
+ blob_init(&down, 0, 0);
1074
+ http_exchange(&up, &down, mFlags, 4, 0);
1075
+ if( zOut ){
1076
+ blob_write_to_file(&down, zOut);
1077
+ fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1078
+ }else{
1079
+ db_multi_exec("ATTACH ':memory:' AS chatbu;");
1080
+ if( g.fSqlTrace ){
1081
+ fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1082
+ blob_size(&down));
1083
+ }
1084
+ rc = sqlite3_deserialize(g.db, "chatbu",
1085
+ (unsigned char*)blob_buffer(&down),
1086
+ blob_size(&down), blob_size(&down), 0);
1087
+ if( rc ){
1088
+ fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1089
+ }
1090
+ nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1091
+ fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1092
+ db_multi_exec(
1093
+ "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1094
+ "fname,fmime,mdel,file)"
1095
+ " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1096
+ " FROM chatbu.chat;"
1097
+ );
1098
+ }
9771099
}else if( strcmp(g.argv[2],"url")==0 ){
9781100
/* Show the URL to access chat. */
9791101
fossil_print("%s/chat\n", zUrl);
9801102
}else{
9811103
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
9821104
}
9831105
}
9841106
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484 ** needs to take care to inject them at the end of the history rather
485 ** than the same place new messages go.
486 **
487 ** If "before" is provided, "name" is ignored.
488 **
 
 
 
 
 
489 ** The reply from this webpage is JSON that describes the new content.
490 ** Format of the json:
491 **
492 ** | {
493 ** | "msgs":[
@@ -543,10 +548,11 @@
543 const int iDelay = 1000; /* Delay until next poll (milliseconds) */
544 int nDelay; /* Maximum delay.*/
545 int msgid = atoi(PD("name","0"));
546 const int msgBefore = atoi(PD("before","0"));
547 int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
 
548 Blob sql = empty_blob;
549 Stmt q1;
550 nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
551 login_check_credentials();
552 if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
620 blob_appendf(&json, "null,");
621 }
622 blob_appendf(&json, "\"uclr\":%!j,",
623 user_color(zFrom ? zFrom : "nobody"));
624
625 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
626 blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
627 fossil_free(zMsg);
 
 
 
 
628
629 if( nByte==0 ){
630 blob_appendf(&json, "\"fsize\":0");
631 }else{
632 blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
806 " VALUES(julianday('now'), %Q, %d);\n"
807 "COMMIT;",
808 mdel, g.zLogin, mdel
809 );
810 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
812 /*
813 ** COMMAND: chat
814 **
815 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
829 ** the response is to bring up a web-browser window to the chatroom
830 ** on the default system web-browser. You can accomplish the same by
831 ** typing the appropriate URL into the web-browser yourself. This
832 ** command is merely a convenience for command-line oriented people.
833 **
 
 
 
 
 
 
 
 
 
 
 
 
834 ** > fossil chat send [ARGUMENTS]
835 **
836 ** This command sends a new message to the chatroom. The message
837 ** to be sent is determined by arguments as follows:
838 **
@@ -972,12 +1026,80 @@
972 fossil_print("ERROR: %s\n", blob_str(&down));
973 }
974 fossil_fatal("unable to send the chat message");
975 }
976 blob_reset(&down);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977 }else if( strcmp(g.argv[2],"url")==0 ){
978 /* Show the URL to access chat. */
979 fossil_print("%s/chat\n", zUrl);
980 }else{
981 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
982 }
983 }
984
--- src/chat.c
+++ src/chat.c
@@ -484,10 +484,15 @@
484 ** needs to take care to inject them at the end of the history rather
485 ** than the same place new messages go.
486 **
487 ** If "before" is provided, "name" is ignored.
488 **
489 ** If "raw" is provided, the "xmsg" text is sent back as-is, in
490 ** markdown format, rather than being HTML-ized. This is not used or
491 ** supported by fossil's own chat client but is intended for 3rd-party
492 ** clients. (Specifically, for Brad Harder's curses-based client.)
493 **
494 ** The reply from this webpage is JSON that describes the new content.
495 ** Format of the json:
496 **
497 ** | {
498 ** | "msgs":[
@@ -543,10 +548,11 @@
548 const int iDelay = 1000; /* Delay until next poll (milliseconds) */
549 int nDelay; /* Maximum delay.*/
550 int msgid = atoi(PD("name","0"));
551 const int msgBefore = atoi(PD("before","0"));
552 int nLimit = msgBefore>0 ? atoi(PD("n","0")) : 0;
553 const int bRaw = P("raw")!=0;
554 Blob sql = empty_blob;
555 Stmt q1;
556 nDelay = db_get_int("chat-poll-timeout",420); /* Default about 7 minutes */
557 login_check_credentials();
558 if( !g.perm.Chat ) {
@@ -620,13 +626,17 @@
626 blob_appendf(&json, "null,");
627 }
628 blob_appendf(&json, "\"uclr\":%!j,",
629 user_color(zFrom ? zFrom : "nobody"));
630
631 if(bRaw){
632 blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
633 }else{
634 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "");
635 blob_appendf(&json, "\"xmsg\":%!j,", zMsg);
636 fossil_free(zMsg);
637 }
638
639 if( nByte==0 ){
640 blob_appendf(&json, "\"fsize\":0");
641 }else{
642 blob_appendf(&json, "\"fsize\":%d,\"fname\":%!j,\"fmime\":%!j",
@@ -806,10 +816,42 @@
816 " VALUES(julianday('now'), %Q, %d);\n"
817 "COMMIT;",
818 mdel, g.zLogin, mdel
819 );
820 }
821
822 /*
823 ** WEBPAGE: chat-backup hidden
824 **
825 ** Download an SQLite database containing all chat content with a
826 ** message-id larger than the "msgid" query parameter. Setup
827 ** privilege is required to use this URL.
828 **
829 ** This is used to implement the "fossil chat pull" command.
830 */
831 void chat_backup_webpage(void){
832 int msgid;
833 unsigned char *pDb = 0;
834 sqlite3_int64 szDb = 0;
835 Blob chatDb;
836 login_check_credentials();
837 if( !g.perm.Setup ) return;
838 msgid = atoi(PD("msgid","0"));
839 db_multi_exec(
840 "ATTACH ':memory:' AS mem1;\n"
841 "PRAGMA mem1.page_size=512;\n"
842 "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
843 msgid
844 );
845 pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
846 if( pDb==0 ){
847 fossil_fatal("Out of memory");
848 }
849 blob_init(&chatDb, (const char*)pDb, (int)szDb);
850 cgi_set_content_type("application/x-sqlite3");
851 cgi_set_content(&chatDb);
852 }
853
854 /*
855 ** COMMAND: chat
856 **
857 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -829,10 +871,22 @@
871 ** the response is to bring up a web-browser window to the chatroom
872 ** on the default system web-browser. You can accomplish the same by
873 ** typing the appropriate URL into the web-browser yourself. This
874 ** command is merely a convenience for command-line oriented people.
875 **
876 ** > fossil chat pull
877 **
878 ** Copy chat content from the server down into the local clone,
879 ** as a backup or archive. Setup privilege is required on the server.
880 **
881 ** --all Download all chat content. Normally only
882 ** previously undownloaded content is retrieved.
883 ** --debug Additional debugging output.
884 ** --out DATABASE Store CHAT table in separate database file
885 ** DATABASE rather that adding to local clone
886 ** --unsafe Allow the use of unencrypted http://
887 **
888 ** > fossil chat send [ARGUMENTS]
889 **
890 ** This command sends a new message to the chatroom. The message
891 ** to be sent is determined by arguments as follows:
892 **
@@ -972,12 +1026,80 @@
1026 fossil_print("ERROR: %s\n", blob_str(&down));
1027 }
1028 fossil_fatal("unable to send the chat message");
1029 }
1030 blob_reset(&down);
1031 }else if( strcmp(g.argv[2],"pull")==0 ){
1032 /* Pull the CHAT table from the default server down into the repository
1033 ** here on the local side */
1034 int allowUnsafe = find_option("unsafe",0,0)!=0;
1035 int bDebug = find_option("debug",0,0)!=0;
1036 const char *zOut = find_option("out",0,1);
1037 int bAll = find_option("all",0,0)!=0;
1038 int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1039 int msgid;
1040 Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1041 char *zObs;
1042 const char *zPw;
1043 Blob up, down;
1044 int nChat;
1045 int rc;
1046 verify_all_options();
1047 chat_create_tables();
1048 msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1049 if( !g.url.isHttps && !allowUnsafe ){
1050 fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1051 }
1052 blob_init(&reqUri, g.url.path, -1);
1053 blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1054 if( g.url.user && g.url.user[0] ){
1055 zObs = obscure(g.url.user);
1056 blob_appendf(&reqUri, "&resid=%t", zObs);
1057 fossil_free(zObs);
1058 }
1059 zPw = g.url.passwd;
1060 if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1061 if( zPw && zPw[0] ){
1062 zObs = obscure(zPw);
1063 blob_appendf(&reqUri, "&token=%t", zObs);
1064 fossil_free(zObs);
1065 }
1066 g.url.path = blob_str(&reqUri);
1067 if( bDebug ){
1068 fossil_print("REQUEST_URI: %s\n", g.url.path);
1069 mFlags &= ~HTTP_QUIET;
1070 mFlags |= HTTP_VERBOSE;
1071 }
1072 blob_init(&up, 0, 0);
1073 blob_init(&down, 0, 0);
1074 http_exchange(&up, &down, mFlags, 4, 0);
1075 if( zOut ){
1076 blob_write_to_file(&down, zOut);
1077 fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1078 }else{
1079 db_multi_exec("ATTACH ':memory:' AS chatbu;");
1080 if( g.fSqlTrace ){
1081 fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1082 blob_size(&down));
1083 }
1084 rc = sqlite3_deserialize(g.db, "chatbu",
1085 (unsigned char*)blob_buffer(&down),
1086 blob_size(&down), blob_size(&down), 0);
1087 if( rc ){
1088 fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1089 }
1090 nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1091 fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1092 db_multi_exec(
1093 "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1094 "fname,fmime,mdel,file)"
1095 " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1096 " FROM chatbu.chat;"
1097 );
1098 }
1099 }else if( strcmp(g.argv[2],"url")==0 ){
1100 /* Show the URL to access chat. */
1101 fossil_print("%s/chat\n", zUrl);
1102 }else{
1103 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
1104 }
1105 }
1106
+3 -4
--- src/configure.c
+++ src/configure.c
@@ -723,12 +723,11 @@
723723
/*
724724
** COMMAND: configuration*
725725
**
726726
** Usage: %fossil configuration METHOD ... ?OPTIONS?
727727
**
728
-** Where METHOD is one of: export import merge pull push reset. All methods
729
-** accept the -R or --repository option to specify a repository.
728
+** Where METHOD is one of: export import merge pull push reset.
730729
**
731730
** > fossil configuration export AREA FILENAME
732731
**
733732
** Write to FILENAME exported configuration information for AREA.
734733
** AREA can be one of:
@@ -769,11 +768,11 @@
769768
**
770769
** Synchronize configuration changes in the local repository with
771770
** the remote repository at URL.
772771
**
773772
** Options:
774
-** -R|--repository REPO Extract info from repository REPO
773
+** -R|--repository REPO Affect repository REPO with changes
775774
**
776775
** See also: [[settings]], [[unset]]
777776
*/
778777
void configuration_cmd(void){
779778
int n;
@@ -837,11 +836,11 @@
837836
}
838837
mask = configure_name_to_mask(g.argv[3], 1);
839838
if( g.argc==5 ){
840839
zServer = g.argv[4];
841840
}
842
- url_parse(zServer, URL_PROMPT_PW);
841
+ url_parse(zServer, URL_PROMPT_PW|URL_USE_CONFIG);
843842
if( g.url.protocol==0 ) fossil_fatal("no server URL specified");
844843
user_select();
845844
url_enable_proxy("via proxy: ");
846845
if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
847846
if( strncmp(zMethod, "push", n)==0 ){
848847
--- src/configure.c
+++ src/configure.c
@@ -723,12 +723,11 @@
723 /*
724 ** COMMAND: configuration*
725 **
726 ** Usage: %fossil configuration METHOD ... ?OPTIONS?
727 **
728 ** Where METHOD is one of: export import merge pull push reset. All methods
729 ** accept the -R or --repository option to specify a repository.
730 **
731 ** > fossil configuration export AREA FILENAME
732 **
733 ** Write to FILENAME exported configuration information for AREA.
734 ** AREA can be one of:
@@ -769,11 +768,11 @@
769 **
770 ** Synchronize configuration changes in the local repository with
771 ** the remote repository at URL.
772 **
773 ** Options:
774 ** -R|--repository REPO Extract info from repository REPO
775 **
776 ** See also: [[settings]], [[unset]]
777 */
778 void configuration_cmd(void){
779 int n;
@@ -837,11 +836,11 @@
837 }
838 mask = configure_name_to_mask(g.argv[3], 1);
839 if( g.argc==5 ){
840 zServer = g.argv[4];
841 }
842 url_parse(zServer, URL_PROMPT_PW);
843 if( g.url.protocol==0 ) fossil_fatal("no server URL specified");
844 user_select();
845 url_enable_proxy("via proxy: ");
846 if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
847 if( strncmp(zMethod, "push", n)==0 ){
848
--- src/configure.c
+++ src/configure.c
@@ -723,12 +723,11 @@
723 /*
724 ** COMMAND: configuration*
725 **
726 ** Usage: %fossil configuration METHOD ... ?OPTIONS?
727 **
728 ** Where METHOD is one of: export import merge pull push reset.
 
729 **
730 ** > fossil configuration export AREA FILENAME
731 **
732 ** Write to FILENAME exported configuration information for AREA.
733 ** AREA can be one of:
@@ -769,11 +768,11 @@
768 **
769 ** Synchronize configuration changes in the local repository with
770 ** the remote repository at URL.
771 **
772 ** Options:
773 ** -R|--repository REPO Affect repository REPO with changes
774 **
775 ** See also: [[settings]], [[unset]]
776 */
777 void configuration_cmd(void){
778 int n;
@@ -837,11 +836,11 @@
836 }
837 mask = configure_name_to_mask(g.argv[3], 1);
838 if( g.argc==5 ){
839 zServer = g.argv[4];
840 }
841 url_parse(zServer, URL_PROMPT_PW|URL_USE_CONFIG);
842 if( g.url.protocol==0 ) fossil_fatal("no server URL specified");
843 user_select();
844 url_enable_proxy("via proxy: ");
845 if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
846 if( strncmp(zMethod, "push", n)==0 ){
847
+105 -33
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
13761376
return;
13771377
}
13781378
zSetting = (const char*)sqlite3_value_text(argv[0]);
13791379
sqlite3_result_int(context, db_setting_is_protected(zSetting));
13801380
}
1381
+
1382
+/*
1383
+** Copied from SQLite ext/misc/uint.c...
1384
+**
1385
+** Compare text in lexicographic order, except strings of digits
1386
+** compare in numeric order.
1387
+**
1388
+** This version modified to also ignore case.
1389
+*/
1390
+static int uintNocaseCollFunc(
1391
+ void *notUsed,
1392
+ int nKey1, const void *pKey1,
1393
+ int nKey2, const void *pKey2
1394
+){
1395
+ const unsigned char *zA = (const unsigned char*)pKey1;
1396
+ const unsigned char *zB = (const unsigned char*)pKey2;
1397
+ int i=0, j=0, x;
1398
+ (void)notUsed;
1399
+ while( i<nKey1 && j<nKey2 ){
1400
+ if( fossil_isdigit(zA[i]) && fossil_isdigit(zB[j]) ){
1401
+ int k;
1402
+ while( i<nKey1 && zA[i]=='0' ){ i++; }
1403
+ while( j<nKey2 && zB[j]=='0' ){ j++; }
1404
+ k = 0;
1405
+ while( i+k<nKey1 && fossil_isdigit(zA[i+k])
1406
+ && j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1407
+ k++;
1408
+ }
1409
+ if( i+k<nKey1 && fossil_isdigit(zA[i+k]) ){
1410
+ return +1;
1411
+ }else if( j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1412
+ return -1;
1413
+ }else{
1414
+ x = memcmp(zA+i, zB+j, k);
1415
+ if( x ) return x;
1416
+ i += k;
1417
+ j += k;
1418
+ }
1419
+ }else
1420
+ if( zA[i]!=zB[j]
1421
+ && (x = fossil_tolower(zA[i]) - fossil_tolower(zB[j]))!=0
1422
+ ){
1423
+ return x;
1424
+ }else{
1425
+ i++;
1426
+ j++;
1427
+ }
1428
+ }
1429
+ return (nKey1 - i) - (nKey2 - j);
1430
+}
1431
+
13811432
13821433
/*
13831434
** Register the SQL functions that are useful both to the internal
13841435
** representation and to the "fossil sql" command.
13851436
*/
13861437
void db_add_aux_functions(sqlite3 *db){
1438
+ sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
13871439
sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
13881440
db_checkin_mtime_function, 0, 0);
13891441
sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
13901442
db_sym2rid_function, 0, 0);
13911443
sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
16351687
** connection. An error results in process abort.
16361688
*/
16371689
LOCAL sqlite3 *db_open(const char *zDbName){
16381690
int rc;
16391691
sqlite3 *db;
1692
+ Blob bNameCheck = BLOB_INITIALIZER;
16401693
16411694
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1642
- if( strcmp(zDbName, g.nameOfExe)==0 ){
1695
+ file_canonical_name(zDbName, &bNameCheck, 0)
1696
+ /* For purposes of the apndvfs check, g.nameOfExe and zDbName must
1697
+ ** both be canonicalized, else chances are very good that they
1698
+ ** will not match even if they're the same file. Details:
1699
+ ** https://fossil-scm.org/forum/forumpost/16880a28aad1a868 */;
1700
+ if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
16431701
extern int sqlite3_appendvfs_init(
16441702
sqlite3 *, char **, const sqlite3_api_routines *
16451703
);
16461704
sqlite3_appendvfs_init(0,0,0);
16471705
g.zVfsName = "apndvfs";
16481706
}
1707
+ blob_zero(&bNameCheck);
16491708
rc = sqlite3_open_v2(
16501709
zDbName, &db,
16511710
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
16521711
g.zVfsName
16531712
);
@@ -2140,13 +2199,13 @@
21402199
int res = 0;
21412200
sqlite3_stmt *pStmt = 0;
21422201
21432202
sz = file_size(zDbName, ExtFILE);
21442203
if( sz<16834 ) return 0;
2145
- if( sz & 0x1ff ) return 0;
2146
- rc = sqlite3_open(zDbName, &db);
2147
- if( rc ) goto is_repo_end;
2204
+ db = db_open(zDbName);
2205
+ if( !db ) return 0;
2206
+ if( !g.zVfsName && sz%512 ) return 0;
21482207
rc = sqlite3_prepare_v2(db,
21492208
"SELECT count(*) FROM sqlite_schema"
21502209
" WHERE name COLLATE nocase IN"
21512210
"('blob','delta','rcvfrom','user','config','mlink','plink');",
21522211
-1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
21792238
/*
21802239
** Open the repository database given by zDbName. If zDbName==NULL then
21812240
** get the name from the already open local database.
21822241
*/
21832242
void db_open_repository(const char *zDbName){
2184
- i64 sz;
21852243
if( g.repositoryOpen ) return;
21862244
if( zDbName==0 ){
21872245
if( g.localOpen ){
21882246
zDbName = db_repository_filename();
21892247
}
21902248
if( zDbName==0 ){
21912249
db_err("unable to find the name of a repository database");
21922250
}
21932251
}
2194
- if( file_access(zDbName, R_OK)
2195
- || (sz = file_size(zDbName, ExtFILE))<16384
2196
- || (sz&0x1ff)!=0
2197
- ){
2252
+ if( !db_looks_like_a_repository(zDbName) ){
21982253
if( file_access(zDbName, F_OK) ){
21992254
#ifdef FOSSIL_ENABLE_JSON
22002255
g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
22012256
#endif
22022257
fossil_fatal("repository does not exist or"
@@ -3869,15 +3924,48 @@
38693924
** If enabled, the /login page provides a button that will automatically
38703925
** fill in the captcha password. This makes things easier for human users,
38713926
** at the expense of also making logins easier for malicious robots.
38723927
*/
38733928
/*
3874
-** SETTING: auto-hyperlink boolean default=on
3875
-** Use javascript to enable hyperlinks on web pages
3876
-** for all users (regardless of the "h" privilege) if the
3877
-** User-Agent string in the HTTP header look like it came
3878
-** from real person, not a spider or bot.
3929
+** SETTING: auto-hyperlink width=16 default=1
3930
+**
3931
+** If non-zero, enable hyperlinks on web pages even for users that lack
3932
+** the "h" privilege as long as the UserAgent string in the HTTP request
3933
+** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and
3934
+** not a robot. Details depend on the value of the setting.
3935
+**
3936
+** (0) Off: No adjustments are made to the 'h' privilege based on
3937
+** the user agent.
3938
+**
3939
+** (1) UserAgent and Javascript: The the href= values of hyperlinks
3940
+** initially point to /honeypot and are changed to point to the
3941
+** correct target by javascript that runs after the page loads.
3942
+** The auto-hyperlink-delay and auto-hyperlink-mouseover settings
3943
+** influence that javascript.
3944
+**
3945
+** (2) UserAgent only: If the HTTP_USER_AGENT looks human
3946
+** then generate hyperlinks, otherwise do not.
3947
+**
3948
+** Better robot exclusion is obtained when this setting is 1 versus 2.
3949
+** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3950
+** to stop working on Safari-derived web browsers. When this setting is 2,
3951
+** the hyperlinks work better on Safari, but more robots are able to sneak
3952
+** in.
3953
+*/
3954
+/* SETTING: auto-hyperlink-delay width=16 default=0
3955
+**
3956
+** When the auto-hyperlink setting is 1, the javascript that runs to set
3957
+** the href= attributes of hyperlinks delays by this many milliseconds
3958
+** after the page load. Suggested values: 50 to 200.
3959
+*/
3960
+/* Setting: auto-hyperlink-mouseover boolean default=off
3961
+**
3962
+** When the auto-hyperlink setting is 1 and this setting is on, the
3963
+** javascript that runs to set the href= attributes of hyperlinks waits
3964
+** until either a mousedown or mousemove event is seen. This helps
3965
+** to distinguish real users from robots. For maximum robot defense,
3966
+** the recommended setting is ON.
38793967
*/
38803968
/*
38813969
** SETTING: auto-shun boolean default=on
38823970
** If enabled, automatically pull the shunning list
38833971
** from a server to which the client autosyncs.
@@ -4291,24 +4379,13 @@
42914379
** OpenSSL CAs. If unset, the default list will be used.
42924380
** Some platforms may add additional certificates.
42934381
** Checking your platform behaviour is required if the
42944382
** exact contents of the CA root is critical for your
42954383
** application.
4296
-*/
4297
-/*
4298
-** SETTING: ssl-cert width=40 block-text sensitive
4299
-** The text of SSL server certificate and private key used by commands
4300
-** like "fossil server". The text should be in the PEM format. Use
4301
-** the "fossil ssl-config load-certs" command to change this setting.
4302
-*/
4303
-/*
4304
-** SETTING: ssl-cert-file width=40 sensitive
4305
-** The name of a file that contains the SSL server certificate, or
4306
-** optionally the concatenation of the certificate and private key,
4307
-** for use by Fossil when it is acting as a server. If this file
4308
-** contains only the certificate, then the ssl-key-file setting must
4309
-** contain the name of a file containing the private key.
4384
+**
4385
+** This setting is overridden by environment variables
4386
+** SSL_CERT_FILE and SSL_CERT_DIR.
43104387
*/
43114388
/*
43124389
** SETTING: ssl-identity width=40 sensitive
43134390
** The full pathname to a file containing a certificate
43144391
** and private key in PEM format. Create by concatenating
@@ -4316,15 +4393,10 @@
43164393
**
43174394
** This identity will be presented to SSL servers to
43184395
** authenticate this client, in addition to the normal
43194396
** password authentication.
43204397
*/
4321
-/*
4322
-** SETTING: ssl-key-file width=40 sensitive
4323
-** The name of a file that contains the SSL server certificate private
4324
-** key. Used in combination with "ssl-cert-file".
4325
-*/
43264398
#ifdef FOSSIL_ENABLE_TCL
43274399
/*
43284400
** SETTING: tcl boolean default=off sensitive
43294401
** If enabled Tcl integration commands will be added to the TH1
43304402
** interpreter, allowing arbitrary Tcl expressions and
43314403
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
1376 return;
1377 }
1378 zSetting = (const char*)sqlite3_value_text(argv[0]);
1379 sqlite3_result_int(context, db_setting_is_protected(zSetting));
1380 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1381
1382 /*
1383 ** Register the SQL functions that are useful both to the internal
1384 ** representation and to the "fossil sql" command.
1385 */
1386 void db_add_aux_functions(sqlite3 *db){
 
1387 sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
1388 db_checkin_mtime_function, 0, 0);
1389 sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
1390 db_sym2rid_function, 0, 0);
1391 sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
1635 ** connection. An error results in process abort.
1636 */
1637 LOCAL sqlite3 *db_open(const char *zDbName){
1638 int rc;
1639 sqlite3 *db;
 
1640
1641 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1642 if( strcmp(zDbName, g.nameOfExe)==0 ){
 
 
 
 
 
1643 extern int sqlite3_appendvfs_init(
1644 sqlite3 *, char **, const sqlite3_api_routines *
1645 );
1646 sqlite3_appendvfs_init(0,0,0);
1647 g.zVfsName = "apndvfs";
1648 }
 
1649 rc = sqlite3_open_v2(
1650 zDbName, &db,
1651 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1652 g.zVfsName
1653 );
@@ -2140,13 +2199,13 @@
2140 int res = 0;
2141 sqlite3_stmt *pStmt = 0;
2142
2143 sz = file_size(zDbName, ExtFILE);
2144 if( sz<16834 ) return 0;
2145 if( sz & 0x1ff ) return 0;
2146 rc = sqlite3_open(zDbName, &db);
2147 if( rc ) goto is_repo_end;
2148 rc = sqlite3_prepare_v2(db,
2149 "SELECT count(*) FROM sqlite_schema"
2150 " WHERE name COLLATE nocase IN"
2151 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2152 -1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
2179 /*
2180 ** Open the repository database given by zDbName. If zDbName==NULL then
2181 ** get the name from the already open local database.
2182 */
2183 void db_open_repository(const char *zDbName){
2184 i64 sz;
2185 if( g.repositoryOpen ) return;
2186 if( zDbName==0 ){
2187 if( g.localOpen ){
2188 zDbName = db_repository_filename();
2189 }
2190 if( zDbName==0 ){
2191 db_err("unable to find the name of a repository database");
2192 }
2193 }
2194 if( file_access(zDbName, R_OK)
2195 || (sz = file_size(zDbName, ExtFILE))<16384
2196 || (sz&0x1ff)!=0
2197 ){
2198 if( file_access(zDbName, F_OK) ){
2199 #ifdef FOSSIL_ENABLE_JSON
2200 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2201 #endif
2202 fossil_fatal("repository does not exist or"
@@ -3869,15 +3924,48 @@
3869 ** If enabled, the /login page provides a button that will automatically
3870 ** fill in the captcha password. This makes things easier for human users,
3871 ** at the expense of also making logins easier for malicious robots.
3872 */
3873 /*
3874 ** SETTING: auto-hyperlink boolean default=on
3875 ** Use javascript to enable hyperlinks on web pages
3876 ** for all users (regardless of the "h" privilege) if the
3877 ** User-Agent string in the HTTP header look like it came
3878 ** from real person, not a spider or bot.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3879 */
3880 /*
3881 ** SETTING: auto-shun boolean default=on
3882 ** If enabled, automatically pull the shunning list
3883 ** from a server to which the client autosyncs.
@@ -4291,24 +4379,13 @@
4291 ** OpenSSL CAs. If unset, the default list will be used.
4292 ** Some platforms may add additional certificates.
4293 ** Checking your platform behaviour is required if the
4294 ** exact contents of the CA root is critical for your
4295 ** application.
4296 */
4297 /*
4298 ** SETTING: ssl-cert width=40 block-text sensitive
4299 ** The text of SSL server certificate and private key used by commands
4300 ** like "fossil server". The text should be in the PEM format. Use
4301 ** the "fossil ssl-config load-certs" command to change this setting.
4302 */
4303 /*
4304 ** SETTING: ssl-cert-file width=40 sensitive
4305 ** The name of a file that contains the SSL server certificate, or
4306 ** optionally the concatenation of the certificate and private key,
4307 ** for use by Fossil when it is acting as a server. If this file
4308 ** contains only the certificate, then the ssl-key-file setting must
4309 ** contain the name of a file containing the private key.
4310 */
4311 /*
4312 ** SETTING: ssl-identity width=40 sensitive
4313 ** The full pathname to a file containing a certificate
4314 ** and private key in PEM format. Create by concatenating
@@ -4316,15 +4393,10 @@
4316 **
4317 ** This identity will be presented to SSL servers to
4318 ** authenticate this client, in addition to the normal
4319 ** password authentication.
4320 */
4321 /*
4322 ** SETTING: ssl-key-file width=40 sensitive
4323 ** The name of a file that contains the SSL server certificate private
4324 ** key. Used in combination with "ssl-cert-file".
4325 */
4326 #ifdef FOSSIL_ENABLE_TCL
4327 /*
4328 ** SETTING: tcl boolean default=off sensitive
4329 ** If enabled Tcl integration commands will be added to the TH1
4330 ** interpreter, allowing arbitrary Tcl expressions and
4331
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
1376 return;
1377 }
1378 zSetting = (const char*)sqlite3_value_text(argv[0]);
1379 sqlite3_result_int(context, db_setting_is_protected(zSetting));
1380 }
1381
1382 /*
1383 ** Copied from SQLite ext/misc/uint.c...
1384 **
1385 ** Compare text in lexicographic order, except strings of digits
1386 ** compare in numeric order.
1387 **
1388 ** This version modified to also ignore case.
1389 */
1390 static int uintNocaseCollFunc(
1391 void *notUsed,
1392 int nKey1, const void *pKey1,
1393 int nKey2, const void *pKey2
1394 ){
1395 const unsigned char *zA = (const unsigned char*)pKey1;
1396 const unsigned char *zB = (const unsigned char*)pKey2;
1397 int i=0, j=0, x;
1398 (void)notUsed;
1399 while( i<nKey1 && j<nKey2 ){
1400 if( fossil_isdigit(zA[i]) && fossil_isdigit(zB[j]) ){
1401 int k;
1402 while( i<nKey1 && zA[i]=='0' ){ i++; }
1403 while( j<nKey2 && zB[j]=='0' ){ j++; }
1404 k = 0;
1405 while( i+k<nKey1 && fossil_isdigit(zA[i+k])
1406 && j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1407 k++;
1408 }
1409 if( i+k<nKey1 && fossil_isdigit(zA[i+k]) ){
1410 return +1;
1411 }else if( j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1412 return -1;
1413 }else{
1414 x = memcmp(zA+i, zB+j, k);
1415 if( x ) return x;
1416 i += k;
1417 j += k;
1418 }
1419 }else
1420 if( zA[i]!=zB[j]
1421 && (x = fossil_tolower(zA[i]) - fossil_tolower(zB[j]))!=0
1422 ){
1423 return x;
1424 }else{
1425 i++;
1426 j++;
1427 }
1428 }
1429 return (nKey1 - i) - (nKey2 - j);
1430 }
1431
1432
1433 /*
1434 ** Register the SQL functions that are useful both to the internal
1435 ** representation and to the "fossil sql" command.
1436 */
1437 void db_add_aux_functions(sqlite3 *db){
1438 sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
1439 sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
1440 db_checkin_mtime_function, 0, 0);
1441 sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
1442 db_sym2rid_function, 0, 0);
1443 sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
1687 ** connection. An error results in process abort.
1688 */
1689 LOCAL sqlite3 *db_open(const char *zDbName){
1690 int rc;
1691 sqlite3 *db;
1692 Blob bNameCheck = BLOB_INITIALIZER;
1693
1694 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1695 file_canonical_name(zDbName, &bNameCheck, 0)
1696 /* For purposes of the apndvfs check, g.nameOfExe and zDbName must
1697 ** both be canonicalized, else chances are very good that they
1698 ** will not match even if they're the same file. Details:
1699 ** https://fossil-scm.org/forum/forumpost/16880a28aad1a868 */;
1700 if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
1701 extern int sqlite3_appendvfs_init(
1702 sqlite3 *, char **, const sqlite3_api_routines *
1703 );
1704 sqlite3_appendvfs_init(0,0,0);
1705 g.zVfsName = "apndvfs";
1706 }
1707 blob_zero(&bNameCheck);
1708 rc = sqlite3_open_v2(
1709 zDbName, &db,
1710 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1711 g.zVfsName
1712 );
@@ -2140,13 +2199,13 @@
2199 int res = 0;
2200 sqlite3_stmt *pStmt = 0;
2201
2202 sz = file_size(zDbName, ExtFILE);
2203 if( sz<16834 ) return 0;
2204 db = db_open(zDbName);
2205 if( !db ) return 0;
2206 if( !g.zVfsName && sz%512 ) return 0;
2207 rc = sqlite3_prepare_v2(db,
2208 "SELECT count(*) FROM sqlite_schema"
2209 " WHERE name COLLATE nocase IN"
2210 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2211 -1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
2238 /*
2239 ** Open the repository database given by zDbName. If zDbName==NULL then
2240 ** get the name from the already open local database.
2241 */
2242 void db_open_repository(const char *zDbName){
 
2243 if( g.repositoryOpen ) return;
2244 if( zDbName==0 ){
2245 if( g.localOpen ){
2246 zDbName = db_repository_filename();
2247 }
2248 if( zDbName==0 ){
2249 db_err("unable to find the name of a repository database");
2250 }
2251 }
2252 if( !db_looks_like_a_repository(zDbName) ){
 
 
 
2253 if( file_access(zDbName, F_OK) ){
2254 #ifdef FOSSIL_ENABLE_JSON
2255 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2256 #endif
2257 fossil_fatal("repository does not exist or"
@@ -3869,15 +3924,48 @@
3924 ** If enabled, the /login page provides a button that will automatically
3925 ** fill in the captcha password. This makes things easier for human users,
3926 ** at the expense of also making logins easier for malicious robots.
3927 */
3928 /*
3929 ** SETTING: auto-hyperlink width=16 default=1
3930 **
3931 ** If non-zero, enable hyperlinks on web pages even for users that lack
3932 ** the "h" privilege as long as the UserAgent string in the HTTP request
3933 ** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and
3934 ** not a robot. Details depend on the value of the setting.
3935 **
3936 ** (0) Off: No adjustments are made to the 'h' privilege based on
3937 ** the user agent.
3938 **
3939 ** (1) UserAgent and Javascript: The the href= values of hyperlinks
3940 ** initially point to /honeypot and are changed to point to the
3941 ** correct target by javascript that runs after the page loads.
3942 ** The auto-hyperlink-delay and auto-hyperlink-mouseover settings
3943 ** influence that javascript.
3944 **
3945 ** (2) UserAgent only: If the HTTP_USER_AGENT looks human
3946 ** then generate hyperlinks, otherwise do not.
3947 **
3948 ** Better robot exclusion is obtained when this setting is 1 versus 2.
3949 ** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3950 ** to stop working on Safari-derived web browsers. When this setting is 2,
3951 ** the hyperlinks work better on Safari, but more robots are able to sneak
3952 ** in.
3953 */
3954 /* SETTING: auto-hyperlink-delay width=16 default=0
3955 **
3956 ** When the auto-hyperlink setting is 1, the javascript that runs to set
3957 ** the href= attributes of hyperlinks delays by this many milliseconds
3958 ** after the page load. Suggested values: 50 to 200.
3959 */
3960 /* Setting: auto-hyperlink-mouseover boolean default=off
3961 **
3962 ** When the auto-hyperlink setting is 1 and this setting is on, the
3963 ** javascript that runs to set the href= attributes of hyperlinks waits
3964 ** until either a mousedown or mousemove event is seen. This helps
3965 ** to distinguish real users from robots. For maximum robot defense,
3966 ** the recommended setting is ON.
3967 */
3968 /*
3969 ** SETTING: auto-shun boolean default=on
3970 ** If enabled, automatically pull the shunning list
3971 ** from a server to which the client autosyncs.
@@ -4291,24 +4379,13 @@
4379 ** OpenSSL CAs. If unset, the default list will be used.
4380 ** Some platforms may add additional certificates.
4381 ** Checking your platform behaviour is required if the
4382 ** exact contents of the CA root is critical for your
4383 ** application.
4384 **
4385 ** This setting is overridden by environment variables
4386 ** SSL_CERT_FILE and SSL_CERT_DIR.
 
 
 
 
 
 
 
 
 
 
 
4387 */
4388 /*
4389 ** SETTING: ssl-identity width=40 sensitive
4390 ** The full pathname to a file containing a certificate
4391 ** and private key in PEM format. Create by concatenating
@@ -4316,15 +4393,10 @@
4393 **
4394 ** This identity will be presented to SSL servers to
4395 ** authenticate this client, in addition to the normal
4396 ** password authentication.
4397 */
 
 
 
 
 
4398 #ifdef FOSSIL_ENABLE_TCL
4399 /*
4400 ** SETTING: tcl boolean default=off sensitive
4401 ** If enabled Tcl integration commands will be added to the TH1
4402 ** interpreter, allowing arbitrary Tcl expressions and
4403
+381 -86
--- src/diff.c
+++ src/diff.c
@@ -121,12 +121,13 @@
121121
*/
122122
typedef struct DLine DLine;
123123
struct DLine {
124124
const char *z; /* The text of the line */
125125
u64 h; /* Hash of the line */
126
- unsigned short indent; /* Indent of the line. Only !=0 with -w/-Z option */
126
+ unsigned short indent; /* Index of first non-space */
127127
unsigned short n; /* number of bytes */
128
+ unsigned short nw; /* number of bytes without leading/trailing space */
128129
unsigned int iNext; /* 1+(Index of next line with same the same hash) */
129130
130131
/* an array of DLine elements serves two purposes. The fields
131132
** above are one per line of input text. But each entry is also
132133
** a bucket in a hash table, as follows: */
@@ -163,12 +164,34 @@
163164
int nEditAlloc; /* Space allocated for aEdit[] */
164165
DLine *aFrom; /* File on left side of the diff */
165166
int nFrom; /* Number of lines in aFrom[] */
166167
DLine *aTo; /* File on right side of the diff */
167168
int nTo; /* Number of lines in aTo[] */
168
- int (*xDiffer)(const DLine*,const DLine*); /* comparison function */
169
+ int (*xDiffer)(const DLine *,const DLine *); /* comparison function */
170
+};
171
+
172
+/* Fast isspace for use by diff */
173
+static const char diffIsSpace[] = {
174
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0,
175
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182
+
183
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169191
};
192
+#define diff_isspace(X) (diffIsSpace[(unsigned char)(X)])
170193
171194
/*
172195
** Count the number of lines in the input string. Include the last line
173196
** in the count even if it lacks the \n terminator. If an empty string
174197
** is specified, the number of lines is zero. For the purposes of this
@@ -245,38 +268,38 @@
245268
k = nn;
246269
if( diffFlags & DIFF_STRIP_EOLCR ){
247270
if( k>0 && z[k-1]=='\r' ){ k--; }
248271
}
249272
a[i].n = k;
250
- s = 0;
251273
if( diffFlags & DIFF_IGNORE_EOLWS ){
252
- while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
274
+ while( k>0 && diff_isspace(z[k-1]) ){ k--; }
253275
}
254276
if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
255277
int numws = 0;
256
- while( s<k && fossil_isspace(z[s]) ){ s++; }
278
+ for(s=0; s<k && z[s]<=' '; s++){}
279
+ a[i].indent = s;
280
+ a[i].nw = k - s;
257281
for(h=0, x=s; x<k; x++){
258282
char c = z[x];
259
- if( fossil_isspace(c) ){
283
+ if( diff_isspace(c) ){
260284
++numws;
261285
}else{
262286
h = (h^c)*9000000000000000041LL;
263287
}
264288
}
265289
k -= numws;
266290
}else{
267291
int k2 = k & ~0x7;
268292
u64 m;
269
- for(h=0, x=s; x<k2; x += 8){
293
+ for(h=x=s=0; x<k2; x += 8){
270294
memcpy(&m, z+x, 8);
271295
h = (h^m)*9000000000000000041LL;
272296
}
273297
m = 0;
274298
memcpy(&m, z+x, k-k2);
275299
h ^= m;
276300
}
277
- a[i].indent = s;
278301
a[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | (k-s);
279302
h2 = h % nLine;
280303
a[i].iNext = a[h2].iHash;
281304
a[h2].iHash = i+1;
282305
z += nn+1; n -= nn+1;
@@ -300,18 +323,20 @@
300323
/*
301324
** Return zero if two DLine elements are identical, ignoring
302325
** all whitespace. The indent field of pA/pB already points
303326
** to the first non-space character in the string.
304327
*/
305
-
306328
static int compare_dline_ignore_allws(const DLine *pA, const DLine *pB){
307
- int a = pA->indent, b = pB->indent;
308329
if( pA->h==pB->h ){
330
+ int a, b;
331
+ if( memcmp(pA->z, pB->z, pA->h&LENGTH_MASK)==0 ) return 0;
332
+ a = pA->indent;
333
+ b = pB->indent;
309334
while( a<pA->n || b<pB->n ){
310335
if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 1;
311
- while( a<pA->n && fossil_isspace(pA->z[a])) ++a;
312
- while( b<pB->n && fossil_isspace(pB->z[b])) ++b;
336
+ while( a<pA->n && diff_isspace(pA->z[a])) ++a;
337
+ while( b<pB->n && diff_isspace(pB->z[b])) ++b;
313338
}
314339
return pA->n-a != pB->n-b;
315340
}
316341
return 1;
317342
}
@@ -338,11 +363,11 @@
338363
** Append a single line of context-diff output to pOut.
339364
*/
340365
static void appendDiffLine(
341366
Blob *pOut, /* Where to write the line of output */
342367
char cPrefix, /* One of " ", "+", or "-" */
343
- DLine *pLine /* The line to be output */
368
+ const DLine *pLine /* The line to be output */
344369
){
345370
blob_append_char(pOut, cPrefix);
346371
blob_append(pOut, pLine->z, pLine->n);
347372
blob_append_char(pOut, '\n');
348373
}
@@ -371,14 +396,14 @@
371396
static void contextDiff(
372397
DContext *p, /* The difference */
373398
Blob *pOut, /* Output a context diff to here */
374399
DiffConfig *pCfg /* Configuration options */
375400
){
376
- DLine *A; /* Left side of the diff */
377
- DLine *B; /* Right side of the diff */
378
- int a = 0; /* Index of next line in A[] */
379
- int b = 0; /* Index of next line in B[] */
401
+ const DLine *A; /* Left side of the diff */
402
+ const DLine *B; /* Right side of the diff */
403
+ int a = 0; /* Index of next line in A[] */
404
+ int b = 0; /* Index of next line in B[] */
380405
int *R; /* Array of COPY/DELETE/INSERT triples */
381406
int r; /* Index into R[] */
382407
int nr; /* Number of COPY/DELETE/INSERT triples to process */
383408
int mxr; /* Maximum value for r */
384409
int na, nb; /* Number of lines shown from A and B */
@@ -619,11 +644,11 @@
619644
/*
620645
** Return true if the string starts with n spaces
621646
*/
622647
static int allSpaces(const char *z, int n){
623648
int i;
624
- for(i=0; i<n && fossil_isspace(z[i]); i++){}
649
+ for(i=0; i<n && diff_isspace(z[i]); i++){}
625650
return i==n;
626651
}
627652
628653
/*
629654
** Try to improve the human-readability of the LineChange p.
@@ -745,17 +770,17 @@
745770
int nLong = nLeft<nRight ? nRight : nLeft;
746771
int nGap = nLong - nShort;
747772
for(i=nShort-nSuffix; i<=nPrefix; i++){
748773
int iVal = 0;
749774
char c = zLeft[i];
750
- if( fossil_isspace(c) ){
775
+ if( diff_isspace(c) ){
751776
iVal += 5;
752777
}else if( !fossil_isalnum(c) ){
753778
iVal += 2;
754779
}
755780
c = zLeft[i+nGap-1];
756
- if( fossil_isspace(c) ){
781
+ if( diff_isspace(c) ){
757782
iVal += 5;
758783
}else if( !fossil_isalnum(c) ){
759784
iVal += 2;
760785
}
761786
if( iVal>iBestVal ){
@@ -889,11 +914,11 @@
889914
struct DiffBuilder {
890915
void (*xSkip)(DiffBuilder*, unsigned int, int);
891916
void (*xCommon)(DiffBuilder*,const DLine*);
892917
void (*xInsert)(DiffBuilder*,const DLine*);
893918
void (*xDelete)(DiffBuilder*,const DLine*);
894
- void (*xReplace)(DiffBuilder*,const DLine*, const DLine*);
919
+ void (*xReplace)(DiffBuilder*,const DLine*,const DLine*);
895920
void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
896921
void (*xEnd)(DiffBuilder*);
897922
unsigned int lnLeft; /* Lines seen on the left (delete) side */
898923
unsigned int lnRight; /* Lines seen on the right (insert) side */
899924
unsigned int nPending; /* Number of pending lines */
@@ -1733,11 +1758,11 @@
17331758
** (3) If the two strings have a common prefix, measure that prefix
17341759
** (4) Find the length of the longest common subsequence that is
17351760
** at least 150% longer than the common prefix.
17361761
** (5) Longer common subsequences yield lower scores.
17371762
*/
1738
-static int match_dline(const DLine *pA, const DLine *pB){
1763
+static int match_dline(DLine *pA, DLine *pB){
17391764
const char *zA; /* Left string */
17401765
const char *zB; /* right string */
17411766
int nA; /* Bytes in zA[] */
17421767
int nB; /* Bytes in zB[] */
17431768
int nMin;
@@ -1749,17 +1774,29 @@
17491774
unsigned char c; /* Character being examined */
17501775
unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */
17511776
unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */
17521777
17531778
zA = pA->z;
1779
+ if( pA->nw==0 && pA->n ){
1780
+ for(i=0; i<pA->n && diff_isspace(zA[i]); i++){}
1781
+ pA->indent = i;
1782
+ for(j=pA->n-1; j>i && diff_isspace(zA[j]); j--){}
1783
+ pA->nw = j - i + 1;
1784
+ }
1785
+ zA += pA->indent;
1786
+ nA = pA->nw;
1787
+
17541788
zB = pB->z;
1755
- nA = pA->n;
1756
- nB = pB->n;
1757
- while( nA>0 && (unsigned char)zA[0]<=' ' ){ nA--; zA++; }
1758
- while( nA>0 && (unsigned char)zA[nA-1]<=' ' ){ nA--; }
1759
- while( nB>0 && (unsigned char)zB[0]<=' ' ){ nB--; zB++; }
1760
- while( nB>0 && (unsigned char)zB[nB-1]<=' ' ){ nB--; }
1789
+ if( pB->nw==0 && pB->n ){
1790
+ for(i=0; i<pB->n && diff_isspace(zB[i]); i++){}
1791
+ pB->indent = i;
1792
+ for(j=pB->n-1; j>i && diff_isspace(zB[j]); j--){}
1793
+ pB->nw = j - i + 1;
1794
+ }
1795
+ zB += pB->indent;
1796
+ nB = pB->nw;
1797
+
17611798
if( nA>250 ) nA = 250;
17621799
if( nB>250 ) nB = 250;
17631800
avg = (nA+nB)/2;
17641801
if( avg==0 ) return 0;
17651802
nMin = nA;
@@ -1785,11 +1822,11 @@
17851822
int limit = minInt(nA-i, nB-j);
17861823
for(k=best; k<=limit && zA[k+i]==zB[k+j]; k++){}
17871824
if( k>best ) best = k;
17881825
}
17891826
}
1790
- score = (best>=avg) ? 0 : (avg - best)*100/avg;
1827
+ score = 5 + ((best>=avg) ? 0 : (avg - best)*95/avg);
17911828
17921829
#if 0
17931830
fprintf(stderr, "A: [%.*s]\nB: [%.*s]\nbest=%d avg=%d score=%d\n",
17941831
nA, zA+1, nB, zB+1, best, avg, score);
17951832
#endif
@@ -1817,10 +1854,183 @@
18171854
b.z = g.argv[3];
18181855
b.n = (int)strlen(b.z);
18191856
x = match_dline(&a, &b);
18201857
fossil_print("%d\n", x);
18211858
}
1859
+
1860
+/* Forward declarations for recursion */
1861
+static unsigned char *diffBlockAlignment(
1862
+ DLine *aLeft, int nLeft, /* Text on the left */
1863
+ DLine *aRight, int nRight, /* Text on the right */
1864
+ DiffConfig *pCfg, /* Configuration options */
1865
+ int *pNResult /* OUTPUT: Bytes of result */
1866
+);
1867
+static void longestCommonSequence(
1868
+ DContext *p, /* Two files being compared */
1869
+ int iS1, int iE1, /* Range of lines in p->aFrom[] */
1870
+ int iS2, int iE2, /* Range of lines in p->aTo[] */
1871
+ int *piSX, int *piEX, /* Write p->aFrom[] common segment here */
1872
+ int *piSY, int *piEY /* Write p->aTo[] common segment here */
1873
+);
1874
+
1875
+/*
1876
+** Make a copy of a list of nLine DLine objects from one array to
1877
+** another. Hash the new array to ignore whitespace.
1878
+*/
1879
+static void diffDLineXfer(
1880
+ DLine *aTo,
1881
+ const DLine *aFrom,
1882
+ int nLine
1883
+){
1884
+ int i, j, k;
1885
+ u64 h, h2;
1886
+ for(i=0; i<nLine; i++) aTo[i].iHash = 0;
1887
+ for(i=0; i<nLine; i++){
1888
+ const char *z = aFrom[i].z;
1889
+ int n = aFrom[i].n;
1890
+ for(j=0; j<n && diff_isspace(z[j]); j++){}
1891
+ aTo[i].z = &z[j];
1892
+ for(k=aFrom[i].n; k>j && diff_isspace(z[k-1]); k--){}
1893
+ aTo[i].n = n = k-j;
1894
+ aTo[i].indent = 0;
1895
+ aTo[i].nw = 0;
1896
+ for(h=0; j<k; j++){
1897
+ char c = z[j];
1898
+ if( !diff_isspace(c) ){
1899
+ h = (h^c)*9000000000000000041LL;
1900
+ }
1901
+ }
1902
+ aTo[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | n;
1903
+ h2 = h % nLine;
1904
+ aTo[i].iNext = aTo[h2].iHash;
1905
+ aTo[h2].iHash = i+1;
1906
+ }
1907
+}
1908
+
1909
+
1910
+/*
1911
+** For a difficult diff-block alignment that was originally for
1912
+** the default consider-all-whitespace algorithm, try to find the
1913
+** longest common subsequence between the two blocks that involves
1914
+** only whitespace changes.
1915
+*/
1916
+static unsigned char *diffBlockAlignmentIgnoreSpace(
1917
+ DLine *aLeft, int nLeft, /* Text on the left */
1918
+ DLine *aRight, int nRight, /* Text on the right */
1919
+ DiffConfig *pCfg, /* Configuration options */
1920
+ int *pNResult /* OUTPUT: Bytes of result */
1921
+){
1922
+ DContext dc;
1923
+ int iSX, iEX; /* Start and end of LCS on the left */
1924
+ int iSY, iEY; /* Start and end of the LCS on the right */
1925
+ unsigned char *a1, *a2;
1926
+ int n1, n2, nLCS;
1927
+
1928
+ dc.aEdit = 0;
1929
+ dc.nEdit = 0;
1930
+ dc.nEditAlloc = 0;
1931
+ dc.nFrom = nLeft;
1932
+ dc.nTo = nRight;
1933
+ dc.xDiffer = compare_dline_ignore_allws;
1934
+ dc.aFrom = fossil_malloc( sizeof(DLine)*(nLeft+nRight) );
1935
+ dc.aTo = &dc.aFrom[dc.nFrom];
1936
+ diffDLineXfer(dc.aFrom, aLeft, nLeft);
1937
+ diffDLineXfer(dc.aTo, aRight, nRight);
1938
+ longestCommonSequence(&dc,0,nLeft,0,nRight,&iSX,&iEX,&iSY,&iEY);
1939
+ fossil_free(dc.aFrom);
1940
+ nLCS = iEX - iSX;
1941
+ if( nLCS<5 ) return 0; /* No good LCS was found */
1942
+
1943
+ if( pCfg->diffFlags & DIFF_DEBUG ){
1944
+ fossil_print(" LCS size=%d\n"
1945
+ " [%.*s]\n"
1946
+ " [%.*s]\n",
1947
+ nLCS, aLeft[iSX].n, aLeft[iSX].z,
1948
+ aLeft[iEX-1].n, aLeft[iEX-1].z);
1949
+ }
1950
+
1951
+ a1 = diffBlockAlignment(aLeft,iSX,aRight,iSY,pCfg,&n1);
1952
+ a2 = diffBlockAlignment(aLeft+iEX, nLeft-iEX,
1953
+ aRight+iEY, nRight-iEY,
1954
+ pCfg, &n2);
1955
+ a1 = fossil_realloc(a1, n1+nLCS+n2);
1956
+ memcpy(a1+n1+nLCS,a2,n2);
1957
+ memset(a1+n1,3,nLCS);
1958
+ fossil_free(a2);
1959
+ *pNResult = n1+n2+nLCS;
1960
+ return a1;
1961
+}
1962
+
1963
+
1964
+/*
1965
+** This is a helper route for diffBlockAlignment(). In this case,
1966
+** a very large block is encountered that might be too expensive to
1967
+** use the O(N*N) Wagner edit distance algorithm. So instead, this
1968
+** block implements a less-precise but faster O(N*logN) divide-and-conquer
1969
+** approach.
1970
+*/
1971
+static unsigned char *diffBlockAlignmentDivideAndConquer(
1972
+ DLine *aLeft, int nLeft, /* Text on the left */
1973
+ DLine *aRight, int nRight, /* Text on the right */
1974
+ DiffConfig *pCfg, /* Configuration options */
1975
+ int *pNResult /* OUTPUT: Bytes of result */
1976
+){
1977
+ DLine *aSmall; /* The smaller of aLeft and aRight */
1978
+ DLine *aBig; /* The larger of aLeft and aRight */
1979
+ int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1980
+ int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1981
+ int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
1982
+ unsigned char *a1, *a2; /* Results of the alignments on two halves */
1983
+ int n1, n2; /* Number of entries in a1 and a2 */
1984
+ int score, bestScore; /* Score and best score seen so far */
1985
+ int i; /* Loop counter */
1986
+
1987
+ if( nLeft>nRight ){
1988
+ aSmall = aRight;
1989
+ nSmall = nRight;
1990
+ aBig = aLeft;
1991
+ nBig = nLeft;
1992
+ }else{
1993
+ aSmall = aLeft;
1994
+ nSmall = nLeft;
1995
+ aBig = aRight;
1996
+ nBig = nRight;
1997
+ }
1998
+ iDivBig = nBig/2;
1999
+ iDivSmall = nSmall/2;
2000
+
2001
+ if( pCfg->diffFlags & DIFF_DEBUG ){
2002
+ fossil_print(" Divide at [%.*s]\n",
2003
+ aBig[iDivBig].n, aBig[iDivBig].z);
2004
+ }
2005
+
2006
+ bestScore = 10000;
2007
+ for(i=0; i<nSmall; i++){
2008
+ score = match_dline(aBig+iDivBig, aSmall+i) + abs(i-nSmall/2)*2;
2009
+ if( score<bestScore ){
2010
+ bestScore = score;
2011
+ iDivSmall = i;
2012
+ }
2013
+ }
2014
+ if( aSmall==aRight ){
2015
+ iDivRight = iDivSmall;
2016
+ iDivLeft = iDivBig;
2017
+ }else{
2018
+ iDivRight = iDivBig;
2019
+ iDivLeft = iDivSmall;
2020
+ }
2021
+ a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
2022
+ a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
2023
+ aRight+iDivRight, nRight-iDivRight,
2024
+ pCfg, &n2);
2025
+ a1 = fossil_realloc(a1, n1+n2 );
2026
+ memcpy(a1+n1,a2,n2);
2027
+ fossil_free(a2);
2028
+ *pNResult = n1+n2;
2029
+ return a1;
2030
+}
2031
+
18222032
18232033
/*
18242034
** The threshold at which diffBlockAlignment transitions from the
18252035
** O(N*N) Wagner minimum-edit-distance algorithm to a less process
18262036
** O(NlogN) divide-and-conquer approach.
@@ -1850,14 +2060,14 @@
18502060
** each other. Insertion and deletion costs are 50. Match costs
18512061
** are between 0 and 100 where 0 is a perfect match 100 is a complete
18522062
** mismatch.
18532063
*/
18542064
static unsigned char *diffBlockAlignment(
1855
- const DLine *aLeft, int nLeft, /* Text on the left */
1856
- const DLine *aRight, int nRight, /* Text on the right */
1857
- DiffConfig *pCfg, /* Configuration options */
1858
- int *pNResult /* OUTPUT: Bytes of result */
2065
+ DLine *aLeft, int nLeft, /* Text on the left */
2066
+ DLine *aRight, int nRight, /* Text on the right */
2067
+ DiffConfig *pCfg, /* Configuration options */
2068
+ int *pNResult /* OUTPUT: Bytes of result */
18592069
){
18602070
int i, j, k; /* Loop counters */
18612071
int *a; /* One row of the Wagner matrix */
18622072
int *pToFree; /* Space that needs to be freed */
18632073
unsigned char *aM; /* Wagner result matrix */
@@ -1875,61 +2085,28 @@
18752085
memset(aM, 1, nLeft);
18762086
*pNResult = nLeft;
18772087
return aM;
18782088
}
18792089
1880
- /* For large alignments, use a divide and conquer algorithm that is
1881
- ** O(NlogN). The result is not as precise, but this whole thing is an
1882
- ** approximation anyhow, and the faster response time is an acceptable
1883
- ** trade-off for reduced precision.
2090
+ if( pCfg->diffFlags & DIFF_DEBUG ){
2091
+ fossil_print("BlockAlignment:\n [%.*s] + %d\n [%.*s] + %d\n",
2092
+ aLeft[0].n, aLeft[0].z, nLeft,
2093
+ aRight[0].n, aRight[0].z, nRight);
2094
+ }
2095
+
2096
+ /* For large alignments, try to use alternative algorithms that are
2097
+ ** faster than the O(N*N) Wagner edit distance.
18842098
*/
18852099
if( nLeft*nRight>DIFF_ALIGN_MX && (pCfg->diffFlags & DIFF_SLOW_SBS)==0 ){
1886
- const DLine *aSmall; /* The smaller of aLeft and aRight */
1887
- const DLine *aBig; /* The larger of aLeft and aRight */
1888
- int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1889
- int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1890
- int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
1891
- unsigned char *a1, *a2; /* Results of the alignments on two halves */
1892
- int n1, n2; /* Number of entries in a1 and a2 */
1893
- int score, bestScore; /* Score and best score seen so far */
1894
- if( nLeft>nRight ){
1895
- aSmall = aRight;
1896
- nSmall = nRight;
1897
- aBig = aLeft;
1898
- nBig = nLeft;
1899
- }else{
1900
- aSmall = aLeft;
1901
- nSmall = nLeft;
1902
- aBig = aRight;
1903
- nBig = nRight;
1904
- }
1905
- iDivBig = nBig/2;
1906
- iDivSmall = nSmall/2;
1907
- bestScore = 10000;
1908
- for(i=0; i<nSmall; i++){
1909
- score = match_dline(aBig+iDivBig, aSmall+i) + abs(i-nSmall/2)*2;
1910
- if( score<bestScore ){
1911
- bestScore = score;
1912
- iDivSmall = i;
1913
- }
1914
- }
1915
- if( aSmall==aRight ){
1916
- iDivRight = iDivSmall;
1917
- iDivLeft = iDivBig;
1918
- }else{
1919
- iDivRight = iDivBig;
1920
- iDivLeft = iDivSmall;
1921
- }
1922
- a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
1923
- a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
1924
- aRight+iDivRight, nRight-iDivRight,
1925
- pCfg, &n2);
1926
- a1 = fossil_realloc(a1, n1+n2 );
1927
- memcpy(a1+n1,a2,n2);
1928
- fossil_free(a2);
1929
- *pNResult = n1+n2;
1930
- return a1;
2100
+ if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==0 ){
2101
+ unsigned char *aRes;
2102
+ aRes = diffBlockAlignmentIgnoreSpace(
2103
+ aLeft, nLeft,aRight, nRight,pCfg,pNResult);
2104
+ if( aRes ) return aRes;
2105
+ }
2106
+ return diffBlockAlignmentDivideAndConquer(
2107
+ aLeft, nLeft,aRight, nRight,pCfg,pNResult);
19312108
}
19322109
19332110
/* If we reach this point, we will be doing an O(N*N) Wagner minimum
19342111
** edit distance to compute the alignment.
19352112
*/
@@ -2026,12 +2203,12 @@
20262203
static void formatDiff(
20272204
DContext *p, /* The computed diff */
20282205
DiffConfig *pCfg, /* Configuration options */
20292206
DiffBuilder *pBuilder /* The formatter object */
20302207
){
2031
- const DLine *A; /* Left side of the diff */
2032
- const DLine *B; /* Right side of the diff */
2208
+ DLine *A; /* Left side of the diff */
2209
+ DLine *B; /* Right side of the diff */
20332210
unsigned int a = 0; /* Index of next line in A[] */
20342211
unsigned int b = 0; /* Index of next line in B[] */
20352212
const int *R; /* Array of COPY/DELETE/INSERT triples */
20362213
unsigned int r; /* Index into R[] */
20372214
unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -2410,10 +2587,125 @@
24102587
}
24112588
p->aEdit[p->nEdit++] = nCopy;
24122589
p->aEdit[p->nEdit++] = nDel;
24132590
p->aEdit[p->nEdit++] = nIns;
24142591
}
2592
+
2593
+/*
2594
+** A common subsequence between p->aFrom and p->aTo has been found.
2595
+** This routine tries to judge if the subsequence really is a valid
2596
+** match or rather is just an artifact of an indentation change.
2597
+**
2598
+** Return non-zero if the subsequence is valid. Return zero if the
2599
+** subsequence seems likely to be an editing artifact and should be
2600
+** ignored.
2601
+**
2602
+** This routine is a heuristic optimization intended to give more
2603
+** intuitive diff results following an indentation change it code that
2604
+** is formatted similarly to C/C++, Javascript, Go, TCL, and similar
2605
+** languages that use {...} for nesting. A correct diff is computed
2606
+** even if this routine always returns true (non-zero). But sometimes
2607
+** a more intuitive diff can result if this routine returns false.
2608
+**
2609
+** The subsequences consists of the rows iSX through iEX-1 (inclusive)
2610
+** in p->aFrom[]. The total sequences is iS1 through iE1-1 (inclusive)
2611
+** of p->aFrom[].
2612
+**
2613
+** Example where this heuristic is useful, see the diff at
2614
+** https://www.sqlite.org/src/fdiff?v1=0e79dd15cbdb4f48&v2=33955a6fd874dd97
2615
+**
2616
+** See also discussion at https://fossil-scm.org/forum/forumpost/9ba3284295
2617
+**
2618
+** ALGORITHM (subject to change and refinement):
2619
+**
2620
+** 1. If the subsequence is larger than 1/7th of the original span,
2621
+** then consider it valid. --> return 1
2622
+**
2623
+** 2. If no lines of the subsequence contains more than one
2624
+** non-whitespace character, --> return 0
2625
+**
2626
+** 3. If any line of the subsequence contains more than one non-whitespace
2627
+** character and is unique across the entire sequence after ignoring
2628
+** leading and trailing whitespace --> return 1
2629
+**
2630
+** 4. Otherwise, it is potentially an artifact of an indentation
2631
+** change. --> return 0
2632
+*/
2633
+static int likelyNotIndentChngArtifact(
2634
+ DContext *p, /* The complete diff context */
2635
+ int iS1, /* Start of the main segment */
2636
+ int iSX, /* Start of the subsequence */
2637
+ int iEX, /* First row past the end of the subsequence */
2638
+ int iE1 /* First row past the end of the main segment */
2639
+){
2640
+ int i, j, n;
2641
+
2642
+ /* Rule (1) */
2643
+ if( (iEX-iSX)*7 >= (iE1-iS1) ) return 1;
2644
+
2645
+ /* Compute DLine.indent and DLine.nw for all lines of the subsequence.
2646
+ ** If no lines contain more than one non-whitespace character return
2647
+ ** 0 because the subsequence could be due to an indentation change.
2648
+ ** Rule (2).
2649
+ */
2650
+ n = 0;
2651
+ for(i=iSX; i<iEX; i++){
2652
+ DLine *pA = &p->aFrom[i];
2653
+ if( pA->nw==0 && pA->n ){
2654
+ const char *zA = pA->z;
2655
+ const int nn = pA->n;
2656
+ int ii, jj;
2657
+ for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2658
+ pA->indent = ii;
2659
+ for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2660
+ pA->nw = jj - ii + 1;
2661
+ }
2662
+ if( pA->nw>1 ) n++;
2663
+ }
2664
+ if( n==0 ) return 0;
2665
+
2666
+ /* Compute DLine.indent and DLine.nw for the entire sequence */
2667
+ for(i=iS1; i<iE1; i++){
2668
+ DLine *pA;
2669
+ if( i==iSX ){
2670
+ i = iEX;
2671
+ if( i>=iE1 ) break;
2672
+ }
2673
+ pA = &p->aFrom[i];
2674
+ if( pA->nw==0 && pA->n ){
2675
+ const char *zA = pA->z;
2676
+ const int nn = pA->n;
2677
+ int ii, jj;
2678
+ for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2679
+ pA->indent = ii;
2680
+ for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2681
+ pA->nw = jj - ii + 1;
2682
+ }
2683
+ }
2684
+
2685
+ /* Check to see if any subsequence line that has more than one
2686
+ ** non-whitespace character is unique across the entire sequence.
2687
+ ** Rule (3)
2688
+ */
2689
+ for(i=iSX; i<iEX; i++){
2690
+ const char *z = p->aFrom[i].z + p->aFrom[i].indent;
2691
+ const int nw = p->aFrom[i].nw;
2692
+ if( nw<=1 ) continue;
2693
+ for(j=iS1; j<iSX; j++){
2694
+ if( p->aFrom[j].nw!=nw ) continue;
2695
+ if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2696
+ }
2697
+ if( j<iSX ) continue;
2698
+ for(j=iEX; j<iE1; j++){
2699
+ if( p->aFrom[j].nw!=nw ) continue;
2700
+ if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2701
+ }
2702
+ if( j>=iE1 ) break;
2703
+ }
2704
+ return i<iEX;
2705
+}
2706
+
24152707
24162708
/*
24172709
** Do a single step in the difference. Compute a sequence of
24182710
** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
24192711
** the input into lines iS2 through iE2-1 of the output and write
@@ -2442,11 +2734,13 @@
24422734
}
24432735
24442736
/* Find the longest matching segment between the two sequences */
24452737
longestCommonSequence(p, iS1, iE1, iS2, iE2, &iSX, &iEX, &iSY, &iEY);
24462738
2447
- if( iEX>iSX ){
2739
+ if( iEX>iSX+5
2740
+ || (iEX>iSX && likelyNotIndentChngArtifact(p,iS1,iSX,iEX,iE1) )
2741
+ ){
24482742
/* A common segment has been found.
24492743
** Recursively diff either side of the matching segment */
24502744
diff_step(p, iS1, iSX, iS2, iSY);
24512745
if( iEX>iSX ){
24522746
appendTriple(p, iEX - iSX, 0, 0);
@@ -3120,11 +3414,12 @@
31203414
if( strcmp(zLimit,"none")==0 ){
31213415
iLimit = 0;
31223416
mxTime = 0;
31233417
}else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
31243418
iLimit = 0;
3125
- mxTime = current_time_in_milliseconds() + 1000.0*atof(zLimit);
3419
+ mxTime =
3420
+ (sqlite3_int64)(current_time_in_milliseconds() + 1000.0*atof(zLimit));
31263421
}else{
31273422
iLimit = atoi(zLimit);
31283423
if( iLimit<=0 ) iLimit = 30;
31293424
mxTime = 0;
31303425
}
31313426
--- src/diff.c
+++ src/diff.c
@@ -121,12 +121,13 @@
121 */
122 typedef struct DLine DLine;
123 struct DLine {
124 const char *z; /* The text of the line */
125 u64 h; /* Hash of the line */
126 unsigned short indent; /* Indent of the line. Only !=0 with -w/-Z option */
127 unsigned short n; /* number of bytes */
 
128 unsigned int iNext; /* 1+(Index of next line with same the same hash) */
129
130 /* an array of DLine elements serves two purposes. The fields
131 ** above are one per line of input text. But each entry is also
132 ** a bucket in a hash table, as follows: */
@@ -163,12 +164,34 @@
163 int nEditAlloc; /* Space allocated for aEdit[] */
164 DLine *aFrom; /* File on left side of the diff */
165 int nFrom; /* Number of lines in aFrom[] */
166 DLine *aTo; /* File on right side of the diff */
167 int nTo; /* Number of lines in aTo[] */
168 int (*xDiffer)(const DLine*,const DLine*); /* comparison function */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169 };
 
170
171 /*
172 ** Count the number of lines in the input string. Include the last line
173 ** in the count even if it lacks the \n terminator. If an empty string
174 ** is specified, the number of lines is zero. For the purposes of this
@@ -245,38 +268,38 @@
245 k = nn;
246 if( diffFlags & DIFF_STRIP_EOLCR ){
247 if( k>0 && z[k-1]=='\r' ){ k--; }
248 }
249 a[i].n = k;
250 s = 0;
251 if( diffFlags & DIFF_IGNORE_EOLWS ){
252 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
253 }
254 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
255 int numws = 0;
256 while( s<k && fossil_isspace(z[s]) ){ s++; }
 
 
257 for(h=0, x=s; x<k; x++){
258 char c = z[x];
259 if( fossil_isspace(c) ){
260 ++numws;
261 }else{
262 h = (h^c)*9000000000000000041LL;
263 }
264 }
265 k -= numws;
266 }else{
267 int k2 = k & ~0x7;
268 u64 m;
269 for(h=0, x=s; x<k2; x += 8){
270 memcpy(&m, z+x, 8);
271 h = (h^m)*9000000000000000041LL;
272 }
273 m = 0;
274 memcpy(&m, z+x, k-k2);
275 h ^= m;
276 }
277 a[i].indent = s;
278 a[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | (k-s);
279 h2 = h % nLine;
280 a[i].iNext = a[h2].iHash;
281 a[h2].iHash = i+1;
282 z += nn+1; n -= nn+1;
@@ -300,18 +323,20 @@
300 /*
301 ** Return zero if two DLine elements are identical, ignoring
302 ** all whitespace. The indent field of pA/pB already points
303 ** to the first non-space character in the string.
304 */
305
306 static int compare_dline_ignore_allws(const DLine *pA, const DLine *pB){
307 int a = pA->indent, b = pB->indent;
308 if( pA->h==pB->h ){
 
 
 
 
309 while( a<pA->n || b<pB->n ){
310 if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 1;
311 while( a<pA->n && fossil_isspace(pA->z[a])) ++a;
312 while( b<pB->n && fossil_isspace(pB->z[b])) ++b;
313 }
314 return pA->n-a != pB->n-b;
315 }
316 return 1;
317 }
@@ -338,11 +363,11 @@
338 ** Append a single line of context-diff output to pOut.
339 */
340 static void appendDiffLine(
341 Blob *pOut, /* Where to write the line of output */
342 char cPrefix, /* One of " ", "+", or "-" */
343 DLine *pLine /* The line to be output */
344 ){
345 blob_append_char(pOut, cPrefix);
346 blob_append(pOut, pLine->z, pLine->n);
347 blob_append_char(pOut, '\n');
348 }
@@ -371,14 +396,14 @@
371 static void contextDiff(
372 DContext *p, /* The difference */
373 Blob *pOut, /* Output a context diff to here */
374 DiffConfig *pCfg /* Configuration options */
375 ){
376 DLine *A; /* Left side of the diff */
377 DLine *B; /* Right side of the diff */
378 int a = 0; /* Index of next line in A[] */
379 int b = 0; /* Index of next line in B[] */
380 int *R; /* Array of COPY/DELETE/INSERT triples */
381 int r; /* Index into R[] */
382 int nr; /* Number of COPY/DELETE/INSERT triples to process */
383 int mxr; /* Maximum value for r */
384 int na, nb; /* Number of lines shown from A and B */
@@ -619,11 +644,11 @@
619 /*
620 ** Return true if the string starts with n spaces
621 */
622 static int allSpaces(const char *z, int n){
623 int i;
624 for(i=0; i<n && fossil_isspace(z[i]); i++){}
625 return i==n;
626 }
627
628 /*
629 ** Try to improve the human-readability of the LineChange p.
@@ -745,17 +770,17 @@
745 int nLong = nLeft<nRight ? nRight : nLeft;
746 int nGap = nLong - nShort;
747 for(i=nShort-nSuffix; i<=nPrefix; i++){
748 int iVal = 0;
749 char c = zLeft[i];
750 if( fossil_isspace(c) ){
751 iVal += 5;
752 }else if( !fossil_isalnum(c) ){
753 iVal += 2;
754 }
755 c = zLeft[i+nGap-1];
756 if( fossil_isspace(c) ){
757 iVal += 5;
758 }else if( !fossil_isalnum(c) ){
759 iVal += 2;
760 }
761 if( iVal>iBestVal ){
@@ -889,11 +914,11 @@
889 struct DiffBuilder {
890 void (*xSkip)(DiffBuilder*, unsigned int, int);
891 void (*xCommon)(DiffBuilder*,const DLine*);
892 void (*xInsert)(DiffBuilder*,const DLine*);
893 void (*xDelete)(DiffBuilder*,const DLine*);
894 void (*xReplace)(DiffBuilder*,const DLine*, const DLine*);
895 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
896 void (*xEnd)(DiffBuilder*);
897 unsigned int lnLeft; /* Lines seen on the left (delete) side */
898 unsigned int lnRight; /* Lines seen on the right (insert) side */
899 unsigned int nPending; /* Number of pending lines */
@@ -1733,11 +1758,11 @@
1733 ** (3) If the two strings have a common prefix, measure that prefix
1734 ** (4) Find the length of the longest common subsequence that is
1735 ** at least 150% longer than the common prefix.
1736 ** (5) Longer common subsequences yield lower scores.
1737 */
1738 static int match_dline(const DLine *pA, const DLine *pB){
1739 const char *zA; /* Left string */
1740 const char *zB; /* right string */
1741 int nA; /* Bytes in zA[] */
1742 int nB; /* Bytes in zB[] */
1743 int nMin;
@@ -1749,17 +1774,29 @@
1749 unsigned char c; /* Character being examined */
1750 unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */
1751 unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */
1752
1753 zA = pA->z;
 
 
 
 
 
 
 
 
 
1754 zB = pB->z;
1755 nA = pA->n;
1756 nB = pB->n;
1757 while( nA>0 && (unsigned char)zA[0]<=' ' ){ nA--; zA++; }
1758 while( nA>0 && (unsigned char)zA[nA-1]<=' ' ){ nA--; }
1759 while( nB>0 && (unsigned char)zB[0]<=' ' ){ nB--; zB++; }
1760 while( nB>0 && (unsigned char)zB[nB-1]<=' ' ){ nB--; }
 
 
 
1761 if( nA>250 ) nA = 250;
1762 if( nB>250 ) nB = 250;
1763 avg = (nA+nB)/2;
1764 if( avg==0 ) return 0;
1765 nMin = nA;
@@ -1785,11 +1822,11 @@
1785 int limit = minInt(nA-i, nB-j);
1786 for(k=best; k<=limit && zA[k+i]==zB[k+j]; k++){}
1787 if( k>best ) best = k;
1788 }
1789 }
1790 score = (best>=avg) ? 0 : (avg - best)*100/avg;
1791
1792 #if 0
1793 fprintf(stderr, "A: [%.*s]\nB: [%.*s]\nbest=%d avg=%d score=%d\n",
1794 nA, zA+1, nB, zB+1, best, avg, score);
1795 #endif
@@ -1817,10 +1854,183 @@
1817 b.z = g.argv[3];
1818 b.n = (int)strlen(b.z);
1819 x = match_dline(&a, &b);
1820 fossil_print("%d\n", x);
1821 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1822
1823 /*
1824 ** The threshold at which diffBlockAlignment transitions from the
1825 ** O(N*N) Wagner minimum-edit-distance algorithm to a less process
1826 ** O(NlogN) divide-and-conquer approach.
@@ -1850,14 +2060,14 @@
1850 ** each other. Insertion and deletion costs are 50. Match costs
1851 ** are between 0 and 100 where 0 is a perfect match 100 is a complete
1852 ** mismatch.
1853 */
1854 static unsigned char *diffBlockAlignment(
1855 const DLine *aLeft, int nLeft, /* Text on the left */
1856 const DLine *aRight, int nRight, /* Text on the right */
1857 DiffConfig *pCfg, /* Configuration options */
1858 int *pNResult /* OUTPUT: Bytes of result */
1859 ){
1860 int i, j, k; /* Loop counters */
1861 int *a; /* One row of the Wagner matrix */
1862 int *pToFree; /* Space that needs to be freed */
1863 unsigned char *aM; /* Wagner result matrix */
@@ -1875,61 +2085,28 @@
1875 memset(aM, 1, nLeft);
1876 *pNResult = nLeft;
1877 return aM;
1878 }
1879
1880 /* For large alignments, use a divide and conquer algorithm that is
1881 ** O(NlogN). The result is not as precise, but this whole thing is an
1882 ** approximation anyhow, and the faster response time is an acceptable
1883 ** trade-off for reduced precision.
 
 
 
 
1884 */
1885 if( nLeft*nRight>DIFF_ALIGN_MX && (pCfg->diffFlags & DIFF_SLOW_SBS)==0 ){
1886 const DLine *aSmall; /* The smaller of aLeft and aRight */
1887 const DLine *aBig; /* The larger of aLeft and aRight */
1888 int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1889 int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1890 int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
1891 unsigned char *a1, *a2; /* Results of the alignments on two halves */
1892 int n1, n2; /* Number of entries in a1 and a2 */
1893 int score, bestScore; /* Score and best score seen so far */
1894 if( nLeft>nRight ){
1895 aSmall = aRight;
1896 nSmall = nRight;
1897 aBig = aLeft;
1898 nBig = nLeft;
1899 }else{
1900 aSmall = aLeft;
1901 nSmall = nLeft;
1902 aBig = aRight;
1903 nBig = nRight;
1904 }
1905 iDivBig = nBig/2;
1906 iDivSmall = nSmall/2;
1907 bestScore = 10000;
1908 for(i=0; i<nSmall; i++){
1909 score = match_dline(aBig+iDivBig, aSmall+i) + abs(i-nSmall/2)*2;
1910 if( score<bestScore ){
1911 bestScore = score;
1912 iDivSmall = i;
1913 }
1914 }
1915 if( aSmall==aRight ){
1916 iDivRight = iDivSmall;
1917 iDivLeft = iDivBig;
1918 }else{
1919 iDivRight = iDivBig;
1920 iDivLeft = iDivSmall;
1921 }
1922 a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
1923 a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
1924 aRight+iDivRight, nRight-iDivRight,
1925 pCfg, &n2);
1926 a1 = fossil_realloc(a1, n1+n2 );
1927 memcpy(a1+n1,a2,n2);
1928 fossil_free(a2);
1929 *pNResult = n1+n2;
1930 return a1;
1931 }
1932
1933 /* If we reach this point, we will be doing an O(N*N) Wagner minimum
1934 ** edit distance to compute the alignment.
1935 */
@@ -2026,12 +2203,12 @@
2026 static void formatDiff(
2027 DContext *p, /* The computed diff */
2028 DiffConfig *pCfg, /* Configuration options */
2029 DiffBuilder *pBuilder /* The formatter object */
2030 ){
2031 const DLine *A; /* Left side of the diff */
2032 const DLine *B; /* Right side of the diff */
2033 unsigned int a = 0; /* Index of next line in A[] */
2034 unsigned int b = 0; /* Index of next line in B[] */
2035 const int *R; /* Array of COPY/DELETE/INSERT triples */
2036 unsigned int r; /* Index into R[] */
2037 unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -2410,10 +2587,125 @@
2410 }
2411 p->aEdit[p->nEdit++] = nCopy;
2412 p->aEdit[p->nEdit++] = nDel;
2413 p->aEdit[p->nEdit++] = nIns;
2414 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2415
2416 /*
2417 ** Do a single step in the difference. Compute a sequence of
2418 ** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
2419 ** the input into lines iS2 through iE2-1 of the output and write
@@ -2442,11 +2734,13 @@
2442 }
2443
2444 /* Find the longest matching segment between the two sequences */
2445 longestCommonSequence(p, iS1, iE1, iS2, iE2, &iSX, &iEX, &iSY, &iEY);
2446
2447 if( iEX>iSX ){
 
 
2448 /* A common segment has been found.
2449 ** Recursively diff either side of the matching segment */
2450 diff_step(p, iS1, iSX, iS2, iSY);
2451 if( iEX>iSX ){
2452 appendTriple(p, iEX - iSX, 0, 0);
@@ -3120,11 +3414,12 @@
3120 if( strcmp(zLimit,"none")==0 ){
3121 iLimit = 0;
3122 mxTime = 0;
3123 }else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
3124 iLimit = 0;
3125 mxTime = current_time_in_milliseconds() + 1000.0*atof(zLimit);
 
3126 }else{
3127 iLimit = atoi(zLimit);
3128 if( iLimit<=0 ) iLimit = 30;
3129 mxTime = 0;
3130 }
3131
--- src/diff.c
+++ src/diff.c
@@ -121,12 +121,13 @@
121 */
122 typedef struct DLine DLine;
123 struct DLine {
124 const char *z; /* The text of the line */
125 u64 h; /* Hash of the line */
126 unsigned short indent; /* Index of first non-space */
127 unsigned short n; /* number of bytes */
128 unsigned short nw; /* number of bytes without leading/trailing space */
129 unsigned int iNext; /* 1+(Index of next line with same the same hash) */
130
131 /* an array of DLine elements serves two purposes. The fields
132 ** above are one per line of input text. But each entry is also
133 ** a bucket in a hash table, as follows: */
@@ -163,12 +164,34 @@
164 int nEditAlloc; /* Space allocated for aEdit[] */
165 DLine *aFrom; /* File on left side of the diff */
166 int nFrom; /* Number of lines in aFrom[] */
167 DLine *aTo; /* File on right side of the diff */
168 int nTo; /* Number of lines in aTo[] */
169 int (*xDiffer)(const DLine *,const DLine *); /* comparison function */
170 };
171
172 /* Fast isspace for use by diff */
173 static const char diffIsSpace[] = {
174 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0,
175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182
183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191 };
192 #define diff_isspace(X) (diffIsSpace[(unsigned char)(X)])
193
194 /*
195 ** Count the number of lines in the input string. Include the last line
196 ** in the count even if it lacks the \n terminator. If an empty string
197 ** is specified, the number of lines is zero. For the purposes of this
@@ -245,38 +268,38 @@
268 k = nn;
269 if( diffFlags & DIFF_STRIP_EOLCR ){
270 if( k>0 && z[k-1]=='\r' ){ k--; }
271 }
272 a[i].n = k;
 
273 if( diffFlags & DIFF_IGNORE_EOLWS ){
274 while( k>0 && diff_isspace(z[k-1]) ){ k--; }
275 }
276 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
277 int numws = 0;
278 for(s=0; s<k && z[s]<=' '; s++){}
279 a[i].indent = s;
280 a[i].nw = k - s;
281 for(h=0, x=s; x<k; x++){
282 char c = z[x];
283 if( diff_isspace(c) ){
284 ++numws;
285 }else{
286 h = (h^c)*9000000000000000041LL;
287 }
288 }
289 k -= numws;
290 }else{
291 int k2 = k & ~0x7;
292 u64 m;
293 for(h=x=s=0; x<k2; x += 8){
294 memcpy(&m, z+x, 8);
295 h = (h^m)*9000000000000000041LL;
296 }
297 m = 0;
298 memcpy(&m, z+x, k-k2);
299 h ^= m;
300 }
 
301 a[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | (k-s);
302 h2 = h % nLine;
303 a[i].iNext = a[h2].iHash;
304 a[h2].iHash = i+1;
305 z += nn+1; n -= nn+1;
@@ -300,18 +323,20 @@
323 /*
324 ** Return zero if two DLine elements are identical, ignoring
325 ** all whitespace. The indent field of pA/pB already points
326 ** to the first non-space character in the string.
327 */
 
328 static int compare_dline_ignore_allws(const DLine *pA, const DLine *pB){
 
329 if( pA->h==pB->h ){
330 int a, b;
331 if( memcmp(pA->z, pB->z, pA->h&LENGTH_MASK)==0 ) return 0;
332 a = pA->indent;
333 b = pB->indent;
334 while( a<pA->n || b<pB->n ){
335 if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 1;
336 while( a<pA->n && diff_isspace(pA->z[a])) ++a;
337 while( b<pB->n && diff_isspace(pB->z[b])) ++b;
338 }
339 return pA->n-a != pB->n-b;
340 }
341 return 1;
342 }
@@ -338,11 +363,11 @@
363 ** Append a single line of context-diff output to pOut.
364 */
365 static void appendDiffLine(
366 Blob *pOut, /* Where to write the line of output */
367 char cPrefix, /* One of " ", "+", or "-" */
368 const DLine *pLine /* The line to be output */
369 ){
370 blob_append_char(pOut, cPrefix);
371 blob_append(pOut, pLine->z, pLine->n);
372 blob_append_char(pOut, '\n');
373 }
@@ -371,14 +396,14 @@
396 static void contextDiff(
397 DContext *p, /* The difference */
398 Blob *pOut, /* Output a context diff to here */
399 DiffConfig *pCfg /* Configuration options */
400 ){
401 const DLine *A; /* Left side of the diff */
402 const DLine *B; /* Right side of the diff */
403 int a = 0; /* Index of next line in A[] */
404 int b = 0; /* Index of next line in B[] */
405 int *R; /* Array of COPY/DELETE/INSERT triples */
406 int r; /* Index into R[] */
407 int nr; /* Number of COPY/DELETE/INSERT triples to process */
408 int mxr; /* Maximum value for r */
409 int na, nb; /* Number of lines shown from A and B */
@@ -619,11 +644,11 @@
644 /*
645 ** Return true if the string starts with n spaces
646 */
647 static int allSpaces(const char *z, int n){
648 int i;
649 for(i=0; i<n && diff_isspace(z[i]); i++){}
650 return i==n;
651 }
652
653 /*
654 ** Try to improve the human-readability of the LineChange p.
@@ -745,17 +770,17 @@
770 int nLong = nLeft<nRight ? nRight : nLeft;
771 int nGap = nLong - nShort;
772 for(i=nShort-nSuffix; i<=nPrefix; i++){
773 int iVal = 0;
774 char c = zLeft[i];
775 if( diff_isspace(c) ){
776 iVal += 5;
777 }else if( !fossil_isalnum(c) ){
778 iVal += 2;
779 }
780 c = zLeft[i+nGap-1];
781 if( diff_isspace(c) ){
782 iVal += 5;
783 }else if( !fossil_isalnum(c) ){
784 iVal += 2;
785 }
786 if( iVal>iBestVal ){
@@ -889,11 +914,11 @@
914 struct DiffBuilder {
915 void (*xSkip)(DiffBuilder*, unsigned int, int);
916 void (*xCommon)(DiffBuilder*,const DLine*);
917 void (*xInsert)(DiffBuilder*,const DLine*);
918 void (*xDelete)(DiffBuilder*,const DLine*);
919 void (*xReplace)(DiffBuilder*,const DLine*,const DLine*);
920 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
921 void (*xEnd)(DiffBuilder*);
922 unsigned int lnLeft; /* Lines seen on the left (delete) side */
923 unsigned int lnRight; /* Lines seen on the right (insert) side */
924 unsigned int nPending; /* Number of pending lines */
@@ -1733,11 +1758,11 @@
1758 ** (3) If the two strings have a common prefix, measure that prefix
1759 ** (4) Find the length of the longest common subsequence that is
1760 ** at least 150% longer than the common prefix.
1761 ** (5) Longer common subsequences yield lower scores.
1762 */
1763 static int match_dline(DLine *pA, DLine *pB){
1764 const char *zA; /* Left string */
1765 const char *zB; /* right string */
1766 int nA; /* Bytes in zA[] */
1767 int nB; /* Bytes in zB[] */
1768 int nMin;
@@ -1749,17 +1774,29 @@
1774 unsigned char c; /* Character being examined */
1775 unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */
1776 unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */
1777
1778 zA = pA->z;
1779 if( pA->nw==0 && pA->n ){
1780 for(i=0; i<pA->n && diff_isspace(zA[i]); i++){}
1781 pA->indent = i;
1782 for(j=pA->n-1; j>i && diff_isspace(zA[j]); j--){}
1783 pA->nw = j - i + 1;
1784 }
1785 zA += pA->indent;
1786 nA = pA->nw;
1787
1788 zB = pB->z;
1789 if( pB->nw==0 && pB->n ){
1790 for(i=0; i<pB->n && diff_isspace(zB[i]); i++){}
1791 pB->indent = i;
1792 for(j=pB->n-1; j>i && diff_isspace(zB[j]); j--){}
1793 pB->nw = j - i + 1;
1794 }
1795 zB += pB->indent;
1796 nB = pB->nw;
1797
1798 if( nA>250 ) nA = 250;
1799 if( nB>250 ) nB = 250;
1800 avg = (nA+nB)/2;
1801 if( avg==0 ) return 0;
1802 nMin = nA;
@@ -1785,11 +1822,11 @@
1822 int limit = minInt(nA-i, nB-j);
1823 for(k=best; k<=limit && zA[k+i]==zB[k+j]; k++){}
1824 if( k>best ) best = k;
1825 }
1826 }
1827 score = 5 + ((best>=avg) ? 0 : (avg - best)*95/avg);
1828
1829 #if 0
1830 fprintf(stderr, "A: [%.*s]\nB: [%.*s]\nbest=%d avg=%d score=%d\n",
1831 nA, zA+1, nB, zB+1, best, avg, score);
1832 #endif
@@ -1817,10 +1854,183 @@
1854 b.z = g.argv[3];
1855 b.n = (int)strlen(b.z);
1856 x = match_dline(&a, &b);
1857 fossil_print("%d\n", x);
1858 }
1859
1860 /* Forward declarations for recursion */
1861 static unsigned char *diffBlockAlignment(
1862 DLine *aLeft, int nLeft, /* Text on the left */
1863 DLine *aRight, int nRight, /* Text on the right */
1864 DiffConfig *pCfg, /* Configuration options */
1865 int *pNResult /* OUTPUT: Bytes of result */
1866 );
1867 static void longestCommonSequence(
1868 DContext *p, /* Two files being compared */
1869 int iS1, int iE1, /* Range of lines in p->aFrom[] */
1870 int iS2, int iE2, /* Range of lines in p->aTo[] */
1871 int *piSX, int *piEX, /* Write p->aFrom[] common segment here */
1872 int *piSY, int *piEY /* Write p->aTo[] common segment here */
1873 );
1874
1875 /*
1876 ** Make a copy of a list of nLine DLine objects from one array to
1877 ** another. Hash the new array to ignore whitespace.
1878 */
1879 static void diffDLineXfer(
1880 DLine *aTo,
1881 const DLine *aFrom,
1882 int nLine
1883 ){
1884 int i, j, k;
1885 u64 h, h2;
1886 for(i=0; i<nLine; i++) aTo[i].iHash = 0;
1887 for(i=0; i<nLine; i++){
1888 const char *z = aFrom[i].z;
1889 int n = aFrom[i].n;
1890 for(j=0; j<n && diff_isspace(z[j]); j++){}
1891 aTo[i].z = &z[j];
1892 for(k=aFrom[i].n; k>j && diff_isspace(z[k-1]); k--){}
1893 aTo[i].n = n = k-j;
1894 aTo[i].indent = 0;
1895 aTo[i].nw = 0;
1896 for(h=0; j<k; j++){
1897 char c = z[j];
1898 if( !diff_isspace(c) ){
1899 h = (h^c)*9000000000000000041LL;
1900 }
1901 }
1902 aTo[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | n;
1903 h2 = h % nLine;
1904 aTo[i].iNext = aTo[h2].iHash;
1905 aTo[h2].iHash = i+1;
1906 }
1907 }
1908
1909
1910 /*
1911 ** For a difficult diff-block alignment that was originally for
1912 ** the default consider-all-whitespace algorithm, try to find the
1913 ** longest common subsequence between the two blocks that involves
1914 ** only whitespace changes.
1915 */
1916 static unsigned char *diffBlockAlignmentIgnoreSpace(
1917 DLine *aLeft, int nLeft, /* Text on the left */
1918 DLine *aRight, int nRight, /* Text on the right */
1919 DiffConfig *pCfg, /* Configuration options */
1920 int *pNResult /* OUTPUT: Bytes of result */
1921 ){
1922 DContext dc;
1923 int iSX, iEX; /* Start and end of LCS on the left */
1924 int iSY, iEY; /* Start and end of the LCS on the right */
1925 unsigned char *a1, *a2;
1926 int n1, n2, nLCS;
1927
1928 dc.aEdit = 0;
1929 dc.nEdit = 0;
1930 dc.nEditAlloc = 0;
1931 dc.nFrom = nLeft;
1932 dc.nTo = nRight;
1933 dc.xDiffer = compare_dline_ignore_allws;
1934 dc.aFrom = fossil_malloc( sizeof(DLine)*(nLeft+nRight) );
1935 dc.aTo = &dc.aFrom[dc.nFrom];
1936 diffDLineXfer(dc.aFrom, aLeft, nLeft);
1937 diffDLineXfer(dc.aTo, aRight, nRight);
1938 longestCommonSequence(&dc,0,nLeft,0,nRight,&iSX,&iEX,&iSY,&iEY);
1939 fossil_free(dc.aFrom);
1940 nLCS = iEX - iSX;
1941 if( nLCS<5 ) return 0; /* No good LCS was found */
1942
1943 if( pCfg->diffFlags & DIFF_DEBUG ){
1944 fossil_print(" LCS size=%d\n"
1945 " [%.*s]\n"
1946 " [%.*s]\n",
1947 nLCS, aLeft[iSX].n, aLeft[iSX].z,
1948 aLeft[iEX-1].n, aLeft[iEX-1].z);
1949 }
1950
1951 a1 = diffBlockAlignment(aLeft,iSX,aRight,iSY,pCfg,&n1);
1952 a2 = diffBlockAlignment(aLeft+iEX, nLeft-iEX,
1953 aRight+iEY, nRight-iEY,
1954 pCfg, &n2);
1955 a1 = fossil_realloc(a1, n1+nLCS+n2);
1956 memcpy(a1+n1+nLCS,a2,n2);
1957 memset(a1+n1,3,nLCS);
1958 fossil_free(a2);
1959 *pNResult = n1+n2+nLCS;
1960 return a1;
1961 }
1962
1963
1964 /*
1965 ** This is a helper route for diffBlockAlignment(). In this case,
1966 ** a very large block is encountered that might be too expensive to
1967 ** use the O(N*N) Wagner edit distance algorithm. So instead, this
1968 ** block implements a less-precise but faster O(N*logN) divide-and-conquer
1969 ** approach.
1970 */
1971 static unsigned char *diffBlockAlignmentDivideAndConquer(
1972 DLine *aLeft, int nLeft, /* Text on the left */
1973 DLine *aRight, int nRight, /* Text on the right */
1974 DiffConfig *pCfg, /* Configuration options */
1975 int *pNResult /* OUTPUT: Bytes of result */
1976 ){
1977 DLine *aSmall; /* The smaller of aLeft and aRight */
1978 DLine *aBig; /* The larger of aLeft and aRight */
1979 int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1980 int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1981 int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
1982 unsigned char *a1, *a2; /* Results of the alignments on two halves */
1983 int n1, n2; /* Number of entries in a1 and a2 */
1984 int score, bestScore; /* Score and best score seen so far */
1985 int i; /* Loop counter */
1986
1987 if( nLeft>nRight ){
1988 aSmall = aRight;
1989 nSmall = nRight;
1990 aBig = aLeft;
1991 nBig = nLeft;
1992 }else{
1993 aSmall = aLeft;
1994 nSmall = nLeft;
1995 aBig = aRight;
1996 nBig = nRight;
1997 }
1998 iDivBig = nBig/2;
1999 iDivSmall = nSmall/2;
2000
2001 if( pCfg->diffFlags & DIFF_DEBUG ){
2002 fossil_print(" Divide at [%.*s]\n",
2003 aBig[iDivBig].n, aBig[iDivBig].z);
2004 }
2005
2006 bestScore = 10000;
2007 for(i=0; i<nSmall; i++){
2008 score = match_dline(aBig+iDivBig, aSmall+i) + abs(i-nSmall/2)*2;
2009 if( score<bestScore ){
2010 bestScore = score;
2011 iDivSmall = i;
2012 }
2013 }
2014 if( aSmall==aRight ){
2015 iDivRight = iDivSmall;
2016 iDivLeft = iDivBig;
2017 }else{
2018 iDivRight = iDivBig;
2019 iDivLeft = iDivSmall;
2020 }
2021 a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
2022 a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
2023 aRight+iDivRight, nRight-iDivRight,
2024 pCfg, &n2);
2025 a1 = fossil_realloc(a1, n1+n2 );
2026 memcpy(a1+n1,a2,n2);
2027 fossil_free(a2);
2028 *pNResult = n1+n2;
2029 return a1;
2030 }
2031
2032
2033 /*
2034 ** The threshold at which diffBlockAlignment transitions from the
2035 ** O(N*N) Wagner minimum-edit-distance algorithm to a less process
2036 ** O(NlogN) divide-and-conquer approach.
@@ -1850,14 +2060,14 @@
2060 ** each other. Insertion and deletion costs are 50. Match costs
2061 ** are between 0 and 100 where 0 is a perfect match 100 is a complete
2062 ** mismatch.
2063 */
2064 static unsigned char *diffBlockAlignment(
2065 DLine *aLeft, int nLeft, /* Text on the left */
2066 DLine *aRight, int nRight, /* Text on the right */
2067 DiffConfig *pCfg, /* Configuration options */
2068 int *pNResult /* OUTPUT: Bytes of result */
2069 ){
2070 int i, j, k; /* Loop counters */
2071 int *a; /* One row of the Wagner matrix */
2072 int *pToFree; /* Space that needs to be freed */
2073 unsigned char *aM; /* Wagner result matrix */
@@ -1875,61 +2085,28 @@
2085 memset(aM, 1, nLeft);
2086 *pNResult = nLeft;
2087 return aM;
2088 }
2089
2090 if( pCfg->diffFlags & DIFF_DEBUG ){
2091 fossil_print("BlockAlignment:\n [%.*s] + %d\n [%.*s] + %d\n",
2092 aLeft[0].n, aLeft[0].z, nLeft,
2093 aRight[0].n, aRight[0].z, nRight);
2094 }
2095
2096 /* For large alignments, try to use alternative algorithms that are
2097 ** faster than the O(N*N) Wagner edit distance.
2098 */
2099 if( nLeft*nRight>DIFF_ALIGN_MX && (pCfg->diffFlags & DIFF_SLOW_SBS)==0 ){
2100 if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==0 ){
2101 unsigned char *aRes;
2102 aRes = diffBlockAlignmentIgnoreSpace(
2103 aLeft, nLeft,aRight, nRight,pCfg,pNResult);
2104 if( aRes ) return aRes;
2105 }
2106 return diffBlockAlignmentDivideAndConquer(
2107 aLeft, nLeft,aRight, nRight,pCfg,pNResult);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2108 }
2109
2110 /* If we reach this point, we will be doing an O(N*N) Wagner minimum
2111 ** edit distance to compute the alignment.
2112 */
@@ -2026,12 +2203,12 @@
2203 static void formatDiff(
2204 DContext *p, /* The computed diff */
2205 DiffConfig *pCfg, /* Configuration options */
2206 DiffBuilder *pBuilder /* The formatter object */
2207 ){
2208 DLine *A; /* Left side of the diff */
2209 DLine *B; /* Right side of the diff */
2210 unsigned int a = 0; /* Index of next line in A[] */
2211 unsigned int b = 0; /* Index of next line in B[] */
2212 const int *R; /* Array of COPY/DELETE/INSERT triples */
2213 unsigned int r; /* Index into R[] */
2214 unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -2410,10 +2587,125 @@
2587 }
2588 p->aEdit[p->nEdit++] = nCopy;
2589 p->aEdit[p->nEdit++] = nDel;
2590 p->aEdit[p->nEdit++] = nIns;
2591 }
2592
2593 /*
2594 ** A common subsequence between p->aFrom and p->aTo has been found.
2595 ** This routine tries to judge if the subsequence really is a valid
2596 ** match or rather is just an artifact of an indentation change.
2597 **
2598 ** Return non-zero if the subsequence is valid. Return zero if the
2599 ** subsequence seems likely to be an editing artifact and should be
2600 ** ignored.
2601 **
2602 ** This routine is a heuristic optimization intended to give more
2603 ** intuitive diff results following an indentation change it code that
2604 ** is formatted similarly to C/C++, Javascript, Go, TCL, and similar
2605 ** languages that use {...} for nesting. A correct diff is computed
2606 ** even if this routine always returns true (non-zero). But sometimes
2607 ** a more intuitive diff can result if this routine returns false.
2608 **
2609 ** The subsequences consists of the rows iSX through iEX-1 (inclusive)
2610 ** in p->aFrom[]. The total sequences is iS1 through iE1-1 (inclusive)
2611 ** of p->aFrom[].
2612 **
2613 ** Example where this heuristic is useful, see the diff at
2614 ** https://www.sqlite.org/src/fdiff?v1=0e79dd15cbdb4f48&v2=33955a6fd874dd97
2615 **
2616 ** See also discussion at https://fossil-scm.org/forum/forumpost/9ba3284295
2617 **
2618 ** ALGORITHM (subject to change and refinement):
2619 **
2620 ** 1. If the subsequence is larger than 1/7th of the original span,
2621 ** then consider it valid. --> return 1
2622 **
2623 ** 2. If no lines of the subsequence contains more than one
2624 ** non-whitespace character, --> return 0
2625 **
2626 ** 3. If any line of the subsequence contains more than one non-whitespace
2627 ** character and is unique across the entire sequence after ignoring
2628 ** leading and trailing whitespace --> return 1
2629 **
2630 ** 4. Otherwise, it is potentially an artifact of an indentation
2631 ** change. --> return 0
2632 */
2633 static int likelyNotIndentChngArtifact(
2634 DContext *p, /* The complete diff context */
2635 int iS1, /* Start of the main segment */
2636 int iSX, /* Start of the subsequence */
2637 int iEX, /* First row past the end of the subsequence */
2638 int iE1 /* First row past the end of the main segment */
2639 ){
2640 int i, j, n;
2641
2642 /* Rule (1) */
2643 if( (iEX-iSX)*7 >= (iE1-iS1) ) return 1;
2644
2645 /* Compute DLine.indent and DLine.nw for all lines of the subsequence.
2646 ** If no lines contain more than one non-whitespace character return
2647 ** 0 because the subsequence could be due to an indentation change.
2648 ** Rule (2).
2649 */
2650 n = 0;
2651 for(i=iSX; i<iEX; i++){
2652 DLine *pA = &p->aFrom[i];
2653 if( pA->nw==0 && pA->n ){
2654 const char *zA = pA->z;
2655 const int nn = pA->n;
2656 int ii, jj;
2657 for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2658 pA->indent = ii;
2659 for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2660 pA->nw = jj - ii + 1;
2661 }
2662 if( pA->nw>1 ) n++;
2663 }
2664 if( n==0 ) return 0;
2665
2666 /* Compute DLine.indent and DLine.nw for the entire sequence */
2667 for(i=iS1; i<iE1; i++){
2668 DLine *pA;
2669 if( i==iSX ){
2670 i = iEX;
2671 if( i>=iE1 ) break;
2672 }
2673 pA = &p->aFrom[i];
2674 if( pA->nw==0 && pA->n ){
2675 const char *zA = pA->z;
2676 const int nn = pA->n;
2677 int ii, jj;
2678 for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2679 pA->indent = ii;
2680 for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2681 pA->nw = jj - ii + 1;
2682 }
2683 }
2684
2685 /* Check to see if any subsequence line that has more than one
2686 ** non-whitespace character is unique across the entire sequence.
2687 ** Rule (3)
2688 */
2689 for(i=iSX; i<iEX; i++){
2690 const char *z = p->aFrom[i].z + p->aFrom[i].indent;
2691 const int nw = p->aFrom[i].nw;
2692 if( nw<=1 ) continue;
2693 for(j=iS1; j<iSX; j++){
2694 if( p->aFrom[j].nw!=nw ) continue;
2695 if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2696 }
2697 if( j<iSX ) continue;
2698 for(j=iEX; j<iE1; j++){
2699 if( p->aFrom[j].nw!=nw ) continue;
2700 if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2701 }
2702 if( j>=iE1 ) break;
2703 }
2704 return i<iEX;
2705 }
2706
2707
2708 /*
2709 ** Do a single step in the difference. Compute a sequence of
2710 ** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
2711 ** the input into lines iS2 through iE2-1 of the output and write
@@ -2442,11 +2734,13 @@
2734 }
2735
2736 /* Find the longest matching segment between the two sequences */
2737 longestCommonSequence(p, iS1, iE1, iS2, iE2, &iSX, &iEX, &iSY, &iEY);
2738
2739 if( iEX>iSX+5
2740 || (iEX>iSX && likelyNotIndentChngArtifact(p,iS1,iSX,iEX,iE1) )
2741 ){
2742 /* A common segment has been found.
2743 ** Recursively diff either side of the matching segment */
2744 diff_step(p, iS1, iSX, iS2, iSY);
2745 if( iEX>iSX ){
2746 appendTriple(p, iEX - iSX, 0, 0);
@@ -3120,11 +3414,12 @@
3414 if( strcmp(zLimit,"none")==0 ){
3415 iLimit = 0;
3416 mxTime = 0;
3417 }else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
3418 iLimit = 0;
3419 mxTime =
3420 (sqlite3_int64)(current_time_in_milliseconds() + 1000.0*atof(zLimit));
3421 }else{
3422 iLimit = atoi(zLimit);
3423 if( iLimit<=0 ) iLimit = 30;
3424 mxTime = 0;
3425 }
3426
+2 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1037,11 +1037,11 @@
10371037
** as binary
10381038
** --branch BRANCH Show diff of all changes on BRANCH
10391039
** --brief Show filenames only
10401040
** -b|--browser Show the diff output in a web-browser
10411041
** --by Shorthand for "--browser -y"
1042
-** --checkin VERSION Show diff of all changes in VERSION
1042
+** -ci|--checkin VERSION Show diff of all changes in VERSION
10431043
** --command PROG External diff program. Overrides "diff-command"
10441044
** -c|--context N Show N lines of context around each change
10451045
** --diff-binary BOOL Include binary files with external commands
10461046
** --exec-abs-paths Force absolute path names on external commands
10471047
** --exec-rel-paths Force relative path names on external commands
@@ -1079,11 +1079,11 @@
10791079
return;
10801080
}
10811081
isGDiff = g.argv[1][0]=='g';
10821082
zFrom = find_option("from", "r", 1);
10831083
zTo = find_option("to", 0, 1);
1084
- zCheckin = find_option("checkin", 0, 1);
1084
+ zCheckin = find_option("checkin", "ci", 1);
10851085
zBranch = find_option("branch", 0, 1);
10861086
againstUndo = find_option("undo",0,0)!=0;
10871087
if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
10881088
fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
10891089
" or --branch");
10901090
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1037,11 +1037,11 @@
1037 ** as binary
1038 ** --branch BRANCH Show diff of all changes on BRANCH
1039 ** --brief Show filenames only
1040 ** -b|--browser Show the diff output in a web-browser
1041 ** --by Shorthand for "--browser -y"
1042 ** --checkin VERSION Show diff of all changes in VERSION
1043 ** --command PROG External diff program. Overrides "diff-command"
1044 ** -c|--context N Show N lines of context around each change
1045 ** --diff-binary BOOL Include binary files with external commands
1046 ** --exec-abs-paths Force absolute path names on external commands
1047 ** --exec-rel-paths Force relative path names on external commands
@@ -1079,11 +1079,11 @@
1079 return;
1080 }
1081 isGDiff = g.argv[1][0]=='g';
1082 zFrom = find_option("from", "r", 1);
1083 zTo = find_option("to", 0, 1);
1084 zCheckin = find_option("checkin", 0, 1);
1085 zBranch = find_option("branch", 0, 1);
1086 againstUndo = find_option("undo",0,0)!=0;
1087 if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
1088 fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
1089 " or --branch");
1090
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1037,11 +1037,11 @@
1037 ** as binary
1038 ** --branch BRANCH Show diff of all changes on BRANCH
1039 ** --brief Show filenames only
1040 ** -b|--browser Show the diff output in a web-browser
1041 ** --by Shorthand for "--browser -y"
1042 ** -ci|--checkin VERSION Show diff of all changes in VERSION
1043 ** --command PROG External diff program. Overrides "diff-command"
1044 ** -c|--context N Show N lines of context around each change
1045 ** --diff-binary BOOL Include binary files with external commands
1046 ** --exec-abs-paths Force absolute path names on external commands
1047 ** --exec-rel-paths Force relative path names on external commands
@@ -1079,11 +1079,11 @@
1079 return;
1080 }
1081 isGDiff = g.argv[1][0]=='g';
1082 zFrom = find_option("from", "r", 1);
1083 zTo = find_option("to", 0, 1);
1084 zCheckin = find_option("checkin", "ci", 1);
1085 zBranch = find_option("branch", 0, 1);
1086 againstUndo = find_option("undo",0,0)!=0;
1087 if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
1088 fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
1089 " or --branch");
1090
--- src/dispatch.c
+++ src/dispatch.c
@@ -1008,17 +1008,20 @@
10081008
/* @-comment: # */
10091009
static const char zOptions[] =
10101010
@ Command-line options common to all commands:
10111011
@
10121012
@ --args FILENAME Read additional arguments and options from FILENAME
1013
+@ --case-sensitive BOOL Set case sensitivity for file names
10131014
@ --cgitrace Active CGI tracing
1015
+@ --chdir PATH Change to PATH before performing any operations
10141016
@ --comfmtflags VALUE Set comment formatting flags to VALUE
10151017
@ --comment-format VALUE Alias for --comfmtflags
10161018
@ --errorlog FILENAME Log errors to FILENAME
10171019
@ --help Show help on the command rather than running it
10181020
@ --httptrace Trace outbound HTTP requests
10191021
@ --localtime Display times using the local timezone
1022
+@ --nocgi Do not act as CGI
10201023
@ --no-th-hook Do not run TH1 hooks
10211024
@ --quiet Reduce the amount of output
10221025
@ --sqlstats Show SQL usage statistics when done
10231026
@ --sqltrace Trace all SQL commands
10241027
@ --sshtrace Trace SSH activity
10251028
--- src/dispatch.c
+++ src/dispatch.c
@@ -1008,17 +1008,20 @@
1008 /* @-comment: # */
1009 static const char zOptions[] =
1010 @ Command-line options common to all commands:
1011 @
1012 @ --args FILENAME Read additional arguments and options from FILENAME
 
1013 @ --cgitrace Active CGI tracing
 
1014 @ --comfmtflags VALUE Set comment formatting flags to VALUE
1015 @ --comment-format VALUE Alias for --comfmtflags
1016 @ --errorlog FILENAME Log errors to FILENAME
1017 @ --help Show help on the command rather than running it
1018 @ --httptrace Trace outbound HTTP requests
1019 @ --localtime Display times using the local timezone
 
1020 @ --no-th-hook Do not run TH1 hooks
1021 @ --quiet Reduce the amount of output
1022 @ --sqlstats Show SQL usage statistics when done
1023 @ --sqltrace Trace all SQL commands
1024 @ --sshtrace Trace SSH activity
1025
--- src/dispatch.c
+++ src/dispatch.c
@@ -1008,17 +1008,20 @@
1008 /* @-comment: # */
1009 static const char zOptions[] =
1010 @ Command-line options common to all commands:
1011 @
1012 @ --args FILENAME Read additional arguments and options from FILENAME
1013 @ --case-sensitive BOOL Set case sensitivity for file names
1014 @ --cgitrace Active CGI tracing
1015 @ --chdir PATH Change to PATH before performing any operations
1016 @ --comfmtflags VALUE Set comment formatting flags to VALUE
1017 @ --comment-format VALUE Alias for --comfmtflags
1018 @ --errorlog FILENAME Log errors to FILENAME
1019 @ --help Show help on the command rather than running it
1020 @ --httptrace Trace outbound HTTP requests
1021 @ --localtime Display times using the local timezone
1022 @ --nocgi Do not act as CGI
1023 @ --no-th-hook Do not run TH1 hooks
1024 @ --quiet Reduce the amount of output
1025 @ --sqlstats Show SQL usage statistics when done
1026 @ --sqltrace Trace all SQL commands
1027 @ --sshtrace Trace SSH activity
1028
+12
--- src/extcgi.c
+++ src/extcgi.c
@@ -68,10 +68,11 @@
6868
"SCRIPT_FILENAME",
6969
"SCRIPT_NAME",
7070
"SERVER_NAME",
7171
"SERVER_PORT",
7272
"SERVER_PROTOCOL",
73
+ "SERVER_SOFTWARE",
7374
};
7475
7576
/*
7677
** Check a pathname to determine if it is acceptable for use as
7778
** extension CGI. Some pathnames are excluded for security reasons.
@@ -171,10 +172,11 @@
171172
int rc; /* Reply code from subroutine call */
172173
int nContent = -1; /* Content length */
173174
const char *zPathInfo; /* Original PATH_INFO value */
174175
Blob reply; /* The reply */
175176
char zLine[1000]; /* One line of the CGI reply */
177
+ const char *zSrvSw; /* SERVER_SOFTWARE */
176178
177179
zPathInfo = P("PATH_INFO");
178180
login_check_credentials();
179181
blob_init(&reply, 0, 0);
180182
if( g.zExtRoot==0 ){
@@ -259,10 +261,20 @@
259261
cgi_set_parameter_nocopy("FOSSIL_REPOSITORY", g.zRepositoryName, 0);
260262
cgi_set_parameter_nocopy("FOSSIL_URI", g.zTop, 0);
261263
cgi_set_parameter_nocopy("FOSSIL_CAPABILITIES",
262264
db_text("","SELECT fullcap(cap) FROM user WHERE login=%Q",
263265
g.zLogin ? g.zLogin : "nobody"), 0);
266
+ zSrvSw = P("SERVER_SOFTWARE");
267
+ if( zSrvSw==0 ){
268
+ zSrvSw = get_version();
269
+ }else{
270
+ char *z = mprintf("fossil version %s", get_version());
271
+ if( strncmp(zSrvSw,z,strlen(z)-4)!=0 ){
272
+ zSrvSw = mprintf("%z, %s", z, zSrvSw);
273
+ }
274
+ }
275
+ cgi_replace_parameter("SERVER_SOFTWARE", zSrvSw);
264276
cgi_replace_parameter("GATEWAY_INTERFACE","CGI/1.0");
265277
for(i=0; i<sizeof(azCgiEnv)/sizeof(azCgiEnv[0]); i++){
266278
(void)P(azCgiEnv[i]);
267279
}
268280
fossil_clearenv();
269281
--- src/extcgi.c
+++ src/extcgi.c
@@ -68,10 +68,11 @@
68 "SCRIPT_FILENAME",
69 "SCRIPT_NAME",
70 "SERVER_NAME",
71 "SERVER_PORT",
72 "SERVER_PROTOCOL",
 
73 };
74
75 /*
76 ** Check a pathname to determine if it is acceptable for use as
77 ** extension CGI. Some pathnames are excluded for security reasons.
@@ -171,10 +172,11 @@
171 int rc; /* Reply code from subroutine call */
172 int nContent = -1; /* Content length */
173 const char *zPathInfo; /* Original PATH_INFO value */
174 Blob reply; /* The reply */
175 char zLine[1000]; /* One line of the CGI reply */
 
176
177 zPathInfo = P("PATH_INFO");
178 login_check_credentials();
179 blob_init(&reply, 0, 0);
180 if( g.zExtRoot==0 ){
@@ -259,10 +261,20 @@
259 cgi_set_parameter_nocopy("FOSSIL_REPOSITORY", g.zRepositoryName, 0);
260 cgi_set_parameter_nocopy("FOSSIL_URI", g.zTop, 0);
261 cgi_set_parameter_nocopy("FOSSIL_CAPABILITIES",
262 db_text("","SELECT fullcap(cap) FROM user WHERE login=%Q",
263 g.zLogin ? g.zLogin : "nobody"), 0);
 
 
 
 
 
 
 
 
 
 
264 cgi_replace_parameter("GATEWAY_INTERFACE","CGI/1.0");
265 for(i=0; i<sizeof(azCgiEnv)/sizeof(azCgiEnv[0]); i++){
266 (void)P(azCgiEnv[i]);
267 }
268 fossil_clearenv();
269
--- src/extcgi.c
+++ src/extcgi.c
@@ -68,10 +68,11 @@
68 "SCRIPT_FILENAME",
69 "SCRIPT_NAME",
70 "SERVER_NAME",
71 "SERVER_PORT",
72 "SERVER_PROTOCOL",
73 "SERVER_SOFTWARE",
74 };
75
76 /*
77 ** Check a pathname to determine if it is acceptable for use as
78 ** extension CGI. Some pathnames are excluded for security reasons.
@@ -171,10 +172,11 @@
172 int rc; /* Reply code from subroutine call */
173 int nContent = -1; /* Content length */
174 const char *zPathInfo; /* Original PATH_INFO value */
175 Blob reply; /* The reply */
176 char zLine[1000]; /* One line of the CGI reply */
177 const char *zSrvSw; /* SERVER_SOFTWARE */
178
179 zPathInfo = P("PATH_INFO");
180 login_check_credentials();
181 blob_init(&reply, 0, 0);
182 if( g.zExtRoot==0 ){
@@ -259,10 +261,20 @@
261 cgi_set_parameter_nocopy("FOSSIL_REPOSITORY", g.zRepositoryName, 0);
262 cgi_set_parameter_nocopy("FOSSIL_URI", g.zTop, 0);
263 cgi_set_parameter_nocopy("FOSSIL_CAPABILITIES",
264 db_text("","SELECT fullcap(cap) FROM user WHERE login=%Q",
265 g.zLogin ? g.zLogin : "nobody"), 0);
266 zSrvSw = P("SERVER_SOFTWARE");
267 if( zSrvSw==0 ){
268 zSrvSw = get_version();
269 }else{
270 char *z = mprintf("fossil version %s", get_version());
271 if( strncmp(zSrvSw,z,strlen(z)-4)!=0 ){
272 zSrvSw = mprintf("%z, %s", z, zSrvSw);
273 }
274 }
275 cgi_replace_parameter("SERVER_SOFTWARE", zSrvSw);
276 cgi_replace_parameter("GATEWAY_INTERFACE","CGI/1.0");
277 for(i=0; i<sizeof(azCgiEnv)/sizeof(azCgiEnv[0]); i++){
278 (void)P(azCgiEnv[i]);
279 }
280 fossil_clearenv();
281
-3
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
12951295
/*
12961296
** The input is the name of an executable, such as one might
12971297
** type on a command-line. This routine resolves that name into
12981298
** a full pathname. The result is obtained from fossil_malloc()
12991299
** and should be freed by the caller.
1300
-**
1301
-** This routine only works on unix. On Windows, simply return
1302
-** a copy of the input.
13031300
*/
13041301
char *file_fullexename(const char *zCmd){
13051302
#ifdef _WIN32
13061303
char *zPath;
13071304
char *z = 0;
13081305
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
1295 /*
1296 ** The input is the name of an executable, such as one might
1297 ** type on a command-line. This routine resolves that name into
1298 ** a full pathname. The result is obtained from fossil_malloc()
1299 ** and should be freed by the caller.
1300 **
1301 ** This routine only works on unix. On Windows, simply return
1302 ** a copy of the input.
1303 */
1304 char *file_fullexename(const char *zCmd){
1305 #ifdef _WIN32
1306 char *zPath;
1307 char *z = 0;
1308
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
1295 /*
1296 ** The input is the name of an executable, such as one might
1297 ** type on a command-line. This routine resolves that name into
1298 ** a full pathname. The result is obtained from fossil_malloc()
1299 ** and should be freed by the caller.
 
 
 
1300 */
1301 char *file_fullexename(const char *zCmd){
1302 #ifdef _WIN32
1303 char *zPath;
1304 char *z = 0;
1305
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -503,11 +503,11 @@
503503
circle "circle" at 1in right of previous
504504
ellipse "ellipse" at 1in right of previous
505505
506506
# second row of objects
507507
OVAL1: oval "oval" at 1in below first box
508
-oval "(tall &amp;" "thin)" "oval" width OVAL1.height height OVAL1.width \
508
+oval "(tall &" "thin)" "oval" width OVAL1.height height OVAL1.width \
509509
at 1in right of previous
510510
cylinder "cylinder" at 1in right of previous
511511
file "file" at 1in right of previous
512512
513513
# third row shows line-type objects
@@ -590,11 +590,11 @@
590590
arrow 50%
591591
circle same "2"
592592
arrow right 0.8in "goes" "offline"
593593
C5: circle same as A3 "5"
594594
arrow right until even with first ellipse.w \
595
- "back online" above "pushes 5" below "pulls 3 &amp; 4" below
595
+ "back online" above "pushes 5" below "pulls 3 & 4" below
596596
ellipse same "future"
597597
598598
# content for the Darlene lane
599599
D1: circle same as A1 at C1-(0,$laneh) "1"
600600
arrow 50%
601601
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -503,11 +503,11 @@
503 circle "circle" at 1in right of previous
504 ellipse "ellipse" at 1in right of previous
505
506 # second row of objects
507 OVAL1: oval "oval" at 1in below first box
508 oval "(tall &amp;" "thin)" "oval" width OVAL1.height height OVAL1.width \
509 at 1in right of previous
510 cylinder "cylinder" at 1in right of previous
511 file "file" at 1in right of previous
512
513 # third row shows line-type objects
@@ -590,11 +590,11 @@
590 arrow 50%
591 circle same "2"
592 arrow right 0.8in "goes" "offline"
593 C5: circle same as A3 "5"
594 arrow right until even with first ellipse.w \
595 "back online" above "pushes 5" below "pulls 3 &amp; 4" below
596 ellipse same "future"
597
598 # content for the Darlene lane
599 D1: circle same as A1 at C1-(0,$laneh) "1"
600 arrow 50%
601
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -503,11 +503,11 @@
503 circle "circle" at 1in right of previous
504 ellipse "ellipse" at 1in right of previous
505
506 # second row of objects
507 OVAL1: oval "oval" at 1in below first box
508 oval "(tall &" "thin)" "oval" width OVAL1.height height OVAL1.width \
509 at 1in right of previous
510 cylinder "cylinder" at 1in right of previous
511 file "file" at 1in right of previous
512
513 # third row shows line-type objects
@@ -590,11 +590,11 @@
590 arrow 50%
591 circle same "2"
592 arrow right 0.8in "goes" "offline"
593 C5: circle same as A3 "5"
594 arrow right until even with first ellipse.w \
595 "back online" above "pushes 5" below "pulls 3 & 4" below
596 ellipse same "future"
597
598 # content for the Darlene lane
599 D1: circle same as A1 at C1-(0,$laneh) "1"
600 arrow 50%
601
+7 -2
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
2020
**
2121
** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
2222
** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
2323
** the Fuse Filesystem, of course.
2424
*/
25
-#ifdef FOSSIL_HAVE_FUSEFS
2625
#include "config.h"
2726
#include <stdio.h>
2827
#include <string.h>
28
+#ifdef FOSSIL_HAVE_FUSEFS
2929
#include <errno.h>
3030
#include <fcntl.h>
3131
#include <stdlib.h>
3232
#include <unistd.h>
3333
#include <sys/types.h>
@@ -283,10 +283,11 @@
283283
static struct fuse_operations fusefs_methods = {
284284
.getattr = fusefs_getattr,
285285
.readdir = fusefs_readdir,
286286
.read = fusefs_read,
287287
};
288
+#endif /* FOSSIL_HAVE_FUSEFS */
288289
289290
/*
290291
** COMMAND: fusefs*
291292
**
292293
** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
314315
** After stopping the "fossil fusefs" command, it might also be necessary
315316
** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316317
** again.
317318
*/
318319
void fusefs_cmd(void){
320
+#ifdef FOSSIL_HAVE_FUSEFS
319321
char *zMountPoint;
320322
char *azNewArgv[5];
321323
int doDebug = find_option("debug","d",0)!=0;
322324
323325
db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
335337
azNewArgv[4] = 0;
336338
g.localOpen = 0; /* Prevent tags like "current" and "prev" */
337339
fuse_main(4, azNewArgv, &fusefs_methods, NULL);
338340
fusefs_reset();
339341
fusefs_clear_path();
340
-}
342
+#else
343
+ fprintf(stderr, "The FuseFS is not available in this build.\n");
344
+ exit(1);
341345
#endif /* FOSSIL_HAVE_FUSEFS */
346
+}
342347
343348
/*
344349
** Return version numbers for the FUSE header that was used at compile-time
345350
** and/or the FUSE library that was loaded at runtime.
346351
*/
347352
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
25 #ifdef FOSSIL_HAVE_FUSEFS
26 #include "config.h"
27 #include <stdio.h>
28 #include <string.h>
 
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
@@ -283,10 +283,11 @@
283 static struct fuse_operations fusefs_methods = {
284 .getattr = fusefs_getattr,
285 .readdir = fusefs_readdir,
286 .read = fusefs_read,
287 };
 
288
289 /*
290 ** COMMAND: fusefs*
291 **
292 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
314 ** After stopping the "fossil fusefs" command, it might also be necessary
315 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316 ** again.
317 */
318 void fusefs_cmd(void){
 
319 char *zMountPoint;
320 char *azNewArgv[5];
321 int doDebug = find_option("debug","d",0)!=0;
322
323 db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
335 azNewArgv[4] = 0;
336 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
337 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
338 fusefs_reset();
339 fusefs_clear_path();
340 }
 
 
341 #endif /* FOSSIL_HAVE_FUSEFS */
 
342
343 /*
344 ** Return version numbers for the FUSE header that was used at compile-time
345 ** and/or the FUSE library that was loaded at runtime.
346 */
347
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
 
25 #include "config.h"
26 #include <stdio.h>
27 #include <string.h>
28 #ifdef FOSSIL_HAVE_FUSEFS
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
@@ -283,10 +283,11 @@
283 static struct fuse_operations fusefs_methods = {
284 .getattr = fusefs_getattr,
285 .readdir = fusefs_readdir,
286 .read = fusefs_read,
287 };
288 #endif /* FOSSIL_HAVE_FUSEFS */
289
290 /*
291 ** COMMAND: fusefs*
292 **
293 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
315 ** After stopping the "fossil fusefs" command, it might also be necessary
316 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
317 ** again.
318 */
319 void fusefs_cmd(void){
320 #ifdef FOSSIL_HAVE_FUSEFS
321 char *zMountPoint;
322 char *azNewArgv[5];
323 int doDebug = find_option("debug","d",0)!=0;
324
325 db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
337 azNewArgv[4] = 0;
338 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
339 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
340 fusefs_reset();
341 fusefs_clear_path();
342 #else
343 fprintf(stderr, "The FuseFS is not available in this build.\n");
344 exit(1);
345 #endif /* FOSSIL_HAVE_FUSEFS */
346 }
347
348 /*
349 ** Return version numbers for the FUSE header that was used at compile-time
350 ** and/or the FUSE library that was loaded at runtime.
351 */
352
+200 -27
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
8282
int idx; /* Row index. Top row is smallest. */
8383
int idxTop; /* Direct descendent highest up on the graph */
8484
GraphRow *pChild; /* Child immediately above this node */
8585
u8 isDup; /* True if this is duplicate of a prior entry */
8686
u8 isLeaf; /* True if this is a leaf node */
87
- u8 isStepParent; /* pChild is actually a step-child */
87
+ u8 isStepParent; /* pChild is actually a step-child. The thick
88
+ ** arrow up to the child is dashed, not solid */
8889
u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
8990
u8 timeWarp; /* Child is earlier in time */
9091
u8 bDescender; /* True if riser from bottom of graph to here. */
9192
u8 selfUp; /* Space above this node but belonging */
9293
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
109110
GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110111
int nBranch; /* Number of distinct branches */
111112
char **azBranch; /* Names of the branches */
112113
int nRow; /* Number of rows */
113114
int nHash; /* Number of slots in apHash[] */
115
+ u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116
+ ** rail that the node */
117
+ u64 mergeRail; /* Rails used for merge lines */
114118
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
115119
u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
116120
};
117121
118122
#endif
@@ -119,11 +123,11 @@
119123
120124
/* The N-th bit */
121125
#define BIT(N) (((u64)1)<<(N))
122126
123127
/*
124
-** Number of rows before and answer a node with a riser or descender
128
+** Number of rows before and after a node with a riser or descender
125129
** that goes off-screen before we can reuse that rail.
126130
*/
127131
#define RISER_MARGIN 4
128132
129133
@@ -275,11 +279,12 @@
275279
** top and bottom, inclusive.
276280
*/
277281
static int findFreeRail(
278282
GraphContext *p, /* The graph context */
279283
int top, int btm, /* Span of rows for which the rail is needed */
280
- int iNearto /* Find rail nearest to this rail */
284
+ int iNearto, /* Find rail nearest to this rail */
285
+ int bMergeRail /* This rail will be used for a merge line */
281286
){
282287
GraphRow *pRow;
283288
int i;
284289
int iBest = 0;
285290
int iBestDist = 9999;
@@ -287,15 +292,38 @@
287292
for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
288293
while( pRow && pRow->idx<=btm ){
289294
inUseMask |= pRow->railInUse;
290295
pRow = pRow->pNext;
291296
}
292
- for(i=0; i<GR_MAX_RAIL; i++){
293
- if( (inUseMask & BIT(i))==0 ){
297
+
298
+ /* First look for a match that honors bMergeRail */
299
+ for(i=0; i<=p->mxRail; i++){
300
+ u64 m = BIT(i);
301
+ int dist;
302
+ if( inUseMask & m ) continue;
303
+ if( (bMergeRail!=0) != ((p->mergeRail & m)!=0) ) continue;
304
+ if( iNearto<=0 ){
305
+ iBest = i;
306
+ iBestDist = 1;
307
+ break;
308
+ }
309
+ dist = i - iNearto;
310
+ if( dist<0 ) dist = -dist;
311
+ if( dist<iBestDist ){
312
+ iBestDist = dist;
313
+ iBest = i;
314
+ }
315
+ }
316
+
317
+ /* If no match, consider all possible rails */
318
+ if( iBestDist>1000 ){
319
+ for(i=0; i<=p->mxRail+1; i++){
294320
int dist;
321
+ if( inUseMask & BIT(i) ) continue;
295322
if( iNearto<=0 ){
296323
iBest = i;
324
+ iBestDist = 1;
297325
break;
298326
}
299327
dist = i - iNearto;
300328
if( dist<0 ) dist = -dist;
301329
if( dist<iBestDist ){
@@ -304,10 +332,11 @@
304332
}
305333
}
306334
}
307335
if( iBestDist>1000 ) p->nErr++;
308336
if( iBest>p->mxRail ) p->mxRail = iBest;
337
+ if( bMergeRail ) p->mergeRail |= BIT(iBest);
309338
return iBest;
310339
}
311340
312341
/*
313342
** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
343372
p->railInUse |= mask;
344373
}
345374
}
346375
}
347376
377
+
378
+/*
379
+** Check to see if rail iRail is clear from pBottom up to and including
380
+** pTop.
381
+*/
382
+static int railIsClear(GraphRow *pBottom, int iTop, int iRail){
383
+ u64 m = BIT(iRail);
384
+ while( pBottom && pBottom->idx>=iTop ){
385
+ if( pBottom->railInUse & m ) return 0;
386
+ pBottom = pBottom->pPrev;
387
+ }
388
+ return 1;
389
+}
390
+
348391
/*
349392
** Create a merge-arrow riser going from pParent up to pChild.
350393
*/
351394
static void createMergeRiser(
352395
GraphContext *p,
353
- GraphRow *pParent,
354
- GraphRow *pChild,
355
- int isCherrypick
396
+ GraphRow *pParent, /* Lower node from which the merge line begins */
397
+ GraphRow *pChild, /* Upper node at which the merge line ends */
398
+ int isCherrypick /* True for a cherry-pick merge */
356399
){
357400
int u;
358401
u64 mask;
359402
GraphRow *pLoop;
360403
361404
if( pParent->mergeOut<0 ){
362405
u = pParent->aiRiser[pParent->iRail];
363
- if( u>0 && u<pChild->idx ){
406
+ if( u<0 && railIsClear(pParent->pPrev, pChild->idx, pParent->iRail) ){
407
+ /* pParent is a leaf and the merge-line can be drawn straight up.*/
408
+ pParent->mergeOut = pParent->iRail;
409
+ mask = BIT(pParent->iRail);
410
+ for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
411
+ pLoop=pLoop->pNext){
412
+ pLoop->railInUse |= mask;
413
+ }
414
+ }else if( u>0 && u<pChild->idx ){
364415
/* The thick arrow up to the next primary child of pDesc goes
365416
** further up than the thin merge arrow riser, so draw them both
366417
** on the same rail. */
367418
pParent->mergeOut = pParent->iRail;
368419
}else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
369420
pParent->mergeOut = pParent->iRail;
370421
}else{
371422
/* The thin merge arrow riser is taller than the thick primary
372423
** child riser, so use separate rails. */
373424
int iTarget = pParent->iRail;
374
- pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
425
+ if( u<0 ) p->hasOffsetMergeRiser = 1;
426
+ pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
427
+ iTarget, 1);
375428
mask = BIT(pParent->mergeOut);
376429
for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
377430
pLoop=pLoop->pNext){
378431
pLoop->railInUse |= mask;
379432
}
@@ -420,11 +473,10 @@
420473
while( pRow && (n--)>0 ){
421474
pRow->railInUse |= mask;
422475
pRow = pRow->pPrev;
423476
}
424477
}
425
-
426478
427479
/*
428480
** Compute the complete graph
429481
**
430482
** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
646698
if( i==0 && pRow->zBranch!=zTrunk ) continue;
647699
if( pRow->iRail>=0 ) continue;
648700
if( pRow->isDup ) continue;
649701
if( pRow->nParent<0 ) continue;
650702
if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
651
- pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin, 0);
703
+ pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0);
652704
if( p->mxRail>=GR_MAX_RAIL ) return;
653705
mask = BIT(pRow->iRail);
654706
if( !omitDescenders ){
655707
int n = RISER_MARGIN;
656708
pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
690742
}
691743
if( pParent->idx>pRow->idx ){
692744
/* Common case: Child occurs after parent and is above the
693745
** parent in the timeline */
694746
pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
695
- pParent->iRail);
747
+ pParent->iRail, 0);
696748
if( p->mxRail>=GR_MAX_RAIL ) return;
697749
pParent->aiRiser[pRow->iRail] = pRow->idx;
698750
}else{
699751
/* Timewarp case: Child occurs earlier in time than parent and
700752
** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
741793
int isCherrypick = 0;
742794
for(i=1; i<pRow->nParent; i++){
743795
GraphRowId parentRid = pRow->aParent[i];
744796
if( i==pRow->nNonCherrypick ){
745797
/* Because full merges are laid out before cherrypicks,
746
- ** it is ok to use a full-merge raise for a cherrypick.
798
+ ** it is ok to use a full-merge raiser for a cherrypick.
747799
** See the graph on check-in 8ac66ef33b464d28 for example
748800
** iReuseIdx = -1;
749801
** iReuseRail = -1; */
750802
isCherrypick = 1;
751803
}
@@ -761,11 +813,11 @@
761813
iMrail = j;
762814
break;
763815
}
764816
}
765817
if( iMrail==-1 ){
766
- iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
818
+ iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1);
767819
if( p->mxRail>=GR_MAX_RAIL ) return;
768820
mergeRiserFrom[iMrail] = parentRid;
769821
}
770822
iReuseIdx = p->nRow+1;
771823
iReuseRail = iMrail;
@@ -838,29 +890,150 @@
838890
839891
/*
840892
** Find the maximum rail number.
841893
*/
842894
find_max_rail(p);
895
+
896
+ /* If a leaf node has a merge riser going up on a different rail,
897
+ ** try to move the rail of the node (and its ancestors) to be underneath
898
+ ** the merge riser. This is an optimization that improves the
899
+ ** appearance of graph but is not strictly necessary.
900
+ */
901
+ if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903
+ GraphRow *pBottom; /* Bottom row of a branch */
904
+ GraphRow *pRoot; /* Node off of which the branch diverges */
905
+ int iFrom; /* Proposed to move from this rail */
906
+ int iTo; /* Move the branch to this rail */
907
+
908
+ iFrom = pRow->iRail;
909
+ if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910
+ if( pRow->mergeOut<0 ) continue; /* No merge riser */
911
+ if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912
+ iTo = pRow->mergeOut;
913
+
914
+ /* Find the bottom (oldest) node in the branch */
915
+ pBottom = 0;
916
+ for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917
+ if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918
+ }
919
+ if( pBottom==0 ) continue; /* Not possible */
920
+
921
+ /* Verify that the rail we want to shift into is clear */
922
+ pLoop = pBottom;
923
+ if( pLoop->pNext ) pLoop = pLoop->pNext;
924
+ if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925
+ /* Other nodes or risers are already using the space that
926
+ ** we propose to move the pRow branch into. */
927
+ continue;
928
+ }
929
+
930
+ /* Find the "root" of the branch. The root is a different branch
931
+ ** from which the pRow branch emerges. There might not be a root
932
+ ** if the pRow branch started off the bottom of the screen.
933
+ */
934
+ for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935
+ if( pRoot->aiRiser[iFrom]>=0 ) break;
936
+ }
937
+ if( pRoot && pRoot->iRail==iTo ){
938
+ /* The parent branch from which this branch emerges is on the
939
+ ** same rail as pRow. Do not shift as that would stack a child
940
+ ** branch directly above its parent. */
941
+ continue;
942
+ }
943
+
944
+ /* All clear. Make the translation
945
+ */
946
+ for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947
+ if( pLoop->iRail==iFrom ){
948
+ pLoop->iRail = iTo;
949
+ pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950
+ pLoop->aiRiser[iFrom] = -1;
951
+ }
952
+ }
953
+ if( pRoot ){
954
+ pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955
+ pRoot->aiRiser[iFrom] = -1;
956
+ }
957
+ }
958
+ }
843959
844960
/*
845
- ** Compute the rail mapping.
961
+ ** Compute the rail mapping that tries to put the branch named
962
+ ** zLeftBranch at the left margin. Other branches that merge
963
+ ** with zLeftBranch are to the right with merge rails in between.
964
+ **
965
+ ** aMap[X]=Y means that the X-th rail is drawn as the Y-th rail.
966
+ **
967
+ ** Do not move rails around if there are timewarps, because that can
968
+ ** seriously mess up the display of timewarps. Timewarps should be
969
+ ** rare so this should not be a serious limitation to the algorithm.
846970
*/
847971
aMap = p->aiRailMap;
848
- for(i=0; i<=p->mxRail; i++) aMap[i] = i;
849
- if( zLeftBranch && nTimewarp==0 ){
850
- char *zLeft = persistBranchName(p, zLeftBranch);
851
- j = 0;
852
- for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
853
- if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
854
- for(i=0; i<=p->mxRail; i++){
855
- if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
856
- }
857
- aMap[pRow->iRail] = j++;
858
- }
972
+ for(i=0; i<=p->mxRail; i++) aMap[i] = i; /* Set up a default mapping */
973
+ if( nTimewarp==0 ){
974
+ /* Priority bits:
975
+ **
976
+ ** 0x04 The preferred branch
977
+ **
978
+ ** 0x02 A merge rail - a rail that contains merge lines
979
+ **
980
+ ** 0x01 A rail that merges with the preferred branch
981
+ */
982
+ u8 aPriority[GR_MAX_RAIL];
983
+ memset(aPriority, 0, p->mxRail+1);
984
+ if( zLeftBranch ){
985
+ char *zLeft = persistBranchName(p, zLeftBranch);
986
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
987
+ if( pRow->zBranch==zLeft ){
988
+ aPriority[pRow->iRail] |= 4;
989
+ for(i=0; i<=p->mxRail; i++){
990
+ if( pRow->mergeIn[i] ) aPriority[i] |= 1;
991
+ }
992
+ if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
993
+ }
994
+ }
995
+ }else{
996
+ j = 1;
997
+ aPriority[0] = 4;
998
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
999
+ if( pRow->iRail==0 ){
1000
+ for(i=0; i<=p->mxRail; i++){
1001
+ if( pRow->mergeIn[i] ) aPriority[i] |= 1;
1002
+ }
1003
+ if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
1004
+ }
1005
+ }
1006
+ }
1007
+ for(i=0; i<=p->mxRail; i++){
1008
+ if( p->mergeRail & BIT(i) ){
1009
+ aPriority[i] |= 2;
1010
+ }
1011
+ }
1012
+
1013
+#if 0
1014
+ fprintf(stderr,"mergeRail: 0x%llx\n", p->mergeRail);
1015
+ fprintf(stderr,"Priority:");
1016
+ for(i=0; i<=p->mxRail; i++) fprintf(stderr," %d", aPriority[i]);
1017
+ fprintf(stderr,"\n");
1018
+#endif
1019
+
1020
+ j = 0;
1021
+ for(i=0; i<=p->mxRail; i++){
1022
+ if( aPriority[i]>=4 ) aMap[i] = j++;
1023
+ }
1024
+ for(i=p->mxRail; i>=0; i--){
1025
+ if( aPriority[i]==3 ) aMap[i] = j++;
1026
+ }
1027
+ for(i=0; i<=p->mxRail; i++){
1028
+ if( aPriority[i]==1 || aPriority[i]==2 ) aMap[i] = j++;
1029
+ }
1030
+ for(i=0; i<=p->mxRail; i++){
1031
+ if( aPriority[i]==0 ) aMap[i] = j++;
8591032
}
8601033
cgi_printf("<!-- aiRailMap =");
8611034
for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
8621035
cgi_printf(" -->\n");
8631036
}
8641037
8651038
p->nErr = 0;
8661039
}
8671040
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child */
 
88 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
89 u8 timeWarp; /* Child is earlier in time */
90 u8 bDescender; /* True if riser from bottom of graph to here. */
91 u8 selfUp; /* Space above this node but belonging */
92 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
109 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110 int nBranch; /* Number of distinct branches */
111 char **azBranch; /* Names of the branches */
112 int nRow; /* Number of rows */
113 int nHash; /* Number of slots in apHash[] */
 
 
 
114 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
115 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
116 };
117
118 #endif
@@ -119,11 +123,11 @@
119
120 /* The N-th bit */
121 #define BIT(N) (((u64)1)<<(N))
122
123 /*
124 ** Number of rows before and answer a node with a riser or descender
125 ** that goes off-screen before we can reuse that rail.
126 */
127 #define RISER_MARGIN 4
128
129
@@ -275,11 +279,12 @@
275 ** top and bottom, inclusive.
276 */
277 static int findFreeRail(
278 GraphContext *p, /* The graph context */
279 int top, int btm, /* Span of rows for which the rail is needed */
280 int iNearto /* Find rail nearest to this rail */
 
281 ){
282 GraphRow *pRow;
283 int i;
284 int iBest = 0;
285 int iBestDist = 9999;
@@ -287,15 +292,38 @@
287 for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
288 while( pRow && pRow->idx<=btm ){
289 inUseMask |= pRow->railInUse;
290 pRow = pRow->pNext;
291 }
292 for(i=0; i<GR_MAX_RAIL; i++){
293 if( (inUseMask & BIT(i))==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294 int dist;
 
295 if( iNearto<=0 ){
296 iBest = i;
 
297 break;
298 }
299 dist = i - iNearto;
300 if( dist<0 ) dist = -dist;
301 if( dist<iBestDist ){
@@ -304,10 +332,11 @@
304 }
305 }
306 }
307 if( iBestDist>1000 ) p->nErr++;
308 if( iBest>p->mxRail ) p->mxRail = iBest;
 
309 return iBest;
310 }
311
312 /*
313 ** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
343 p->railInUse |= mask;
344 }
345 }
346 }
347
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348 /*
349 ** Create a merge-arrow riser going from pParent up to pChild.
350 */
351 static void createMergeRiser(
352 GraphContext *p,
353 GraphRow *pParent,
354 GraphRow *pChild,
355 int isCherrypick
356 ){
357 int u;
358 u64 mask;
359 GraphRow *pLoop;
360
361 if( pParent->mergeOut<0 ){
362 u = pParent->aiRiser[pParent->iRail];
363 if( u>0 && u<pChild->idx ){
 
 
 
 
 
 
 
 
364 /* The thick arrow up to the next primary child of pDesc goes
365 ** further up than the thin merge arrow riser, so draw them both
366 ** on the same rail. */
367 pParent->mergeOut = pParent->iRail;
368 }else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
369 pParent->mergeOut = pParent->iRail;
370 }else{
371 /* The thin merge arrow riser is taller than the thick primary
372 ** child riser, so use separate rails. */
373 int iTarget = pParent->iRail;
374 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
 
 
375 mask = BIT(pParent->mergeOut);
376 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
377 pLoop=pLoop->pNext){
378 pLoop->railInUse |= mask;
379 }
@@ -420,11 +473,10 @@
420 while( pRow && (n--)>0 ){
421 pRow->railInUse |= mask;
422 pRow = pRow->pPrev;
423 }
424 }
425
426
427 /*
428 ** Compute the complete graph
429 **
430 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
646 if( i==0 && pRow->zBranch!=zTrunk ) continue;
647 if( pRow->iRail>=0 ) continue;
648 if( pRow->isDup ) continue;
649 if( pRow->nParent<0 ) continue;
650 if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
651 pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin, 0);
652 if( p->mxRail>=GR_MAX_RAIL ) return;
653 mask = BIT(pRow->iRail);
654 if( !omitDescenders ){
655 int n = RISER_MARGIN;
656 pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
690 }
691 if( pParent->idx>pRow->idx ){
692 /* Common case: Child occurs after parent and is above the
693 ** parent in the timeline */
694 pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
695 pParent->iRail);
696 if( p->mxRail>=GR_MAX_RAIL ) return;
697 pParent->aiRiser[pRow->iRail] = pRow->idx;
698 }else{
699 /* Timewarp case: Child occurs earlier in time than parent and
700 ** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
741 int isCherrypick = 0;
742 for(i=1; i<pRow->nParent; i++){
743 GraphRowId parentRid = pRow->aParent[i];
744 if( i==pRow->nNonCherrypick ){
745 /* Because full merges are laid out before cherrypicks,
746 ** it is ok to use a full-merge raise for a cherrypick.
747 ** See the graph on check-in 8ac66ef33b464d28 for example
748 ** iReuseIdx = -1;
749 ** iReuseRail = -1; */
750 isCherrypick = 1;
751 }
@@ -761,11 +813,11 @@
761 iMrail = j;
762 break;
763 }
764 }
765 if( iMrail==-1 ){
766 iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
767 if( p->mxRail>=GR_MAX_RAIL ) return;
768 mergeRiserFrom[iMrail] = parentRid;
769 }
770 iReuseIdx = p->nRow+1;
771 iReuseRail = iMrail;
@@ -838,29 +890,150 @@
838
839 /*
840 ** Find the maximum rail number.
841 */
842 find_max_rail(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
844 /*
845 ** Compute the rail mapping.
 
 
 
 
 
 
 
 
846 */
847 aMap = p->aiRailMap;
848 for(i=0; i<=p->mxRail; i++) aMap[i] = i;
849 if( zLeftBranch && nTimewarp==0 ){
850 char *zLeft = persistBranchName(p, zLeftBranch);
851 j = 0;
852 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
853 if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
854 for(i=0; i<=p->mxRail; i++){
855 if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
856 }
857 aMap[pRow->iRail] = j++;
858 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
859 }
860 cgi_printf("<!-- aiRailMap =");
861 for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
862 cgi_printf(" -->\n");
863 }
864
865 p->nErr = 0;
866 }
867
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child. The thick
88 ** arrow up to the child is dashed, not solid */
89 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
90 u8 timeWarp; /* Child is earlier in time */
91 u8 bDescender; /* True if riser from bottom of graph to here. */
92 u8 selfUp; /* Space above this node but belonging */
93 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
110 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
111 int nBranch; /* Number of distinct branches */
112 char **azBranch; /* Names of the branches */
113 int nRow; /* Number of rows */
114 int nHash; /* Number of slots in apHash[] */
115 u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116 ** rail that the node */
117 u64 mergeRail; /* Rails used for merge lines */
118 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
119 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
120 };
121
122 #endif
@@ -119,11 +123,11 @@
123
124 /* The N-th bit */
125 #define BIT(N) (((u64)1)<<(N))
126
127 /*
128 ** Number of rows before and after a node with a riser or descender
129 ** that goes off-screen before we can reuse that rail.
130 */
131 #define RISER_MARGIN 4
132
133
@@ -275,11 +279,12 @@
279 ** top and bottom, inclusive.
280 */
281 static int findFreeRail(
282 GraphContext *p, /* The graph context */
283 int top, int btm, /* Span of rows for which the rail is needed */
284 int iNearto, /* Find rail nearest to this rail */
285 int bMergeRail /* This rail will be used for a merge line */
286 ){
287 GraphRow *pRow;
288 int i;
289 int iBest = 0;
290 int iBestDist = 9999;
@@ -287,15 +292,38 @@
292 for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
293 while( pRow && pRow->idx<=btm ){
294 inUseMask |= pRow->railInUse;
295 pRow = pRow->pNext;
296 }
297
298 /* First look for a match that honors bMergeRail */
299 for(i=0; i<=p->mxRail; i++){
300 u64 m = BIT(i);
301 int dist;
302 if( inUseMask & m ) continue;
303 if( (bMergeRail!=0) != ((p->mergeRail & m)!=0) ) continue;
304 if( iNearto<=0 ){
305 iBest = i;
306 iBestDist = 1;
307 break;
308 }
309 dist = i - iNearto;
310 if( dist<0 ) dist = -dist;
311 if( dist<iBestDist ){
312 iBestDist = dist;
313 iBest = i;
314 }
315 }
316
317 /* If no match, consider all possible rails */
318 if( iBestDist>1000 ){
319 for(i=0; i<=p->mxRail+1; i++){
320 int dist;
321 if( inUseMask & BIT(i) ) continue;
322 if( iNearto<=0 ){
323 iBest = i;
324 iBestDist = 1;
325 break;
326 }
327 dist = i - iNearto;
328 if( dist<0 ) dist = -dist;
329 if( dist<iBestDist ){
@@ -304,10 +332,11 @@
332 }
333 }
334 }
335 if( iBestDist>1000 ) p->nErr++;
336 if( iBest>p->mxRail ) p->mxRail = iBest;
337 if( bMergeRail ) p->mergeRail |= BIT(iBest);
338 return iBest;
339 }
340
341 /*
342 ** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
372 p->railInUse |= mask;
373 }
374 }
375 }
376
377
378 /*
379 ** Check to see if rail iRail is clear from pBottom up to and including
380 ** pTop.
381 */
382 static int railIsClear(GraphRow *pBottom, int iTop, int iRail){
383 u64 m = BIT(iRail);
384 while( pBottom && pBottom->idx>=iTop ){
385 if( pBottom->railInUse & m ) return 0;
386 pBottom = pBottom->pPrev;
387 }
388 return 1;
389 }
390
391 /*
392 ** Create a merge-arrow riser going from pParent up to pChild.
393 */
394 static void createMergeRiser(
395 GraphContext *p,
396 GraphRow *pParent, /* Lower node from which the merge line begins */
397 GraphRow *pChild, /* Upper node at which the merge line ends */
398 int isCherrypick /* True for a cherry-pick merge */
399 ){
400 int u;
401 u64 mask;
402 GraphRow *pLoop;
403
404 if( pParent->mergeOut<0 ){
405 u = pParent->aiRiser[pParent->iRail];
406 if( u<0 && railIsClear(pParent->pPrev, pChild->idx, pParent->iRail) ){
407 /* pParent is a leaf and the merge-line can be drawn straight up.*/
408 pParent->mergeOut = pParent->iRail;
409 mask = BIT(pParent->iRail);
410 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
411 pLoop=pLoop->pNext){
412 pLoop->railInUse |= mask;
413 }
414 }else if( u>0 && u<pChild->idx ){
415 /* The thick arrow up to the next primary child of pDesc goes
416 ** further up than the thin merge arrow riser, so draw them both
417 ** on the same rail. */
418 pParent->mergeOut = pParent->iRail;
419 }else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
420 pParent->mergeOut = pParent->iRail;
421 }else{
422 /* The thin merge arrow riser is taller than the thick primary
423 ** child riser, so use separate rails. */
424 int iTarget = pParent->iRail;
425 if( u<0 ) p->hasOffsetMergeRiser = 1;
426 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
427 iTarget, 1);
428 mask = BIT(pParent->mergeOut);
429 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
430 pLoop=pLoop->pNext){
431 pLoop->railInUse |= mask;
432 }
@@ -420,11 +473,10 @@
473 while( pRow && (n--)>0 ){
474 pRow->railInUse |= mask;
475 pRow = pRow->pPrev;
476 }
477 }
 
478
479 /*
480 ** Compute the complete graph
481 **
482 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
698 if( i==0 && pRow->zBranch!=zTrunk ) continue;
699 if( pRow->iRail>=0 ) continue;
700 if( pRow->isDup ) continue;
701 if( pRow->nParent<0 ) continue;
702 if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
703 pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0);
704 if( p->mxRail>=GR_MAX_RAIL ) return;
705 mask = BIT(pRow->iRail);
706 if( !omitDescenders ){
707 int n = RISER_MARGIN;
708 pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
742 }
743 if( pParent->idx>pRow->idx ){
744 /* Common case: Child occurs after parent and is above the
745 ** parent in the timeline */
746 pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
747 pParent->iRail, 0);
748 if( p->mxRail>=GR_MAX_RAIL ) return;
749 pParent->aiRiser[pRow->iRail] = pRow->idx;
750 }else{
751 /* Timewarp case: Child occurs earlier in time than parent and
752 ** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
793 int isCherrypick = 0;
794 for(i=1; i<pRow->nParent; i++){
795 GraphRowId parentRid = pRow->aParent[i];
796 if( i==pRow->nNonCherrypick ){
797 /* Because full merges are laid out before cherrypicks,
798 ** it is ok to use a full-merge raiser for a cherrypick.
799 ** See the graph on check-in 8ac66ef33b464d28 for example
800 ** iReuseIdx = -1;
801 ** iReuseRail = -1; */
802 isCherrypick = 1;
803 }
@@ -761,11 +813,11 @@
813 iMrail = j;
814 break;
815 }
816 }
817 if( iMrail==-1 ){
818 iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1);
819 if( p->mxRail>=GR_MAX_RAIL ) return;
820 mergeRiserFrom[iMrail] = parentRid;
821 }
822 iReuseIdx = p->nRow+1;
823 iReuseRail = iMrail;
@@ -838,29 +890,150 @@
890
891 /*
892 ** Find the maximum rail number.
893 */
894 find_max_rail(p);
895
896 /* If a leaf node has a merge riser going up on a different rail,
897 ** try to move the rail of the node (and its ancestors) to be underneath
898 ** the merge riser. This is an optimization that improves the
899 ** appearance of graph but is not strictly necessary.
900 */
901 if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903 GraphRow *pBottom; /* Bottom row of a branch */
904 GraphRow *pRoot; /* Node off of which the branch diverges */
905 int iFrom; /* Proposed to move from this rail */
906 int iTo; /* Move the branch to this rail */
907
908 iFrom = pRow->iRail;
909 if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910 if( pRow->mergeOut<0 ) continue; /* No merge riser */
911 if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912 iTo = pRow->mergeOut;
913
914 /* Find the bottom (oldest) node in the branch */
915 pBottom = 0;
916 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917 if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918 }
919 if( pBottom==0 ) continue; /* Not possible */
920
921 /* Verify that the rail we want to shift into is clear */
922 pLoop = pBottom;
923 if( pLoop->pNext ) pLoop = pLoop->pNext;
924 if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925 /* Other nodes or risers are already using the space that
926 ** we propose to move the pRow branch into. */
927 continue;
928 }
929
930 /* Find the "root" of the branch. The root is a different branch
931 ** from which the pRow branch emerges. There might not be a root
932 ** if the pRow branch started off the bottom of the screen.
933 */
934 for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935 if( pRoot->aiRiser[iFrom]>=0 ) break;
936 }
937 if( pRoot && pRoot->iRail==iTo ){
938 /* The parent branch from which this branch emerges is on the
939 ** same rail as pRow. Do not shift as that would stack a child
940 ** branch directly above its parent. */
941 continue;
942 }
943
944 /* All clear. Make the translation
945 */
946 for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947 if( pLoop->iRail==iFrom ){
948 pLoop->iRail = iTo;
949 pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950 pLoop->aiRiser[iFrom] = -1;
951 }
952 }
953 if( pRoot ){
954 pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955 pRoot->aiRiser[iFrom] = -1;
956 }
957 }
958 }
959
960 /*
961 ** Compute the rail mapping that tries to put the branch named
962 ** zLeftBranch at the left margin. Other branches that merge
963 ** with zLeftBranch are to the right with merge rails in between.
964 **
965 ** aMap[X]=Y means that the X-th rail is drawn as the Y-th rail.
966 **
967 ** Do not move rails around if there are timewarps, because that can
968 ** seriously mess up the display of timewarps. Timewarps should be
969 ** rare so this should not be a serious limitation to the algorithm.
970 */
971 aMap = p->aiRailMap;
972 for(i=0; i<=p->mxRail; i++) aMap[i] = i; /* Set up a default mapping */
973 if( nTimewarp==0 ){
974 /* Priority bits:
975 **
976 ** 0x04 The preferred branch
977 **
978 ** 0x02 A merge rail - a rail that contains merge lines
979 **
980 ** 0x01 A rail that merges with the preferred branch
981 */
982 u8 aPriority[GR_MAX_RAIL];
983 memset(aPriority, 0, p->mxRail+1);
984 if( zLeftBranch ){
985 char *zLeft = persistBranchName(p, zLeftBranch);
986 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
987 if( pRow->zBranch==zLeft ){
988 aPriority[pRow->iRail] |= 4;
989 for(i=0; i<=p->mxRail; i++){
990 if( pRow->mergeIn[i] ) aPriority[i] |= 1;
991 }
992 if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
993 }
994 }
995 }else{
996 j = 1;
997 aPriority[0] = 4;
998 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
999 if( pRow->iRail==0 ){
1000 for(i=0; i<=p->mxRail; i++){
1001 if( pRow->mergeIn[i] ) aPriority[i] |= 1;
1002 }
1003 if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
1004 }
1005 }
1006 }
1007 for(i=0; i<=p->mxRail; i++){
1008 if( p->mergeRail & BIT(i) ){
1009 aPriority[i] |= 2;
1010 }
1011 }
1012
1013 #if 0
1014 fprintf(stderr,"mergeRail: 0x%llx\n", p->mergeRail);
1015 fprintf(stderr,"Priority:");
1016 for(i=0; i<=p->mxRail; i++) fprintf(stderr," %d", aPriority[i]);
1017 fprintf(stderr,"\n");
1018 #endif
1019
1020 j = 0;
1021 for(i=0; i<=p->mxRail; i++){
1022 if( aPriority[i]>=4 ) aMap[i] = j++;
1023 }
1024 for(i=p->mxRail; i>=0; i--){
1025 if( aPriority[i]==3 ) aMap[i] = j++;
1026 }
1027 for(i=0; i<=p->mxRail; i++){
1028 if( aPriority[i]==1 || aPriority[i]==2 ) aMap[i] = j++;
1029 }
1030 for(i=0; i<=p->mxRail; i++){
1031 if( aPriority[i]==0 ) aMap[i] = j++;
1032 }
1033 cgi_printf("<!-- aiRailMap =");
1034 for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
1035 cgi_printf(" -->\n");
1036 }
1037
1038 p->nErr = 0;
1039 }
1040
+11 -8
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
5353
** is the rail on which the riser should run and the second integer
5454
** is the id of the node upto which the riser should run. If there
5555
** are no risers, this array does not exist.
5656
** mi: "merge-in". An array of integer rail positions from which
5757
** merge arrows should be drawn into this node. If the value is
58
-** negative, then the rail position is the absolute value of mi[]
59
-** and a thin merge-arrow descender is drawn to the bottom of
60
-** the screen. This array is omitted if there are no inbound
61
-** merges.
58
+** negative, then the rail position is -1-mi[] and a thin merge-arrow
59
+** descender is drawn to the bottom of the screen. This array is
60
+** omitted if there are no inbound merges.
6261
** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
6362
** omitted if there are no cherrypick merges.
6463
** h: The artifact hash of the object being graphed
6564
*/
6665
/* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
355354
}
356355
function drawCherrypickLine(x0,y0,x1,y1){
357356
drawLine(cpLine,null,x0,y0,x1,y1);
358357
}
359358
/* Draw an arrow representing an in-bound merge from the "rail"-th rail
360
- ** over to the node of "p". Make is a checkpoint merge is "isCP" is true */
359
+ ** over to the node of "p". Make it a checkpoint merge is "isCP" is true */
361360
function drawMergeArrow(p,rail,isCP){
362361
var x0 = rail*railPitch + node.w/2;
363362
if( rail in mergeLines ){
364363
x0 += mergeLines[rail];
365364
if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
422421
}
423422
if( p.hasOwnProperty('mo') ){
424423
var x0 = p.x + node.w/2;
425424
var x1 = p.mo*railPitch + node.w/2;
426425
var u = tx.rowinfo[p.mu-tx.iTopRow];
426
+ var mtop = u;
427
+ if( p.hasOwnProperty('cu') ){
428
+ mtop = tx.rowinfo[p.cu-tx.iTopRow];
429
+ }
427430
var y1 = miLineY(u);
428431
if( p.u<=0 || p.mo!=p.r ){
429432
if( p.u==0 && p.mo==p.r ){
430
- mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
433
+ mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
431434
}else{
432435
mergeLines[p.mo] = -mLine.w/2;
433436
}
434437
x1 += mergeLines[p.mo]
435438
var y0 = p.y+2;
@@ -458,11 +461,11 @@
458461
var u2 = tx.rowinfo[p.cu-tx.iTopRow];
459462
var y2 = miLineY(u2);
460463
drawCherrypickLine(x1,y1,null,y2);
461464
}
462465
}else if( mergeOffset ){
463
- mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
466
+ mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
464467
x1 += mergeLines[p.mo];
465468
if( p.mu<p.id ){
466469
drawMergeLine(x1,p.y+node.h/2,null,y1);
467470
}
468471
if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
508511
}
509512
if( p.hasOwnProperty('mi') ){
510513
for( var i=0; i<p.mi.length; i++ ){
511514
var rail = p.mi[i];
512515
if( rail<0 ){
513
- rail = -rail;
516
+ rail = -1-rail;
514517
mergeLines[rail] = -mLine.w/2;
515518
var x = rail*railPitch + (node.w-mLine.w)/2;
516519
var y = miLineY(p);
517520
drawMergeLine(x,y,null,mergeBtm[rail]);
518521
mergeBtm[rail] = y;
519522
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
53 ** is the rail on which the riser should run and the second integer
54 ** is the id of the node upto which the riser should run. If there
55 ** are no risers, this array does not exist.
56 ** mi: "merge-in". An array of integer rail positions from which
57 ** merge arrows should be drawn into this node. If the value is
58 ** negative, then the rail position is the absolute value of mi[]
59 ** and a thin merge-arrow descender is drawn to the bottom of
60 ** the screen. This array is omitted if there are no inbound
61 ** merges.
62 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
63 ** omitted if there are no cherrypick merges.
64 ** h: The artifact hash of the object being graphed
65 */
66 /* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
355 }
356 function drawCherrypickLine(x0,y0,x1,y1){
357 drawLine(cpLine,null,x0,y0,x1,y1);
358 }
359 /* Draw an arrow representing an in-bound merge from the "rail"-th rail
360 ** over to the node of "p". Make is a checkpoint merge is "isCP" is true */
361 function drawMergeArrow(p,rail,isCP){
362 var x0 = rail*railPitch + node.w/2;
363 if( rail in mergeLines ){
364 x0 += mergeLines[rail];
365 if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
422 }
423 if( p.hasOwnProperty('mo') ){
424 var x0 = p.x + node.w/2;
425 var x1 = p.mo*railPitch + node.w/2;
426 var u = tx.rowinfo[p.mu-tx.iTopRow];
 
 
 
 
427 var y1 = miLineY(u);
428 if( p.u<=0 || p.mo!=p.r ){
429 if( p.u==0 && p.mo==p.r ){
430 mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
431 }else{
432 mergeLines[p.mo] = -mLine.w/2;
433 }
434 x1 += mergeLines[p.mo]
435 var y0 = p.y+2;
@@ -458,11 +461,11 @@
458 var u2 = tx.rowinfo[p.cu-tx.iTopRow];
459 var y2 = miLineY(u2);
460 drawCherrypickLine(x1,y1,null,y2);
461 }
462 }else if( mergeOffset ){
463 mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
464 x1 += mergeLines[p.mo];
465 if( p.mu<p.id ){
466 drawMergeLine(x1,p.y+node.h/2,null,y1);
467 }
468 if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
508 }
509 if( p.hasOwnProperty('mi') ){
510 for( var i=0; i<p.mi.length; i++ ){
511 var rail = p.mi[i];
512 if( rail<0 ){
513 rail = -rail;
514 mergeLines[rail] = -mLine.w/2;
515 var x = rail*railPitch + (node.w-mLine.w)/2;
516 var y = miLineY(p);
517 drawMergeLine(x,y,null,mergeBtm[rail]);
518 mergeBtm[rail] = y;
519
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
53 ** is the rail on which the riser should run and the second integer
54 ** is the id of the node upto which the riser should run. If there
55 ** are no risers, this array does not exist.
56 ** mi: "merge-in". An array of integer rail positions from which
57 ** merge arrows should be drawn into this node. If the value is
58 ** negative, then the rail position is -1-mi[] and a thin merge-arrow
59 ** descender is drawn to the bottom of the screen. This array is
60 ** omitted if there are no inbound merges.
 
61 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
62 ** omitted if there are no cherrypick merges.
63 ** h: The artifact hash of the object being graphed
64 */
65 /* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
354 }
355 function drawCherrypickLine(x0,y0,x1,y1){
356 drawLine(cpLine,null,x0,y0,x1,y1);
357 }
358 /* Draw an arrow representing an in-bound merge from the "rail"-th rail
359 ** over to the node of "p". Make it a checkpoint merge is "isCP" is true */
360 function drawMergeArrow(p,rail,isCP){
361 var x0 = rail*railPitch + node.w/2;
362 if( rail in mergeLines ){
363 x0 += mergeLines[rail];
364 if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
421 }
422 if( p.hasOwnProperty('mo') ){
423 var x0 = p.x + node.w/2;
424 var x1 = p.mo*railPitch + node.w/2;
425 var u = tx.rowinfo[p.mu-tx.iTopRow];
426 var mtop = u;
427 if( p.hasOwnProperty('cu') ){
428 mtop = tx.rowinfo[p.cu-tx.iTopRow];
429 }
430 var y1 = miLineY(u);
431 if( p.u<=0 || p.mo!=p.r ){
432 if( p.u==0 && p.mo==p.r ){
433 mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
434 }else{
435 mergeLines[p.mo] = -mLine.w/2;
436 }
437 x1 += mergeLines[p.mo]
438 var y0 = p.y+2;
@@ -458,11 +461,11 @@
461 var u2 = tx.rowinfo[p.cu-tx.iTopRow];
462 var y2 = miLineY(u2);
463 drawCherrypickLine(x1,y1,null,y2);
464 }
465 }else if( mergeOffset ){
466 mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
467 x1 += mergeLines[p.mo];
468 if( p.mu<p.id ){
469 drawMergeLine(x1,p.y+node.h/2,null,y1);
470 }
471 if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
511 }
512 if( p.hasOwnProperty('mi') ){
513 for( var i=0; i<p.mi.length; i++ ){
514 var rail = p.mi[i];
515 if( rail<0 ){
516 rail = -1-rail;
517 mergeLines[rail] = -mLine.w/2;
518 var x = rail*railPitch + (node.w-mLine.w)/2;
519 var y = miLineY(p);
520 drawMergeLine(x,y,null,mergeBtm[rail]);
521 mergeBtm[rail] = y;
522
+27 -9
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
1212
**
1313
** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
1414
**
1515
** The <script> must have an id='href-data'. DELAY is the number
1616
** milliseconds delay prior to populating href= and action=. If the
17
-** mouseover boolean is true, then the timer does not start until a
18
-** mouse motion event occurs over top of the document.
17
+** mouseover boolean is true, then the href= rewrite is further delayed
18
+** until the first mousedown event that occurs after the timer expires.
1919
*/
20
-function setAllHrefs(){
20
+var antiRobot = 0;
21
+var antiRobotBody = document.getElementsByTagName("body")[0];
22
+function antiRobotGo(){
23
+ if( antiRobot!=3 ) return;
24
+ antiRobot = 7;
2125
var anchors = document.getElementsByTagName("a");
2226
for(var i=0; i<anchors.length; i++){
2327
var j = anchors[i];
2428
if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
2529
}
@@ -31,16 +35,30 @@
3135
}
3236
function antiRobotDefense(){
3337
var x = document.getElementById("href-data");
3438
var jx = x.textContent || x.innerText;
3539
var g = JSON.parse(jx);
36
- var isOperaMini =
37
- Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38
- if(g.mouseover && !isOperaMini){
39
- document.getElementsByTagName("body")[0].onmousemove=function(){
40
- setTimeout(setAllHrefs, g.delay);
40
+ if( g.mouseover ){
41
+ antiRobotBody.onmousedown=function(){
42
+ antiRobot |= 2;
43
+ antiRobotGo();
44
+ antiRobotBody.onmousedown=null;
45
+ }
46
+ antiRobotBody.onmousemove=function(){
47
+ antiRobot |= 2;
48
+ antiRobotGo();
49
+ antiRobotBody.onmousemove=null;
4150
}
4251
}else{
43
- setTimeout(setAllHrefs, g.delay);
52
+ antiRobot |= 2;
53
+ }
54
+ if( g.delay>0 ){
55
+ setTimeout(function(){
56
+ antiRobot |= 1;
57
+ antiRobotGo();
58
+ }, g.delay)
59
+ }else{
60
+ antiRobot |= 1;
4461
}
62
+ antiRobotGo();
4563
}
4664
antiRobotDefense();
4765
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
12 **
13 ** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
14 **
15 ** The <script> must have an id='href-data'. DELAY is the number
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the timer does not start until a
18 ** mouse motion event occurs over top of the document.
19 */
20 function setAllHrefs(){
 
 
 
 
21 var anchors = document.getElementsByTagName("a");
22 for(var i=0; i<anchors.length; i++){
23 var j = anchors[i];
24 if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
25 }
@@ -31,16 +35,30 @@
31 }
32 function antiRobotDefense(){
33 var x = document.getElementById("href-data");
34 var jx = x.textContent || x.innerText;
35 var g = JSON.parse(jx);
36 var isOperaMini =
37 Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38 if(g.mouseover && !isOperaMini){
39 document.getElementsByTagName("body")[0].onmousemove=function(){
40 setTimeout(setAllHrefs, g.delay);
 
 
 
 
 
41 }
42 }else{
43 setTimeout(setAllHrefs, g.delay);
 
 
 
 
 
 
 
 
44 }
 
45 }
46 antiRobotDefense();
47
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
12 **
13 ** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
14 **
15 ** The <script> must have an id='href-data'. DELAY is the number
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the href= rewrite is further delayed
18 ** until the first mousedown event that occurs after the timer expires.
19 */
20 var antiRobot = 0;
21 var antiRobotBody = document.getElementsByTagName("body")[0];
22 function antiRobotGo(){
23 if( antiRobot!=3 ) return;
24 antiRobot = 7;
25 var anchors = document.getElementsByTagName("a");
26 for(var i=0; i<anchors.length; i++){
27 var j = anchors[i];
28 if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
29 }
@@ -31,16 +35,30 @@
35 }
36 function antiRobotDefense(){
37 var x = document.getElementById("href-data");
38 var jx = x.textContent || x.innerText;
39 var g = JSON.parse(jx);
40 if( g.mouseover ){
41 antiRobotBody.onmousedown=function(){
42 antiRobot |= 2;
43 antiRobotGo();
44 antiRobotBody.onmousedown=null;
45 }
46 antiRobotBody.onmousemove=function(){
47 antiRobot |= 2;
48 antiRobotGo();
49 antiRobotBody.onmousemove=null;
50 }
51 }else{
52 antiRobot |= 2;
53 }
54 if( g.delay>0 ){
55 setTimeout(function(){
56 antiRobot |= 1;
57 antiRobotGo();
58 }, g.delay)
59 }else{
60 antiRobot |= 1;
61 }
62 antiRobotGo();
63 }
64 antiRobotDefense();
65
+3 -4
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454454
isCompressed = 0;
455455
}else if( fossil_strnicmp(&zLine[14],
456456
"application/x-fossil-uncompressed", -1)==0 ){
457457
isCompressed = 0;
458458
}else{
459
- if( (mHttpFlags & HTTP_GENERIC)==0
460
- && fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0
461
- ){
459
+ if( mHttpFlags & HTTP_GENERIC ){
460
+ if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
461
+ }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
462462
isError = 1;
463463
}
464464
}
465465
}
466466
}
@@ -562,11 +562,10 @@
562562
if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
563563
if( find_option("xfer",0,0)!=0 ){
564564
mHttpFlags |= HTTP_USE_LOGIN;
565565
mHttpFlags &= ~HTTP_GENERIC;
566566
}
567
- db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_ANY_SCHEMA, 0);
568567
verify_all_options();
569568
if( g.argc<3 || g.argc>5 ){
570569
usage("URL ?PAYLOAD? ?OUTPUT?");
571570
}
572571
zInFile = g.argc>=4 ? g.argv[3] : 0;
573572
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454 isCompressed = 0;
455 }else if( fossil_strnicmp(&zLine[14],
456 "application/x-fossil-uncompressed", -1)==0 ){
457 isCompressed = 0;
458 }else{
459 if( (mHttpFlags & HTTP_GENERIC)==0
460 && fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0
461 ){
462 isError = 1;
463 }
464 }
465 }
466 }
@@ -562,11 +562,10 @@
562 if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
563 if( find_option("xfer",0,0)!=0 ){
564 mHttpFlags |= HTTP_USE_LOGIN;
565 mHttpFlags &= ~HTTP_GENERIC;
566 }
567 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_ANY_SCHEMA, 0);
568 verify_all_options();
569 if( g.argc<3 || g.argc>5 ){
570 usage("URL ?PAYLOAD? ?OUTPUT?");
571 }
572 zInFile = g.argc>=4 ? g.argv[3] : 0;
573
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454 isCompressed = 0;
455 }else if( fossil_strnicmp(&zLine[14],
456 "application/x-fossil-uncompressed", -1)==0 ){
457 isCompressed = 0;
458 }else{
459 if( mHttpFlags & HTTP_GENERIC ){
460 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
461 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
462 isError = 1;
463 }
464 }
465 }
466 }
@@ -562,11 +562,10 @@
562 if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
563 if( find_option("xfer",0,0)!=0 ){
564 mHttpFlags |= HTTP_USE_LOGIN;
565 mHttpFlags &= ~HTTP_GENERIC;
566 }
 
567 verify_all_options();
568 if( g.argc<3 || g.argc>5 ){
569 usage("URL ?PAYLOAD? ?OUTPUT?");
570 }
571 zInFile = g.argc>=4 ? g.argv[3] : 0;
572
+187 -235
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -248,47 +248,68 @@
248248
/*
249249
** Call this routine once before any other use of the SSL interface.
250250
** This routine does initial configuration of the SSL module.
251251
*/
252252
static void ssl_global_init_client(void){
253
- const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
254253
const char *identityFile;
255254
256255
if( sslIsInit==0 ){
256
+ const char *zFile;
257
+ const char *zCaFile = 0;
258
+ const char *zCaDirectory = 0;
259
+ int i;
260
+
257261
SSL_library_init();
258262
SSL_load_error_strings();
259263
OpenSSL_add_all_algorithms();
260264
sslCtx = SSL_CTX_new(SSLv23_client_method());
261265
/* Disable SSLv2 and SSLv3 */
262266
SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
263267
264
- /* Set up acceptable CA root certificates */
265
- zCaSetting = db_get("ssl-ca-location", 0);
266
- if( zCaSetting==0 || zCaSetting[0]=='\0' ){
267
- /* CA location not specified, use platform's default certificate store */
268
- X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
269
- }else{
270
- /* User has specified a CA location, make sure it exists and use it */
271
- switch( file_isdir(zCaSetting, ExtFILE) ){
268
+ /* Find the trust store */
269
+ zFile = 0;
270
+ for(i=0; zFile==0 && i<5; i++){
271
+ switch( i ){
272
+ case 0: /* First priority is environmentn variables */
273
+ zFile = fossil_getenv(X509_get_default_cert_file_env());
274
+ break;
275
+ case 1:
276
+ zFile = fossil_getenv(X509_get_default_cert_dir_env());
277
+ break;
278
+ case 2:
279
+ if( !g.repositoryOpen ) db_open_config(0,0);
280
+ zFile = db_get("ssl-ca-location",0);
281
+ break;
282
+ case 3:
283
+ zFile = X509_get_default_cert_file();
284
+ break;
285
+ case 4:
286
+ zFile = X509_get_default_cert_dir();
287
+ break;
288
+ }
289
+ if( zFile==0 ) continue;
290
+ switch( file_isdir(zFile, ExtFILE) ){
272291
case 0: { /* doesn't exist */
273
- fossil_fatal("ssl-ca-location is set to '%s', "
274
- "but is not a file or directory", zCaSetting);
292
+ zFile = 0;
275293
break;
276294
}
277295
case 1: { /* directory */
278
- zCaDirectory = zCaSetting;
296
+ zCaFile = 0;
297
+ zCaDirectory = zFile;
279298
break;
280299
}
281300
case 2: { /* file */
282
- zCaFile = zCaSetting;
301
+ zCaFile = zFile;
302
+ zCaDirectory = 0;
283303
break;
284304
}
285305
}
286
- if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
287
- fossil_fatal("Failed to use CA root certificates from "
288
- "ssl-ca-location '%s'", zCaSetting);
289
- }
306
+ }
307
+ if( zFile==0 ){
308
+ /* fossil_fatal("Cannot find a trust store"); */
309
+ }else if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
310
+ fossil_fatal("Cannot load CA root certificates from %s", zFile);
290311
}
291312
292313
/* Load client SSL identity, preferring the filename specified on the
293314
** command line */
294315
if( g.zSSLIdentity!=0 ){
@@ -697,47 +718,48 @@
697718
** of disk files that hold the certificate and private-key for the
698719
** server. If zCertFile is not NULL but zKeyFile is NULL, then
699720
** zCertFile is assumed to be a concatenation of the certificate and
700721
** the private-key in the PEM format.
701722
**
702
-** If zCertFile is NULL, then "ssl-cert" setting is consulted
703
-** to get the certificate and private-key (concatenated together, in
704
-** the PEM format). If there is no ssl-cert setting, then
705
-** a built-in self-signed cert is used.
723
+** If zCertFile is "unsafe-builtin", then a built-in self-signed cert
724
+** is used. This built-in cert is insecure and should only be used for
725
+** testing and debugging.
706726
*/
707727
void ssl_init_server(const char *zCertFile, const char *zKeyFile){
708
- if( sslIsInit==0 ){
709
- const char *zTlsCert;
728
+ if( sslIsInit==0 && zCertFile ){
710729
SSL_library_init();
711730
SSL_load_error_strings();
712731
OpenSSL_add_all_algorithms();
713732
sslCtx = SSL_CTX_new(SSLv23_server_method());
714733
if( sslCtx==0 ){
715734
ERR_print_errors_fp(stderr);
716735
fossil_fatal("Error initializing the SSL server");
717736
}
718
- if( zCertFile && zCertFile[0] ){
737
+ if( fossil_strcmp(zCertFile,"unsafe-builtin")==0 ){
738
+ if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
739
+ || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1)
740
+ ){
741
+ fossil_fatal("Error loading self-signed CERT and KEY");
742
+ }
743
+ }else{
719744
if( SSL_CTX_use_certificate_chain_file(sslCtx,zCertFile)!=1 ){
720745
ERR_print_errors_fp(stderr);
721746
fossil_fatal("Error loading CERT file \"%s\"", zCertFile);
722747
}
723748
if( zKeyFile==0 ) zKeyFile = zCertFile;
724749
if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
725750
ERR_print_errors_fp(stderr);
726
- fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile);
727
- }
728
- }else
729
- if( (zTlsCert = db_get("ssl-cert",0))!=0 ){
730
- if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1)
731
- || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1)
732
- ){
733
- fossil_fatal("Error loading the CERT from the"
734
- " 'ssl-cert' setting");
735
- }
736
- }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
737
- || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){
738
- fossil_fatal("Error loading self-signed CERT");
751
+ if( strcmp(zKeyFile,zCertFile)==0 ){
752
+ fossil_fatal("The private key is not found in \"%s\". "
753
+ "Either append the private key to the certification in that "
754
+ "file or use a separate --pkey option to specify the private key.",
755
+ zKeyFile);
756
+ }else{
757
+ fossil_fatal("Error loading the private key from file \"%s\"",
758
+ zKeyFile);
759
+ }
760
+ }
739761
}
740762
if( !SSL_CTX_check_private_key(sslCtx) ){
741763
fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
742764
zKeyFile, zCertFile);
743765
}
@@ -748,11 +770,10 @@
748770
}
749771
}
750772
751773
typedef struct SslServerConn {
752774
SSL *ssl; /* The SSL codec */
753
- int atEof; /* True when EOF reached. */
754775
int iSocket; /* The socket */
755776
BIO *bio; /* BIO object. Needed for EOF detection. */
756777
} SslServerConn;
757778
758779
/*
@@ -762,11 +783,10 @@
762783
*/
763784
void *ssl_new_server(int iSocket){
764785
SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
765786
BIO *b = BIO_new_socket(iSocket, 0);
766787
pServer->ssl = SSL_new(sslCtx);
767
- pServer->atEof = 0;
768788
pServer->iSocket = iSocket;
769789
pServer->bio = b;
770790
SSL_set_bio(pServer->ssl, b, b);
771791
SSL_accept(pServer->ssl);
772792
return (void*)pServer;
@@ -785,46 +805,54 @@
785805
** Return TRUE if there are no more bytes available to be read from
786806
** the client.
787807
*/
788808
int ssl_eof(void *pServerArg){
789809
SslServerConn *pServer = (SslServerConn*)pServerArg;
790
- return pServer->atEof;
810
+ return BIO_eof(pServer->bio);
791811
}
792812
793813
/*
794814
** Read cleartext bytes that have been received from the client and
795815
** decrypted by the SSL server codec.
816
+**
817
+** If the expected payload size unknown, i.e. if the HTTP
818
+** Content-Length: header field has not been parsed, the doLoop
819
+** argument should be 0, or SSL_read() may block and wait for more
820
+** data than is eventually going to arrive (on Windows). On
821
+** non-Windows builds, it has been our experience that the final
822
+** argument must always be true, as discussed at length at:
823
+**
824
+** https://fossil-scm.org/forum/forumpost/2f818850abb72719
796825
*/
797
-size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
798
- int n, err = 0;
826
+size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
827
+ int n;
799828
size_t rc = 0;
800829
SslServerConn *pServer = (SslServerConn*)pServerArg;
801830
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
802
- while( 0==err && nBuf!=rc && 0==pServer->atEof ){
831
+ while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
803832
n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
804
- if( n==0 ){
805
- pServer->atEof = 1;
806
- break;
807
- }
808
- err = SSL_get_error(pServer->ssl, n);
809
- if(0==err){
833
+ if( n>0 ){
810834
rc += n;
811
- pServer->atEof = BIO_eof(pServer->bio);
835
+ }
836
+ if( doLoop==0 || n<=0 ){
837
+ break;
812838
}
813839
}
814840
return rc;
815841
}
816842
817843
/*
818
-** Read a single line of text from the client.
844
+** Read a single line of text from the client, up to nBuf-1 bytes. On
845
+** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846
+** Returns NULL on an I/O error or at EOF.
819847
*/
820848
char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
821849
int n = 0;
822850
int i;
823851
SslServerConn *pServer = (SslServerConn*)pServerArg;
824
-
825
- if( pServer->atEof ) return 0;
852
+
853
+ if( BIO_eof(pServer->bio) ) return 0;
826854
for(i=0; i<nBuf-1; i++){
827855
n = SSL_read(pServer->ssl, &zBuf[i], 1);
828856
if( n<=0 ){
829857
return 0;
830858
}
@@ -852,10 +880,24 @@
852880
}
853881
}
854882
855883
#endif /* FOSSIL_ENABLE_SSL */
856884
885
+#ifdef FOSSIL_ENABLE_SSL
886
+/*
887
+** zPath is a name that might be a file or directory containing a trust
888
+** store. *pzStore is the name of the trust store to actually use.
889
+**
890
+** If *pzStore is not NULL (meaning no trust store has been found yet)
891
+** and if zPath exists, then set *pzStore to point to zPath.
892
+*/
893
+static void trust_location_usable(const char *zPath, const char **pzStore){
894
+ if( *pzStore!=0 ) return;
895
+ if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
896
+}
897
+#endif /* FOSSIL_ENABLE_SSL */
898
+
857899
/*
858900
** COMMAND: tls-config*
859901
** COMMAND: ssl-config
860902
**
861903
** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
@@ -864,21 +906,10 @@
864906
** Security) configuration for Fossil. TLS (formerly SSL) is the
865907
** encryption technology used for secure HTTPS transport.
866908
**
867909
** Sub-commands:
868910
**
869
-** clear-cert Remove information about server certificates.
870
-** This is a subset of the "scrub" command.
871
-**
872
-** load-cert PEM-FILES... Identify server certificate files. These
873
-** should be in the PEM format. There are
874
-** normally two files, the certificate and the
875
-** private-key. By default, the text of both
876
-** files is concatenated and added to the
877
-** "ssl-cert" setting. Use --filename to store
878
-** just the filenames.
879
-**
880911
** remove-exception DOMAINS Remove TLS cert exceptions for the domains
881912
** listed. Or remove them all if the --all
882913
** option is specified.
883914
**
884915
** scrub ?--force? Remove all SSL configuration data from the
@@ -890,111 +921,20 @@
890921
*/
891922
void test_tlsconfig_info(void){
892923
const char *zCmd;
893924
size_t nCmd;
894925
int nHit = 0;
926
+
895927
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
896928
db_open_config(1,0);
897929
if( g.argc==2 || (g.argc>=3 && g.argv[2][0]=='-') ){
898930
zCmd = "show";
899931
nCmd = 4;
900932
}else{
901933
zCmd = g.argv[2];
902934
nCmd = strlen(zCmd);
903935
}
904
- if( strncmp("clear-cert",zCmd,nCmd)==0 && nCmd>=4 ){
905
- int bForce = find_option("force","f",0)!=0;
906
- verify_all_options();
907
- if( !bForce ){
908
- Blob ans;
909
- char cReply;
910
- prompt_user(
911
- "Confirm removing of the SSL server certificate from this repository.\n"
912
- "The removal cannot be undone. Continue (y/N)? ", &ans);
913
- cReply = blob_str(&ans)[0];
914
- if( cReply!='y' && cReply!='Y' ){
915
- fossil_exit(1);
916
- }
917
- }
918
- db_unprotect(PROTECT_ALL);
919
- db_multi_exec(
920
- "PRAGMA secure_delete=ON;"
921
- "DELETE FROM config "
922
- " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
923
- );
924
- db_protect_pop();
925
- }else
926
- if( strncmp("load-cert",zCmd,nCmd)==0 && nCmd>=4 ){
927
- int bFN = find_option("filename",0,0)!=0;
928
- int i;
929
- Blob allText = BLOB_INITIALIZER;
930
- int haveCert = 0;
931
- int haveKey = 0;
932
- verify_all_options();
933
- db_begin_transaction();
934
- db_unprotect(PROTECT_ALL);
935
- db_multi_exec(
936
- "PRAGMA secure_delete=ON;"
937
- "DELETE FROM config "
938
- " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
939
- );
940
- nHit = 0;
941
- for(i=3; i<g.argc; i++){
942
- Blob x;
943
- int isCert;
944
- int isKey;
945
- if( !file_isfile(g.argv[i], ExtFILE) ){
946
- fossil_fatal("no such file: \"%s\"", g.argv[i]);
947
- }
948
- blob_read_from_file(&x, g.argv[i], ExtFILE);
949
- isCert = strstr(blob_str(&x),"-----BEGIN CERTIFICATE-----")!=0;
950
- isKey = strstr(blob_str(&x),"-----BEGIN PRIVATE KEY-----")!=0;
951
- if( !isCert && !isKey ){
952
- fossil_fatal("not a certificate or a private key: \"%s\"", g.argv[i]);
953
- }
954
- if( isCert ){
955
- if( haveCert ){
956
- fossil_fatal("more than one certificate provided");
957
- }
958
- haveCert = 1;
959
- if( bFN ){
960
- db_set("ssl-cert-file", file_canonical_name_dup(g.argv[i]), 0);
961
- }else{
962
- blob_append(&allText, blob_buffer(&x), blob_size(&x));
963
- }
964
- if( isKey && !haveKey ){
965
- haveKey = 1;
966
- isKey = 0;
967
- }
968
- }
969
- if( isKey ){
970
- if( haveKey ){
971
- fossil_fatal("more than one private key provided");
972
- }
973
- haveKey = 1;
974
- if( bFN ){
975
- db_set("ssl-key-file", file_canonical_name_dup(g.argv[i]), 0);
976
- }else{
977
- blob_append(&allText, blob_buffer(&x), blob_size(&x));
978
- }
979
- }
980
- }
981
- if( !haveCert ){
982
- if( !haveKey ){
983
- fossil_fatal("missing certificate and private-key");
984
- }else{
985
- fossil_fatal("missing certificate");
986
- }
987
- }else if( !haveKey ){
988
- fossil_fatal("missing private-key");
989
- }
990
- if( !bFN ){
991
- db_set("ssl-cert", blob_str(&allText), 0);
992
- }
993
- db_protect_pop();
994
- db_commit_transaction();
995
- }else
996936
if( strncmp("scrub",zCmd,nCmd)==0 && nCmd>4 ){
997937
int bForce = find_option("force","f",0)!=0;
998938
verify_all_options();
999939
if( !bForce ){
1000940
Blob ans;
@@ -1013,121 +953,133 @@
1013953
"DELETE FROM config WHERE name GLOB 'ssl-*';"
1014954
);
1015955
db_protect_pop();
1016956
}else
1017957
if( strncmp("show",zCmd,nCmd)==0 ){
958
+#if defined(FOSSIL_ENABLE_SSL)
1018959
const char *zName, *zValue;
960
+ const char *zUsed = 0; /* Trust store location actually used */
1019961
size_t nName;
962
+#endif
1020963
Stmt q;
1021964
int verbose = find_option("verbose","v",0)!=0;
1022965
verify_all_options();
1023966
1024967
#if !defined(FOSSIL_ENABLE_SSL)
1025
- fossil_print("OpenSSL-version: (none)\n");
968
+ fossil_print("OpenSSL-version: (none)\n");
1026969
if( verbose ){
1027970
fossil_print("\n"
1028971
" The OpenSSL library is not used by this build of Fossil\n\n"
1029972
);
1030973
}
1031974
#else
1032
- fossil_print("OpenSSL-version: %s (0x%09x)\n",
975
+ fossil_print("OpenSSL-version: %s (0x%09x)\n",
1033976
SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
1034977
if( verbose ){
1035978
fossil_print("\n"
1036979
" The version of the OpenSSL library being used\n"
1037980
" by this instance of Fossil. Version 3.0.0 or\n"
1038981
" later is recommended.\n\n"
1039982
);
1040983
}
1041984
1042
- fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
1043
- fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1044
- if( verbose ){
1045
- fossil_print("\n"
1046
- " The default locations for the set of root certificates\n"
1047
- " used by the \"fossil sync\" and similar commands to verify\n"
1048
- " the identity of servers for \"https:\" URLs. These values\n"
1049
- " come into play when Fossil is used as a TLS client. These\n"
1050
- " values are built into your OpenSSL library.\n\n"
1051
- );
1052
- }
1053
-
1054
- zName = X509_get_default_cert_file_env();
1055
- zValue = fossil_getenv(zName);
1056
- if( zValue==0 ) zValue = "";
1057
- nName = strlen(zName);
1058
- fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
1059
- zName = X509_get_default_cert_dir_env();
1060
- zValue = fossil_getenv(zName);
1061
- if( zValue==0 ) zValue = "";
1062
- nName = strlen(zName);
1063
- fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
1064
- if( verbose ){
1065
- fossil_print("\n"
1066
- " Alternative locations for the root certificates used by Fossil\n"
1067
- " when it is acting as a SSL client in order to verify the identity\n"
1068
- " of servers. If specified, these alternative locations override\n"
1069
- " the built-in locations.\n\n"
1070
- );
1071
- }
1072
-#endif /* FOSSIL_ENABLE_SSL */
1073
-
1074
- fossil_print("ssl-ca-location: %s\n", db_get("ssl-ca-location",""));
1075
- if( verbose ){
1076
- fossil_print("\n"
1077
- " This setting is the name of a file or directory that contains\n"
1078
- " the complete set of root certificates used by Fossil when it\n"
1079
- " is acting as a SSL client. If defined, this setting takes\n"
1080
- " priority over built-in paths and environment variables\n\n"
1081
- );
1082
- }
1083
-
1084
- fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1085
- if( verbose ){
1086
- fossil_print("\n"
1087
- " This setting is the name of a file that contains the PEM-format\n"
1088
- " certificate and private-key used by Fossil clients to authenticate\n"
1089
- " with servers. Few servers actually require this, so this setting\n"
1090
- " is usually blank.\n\n"
1091
- );
1092
- }
1093
-
1094
- zValue = db_get("ssl-cert",0);
1095
- if( zValue ){
1096
- fossil_print("ssl-cert: (%d-byte PEM)\n", (int)strlen(zValue));
1097
- }else{
1098
- fossil_print("ssl-cert:\n");
1099
- }
1100
- if( verbose ){
1101
- fossil_print("\n"
1102
- " This setting is the PEM-formatted value of the SSL server\n"
1103
- " certificate and private-key, used by Fossil when it is acting\n"
1104
- " as a server via the \"fossil server\" command or similar.\n\n"
1105
- );
1106
- }
1107
-
1108
- fossil_print("ssl-cert-file: %s\n", db_get("ssl-cert-file",""));
1109
- fossil_print("ssl-key-file: %s\n", db_get("ssl-key-file",""));
1110
- if( verbose ){
1111
- fossil_print("\n"
1112
- " This settings are the names of files that contain the certificate\n"
1113
- " private-key used by Fossil when it is acting as a server.\n\n"
985
+ fossil_print("Trust store location\n");
986
+ zName = X509_get_default_cert_file_env();
987
+ zValue = fossil_getenv(zName);
988
+ if( zValue==0 ) zValue = "";
989
+ trust_location_usable(zValue, &zUsed);
990
+ nName = strlen(zName);
991
+ fossil_print(" %s:%*s%s\n", zName, 19-nName, "", zValue);
992
+ zName = X509_get_default_cert_dir_env();
993
+ zValue = fossil_getenv(zName);
994
+ if( zValue==0 ) zValue = "";
995
+ trust_location_usable(zValue, &zUsed);
996
+ nName = strlen(zName);
997
+ fossil_print(" %s:%*s%s\n", zName, 19-nName, "", zValue);
998
+ if( verbose ){
999
+ fossil_print("\n"
1000
+ " Environment variables that determine alternative locations for\n"
1001
+ " the root certificates used by Fossil when it is acting as a SSL\n"
1002
+ " client. If specified, these alternative locations take top\n"
1003
+ " priority.\n\n"
1004
+ );
1005
+ }
1006
+
1007
+ zValue = db_get("ssl-ca-location","");
1008
+ trust_location_usable(zValue, &zUsed);
1009
+ fossil_print(" ssl-ca-location: %s\n", zValue);
1010
+ if( verbose ){
1011
+ fossil_print("\n"
1012
+ " This setting is the name of a file or directory that contains\n"
1013
+ " the complete set of root certificates used by Fossil when it\n"
1014
+ " is acting as a SSL client. If defined, this setting takes\n"
1015
+ " priority over built-in paths.\n\n"
1016
+ );
1017
+ }
1018
+
1019
+
1020
+ zValue = X509_get_default_cert_file();
1021
+ trust_location_usable(zValue, &zUsed);
1022
+ fossil_print(" OpenSSL-cert-file: %s\n", zValue);
1023
+ zValue = X509_get_default_cert_dir();
1024
+ trust_location_usable(zValue, &zUsed);
1025
+ fossil_print(" OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1026
+ if( verbose ){
1027
+ fossil_print("\n"
1028
+ " The default locations for the set of root certificates\n"
1029
+ " used by the \"fossil sync\" and similar commands to verify\n"
1030
+ " the identity of servers for \"https:\" URLs. These values\n"
1031
+ " come into play when Fossil is used as a TLS client. These\n"
1032
+ " values are built into your OpenSSL library.\n\n"
1033
+ );
1034
+ }
1035
+
1036
+ if( zUsed==0 ) zUsed = "";
1037
+ fossil_print(" Trust store used: %s\n", zUsed);
1038
+ if( verbose ){
1039
+ fossil_print("\n"
1040
+ " The location that is actually used for the root certificates\n"
1041
+ " used to verify the identity of servers for \"https:\" URLs.\n"
1042
+ " This will be one of the first of the five locations listed\n"
1043
+ " above that actually exists.\n\n"
1044
+ );
1045
+ }
1046
+
1047
+
1048
+#endif /* FOSSIL_ENABLE_SSL */
1049
+
1050
+
1051
+ fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1052
+ if( verbose ){
1053
+ fossil_print("\n"
1054
+ " This setting is the name of a file that contains the PEM-format\n"
1055
+ " certificate and private-key used by Fossil clients to authenticate\n"
1056
+ " with servers. Few servers actually require this, so this setting\n"
1057
+ " is usually blank.\n\n"
11141058
);
11151059
}
11161060
11171061
db_prepare(&q,
1118
- "SELECT name, '' FROM global_config"
1062
+ "SELECT name, '', value FROM global_config"
11191063
" WHERE name GLOB 'cert:*'"
11201064
"UNION ALL "
1121
- "SELECT name, date(mtime,'unixepoch') FROM config"
1065
+ "SELECT name, date(mtime,'unixepoch'), value FROM config"
11221066
" WHERE name GLOB 'cert:*'"
11231067
" ORDER BY name"
11241068
);
11251069
nHit = 0;
11261070
while( db_step(&q)==SQLITE_ROW ){
1127
- fossil_print("exception: %-40s %s\n",
1128
- db_column_text(&q,0)+5, db_column_text(&q,1));
1071
+ /* 123456789 123456789 123456789 */
1072
+ if( verbose ){
1073
+ fossil_print("exception: %-40s %s\n"
1074
+ " hash: %.57s\n",
1075
+ db_column_text(&q,0)+5, db_column_text(&q,1),
1076
+ db_column_text(&q,2));
1077
+ }else{
1078
+ fossil_print("exception: %-40s %s\n",
1079
+ db_column_text(&q,0)+5, db_column_text(&q,1));
1080
+ }
11291081
nHit++;
11301082
}
11311083
db_finalize(&q);
11321084
if( nHit && verbose ){
11331085
fossil_print("\n"
@@ -1177,11 +1129,11 @@
11771129
db_commit_transaction();
11781130
blob_reset(&sql);
11791131
}else
11801132
/*default*/{
11811133
fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
1182
- " clear-cert load-cert remove-exception scrub show",
1134
+ " remove-exception scrub show",
11831135
zCmd);
11841136
}
11851137
}
11861138
11871139
/*
11881140
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -248,47 +248,68 @@
248 /*
249 ** Call this routine once before any other use of the SSL interface.
250 ** This routine does initial configuration of the SSL module.
251 */
252 static void ssl_global_init_client(void){
253 const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
254 const char *identityFile;
255
256 if( sslIsInit==0 ){
 
 
 
 
 
257 SSL_library_init();
258 SSL_load_error_strings();
259 OpenSSL_add_all_algorithms();
260 sslCtx = SSL_CTX_new(SSLv23_client_method());
261 /* Disable SSLv2 and SSLv3 */
262 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
263
264 /* Set up acceptable CA root certificates */
265 zCaSetting = db_get("ssl-ca-location", 0);
266 if( zCaSetting==0 || zCaSetting[0]=='\0' ){
267 /* CA location not specified, use platform's default certificate store */
268 X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
269 }else{
270 /* User has specified a CA location, make sure it exists and use it */
271 switch( file_isdir(zCaSetting, ExtFILE) ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272 case 0: { /* doesn't exist */
273 fossil_fatal("ssl-ca-location is set to '%s', "
274 "but is not a file or directory", zCaSetting);
275 break;
276 }
277 case 1: { /* directory */
278 zCaDirectory = zCaSetting;
 
279 break;
280 }
281 case 2: { /* file */
282 zCaFile = zCaSetting;
 
283 break;
284 }
285 }
286 if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
287 fossil_fatal("Failed to use CA root certificates from "
288 "ssl-ca-location '%s'", zCaSetting);
289 }
 
290 }
291
292 /* Load client SSL identity, preferring the filename specified on the
293 ** command line */
294 if( g.zSSLIdentity!=0 ){
@@ -697,47 +718,48 @@
697 ** of disk files that hold the certificate and private-key for the
698 ** server. If zCertFile is not NULL but zKeyFile is NULL, then
699 ** zCertFile is assumed to be a concatenation of the certificate and
700 ** the private-key in the PEM format.
701 **
702 ** If zCertFile is NULL, then "ssl-cert" setting is consulted
703 ** to get the certificate and private-key (concatenated together, in
704 ** the PEM format). If there is no ssl-cert setting, then
705 ** a built-in self-signed cert is used.
706 */
707 void ssl_init_server(const char *zCertFile, const char *zKeyFile){
708 if( sslIsInit==0 ){
709 const char *zTlsCert;
710 SSL_library_init();
711 SSL_load_error_strings();
712 OpenSSL_add_all_algorithms();
713 sslCtx = SSL_CTX_new(SSLv23_server_method());
714 if( sslCtx==0 ){
715 ERR_print_errors_fp(stderr);
716 fossil_fatal("Error initializing the SSL server");
717 }
718 if( zCertFile && zCertFile[0] ){
 
 
 
 
 
 
719 if( SSL_CTX_use_certificate_chain_file(sslCtx,zCertFile)!=1 ){
720 ERR_print_errors_fp(stderr);
721 fossil_fatal("Error loading CERT file \"%s\"", zCertFile);
722 }
723 if( zKeyFile==0 ) zKeyFile = zCertFile;
724 if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
725 ERR_print_errors_fp(stderr);
726 fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile);
727 }
728 }else
729 if( (zTlsCert = db_get("ssl-cert",0))!=0 ){
730 if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1)
731 || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1)
732 ){
733 fossil_fatal("Error loading the CERT from the"
734 " 'ssl-cert' setting");
735 }
736 }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
737 || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){
738 fossil_fatal("Error loading self-signed CERT");
739 }
740 if( !SSL_CTX_check_private_key(sslCtx) ){
741 fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
742 zKeyFile, zCertFile);
743 }
@@ -748,11 +770,10 @@
748 }
749 }
750
751 typedef struct SslServerConn {
752 SSL *ssl; /* The SSL codec */
753 int atEof; /* True when EOF reached. */
754 int iSocket; /* The socket */
755 BIO *bio; /* BIO object. Needed for EOF detection. */
756 } SslServerConn;
757
758 /*
@@ -762,11 +783,10 @@
762 */
763 void *ssl_new_server(int iSocket){
764 SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
765 BIO *b = BIO_new_socket(iSocket, 0);
766 pServer->ssl = SSL_new(sslCtx);
767 pServer->atEof = 0;
768 pServer->iSocket = iSocket;
769 pServer->bio = b;
770 SSL_set_bio(pServer->ssl, b, b);
771 SSL_accept(pServer->ssl);
772 return (void*)pServer;
@@ -785,46 +805,54 @@
785 ** Return TRUE if there are no more bytes available to be read from
786 ** the client.
787 */
788 int ssl_eof(void *pServerArg){
789 SslServerConn *pServer = (SslServerConn*)pServerArg;
790 return pServer->atEof;
791 }
792
793 /*
794 ** Read cleartext bytes that have been received from the client and
795 ** decrypted by the SSL server codec.
 
 
 
 
 
 
 
 
 
796 */
797 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
798 int n, err = 0;
799 size_t rc = 0;
800 SslServerConn *pServer = (SslServerConn*)pServerArg;
801 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
802 while( 0==err && nBuf!=rc && 0==pServer->atEof ){
803 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
804 if( n==0 ){
805 pServer->atEof = 1;
806 break;
807 }
808 err = SSL_get_error(pServer->ssl, n);
809 if(0==err){
810 rc += n;
811 pServer->atEof = BIO_eof(pServer->bio);
 
 
812 }
813 }
814 return rc;
815 }
816
817 /*
818 ** Read a single line of text from the client.
 
 
819 */
820 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
821 int n = 0;
822 int i;
823 SslServerConn *pServer = (SslServerConn*)pServerArg;
824
825 if( pServer->atEof ) return 0;
826 for(i=0; i<nBuf-1; i++){
827 n = SSL_read(pServer->ssl, &zBuf[i], 1);
828 if( n<=0 ){
829 return 0;
830 }
@@ -852,10 +880,24 @@
852 }
853 }
854
855 #endif /* FOSSIL_ENABLE_SSL */
856
 
 
 
 
 
 
 
 
 
 
 
 
 
 
857 /*
858 ** COMMAND: tls-config*
859 ** COMMAND: ssl-config
860 **
861 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
@@ -864,21 +906,10 @@
864 ** Security) configuration for Fossil. TLS (formerly SSL) is the
865 ** encryption technology used for secure HTTPS transport.
866 **
867 ** Sub-commands:
868 **
869 ** clear-cert Remove information about server certificates.
870 ** This is a subset of the "scrub" command.
871 **
872 ** load-cert PEM-FILES... Identify server certificate files. These
873 ** should be in the PEM format. There are
874 ** normally two files, the certificate and the
875 ** private-key. By default, the text of both
876 ** files is concatenated and added to the
877 ** "ssl-cert" setting. Use --filename to store
878 ** just the filenames.
879 **
880 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
881 ** listed. Or remove them all if the --all
882 ** option is specified.
883 **
884 ** scrub ?--force? Remove all SSL configuration data from the
@@ -890,111 +921,20 @@
890 */
891 void test_tlsconfig_info(void){
892 const char *zCmd;
893 size_t nCmd;
894 int nHit = 0;
 
895 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
896 db_open_config(1,0);
897 if( g.argc==2 || (g.argc>=3 && g.argv[2][0]=='-') ){
898 zCmd = "show";
899 nCmd = 4;
900 }else{
901 zCmd = g.argv[2];
902 nCmd = strlen(zCmd);
903 }
904 if( strncmp("clear-cert",zCmd,nCmd)==0 && nCmd>=4 ){
905 int bForce = find_option("force","f",0)!=0;
906 verify_all_options();
907 if( !bForce ){
908 Blob ans;
909 char cReply;
910 prompt_user(
911 "Confirm removing of the SSL server certificate from this repository.\n"
912 "The removal cannot be undone. Continue (y/N)? ", &ans);
913 cReply = blob_str(&ans)[0];
914 if( cReply!='y' && cReply!='Y' ){
915 fossil_exit(1);
916 }
917 }
918 db_unprotect(PROTECT_ALL);
919 db_multi_exec(
920 "PRAGMA secure_delete=ON;"
921 "DELETE FROM config "
922 " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
923 );
924 db_protect_pop();
925 }else
926 if( strncmp("load-cert",zCmd,nCmd)==0 && nCmd>=4 ){
927 int bFN = find_option("filename",0,0)!=0;
928 int i;
929 Blob allText = BLOB_INITIALIZER;
930 int haveCert = 0;
931 int haveKey = 0;
932 verify_all_options();
933 db_begin_transaction();
934 db_unprotect(PROTECT_ALL);
935 db_multi_exec(
936 "PRAGMA secure_delete=ON;"
937 "DELETE FROM config "
938 " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
939 );
940 nHit = 0;
941 for(i=3; i<g.argc; i++){
942 Blob x;
943 int isCert;
944 int isKey;
945 if( !file_isfile(g.argv[i], ExtFILE) ){
946 fossil_fatal("no such file: \"%s\"", g.argv[i]);
947 }
948 blob_read_from_file(&x, g.argv[i], ExtFILE);
949 isCert = strstr(blob_str(&x),"-----BEGIN CERTIFICATE-----")!=0;
950 isKey = strstr(blob_str(&x),"-----BEGIN PRIVATE KEY-----")!=0;
951 if( !isCert && !isKey ){
952 fossil_fatal("not a certificate or a private key: \"%s\"", g.argv[i]);
953 }
954 if( isCert ){
955 if( haveCert ){
956 fossil_fatal("more than one certificate provided");
957 }
958 haveCert = 1;
959 if( bFN ){
960 db_set("ssl-cert-file", file_canonical_name_dup(g.argv[i]), 0);
961 }else{
962 blob_append(&allText, blob_buffer(&x), blob_size(&x));
963 }
964 if( isKey && !haveKey ){
965 haveKey = 1;
966 isKey = 0;
967 }
968 }
969 if( isKey ){
970 if( haveKey ){
971 fossil_fatal("more than one private key provided");
972 }
973 haveKey = 1;
974 if( bFN ){
975 db_set("ssl-key-file", file_canonical_name_dup(g.argv[i]), 0);
976 }else{
977 blob_append(&allText, blob_buffer(&x), blob_size(&x));
978 }
979 }
980 }
981 if( !haveCert ){
982 if( !haveKey ){
983 fossil_fatal("missing certificate and private-key");
984 }else{
985 fossil_fatal("missing certificate");
986 }
987 }else if( !haveKey ){
988 fossil_fatal("missing private-key");
989 }
990 if( !bFN ){
991 db_set("ssl-cert", blob_str(&allText), 0);
992 }
993 db_protect_pop();
994 db_commit_transaction();
995 }else
996 if( strncmp("scrub",zCmd,nCmd)==0 && nCmd>4 ){
997 int bForce = find_option("force","f",0)!=0;
998 verify_all_options();
999 if( !bForce ){
1000 Blob ans;
@@ -1013,121 +953,133 @@
1013 "DELETE FROM config WHERE name GLOB 'ssl-*';"
1014 );
1015 db_protect_pop();
1016 }else
1017 if( strncmp("show",zCmd,nCmd)==0 ){
 
1018 const char *zName, *zValue;
 
1019 size_t nName;
 
1020 Stmt q;
1021 int verbose = find_option("verbose","v",0)!=0;
1022 verify_all_options();
1023
1024 #if !defined(FOSSIL_ENABLE_SSL)
1025 fossil_print("OpenSSL-version: (none)\n");
1026 if( verbose ){
1027 fossil_print("\n"
1028 " The OpenSSL library is not used by this build of Fossil\n\n"
1029 );
1030 }
1031 #else
1032 fossil_print("OpenSSL-version: %s (0x%09x)\n",
1033 SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
1034 if( verbose ){
1035 fossil_print("\n"
1036 " The version of the OpenSSL library being used\n"
1037 " by this instance of Fossil. Version 3.0.0 or\n"
1038 " later is recommended.\n\n"
1039 );
1040 }
1041
1042 fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
1043 fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1044 if( verbose ){
1045 fossil_print("\n"
1046 " The default locations for the set of root certificates\n"
1047 " used by the \"fossil sync\" and similar commands to verify\n"
1048 " the identity of servers for \"https:\" URLs. These values\n"
1049 " come into play when Fossil is used as a TLS client. These\n"
1050 " values are built into your OpenSSL library.\n\n"
1051 );
1052 }
1053
1054 zName = X509_get_default_cert_file_env();
1055 zValue = fossil_getenv(zName);
1056 if( zValue==0 ) zValue = "";
1057 nName = strlen(zName);
1058 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
1059 zName = X509_get_default_cert_dir_env();
1060 zValue = fossil_getenv(zName);
1061 if( zValue==0 ) zValue = "";
1062 nName = strlen(zName);
1063 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
1064 if( verbose ){
1065 fossil_print("\n"
1066 " Alternative locations for the root certificates used by Fossil\n"
1067 " when it is acting as a SSL client in order to verify the identity\n"
1068 " of servers. If specified, these alternative locations override\n"
1069 " the built-in locations.\n\n"
1070 );
1071 }
1072 #endif /* FOSSIL_ENABLE_SSL */
1073
1074 fossil_print("ssl-ca-location: %s\n", db_get("ssl-ca-location",""));
1075 if( verbose ){
1076 fossil_print("\n"
1077 " This setting is the name of a file or directory that contains\n"
1078 " the complete set of root certificates used by Fossil when it\n"
1079 " is acting as a SSL client. If defined, this setting takes\n"
1080 " priority over built-in paths and environment variables\n\n"
1081 );
1082 }
1083
1084 fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1085 if( verbose ){
1086 fossil_print("\n"
1087 " This setting is the name of a file that contains the PEM-format\n"
1088 " certificate and private-key used by Fossil clients to authenticate\n"
1089 " with servers. Few servers actually require this, so this setting\n"
1090 " is usually blank.\n\n"
1091 );
1092 }
1093
1094 zValue = db_get("ssl-cert",0);
1095 if( zValue ){
1096 fossil_print("ssl-cert: (%d-byte PEM)\n", (int)strlen(zValue));
1097 }else{
1098 fossil_print("ssl-cert:\n");
1099 }
1100 if( verbose ){
1101 fossil_print("\n"
1102 " This setting is the PEM-formatted value of the SSL server\n"
1103 " certificate and private-key, used by Fossil when it is acting\n"
1104 " as a server via the \"fossil server\" command or similar.\n\n"
1105 );
1106 }
1107
1108 fossil_print("ssl-cert-file: %s\n", db_get("ssl-cert-file",""));
1109 fossil_print("ssl-key-file: %s\n", db_get("ssl-key-file",""));
1110 if( verbose ){
1111 fossil_print("\n"
1112 " This settings are the names of files that contain the certificate\n"
1113 " private-key used by Fossil when it is acting as a server.\n\n"
 
1114 );
1115 }
1116
1117 db_prepare(&q,
1118 "SELECT name, '' FROM global_config"
1119 " WHERE name GLOB 'cert:*'"
1120 "UNION ALL "
1121 "SELECT name, date(mtime,'unixepoch') FROM config"
1122 " WHERE name GLOB 'cert:*'"
1123 " ORDER BY name"
1124 );
1125 nHit = 0;
1126 while( db_step(&q)==SQLITE_ROW ){
1127 fossil_print("exception: %-40s %s\n",
1128 db_column_text(&q,0)+5, db_column_text(&q,1));
 
 
 
 
 
 
 
 
1129 nHit++;
1130 }
1131 db_finalize(&q);
1132 if( nHit && verbose ){
1133 fossil_print("\n"
@@ -1177,11 +1129,11 @@
1177 db_commit_transaction();
1178 blob_reset(&sql);
1179 }else
1180 /*default*/{
1181 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
1182 " clear-cert load-cert remove-exception scrub show",
1183 zCmd);
1184 }
1185 }
1186
1187 /*
1188
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -248,47 +248,68 @@
248 /*
249 ** Call this routine once before any other use of the SSL interface.
250 ** This routine does initial configuration of the SSL module.
251 */
252 static void ssl_global_init_client(void){
 
253 const char *identityFile;
254
255 if( sslIsInit==0 ){
256 const char *zFile;
257 const char *zCaFile = 0;
258 const char *zCaDirectory = 0;
259 int i;
260
261 SSL_library_init();
262 SSL_load_error_strings();
263 OpenSSL_add_all_algorithms();
264 sslCtx = SSL_CTX_new(SSLv23_client_method());
265 /* Disable SSLv2 and SSLv3 */
266 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
267
268 /* Find the trust store */
269 zFile = 0;
270 for(i=0; zFile==0 && i<5; i++){
271 switch( i ){
272 case 0: /* First priority is environmentn variables */
273 zFile = fossil_getenv(X509_get_default_cert_file_env());
274 break;
275 case 1:
276 zFile = fossil_getenv(X509_get_default_cert_dir_env());
277 break;
278 case 2:
279 if( !g.repositoryOpen ) db_open_config(0,0);
280 zFile = db_get("ssl-ca-location",0);
281 break;
282 case 3:
283 zFile = X509_get_default_cert_file();
284 break;
285 case 4:
286 zFile = X509_get_default_cert_dir();
287 break;
288 }
289 if( zFile==0 ) continue;
290 switch( file_isdir(zFile, ExtFILE) ){
291 case 0: { /* doesn't exist */
292 zFile = 0;
 
293 break;
294 }
295 case 1: { /* directory */
296 zCaFile = 0;
297 zCaDirectory = zFile;
298 break;
299 }
300 case 2: { /* file */
301 zCaFile = zFile;
302 zCaDirectory = 0;
303 break;
304 }
305 }
306 }
307 if( zFile==0 ){
308 /* fossil_fatal("Cannot find a trust store"); */
309 }else if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
310 fossil_fatal("Cannot load CA root certificates from %s", zFile);
311 }
312
313 /* Load client SSL identity, preferring the filename specified on the
314 ** command line */
315 if( g.zSSLIdentity!=0 ){
@@ -697,47 +718,48 @@
718 ** of disk files that hold the certificate and private-key for the
719 ** server. If zCertFile is not NULL but zKeyFile is NULL, then
720 ** zCertFile is assumed to be a concatenation of the certificate and
721 ** the private-key in the PEM format.
722 **
723 ** If zCertFile is "unsafe-builtin", then a built-in self-signed cert
724 ** is used. This built-in cert is insecure and should only be used for
725 ** testing and debugging.
 
726 */
727 void ssl_init_server(const char *zCertFile, const char *zKeyFile){
728 if( sslIsInit==0 && zCertFile ){
 
729 SSL_library_init();
730 SSL_load_error_strings();
731 OpenSSL_add_all_algorithms();
732 sslCtx = SSL_CTX_new(SSLv23_server_method());
733 if( sslCtx==0 ){
734 ERR_print_errors_fp(stderr);
735 fossil_fatal("Error initializing the SSL server");
736 }
737 if( fossil_strcmp(zCertFile,"unsafe-builtin")==0 ){
738 if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
739 || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1)
740 ){
741 fossil_fatal("Error loading self-signed CERT and KEY");
742 }
743 }else{
744 if( SSL_CTX_use_certificate_chain_file(sslCtx,zCertFile)!=1 ){
745 ERR_print_errors_fp(stderr);
746 fossil_fatal("Error loading CERT file \"%s\"", zCertFile);
747 }
748 if( zKeyFile==0 ) zKeyFile = zCertFile;
749 if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
750 ERR_print_errors_fp(stderr);
751 if( strcmp(zKeyFile,zCertFile)==0 ){
752 fossil_fatal("The private key is not found in \"%s\". "
753 "Either append the private key to the certification in that "
754 "file or use a separate --pkey option to specify the private key.",
755 zKeyFile);
756 }else{
757 fossil_fatal("Error loading the private key from file \"%s\"",
758 zKeyFile);
759 }
760 }
 
 
 
761 }
762 if( !SSL_CTX_check_private_key(sslCtx) ){
763 fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
764 zKeyFile, zCertFile);
765 }
@@ -748,11 +770,10 @@
770 }
771 }
772
773 typedef struct SslServerConn {
774 SSL *ssl; /* The SSL codec */
 
775 int iSocket; /* The socket */
776 BIO *bio; /* BIO object. Needed for EOF detection. */
777 } SslServerConn;
778
779 /*
@@ -762,11 +783,10 @@
783 */
784 void *ssl_new_server(int iSocket){
785 SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
786 BIO *b = BIO_new_socket(iSocket, 0);
787 pServer->ssl = SSL_new(sslCtx);
 
788 pServer->iSocket = iSocket;
789 pServer->bio = b;
790 SSL_set_bio(pServer->ssl, b, b);
791 SSL_accept(pServer->ssl);
792 return (void*)pServer;
@@ -785,46 +805,54 @@
805 ** Return TRUE if there are no more bytes available to be read from
806 ** the client.
807 */
808 int ssl_eof(void *pServerArg){
809 SslServerConn *pServer = (SslServerConn*)pServerArg;
810 return BIO_eof(pServer->bio);
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
816 **
817 ** If the expected payload size unknown, i.e. if the HTTP
818 ** Content-Length: header field has not been parsed, the doLoop
819 ** argument should be 0, or SSL_read() may block and wait for more
820 ** data than is eventually going to arrive (on Windows). On
821 ** non-Windows builds, it has been our experience that the final
822 ** argument must always be true, as discussed at length at:
823 **
824 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719
825 */
826 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
827 int n;
828 size_t rc = 0;
829 SslServerConn *pServer = (SslServerConn*)pServerArg;
830 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
831 while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
832 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
833 if( n>0 ){
 
 
 
 
 
834 rc += n;
835 }
836 if( doLoop==0 || n<=0 ){
837 break;
838 }
839 }
840 return rc;
841 }
842
843 /*
844 ** Read a single line of text from the client, up to nBuf-1 bytes. On
845 ** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846 ** Returns NULL on an I/O error or at EOF.
847 */
848 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
849 int n = 0;
850 int i;
851 SslServerConn *pServer = (SslServerConn*)pServerArg;
852
853 if( BIO_eof(pServer->bio) ) return 0;
854 for(i=0; i<nBuf-1; i++){
855 n = SSL_read(pServer->ssl, &zBuf[i], 1);
856 if( n<=0 ){
857 return 0;
858 }
@@ -852,10 +880,24 @@
880 }
881 }
882
883 #endif /* FOSSIL_ENABLE_SSL */
884
885 #ifdef FOSSIL_ENABLE_SSL
886 /*
887 ** zPath is a name that might be a file or directory containing a trust
888 ** store. *pzStore is the name of the trust store to actually use.
889 **
890 ** If *pzStore is not NULL (meaning no trust store has been found yet)
891 ** and if zPath exists, then set *pzStore to point to zPath.
892 */
893 static void trust_location_usable(const char *zPath, const char **pzStore){
894 if( *pzStore!=0 ) return;
895 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
896 }
897 #endif /* FOSSIL_ENABLE_SSL */
898
899 /*
900 ** COMMAND: tls-config*
901 ** COMMAND: ssl-config
902 **
903 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
@@ -864,21 +906,10 @@
906 ** Security) configuration for Fossil. TLS (formerly SSL) is the
907 ** encryption technology used for secure HTTPS transport.
908 **
909 ** Sub-commands:
910 **
 
 
 
 
 
 
 
 
 
 
 
911 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
912 ** listed. Or remove them all if the --all
913 ** option is specified.
914 **
915 ** scrub ?--force? Remove all SSL configuration data from the
@@ -890,111 +921,20 @@
921 */
922 void test_tlsconfig_info(void){
923 const char *zCmd;
924 size_t nCmd;
925 int nHit = 0;
926
927 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
928 db_open_config(1,0);
929 if( g.argc==2 || (g.argc>=3 && g.argv[2][0]=='-') ){
930 zCmd = "show";
931 nCmd = 4;
932 }else{
933 zCmd = g.argv[2];
934 nCmd = strlen(zCmd);
935 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936 if( strncmp("scrub",zCmd,nCmd)==0 && nCmd>4 ){
937 int bForce = find_option("force","f",0)!=0;
938 verify_all_options();
939 if( !bForce ){
940 Blob ans;
@@ -1013,121 +953,133 @@
953 "DELETE FROM config WHERE name GLOB 'ssl-*';"
954 );
955 db_protect_pop();
956 }else
957 if( strncmp("show",zCmd,nCmd)==0 ){
958 #if defined(FOSSIL_ENABLE_SSL)
959 const char *zName, *zValue;
960 const char *zUsed = 0; /* Trust store location actually used */
961 size_t nName;
962 #endif
963 Stmt q;
964 int verbose = find_option("verbose","v",0)!=0;
965 verify_all_options();
966
967 #if !defined(FOSSIL_ENABLE_SSL)
968 fossil_print("OpenSSL-version: (none)\n");
969 if( verbose ){
970 fossil_print("\n"
971 " The OpenSSL library is not used by this build of Fossil\n\n"
972 );
973 }
974 #else
975 fossil_print("OpenSSL-version: %s (0x%09x)\n",
976 SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
977 if( verbose ){
978 fossil_print("\n"
979 " The version of the OpenSSL library being used\n"
980 " by this instance of Fossil. Version 3.0.0 or\n"
981 " later is recommended.\n\n"
982 );
983 }
984
985 fossil_print("Trust store location\n");
986 zName = X509_get_default_cert_file_env();
987 zValue = fossil_getenv(zName);
988 if( zValue==0 ) zValue = "";
989 trust_location_usable(zValue, &zUsed);
990 nName = strlen(zName);
991 fossil_print(" %s:%*s%s\n", zName, 19-nName, "", zValue);
992 zName = X509_get_default_cert_dir_env();
993 zValue = fossil_getenv(zName);
994 if( zValue==0 ) zValue = "";
995 trust_location_usable(zValue, &zUsed);
996 nName = strlen(zName);
997 fossil_print(" %s:%*s%s\n", zName, 19-nName, "", zValue);
998 if( verbose ){
999 fossil_print("\n"
1000 " Environment variables that determine alternative locations for\n"
1001 " the root certificates used by Fossil when it is acting as a SSL\n"
1002 " client. If specified, these alternative locations take top\n"
1003 " priority.\n\n"
1004 );
1005 }
1006
1007 zValue = db_get("ssl-ca-location","");
1008 trust_location_usable(zValue, &zUsed);
1009 fossil_print(" ssl-ca-location: %s\n", zValue);
1010 if( verbose ){
1011 fossil_print("\n"
1012 " This setting is the name of a file or directory that contains\n"
1013 " the complete set of root certificates used by Fossil when it\n"
1014 " is acting as a SSL client. If defined, this setting takes\n"
1015 " priority over built-in paths.\n\n"
1016 );
1017 }
1018
1019
1020 zValue = X509_get_default_cert_file();
1021 trust_location_usable(zValue, &zUsed);
1022 fossil_print(" OpenSSL-cert-file: %s\n", zValue);
1023 zValue = X509_get_default_cert_dir();
1024 trust_location_usable(zValue, &zUsed);
1025 fossil_print(" OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1026 if( verbose ){
1027 fossil_print("\n"
1028 " The default locations for the set of root certificates\n"
1029 " used by the \"fossil sync\" and similar commands to verify\n"
1030 " the identity of servers for \"https:\" URLs. These values\n"
1031 " come into play when Fossil is used as a TLS client. These\n"
1032 " values are built into your OpenSSL library.\n\n"
1033 );
1034 }
1035
1036 if( zUsed==0 ) zUsed = "";
1037 fossil_print(" Trust store used: %s\n", zUsed);
1038 if( verbose ){
1039 fossil_print("\n"
1040 " The location that is actually used for the root certificates\n"
1041 " used to verify the identity of servers for \"https:\" URLs.\n"
1042 " This will be one of the first of the five locations listed\n"
1043 " above that actually exists.\n\n"
1044 );
1045 }
1046
1047
1048 #endif /* FOSSIL_ENABLE_SSL */
1049
1050
1051 fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1052 if( verbose ){
1053 fossil_print("\n"
1054 " This setting is the name of a file that contains the PEM-format\n"
1055 " certificate and private-key used by Fossil clients to authenticate\n"
1056 " with servers. Few servers actually require this, so this setting\n"
1057 " is usually blank.\n\n"
1058 );
1059 }
1060
1061 db_prepare(&q,
1062 "SELECT name, '', value FROM global_config"
1063 " WHERE name GLOB 'cert:*'"
1064 "UNION ALL "
1065 "SELECT name, date(mtime,'unixepoch'), value FROM config"
1066 " WHERE name GLOB 'cert:*'"
1067 " ORDER BY name"
1068 );
1069 nHit = 0;
1070 while( db_step(&q)==SQLITE_ROW ){
1071 /* 123456789 123456789 123456789 */
1072 if( verbose ){
1073 fossil_print("exception: %-40s %s\n"
1074 " hash: %.57s\n",
1075 db_column_text(&q,0)+5, db_column_text(&q,1),
1076 db_column_text(&q,2));
1077 }else{
1078 fossil_print("exception: %-40s %s\n",
1079 db_column_text(&q,0)+5, db_column_text(&q,1));
1080 }
1081 nHit++;
1082 }
1083 db_finalize(&q);
1084 if( nHit && verbose ){
1085 fossil_print("\n"
@@ -1177,11 +1129,11 @@
1129 db_commit_transaction();
1130 blob_reset(&sql);
1131 }else
1132 /*default*/{
1133 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
1134 " remove-exception scrub show",
1135 zCmd);
1136 }
1137 }
1138
1139 /*
1140
+4 -4
--- src/info.c
+++ src/info.c
@@ -986,13 +986,13 @@
986986
}
987987
}
988988
style_header("Update of \"%h\"", pWiki->zWikiTitle);
989989
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
990990
zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
991
- style_submenu_element("Raw", "artifact/%s", zUuid);
992
- style_submenu_element("History", "whistory?name=%t", pWiki->zWikiTitle);
993
- style_submenu_element("Page", "wiki?name=%t", pWiki->zWikiTitle);
991
+ style_submenu_element("Raw", "%R/artifact/%s", zUuid);
992
+ style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
993
+ style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
994994
login_anonymous_available();
995995
@ <div class="section">Overview</div>
996996
@ <p><table class="label-value">
997997
@ <tr><th>Artifact&nbsp;ID:</th>
998998
@ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1014,11 @@
10141014
if( pWiki->nParent>0 ){
10151015
int i;
10161016
@ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
10171017
for(i=0; i<pWiki->nParent; i++){
10181018
char *zParent = pWiki->azParent[i];
1019
- @ %z(href("info/%!S",zParent))%s(zParent)</a>
1019
+ @ %z(href("%R/info/%!S",zParent))%s(zParent)</a>
10201020
@ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
10211021
}
10221022
@ </td></tr>
10231023
}
10241024
tagid = wiki_tagid(pWiki->zWikiTitle);
10251025
--- src/info.c
+++ src/info.c
@@ -986,13 +986,13 @@
986 }
987 }
988 style_header("Update of \"%h\"", pWiki->zWikiTitle);
989 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
990 zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
991 style_submenu_element("Raw", "artifact/%s", zUuid);
992 style_submenu_element("History", "whistory?name=%t", pWiki->zWikiTitle);
993 style_submenu_element("Page", "wiki?name=%t", pWiki->zWikiTitle);
994 login_anonymous_available();
995 @ <div class="section">Overview</div>
996 @ <p><table class="label-value">
997 @ <tr><th>Artifact&nbsp;ID:</th>
998 @ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1014,11 @@
1014 if( pWiki->nParent>0 ){
1015 int i;
1016 @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
1017 for(i=0; i<pWiki->nParent; i++){
1018 char *zParent = pWiki->azParent[i];
1019 @ %z(href("info/%!S",zParent))%s(zParent)</a>
1020 @ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
1021 }
1022 @ </td></tr>
1023 }
1024 tagid = wiki_tagid(pWiki->zWikiTitle);
1025
--- src/info.c
+++ src/info.c
@@ -986,13 +986,13 @@
986 }
987 }
988 style_header("Update of \"%h\"", pWiki->zWikiTitle);
989 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
990 zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
991 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
992 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
993 style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
994 login_anonymous_available();
995 @ <div class="section">Overview</div>
996 @ <p><table class="label-value">
997 @ <tr><th>Artifact&nbsp;ID:</th>
998 @ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1014,11 @@
1014 if( pWiki->nParent>0 ){
1015 int i;
1016 @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
1017 for(i=0; i<pWiki->nParent; i++){
1018 char *zParent = pWiki->azParent[i];
1019 @ %z(href("%R/info/%!S",zParent))%s(zParent)</a>
1020 @ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
1021 }
1022 @ </td></tr>
1023 }
1024 tagid = wiki_tagid(pWiki->zWikiTitle);
1025
+6 -15
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
11
#ifdef FOSSIL_ENABLE_JSON
22
/*
3
-** Copyright (c) 2011 D. Richard Hipp
3
+** Copyright (c) 2011-2022 D. Richard Hipp
44
**
55
** This program is free software; you can redistribute it and/or
66
** modify it under the terms of the Simplified BSD License (also
77
** known as the "2-Clause License" or "FreeBSD License".)
88
@@ -172,21 +172,10 @@
172172
Blob * b = (Blob*)pState;
173173
blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174174
return 0;
175175
}
176176
177
-/*
178
-** Implements the cson_data_source_f() interface and reads input from
179
-** a fossil Blob object. pState must be-a (Blob*) populated with JSON
180
-** data.
181
-*/
182
-int cson_data_src_Blob(void * pState, void * dest, unsigned int * n){
183
- Blob * b = (Blob*)pState;
184
- *n = blob_read( b, dest, *n );
185
- return 0;
186
-}
187
-
188177
/*
189178
** Convenience wrapper around cson_output() which appends the output
190179
** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
191180
*/
192181
int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
204193
** On success a new JSON Object or Array is returned (owned by the
205194
** caller). On error NULL is returned.
206195
*/
207196
cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
208197
cson_value * root = NULL;
209
- blob_rewind( pSrc );
210
- cson_parse( &root, cson_data_src_Blob, pSrc, NULL, pInfo );
198
+ cson_parse_string( &root, blob_str(pSrc), blob_size(pSrc), NULL, pInfo );
211199
return root;
212200
}
213201
214202
/*
215203
** Implements the cson_data_dest_f() interface and outputs the data to
@@ -1065,10 +1053,11 @@
10651053
because outOpt cannot (generically) be configured until after
10661054
POST-reading is finished.
10671055
*/
10681056
FILE * inFile = NULL;
10691057
char const * jfile = find_option("json-input",NULL,1);
1058
+ Blob json = BLOB_INITIALIZER;
10701059
if(!jfile || !*jfile){
10711060
break;
10721061
}
10731062
inFile = (0==strcmp("-",jfile))
10741063
? stdin
@@ -1077,12 +1066,14 @@
10771066
g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
10781067
fossil_fatal("Could not open JSON file [%s].",jfile)
10791068
/* Does not return. */
10801069
;
10811070
}
1082
- cgi_parse_POST_JSON(inFile, 0);
1071
+ blob_read_from_channel(&json, inFile, -1);
10831072
fossil_fclose(inFile);
1073
+ cgi_parse_POST_JSON(&json);
1074
+ blob_reset(&json);
10841075
break;
10851076
}
10861077
10871078
/* g.json.reqPayload exists only to simplify some of our access to
10881079
the request payload. We currently only use this in the context of
10891080
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
1 #ifdef FOSSIL_ENABLE_JSON
2 /*
3 ** Copyright (c) 2011 D. Richard Hipp
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of the Simplified BSD License (also
7 ** known as the "2-Clause License" or "FreeBSD License".)
8
@@ -172,21 +172,10 @@
172 Blob * b = (Blob*)pState;
173 blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174 return 0;
175 }
176
177 /*
178 ** Implements the cson_data_source_f() interface and reads input from
179 ** a fossil Blob object. pState must be-a (Blob*) populated with JSON
180 ** data.
181 */
182 int cson_data_src_Blob(void * pState, void * dest, unsigned int * n){
183 Blob * b = (Blob*)pState;
184 *n = blob_read( b, dest, *n );
185 return 0;
186 }
187
188 /*
189 ** Convenience wrapper around cson_output() which appends the output
190 ** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
191 */
192 int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
204 ** On success a new JSON Object or Array is returned (owned by the
205 ** caller). On error NULL is returned.
206 */
207 cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
208 cson_value * root = NULL;
209 blob_rewind( pSrc );
210 cson_parse( &root, cson_data_src_Blob, pSrc, NULL, pInfo );
211 return root;
212 }
213
214 /*
215 ** Implements the cson_data_dest_f() interface and outputs the data to
@@ -1065,10 +1053,11 @@
1065 because outOpt cannot (generically) be configured until after
1066 POST-reading is finished.
1067 */
1068 FILE * inFile = NULL;
1069 char const * jfile = find_option("json-input",NULL,1);
 
1070 if(!jfile || !*jfile){
1071 break;
1072 }
1073 inFile = (0==strcmp("-",jfile))
1074 ? stdin
@@ -1077,12 +1066,14 @@
1077 g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
1078 fossil_fatal("Could not open JSON file [%s].",jfile)
1079 /* Does not return. */
1080 ;
1081 }
1082 cgi_parse_POST_JSON(inFile, 0);
1083 fossil_fclose(inFile);
 
 
1084 break;
1085 }
1086
1087 /* g.json.reqPayload exists only to simplify some of our access to
1088 the request payload. We currently only use this in the context of
1089
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
1 #ifdef FOSSIL_ENABLE_JSON
2 /*
3 ** Copyright (c) 2011-2022 D. Richard Hipp
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of the Simplified BSD License (also
7 ** known as the "2-Clause License" or "FreeBSD License".)
8
@@ -172,21 +172,10 @@
172 Blob * b = (Blob*)pState;
173 blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174 return 0;
175 }
176
 
 
 
 
 
 
 
 
 
 
 
177 /*
178 ** Convenience wrapper around cson_output() which appends the output
179 ** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
180 */
181 int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
193 ** On success a new JSON Object or Array is returned (owned by the
194 ** caller). On error NULL is returned.
195 */
196 cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
197 cson_value * root = NULL;
198 cson_parse_string( &root, blob_str(pSrc), blob_size(pSrc), NULL, pInfo );
 
199 return root;
200 }
201
202 /*
203 ** Implements the cson_data_dest_f() interface and outputs the data to
@@ -1065,10 +1053,11 @@
1053 because outOpt cannot (generically) be configured until after
1054 POST-reading is finished.
1055 */
1056 FILE * inFile = NULL;
1057 char const * jfile = find_option("json-input",NULL,1);
1058 Blob json = BLOB_INITIALIZER;
1059 if(!jfile || !*jfile){
1060 break;
1061 }
1062 inFile = (0==strcmp("-",jfile))
1063 ? stdin
@@ -1077,12 +1066,14 @@
1066 g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
1067 fossil_fatal("Could not open JSON file [%s].",jfile)
1068 /* Does not return. */
1069 ;
1070 }
1071 blob_read_from_channel(&json, inFile, -1);
1072 fossil_fclose(inFile);
1073 cgi_parse_POST_JSON(&json);
1074 blob_reset(&json);
1075 break;
1076 }
1077
1078 /* g.json.reqPayload exists only to simplify some of our access to
1079 the request payload. We currently only use this in the context of
1080
+27 -6
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273273
return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274274
}
275275
276276
/*
277277
** Implementation of /json/wiki/preview.
278
-**
279278
*/
280279
static cson_value * json_wiki_preview(){
281280
char const * zContent = NULL;
281
+ char const * zMime = NULL;
282
+ cson_string * sContent = NULL;
282283
cson_value * pay = NULL;
283284
Blob contentOrig = empty_blob;
284285
Blob contentHtml = empty_blob;
285286
if( !g.perm.WrWiki ){
286287
json_set_err(FSL_JSON_E_DENIED,
287288
"Requires 'k' access.");
288289
return NULL;
289290
}
290
- zContent = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v));
291
- if(!zContent) {
291
+
292
+ if(g.json.reqPayload.o){
293
+ sContent = cson_value_get_string(
294
+ cson_object_get(g.json.reqPayload.o, "body"));
295
+ zMime = cson_value_get_cstr(cson_object_get(g.json.reqPayload.o,
296
+ "mimetype"));
297
+ }else{
298
+ sContent = cson_value_get_string(g.json.reqPayload.v);
299
+ }
300
+ if(!sContent) {
292301
json_set_err(FSL_JSON_E_MISSING_ARGS,
293
- "The 'payload' property must be a string containing the wiki code to preview.");
302
+ "The 'payload' property must be either a string containing the "
303
+ "Fossil wiki code to preview or an object with body + mimetype "
304
+ "properties.");
294305
return NULL;
295306
}
296
- blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(cson_value_get_string(g.json.reqPayload.v)) );
297
- wiki_convert( &contentOrig, &contentHtml, 0 );
307
+ zContent = cson_string_cstr(sContent);
308
+ blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(sContent) );
309
+ zMime = wiki_filter_mimetypes(zMime);
310
+ if( 0==fossil_strcmp(zMime, "text/x-markdown") ){
311
+ markdown_to_html(&contentOrig, 0, &contentHtml);
312
+ }else if( 0==fossil_strcmp(zMime, "text/plain") ){
313
+ blob_append(&contentHtml, "<pre class='textPlain'>", -1);
314
+ blob_append(&contentHtml, blob_str(&contentOrig), blob_size(&contentOrig));
315
+ blob_append(&contentHtml, "</pre>", -1);
316
+ }else{
317
+ wiki_convert( &contentOrig, &contentHtml, 0 );
318
+ }
298319
blob_reset( &contentOrig );
299320
pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
300321
blob_reset( &contentHtml );
301322
return pay;
302323
}
303324
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273 return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274 }
275
276 /*
277 ** Implementation of /json/wiki/preview.
278 **
279 */
280 static cson_value * json_wiki_preview(){
281 char const * zContent = NULL;
 
 
282 cson_value * pay = NULL;
283 Blob contentOrig = empty_blob;
284 Blob contentHtml = empty_blob;
285 if( !g.perm.WrWiki ){
286 json_set_err(FSL_JSON_E_DENIED,
287 "Requires 'k' access.");
288 return NULL;
289 }
290 zContent = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v));
291 if(!zContent) {
 
 
 
 
 
 
 
 
292 json_set_err(FSL_JSON_E_MISSING_ARGS,
293 "The 'payload' property must be a string containing the wiki code to preview.");
 
 
294 return NULL;
295 }
296 blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(cson_value_get_string(g.json.reqPayload.v)) );
297 wiki_convert( &contentOrig, &contentHtml, 0 );
 
 
 
 
 
 
 
 
 
 
298 blob_reset( &contentOrig );
299 pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
300 blob_reset( &contentHtml );
301 return pay;
302 }
303
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273 return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274 }
275
276 /*
277 ** Implementation of /json/wiki/preview.
 
278 */
279 static cson_value * json_wiki_preview(){
280 char const * zContent = NULL;
281 char const * zMime = NULL;
282 cson_string * sContent = NULL;
283 cson_value * pay = NULL;
284 Blob contentOrig = empty_blob;
285 Blob contentHtml = empty_blob;
286 if( !g.perm.WrWiki ){
287 json_set_err(FSL_JSON_E_DENIED,
288 "Requires 'k' access.");
289 return NULL;
290 }
291
292 if(g.json.reqPayload.o){
293 sContent = cson_value_get_string(
294 cson_object_get(g.json.reqPayload.o, "body"));
295 zMime = cson_value_get_cstr(cson_object_get(g.json.reqPayload.o,
296 "mimetype"));
297 }else{
298 sContent = cson_value_get_string(g.json.reqPayload.v);
299 }
300 if(!sContent) {
301 json_set_err(FSL_JSON_E_MISSING_ARGS,
302 "The 'payload' property must be either a string containing the "
303 "Fossil wiki code to preview or an object with body + mimetype "
304 "properties.");
305 return NULL;
306 }
307 zContent = cson_string_cstr(sContent);
308 blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(sContent) );
309 zMime = wiki_filter_mimetypes(zMime);
310 if( 0==fossil_strcmp(zMime, "text/x-markdown") ){
311 markdown_to_html(&contentOrig, 0, &contentHtml);
312 }else if( 0==fossil_strcmp(zMime, "text/plain") ){
313 blob_append(&contentHtml, "<pre class='textPlain'>", -1);
314 blob_append(&contentHtml, blob_str(&contentOrig), blob_size(&contentOrig));
315 blob_append(&contentHtml, "</pre>", -1);
316 }else{
317 wiki_convert( &contentOrig, &contentHtml, 0 );
318 }
319 blob_reset( &contentOrig );
320 pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
321 blob_reset( &contentHtml );
322 return pay;
323 }
324
+8 -7
--- src/login.c
+++ src/login.c
@@ -1178,17 +1178,18 @@
11781178
** enabled for this repository and make appropriate adjustments to the
11791179
** permission flags if it is. This should be done before the permissions
11801180
** are (potentially) copied to the anonymous permission set; otherwise,
11811181
** those will be out-of-sync.
11821182
*/
1183
- if( zCap[0]
1184
- && !g.perm.Hyperlink
1185
- && g.isHuman
1186
- && db_get_boolean("auto-hyperlink",1)
1187
- ){
1188
- g.perm.Hyperlink = 1;
1189
- g.javascriptHyperlink = 1;
1183
+ if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){
1184
+ int autoLink = db_get_int("auto-hyperlink",1);
1185
+ if( autoLink==1 ){
1186
+ g.jsHref = 1;
1187
+ g.perm.Hyperlink = 1;
1188
+ }else if( autoLink==2 ){
1189
+ g.perm.Hyperlink = 1;
1190
+ }
11901191
}
11911192
11921193
/*
11931194
** At this point, the capabilities for the logged in user are not going
11941195
** to be modified anymore; therefore, we can copy them over to the ones
11951196
--- src/login.c
+++ src/login.c
@@ -1178,17 +1178,18 @@
1178 ** enabled for this repository and make appropriate adjustments to the
1179 ** permission flags if it is. This should be done before the permissions
1180 ** are (potentially) copied to the anonymous permission set; otherwise,
1181 ** those will be out-of-sync.
1182 */
1183 if( zCap[0]
1184 && !g.perm.Hyperlink
1185 && g.isHuman
1186 && db_get_boolean("auto-hyperlink",1)
1187 ){
1188 g.perm.Hyperlink = 1;
1189 g.javascriptHyperlink = 1;
 
1190 }
1191
1192 /*
1193 ** At this point, the capabilities for the logged in user are not going
1194 ** to be modified anymore; therefore, we can copy them over to the ones
1195
--- src/login.c
+++ src/login.c
@@ -1178,17 +1178,18 @@
1178 ** enabled for this repository and make appropriate adjustments to the
1179 ** permission flags if it is. This should be done before the permissions
1180 ** are (potentially) copied to the anonymous permission set; otherwise,
1181 ** those will be out-of-sync.
1182 */
1183 if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){
1184 int autoLink = db_get_int("auto-hyperlink",1);
1185 if( autoLink==1 ){
1186 g.jsHref = 1;
1187 g.perm.Hyperlink = 1;
1188 }else if( autoLink==2 ){
1189 g.perm.Hyperlink = 1;
1190 }
1191 }
1192
1193 /*
1194 ** At this point, the capabilities for the logged in user are not going
1195 ** to be modified anymore; therefore, we can copy them over to the ones
1196
+71 -62
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206206
int markPrivate; /* All new artifacts are private if true */
207207
char *ckinLockFail; /* Check-in lock failure received from server */
208208
int clockSkewSeen; /* True if clocks on client and server out of sync */
209209
int wikiFlags; /* Wiki conversion flags applied to %W */
210210
char isHTTP; /* True if server/CGI modes, else assume CLI. */
211
- char javascriptHyperlink; /* If true, set href= using script, not HTML */
211
+ char jsHref; /* If true, set href= using javascript, not HTML */
212212
Blob httpHeader; /* Complete text of the HTTP request header */
213213
UrlData url; /* Information about current URL */
214214
const char *zLogin; /* Login name. NULL or "" if not logged in. */
215215
const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216216
const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -420,28 +420,20 @@
420420
unsigned int nArg; /* Number of new arguments */
421421
char *z; /* General use string pointer */
422422
char **newArgv; /* New expanded g.argv under construction */
423423
const char *zFileName; /* input file name */
424424
FILE *inFile; /* input FILE */
425
-#if defined(_WIN32)
426
- wchar_t buf[MAX_PATH];
427
-#endif
428425
429426
g.argc = argc;
430427
g.argv = argv;
431428
sqlite3_initialize();
432429
#if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
433430
for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
434431
#else
435432
for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
436433
#endif
437
-#if defined(_WIN32)
438
- GetModuleFileNameW(NULL, buf, MAX_PATH);
439
- g.nameOfExe = fossil_path_to_utf8(buf);
440
-#else
441
- g.nameOfExe = g.argv[0];
442
-#endif
434
+ g.nameOfExe = file_fullexename(g.argv[0]);
443435
for(i=1; i<g.argc-1; i++){
444436
z = g.argv[i];
445437
if( z[0]!='-' ) continue;
446438
z++;
447439
if( z[0]=='-' ) z++;
@@ -1596,10 +1588,30 @@
15961588
cgi_redirect_with_status(zURL, 301, "Moved Permanently");
15971589
return 1;
15981590
}
15991591
return 0;
16001592
}
1593
+
1594
+/*
1595
+** Send a 404 Not Found reply
1596
+*/
1597
+void fossil_not_found_page(void){
1598
+#ifdef FOSSIL_ENABLE_JSON
1599
+ if(g.json.isJsonMode){
1600
+ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1601
+ return;
1602
+ }
1603
+#endif
1604
+ @ <html><head>
1605
+ @ <meta name="viewport" \
1606
+ @ content="width=device-width, initial-scale=1.0">
1607
+ @ </head><body>
1608
+ @ <h1>Not Found</h1>
1609
+ @ </body>
1610
+ cgi_set_status(404, "Not Found");
1611
+ cgi_reply();
1612
+}
16011613
16021614
/*
16031615
** Preconditions:
16041616
**
16051617
** * Environment variables are set up according to the CGI standard.
@@ -1819,24 +1831,11 @@
18191831
&& repo_list_page() ){
18201832
/* Will return a list of repositories */
18211833
}else if( zNotFound ){
18221834
cgi_redirect(zNotFound);
18231835
}else{
1824
-#ifdef FOSSIL_ENABLE_JSON
1825
- if(g.json.isJsonMode){
1826
- json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1827
- return;
1828
- }
1829
-#endif
1830
- @ <html><head>
1831
- @ <meta name="viewport" \
1832
- @ content="width=device-width, initial-scale=1.0">
1833
- @ </head><body>
1834
- @ <h1>Not Found</h1>
1835
- @ </body>
1836
- cgi_set_status(404, "Not Found");
1837
- cgi_reply();
1836
+ fossil_not_found_page();
18381837
}
18391838
return;
18401839
}
18411840
break;
18421841
}
@@ -1887,10 +1886,15 @@
18871886
&& zPathInfo[6]>='1' && zPathInfo[6]<='9'
18881887
&& (zPathInfo[7]=='/' || zPathInfo[7]==0)
18891888
){
18901889
int iSkin = zPathInfo[6] - '0';
18911890
char *zNewScript;
1891
+ if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892
+ iSkin)<5 ){
1893
+ fossil_not_found_page();
1894
+ fossil_exit(0);
1895
+ }
18921896
skin_use_draft(iSkin);
18931897
zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
18941898
if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
18951899
if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
18961900
zPathInfo += 7;
@@ -2597,18 +2601,18 @@
25972601
** SSL should be used, and initialize the SSL decoder.
25982602
*/
25992603
static void decode_ssl_options(void){
26002604
#if FOSSIL_ENABLE_SSL
26012605
const char *zCertFile = 0;
2602
- zCertFile = find_option("tls-cert-file",0,1);
2606
+ const char *zKeyFile = 0;
2607
+ zCertFile = find_option("cert",0,1);
2608
+ zKeyFile = find_option("pkey",0,1);
26032609
if( zCertFile ){
26042610
g.httpUseSSL = 1;
2605
- ssl_init_server(zCertFile, zCertFile);
2606
- }
2607
- if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){
2608
- g.httpUseSSL = 1;
2609
- ssl_init_server(0,0);
2611
+ ssl_init_server(zCertFile, zKeyFile);
2612
+ }else if( zKeyFile ){
2613
+ fossil_fatal("--pkey without a corresponding --cert");
26102614
}
26112615
#endif
26122616
}
26132617
26142618
/*
@@ -2616,12 +2620,12 @@
26162620
**
26172621
** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
26182622
**
26192623
** Handle a single HTTP request appearing on stdin. The resulting webpage
26202624
** is delivered on stdout. This method is used to launch an HTTP request
2621
-** handler from inetd, for example. The argument is the name of the
2622
-** repository.
2625
+** handler from inetd, for example. The REPOSITORY argument is the name of
2626
+** the repository.
26232627
**
26242628
** If REPOSITORY is a directory that contains one or more repositories,
26252629
** either directly in REPOSITORY itself or in subdirectories, and
26262630
** with names of the form "*.fossil" then a prefix of the URL pathname
26272631
** selects from among the various repositories. If the pathname does
@@ -2632,29 +2636,24 @@
26322636
** and every "." must be surrounded on both sides by alphanumerics or else
26332637
** a 404 error is returned. Static content files in the directory are
26342638
** returned if they match comma-separate GLOB pattern specified by --files
26352639
** and do not match "*.fossil*" and have a well-known suffix.
26362640
**
2637
-** The --host option can be used to specify the hostname for the server.
2638
-** The --https option indicates that the request came from HTTPS rather
2639
-** than HTTP. If --nossl is given, then SSL connections will not be available,
2640
-** thus also no redirecting from http: to https: will take place.
2641
-**
2642
-** If the --localauth option is given, then automatic login is performed
2643
-** for requests coming from localhost, if the "localauth" setting is not
2644
-** enabled.
2645
-**
26462641
** Options:
26472642
** --acme Deliver files from the ".well-known" subdirectory
26482643
** --baseurl URL base URL (useful with reverse proxies)
2644
+** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2645
+** fullchain.pem) taken from FILE.
26492646
** --chroot DIR Use directory for chroot instead of repository path.
26502647
** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
26512648
** /doc/ckout/...
2652
-** --extroot DIR document root for the /ext extension mechanism
2653
-** --files GLOB comma-separate glob patterns for static file to serve
2654
-** --host NAME specify hostname of the server
2655
-** --https signal a request coming in via https
2649
+** --extroot DIR Document root for the /ext extension mechanism
2650
+** --files GLOB Comma-separate glob patterns for static file to serve
2651
+** --host NAME DNS Hostname of the server
2652
+** --https The HTTP request originated from https but has already
2653
+** been decoded by a reverse proxy. Hence, URLs created
2654
+** by Fossil should use "https:" rather than "http:".
26562655
** --in FILE Take input from FILE instead of standard input
26572656
** --ipaddr ADDR Assume the request comes from the given IP address
26582657
** --jsmode MODE Determine how JavaScript is delivered with pages.
26592658
** Mode can be one of:
26602659
** inline All JavaScript is inserted inline at
@@ -2666,27 +2665,28 @@
26662665
** concatenate scripts together.
26672666
** Depending on the needs of any given page, inline
26682667
** and bundled modes might result in a single
26692668
** amalgamated script or several, but both approaches
26702669
** result in fewer HTTP requests than the separate mode.
2671
-** --localauth enable automatic login for local connections
2670
+** --localauth Connections from localhost are given "setup"
2671
+** privileges without having to log in.
26722672
** --mainmenu FILE Override the mainmenu config setting with the contents
26732673
** of the given file.
2674
-** --nocompress do not compress HTTP replies
2675
-** --nodelay omit backoffice processing if it would delay
2674
+** --nocompress Do not compress HTTP replies
2675
+** --nodelay Omit backoffice processing if it would delay
26762676
** process exit
2677
-** --nojail drop root privilege but do not enter the chroot jail
2678
-** --nossl signal that no SSL connections are available
2679
-** --notfound URL use URL as "HTTP 404, object not found" page.
2680
-** --out FILE write results to FILE instead of to standard output
2677
+** --nojail Drop root privilege but do not enter the chroot jail
2678
+** --nossl Do not do http: to https: redirects, regardless of
2679
+** the redirect-to-https setting.
2680
+** --notfound URL Use URL as the "HTTP 404, object not found" page.
2681
+** --out FILE Write the HTTP reply to FILE instead of to
2682
+** standard output
2683
+** --pkey FILE Read the private key used for TLS from FILE.
26812684
** --repolist If REPOSITORY is directory, URL "/" lists all repos
26822685
** --scgi Interpret input as SCGI rather than HTTP
26832686
** --skin LABEL Use override skin LABEL
2684
-** --ssl Use TLS (HTTPS) encryption. Alias for --tls
2685
-** --th-trace trace TH1 execution (for debugging purposes)
2686
-** --tls Use TLS (HTTPS) encryption.
2687
-** --tls-cert-file FN Read the TLS certificate and private key from FN
2687
+** --th-trace Trace TH1 execution (for debugging purposes)
26882688
** --usepidkey Use saved encryption key from parent process. This is
26892689
** only necessary when using SEE on Windows.
26902690
**
26912691
** See also: [[cgi]], [[server]], [[winsrv]]
26922692
*/
@@ -2733,17 +2733,23 @@
27332733
backoffice_disable();
27342734
g.httpIn = fossil_fopen(zInFile, "rb");
27352735
if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
27362736
}else{
27372737
g.httpIn = stdin;
2738
+#if defined(_WIN32)
2739
+ _setmode(_fileno(stdin), _O_BINARY);
2740
+#endif
27382741
}
27392742
zOutFile = find_option("out",0,1);
27402743
if( zOutFile ){
27412744
g.httpOut = fossil_fopen(zOutFile, "wb");
27422745
if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
27432746
}else{
27442747
g.httpOut = stdout;
2748
+#if defined(_WIN32)
2749
+ _setmode(_fileno(stdout), _O_BINARY);
2750
+#endif
27452751
}
27462752
zIpAddr = find_option("ipaddr",0,1);
27472753
useSCGI = find_option("scgi", 0, 0)!=0;
27482754
zAltBase = find_option("baseurl", 0, 1);
27492755
if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
@@ -2976,10 +2982,12 @@
29762982
** by default.
29772983
**
29782984
** Options:
29792985
** --acme Deliver files from the ".well-known" subdirectory.
29802986
** --baseurl URL Use URL as the base (useful for reverse proxies)
2987
+** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2988
+** fullchain.pem) taken from FILE.
29812989
** --chroot DIR Use directory for chroot instead of repository path.
29822990
** --ckout-alias NAME Treat URIs of the form /doc/NAME/... as if they were
29832991
** /doc/ckout/...
29842992
** --create Create a new REPOSITORY if it does not already exist
29852993
** --extroot DIR Document root for the /ext extension mechanism
@@ -3008,22 +3016,21 @@
30083016
** seconds (only works on unix)
30093017
** --nobrowser Do not automatically launch a web-browser for the
30103018
** "fossil ui" command.
30113019
** --nocompress Do not compress HTTP replies
30123020
** --nojail Drop root privileges but do not enter the chroot jail
3013
-** --nossl signal that no SSL connections are available (Always
3014
-** set by default for the "ui" command)
3015
-** --notfound URL Redirect
3021
+** --nossl do not force redirects to SSL even if the repository
3022
+** setting "redirect-to-https" requests it. This is set
3023
+** by default for the "ui" command.
3024
+** --notfound URL Redirect to URL if a page is not found.
30163025
** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
3026
+** --pkey FILE Read the private key used for TLS from FILE.
30173027
** -P|--port TCPPORT listen to request on port TCPPORT
30183028
** --repolist If REPOSITORY is dir, URL "/" lists repos.
30193029
** --scgi Accept SCGI rather than HTTP
30203030
** --skin LABEL Use override skin LABEL
3021
-** --ssl Use TLS (HTTPS) encryption. Alias for --tls
30223031
** --th-trace trace TH1 execution (for debugging purposes)
3023
-** --tls Use TLS (HTTPS) encryption.
3024
-** --tls-cert-file FN Read the TLS certificate and private key from FN
30253032
** --usepidkey Use saved encryption key from parent process. This is
30263033
** only necessary when using SEE on Windows.
30273034
**
30283035
** See also: [[cgi]], [[http]], [[winsrv]]
30293036
*/
@@ -3255,10 +3262,12 @@
32553262
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
32563263
db_close(1);
32573264
32583265
/* Start up an HTTP server
32593266
*/
3267
+ fossil_setenv("SERVER_SOFTWARE", "fossil version " RELEASE_VERSION
3268
+ " " MANIFEST_VERSION " " MANIFEST_DATE);
32603269
#if !defined(_WIN32)
32613270
/* Unix implementation */
32623271
if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
32633272
fossil_fatal("unable to listen on TCP socket %d", iPort);
32643273
}
32653274
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char javascriptHyperlink; /* If true, set href= using script, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -420,28 +420,20 @@
420 unsigned int nArg; /* Number of new arguments */
421 char *z; /* General use string pointer */
422 char **newArgv; /* New expanded g.argv under construction */
423 const char *zFileName; /* input file name */
424 FILE *inFile; /* input FILE */
425 #if defined(_WIN32)
426 wchar_t buf[MAX_PATH];
427 #endif
428
429 g.argc = argc;
430 g.argv = argv;
431 sqlite3_initialize();
432 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
433 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
434 #else
435 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
436 #endif
437 #if defined(_WIN32)
438 GetModuleFileNameW(NULL, buf, MAX_PATH);
439 g.nameOfExe = fossil_path_to_utf8(buf);
440 #else
441 g.nameOfExe = g.argv[0];
442 #endif
443 for(i=1; i<g.argc-1; i++){
444 z = g.argv[i];
445 if( z[0]!='-' ) continue;
446 z++;
447 if( z[0]=='-' ) z++;
@@ -1596,10 +1588,30 @@
1596 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1597 return 1;
1598 }
1599 return 0;
1600 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1601
1602 /*
1603 ** Preconditions:
1604 **
1605 ** * Environment variables are set up according to the CGI standard.
@@ -1819,24 +1831,11 @@
1819 && repo_list_page() ){
1820 /* Will return a list of repositories */
1821 }else if( zNotFound ){
1822 cgi_redirect(zNotFound);
1823 }else{
1824 #ifdef FOSSIL_ENABLE_JSON
1825 if(g.json.isJsonMode){
1826 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1827 return;
1828 }
1829 #endif
1830 @ <html><head>
1831 @ <meta name="viewport" \
1832 @ content="width=device-width, initial-scale=1.0">
1833 @ </head><body>
1834 @ <h1>Not Found</h1>
1835 @ </body>
1836 cgi_set_status(404, "Not Found");
1837 cgi_reply();
1838 }
1839 return;
1840 }
1841 break;
1842 }
@@ -1887,10 +1886,15 @@
1887 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1888 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1889 ){
1890 int iSkin = zPathInfo[6] - '0';
1891 char *zNewScript;
 
 
 
 
 
1892 skin_use_draft(iSkin);
1893 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1894 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1895 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1896 zPathInfo += 7;
@@ -2597,18 +2601,18 @@
2597 ** SSL should be used, and initialize the SSL decoder.
2598 */
2599 static void decode_ssl_options(void){
2600 #if FOSSIL_ENABLE_SSL
2601 const char *zCertFile = 0;
2602 zCertFile = find_option("tls-cert-file",0,1);
 
 
2603 if( zCertFile ){
2604 g.httpUseSSL = 1;
2605 ssl_init_server(zCertFile, zCertFile);
2606 }
2607 if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){
2608 g.httpUseSSL = 1;
2609 ssl_init_server(0,0);
2610 }
2611 #endif
2612 }
2613
2614 /*
@@ -2616,12 +2620,12 @@
2616 **
2617 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2618 **
2619 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2620 ** is delivered on stdout. This method is used to launch an HTTP request
2621 ** handler from inetd, for example. The argument is the name of the
2622 ** repository.
2623 **
2624 ** If REPOSITORY is a directory that contains one or more repositories,
2625 ** either directly in REPOSITORY itself or in subdirectories, and
2626 ** with names of the form "*.fossil" then a prefix of the URL pathname
2627 ** selects from among the various repositories. If the pathname does
@@ -2632,29 +2636,24 @@
2632 ** and every "." must be surrounded on both sides by alphanumerics or else
2633 ** a 404 error is returned. Static content files in the directory are
2634 ** returned if they match comma-separate GLOB pattern specified by --files
2635 ** and do not match "*.fossil*" and have a well-known suffix.
2636 **
2637 ** The --host option can be used to specify the hostname for the server.
2638 ** The --https option indicates that the request came from HTTPS rather
2639 ** than HTTP. If --nossl is given, then SSL connections will not be available,
2640 ** thus also no redirecting from http: to https: will take place.
2641 **
2642 ** If the --localauth option is given, then automatic login is performed
2643 ** for requests coming from localhost, if the "localauth" setting is not
2644 ** enabled.
2645 **
2646 ** Options:
2647 ** --acme Deliver files from the ".well-known" subdirectory
2648 ** --baseurl URL base URL (useful with reverse proxies)
 
 
2649 ** --chroot DIR Use directory for chroot instead of repository path.
2650 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2651 ** /doc/ckout/...
2652 ** --extroot DIR document root for the /ext extension mechanism
2653 ** --files GLOB comma-separate glob patterns for static file to serve
2654 ** --host NAME specify hostname of the server
2655 ** --https signal a request coming in via https
 
 
2656 ** --in FILE Take input from FILE instead of standard input
2657 ** --ipaddr ADDR Assume the request comes from the given IP address
2658 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2659 ** Mode can be one of:
2660 ** inline All JavaScript is inserted inline at
@@ -2666,27 +2665,28 @@
2666 ** concatenate scripts together.
2667 ** Depending on the needs of any given page, inline
2668 ** and bundled modes might result in a single
2669 ** amalgamated script or several, but both approaches
2670 ** result in fewer HTTP requests than the separate mode.
2671 ** --localauth enable automatic login for local connections
 
2672 ** --mainmenu FILE Override the mainmenu config setting with the contents
2673 ** of the given file.
2674 ** --nocompress do not compress HTTP replies
2675 ** --nodelay omit backoffice processing if it would delay
2676 ** process exit
2677 ** --nojail drop root privilege but do not enter the chroot jail
2678 ** --nossl signal that no SSL connections are available
2679 ** --notfound URL use URL as "HTTP 404, object not found" page.
2680 ** --out FILE write results to FILE instead of to standard output
 
 
 
2681 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2682 ** --scgi Interpret input as SCGI rather than HTTP
2683 ** --skin LABEL Use override skin LABEL
2684 ** --ssl Use TLS (HTTPS) encryption. Alias for --tls
2685 ** --th-trace trace TH1 execution (for debugging purposes)
2686 ** --tls Use TLS (HTTPS) encryption.
2687 ** --tls-cert-file FN Read the TLS certificate and private key from FN
2688 ** --usepidkey Use saved encryption key from parent process. This is
2689 ** only necessary when using SEE on Windows.
2690 **
2691 ** See also: [[cgi]], [[server]], [[winsrv]]
2692 */
@@ -2733,17 +2733,23 @@
2733 backoffice_disable();
2734 g.httpIn = fossil_fopen(zInFile, "rb");
2735 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2736 }else{
2737 g.httpIn = stdin;
 
 
 
2738 }
2739 zOutFile = find_option("out",0,1);
2740 if( zOutFile ){
2741 g.httpOut = fossil_fopen(zOutFile, "wb");
2742 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2743 }else{
2744 g.httpOut = stdout;
 
 
 
2745 }
2746 zIpAddr = find_option("ipaddr",0,1);
2747 useSCGI = find_option("scgi", 0, 0)!=0;
2748 zAltBase = find_option("baseurl", 0, 1);
2749 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
@@ -2976,10 +2982,12 @@
2976 ** by default.
2977 **
2978 ** Options:
2979 ** --acme Deliver files from the ".well-known" subdirectory.
2980 ** --baseurl URL Use URL as the base (useful for reverse proxies)
 
 
2981 ** --chroot DIR Use directory for chroot instead of repository path.
2982 ** --ckout-alias NAME Treat URIs of the form /doc/NAME/... as if they were
2983 ** /doc/ckout/...
2984 ** --create Create a new REPOSITORY if it does not already exist
2985 ** --extroot DIR Document root for the /ext extension mechanism
@@ -3008,22 +3016,21 @@
3008 ** seconds (only works on unix)
3009 ** --nobrowser Do not automatically launch a web-browser for the
3010 ** "fossil ui" command.
3011 ** --nocompress Do not compress HTTP replies
3012 ** --nojail Drop root privileges but do not enter the chroot jail
3013 ** --nossl signal that no SSL connections are available (Always
3014 ** set by default for the "ui" command)
3015 ** --notfound URL Redirect
 
3016 ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
 
3017 ** -P|--port TCPPORT listen to request on port TCPPORT
3018 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
3019 ** --scgi Accept SCGI rather than HTTP
3020 ** --skin LABEL Use override skin LABEL
3021 ** --ssl Use TLS (HTTPS) encryption. Alias for --tls
3022 ** --th-trace trace TH1 execution (for debugging purposes)
3023 ** --tls Use TLS (HTTPS) encryption.
3024 ** --tls-cert-file FN Read the TLS certificate and private key from FN
3025 ** --usepidkey Use saved encryption key from parent process. This is
3026 ** only necessary when using SEE on Windows.
3027 **
3028 ** See also: [[cgi]], [[http]], [[winsrv]]
3029 */
@@ -3255,10 +3262,12 @@
3255 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
3256 db_close(1);
3257
3258 /* Start up an HTTP server
3259 */
 
 
3260 #if !defined(_WIN32)
3261 /* Unix implementation */
3262 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
3263 fossil_fatal("unable to listen on TCP socket %d", iPort);
3264 }
3265
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char jsHref; /* If true, set href= using javascript, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -420,28 +420,20 @@
420 unsigned int nArg; /* Number of new arguments */
421 char *z; /* General use string pointer */
422 char **newArgv; /* New expanded g.argv under construction */
423 const char *zFileName; /* input file name */
424 FILE *inFile; /* input FILE */
 
 
 
425
426 g.argc = argc;
427 g.argv = argv;
428 sqlite3_initialize();
429 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
430 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
431 #else
432 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
433 #endif
434 g.nameOfExe = file_fullexename(g.argv[0]);
 
 
 
 
 
435 for(i=1; i<g.argc-1; i++){
436 z = g.argv[i];
437 if( z[0]!='-' ) continue;
438 z++;
439 if( z[0]=='-' ) z++;
@@ -1596,10 +1588,30 @@
1588 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1589 return 1;
1590 }
1591 return 0;
1592 }
1593
1594 /*
1595 ** Send a 404 Not Found reply
1596 */
1597 void fossil_not_found_page(void){
1598 #ifdef FOSSIL_ENABLE_JSON
1599 if(g.json.isJsonMode){
1600 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1601 return;
1602 }
1603 #endif
1604 @ <html><head>
1605 @ <meta name="viewport" \
1606 @ content="width=device-width, initial-scale=1.0">
1607 @ </head><body>
1608 @ <h1>Not Found</h1>
1609 @ </body>
1610 cgi_set_status(404, "Not Found");
1611 cgi_reply();
1612 }
1613
1614 /*
1615 ** Preconditions:
1616 **
1617 ** * Environment variables are set up according to the CGI standard.
@@ -1819,24 +1831,11 @@
1831 && repo_list_page() ){
1832 /* Will return a list of repositories */
1833 }else if( zNotFound ){
1834 cgi_redirect(zNotFound);
1835 }else{
1836 fossil_not_found_page();
 
 
 
 
 
 
 
 
 
 
 
 
 
1837 }
1838 return;
1839 }
1840 break;
1841 }
@@ -1887,10 +1886,15 @@
1886 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1887 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1888 ){
1889 int iSkin = zPathInfo[6] - '0';
1890 char *zNewScript;
1891 if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892 iSkin)<5 ){
1893 fossil_not_found_page();
1894 fossil_exit(0);
1895 }
1896 skin_use_draft(iSkin);
1897 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1898 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1899 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1900 zPathInfo += 7;
@@ -2597,18 +2601,18 @@
2601 ** SSL should be used, and initialize the SSL decoder.
2602 */
2603 static void decode_ssl_options(void){
2604 #if FOSSIL_ENABLE_SSL
2605 const char *zCertFile = 0;
2606 const char *zKeyFile = 0;
2607 zCertFile = find_option("cert",0,1);
2608 zKeyFile = find_option("pkey",0,1);
2609 if( zCertFile ){
2610 g.httpUseSSL = 1;
2611 ssl_init_server(zCertFile, zKeyFile);
2612 }else if( zKeyFile ){
2613 fossil_fatal("--pkey without a corresponding --cert");
 
 
2614 }
2615 #endif
2616 }
2617
2618 /*
@@ -2616,12 +2620,12 @@
2620 **
2621 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2622 **
2623 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2624 ** is delivered on stdout. This method is used to launch an HTTP request
2625 ** handler from inetd, for example. The REPOSITORY argument is the name of
2626 ** the repository.
2627 **
2628 ** If REPOSITORY is a directory that contains one or more repositories,
2629 ** either directly in REPOSITORY itself or in subdirectories, and
2630 ** with names of the form "*.fossil" then a prefix of the URL pathname
2631 ** selects from among the various repositories. If the pathname does
@@ -2632,29 +2636,24 @@
2636 ** and every "." must be surrounded on both sides by alphanumerics or else
2637 ** a 404 error is returned. Static content files in the directory are
2638 ** returned if they match comma-separate GLOB pattern specified by --files
2639 ** and do not match "*.fossil*" and have a well-known suffix.
2640 **
 
 
 
 
 
 
 
 
 
2641 ** Options:
2642 ** --acme Deliver files from the ".well-known" subdirectory
2643 ** --baseurl URL base URL (useful with reverse proxies)
2644 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2645 ** fullchain.pem) taken from FILE.
2646 ** --chroot DIR Use directory for chroot instead of repository path.
2647 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2648 ** /doc/ckout/...
2649 ** --extroot DIR Document root for the /ext extension mechanism
2650 ** --files GLOB Comma-separate glob patterns for static file to serve
2651 ** --host NAME DNS Hostname of the server
2652 ** --https The HTTP request originated from https but has already
2653 ** been decoded by a reverse proxy. Hence, URLs created
2654 ** by Fossil should use "https:" rather than "http:".
2655 ** --in FILE Take input from FILE instead of standard input
2656 ** --ipaddr ADDR Assume the request comes from the given IP address
2657 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2658 ** Mode can be one of:
2659 ** inline All JavaScript is inserted inline at
@@ -2666,27 +2665,28 @@
2665 ** concatenate scripts together.
2666 ** Depending on the needs of any given page, inline
2667 ** and bundled modes might result in a single
2668 ** amalgamated script or several, but both approaches
2669 ** result in fewer HTTP requests than the separate mode.
2670 ** --localauth Connections from localhost are given "setup"
2671 ** privileges without having to log in.
2672 ** --mainmenu FILE Override the mainmenu config setting with the contents
2673 ** of the given file.
2674 ** --nocompress Do not compress HTTP replies
2675 ** --nodelay Omit backoffice processing if it would delay
2676 ** process exit
2677 ** --nojail Drop root privilege but do not enter the chroot jail
2678 ** --nossl Do not do http: to https: redirects, regardless of
2679 ** the redirect-to-https setting.
2680 ** --notfound URL Use URL as the "HTTP 404, object not found" page.
2681 ** --out FILE Write the HTTP reply to FILE instead of to
2682 ** standard output
2683 ** --pkey FILE Read the private key used for TLS from FILE.
2684 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2685 ** --scgi Interpret input as SCGI rather than HTTP
2686 ** --skin LABEL Use override skin LABEL
2687 ** --th-trace Trace TH1 execution (for debugging purposes)
 
 
 
2688 ** --usepidkey Use saved encryption key from parent process. This is
2689 ** only necessary when using SEE on Windows.
2690 **
2691 ** See also: [[cgi]], [[server]], [[winsrv]]
2692 */
@@ -2733,17 +2733,23 @@
2733 backoffice_disable();
2734 g.httpIn = fossil_fopen(zInFile, "rb");
2735 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2736 }else{
2737 g.httpIn = stdin;
2738 #if defined(_WIN32)
2739 _setmode(_fileno(stdin), _O_BINARY);
2740 #endif
2741 }
2742 zOutFile = find_option("out",0,1);
2743 if( zOutFile ){
2744 g.httpOut = fossil_fopen(zOutFile, "wb");
2745 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2746 }else{
2747 g.httpOut = stdout;
2748 #if defined(_WIN32)
2749 _setmode(_fileno(stdout), _O_BINARY);
2750 #endif
2751 }
2752 zIpAddr = find_option("ipaddr",0,1);
2753 useSCGI = find_option("scgi", 0, 0)!=0;
2754 zAltBase = find_option("baseurl", 0, 1);
2755 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
@@ -2976,10 +2982,12 @@
2982 ** by default.
2983 **
2984 ** Options:
2985 ** --acme Deliver files from the ".well-known" subdirectory.
2986 ** --baseurl URL Use URL as the base (useful for reverse proxies)
2987 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2988 ** fullchain.pem) taken from FILE.
2989 ** --chroot DIR Use directory for chroot instead of repository path.
2990 ** --ckout-alias NAME Treat URIs of the form /doc/NAME/... as if they were
2991 ** /doc/ckout/...
2992 ** --create Create a new REPOSITORY if it does not already exist
2993 ** --extroot DIR Document root for the /ext extension mechanism
@@ -3008,22 +3016,21 @@
3016 ** seconds (only works on unix)
3017 ** --nobrowser Do not automatically launch a web-browser for the
3018 ** "fossil ui" command.
3019 ** --nocompress Do not compress HTTP replies
3020 ** --nojail Drop root privileges but do not enter the chroot jail
3021 ** --nossl do not force redirects to SSL even if the repository
3022 ** setting "redirect-to-https" requests it. This is set
3023 ** by default for the "ui" command.
3024 ** --notfound URL Redirect to URL if a page is not found.
3025 ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
3026 ** --pkey FILE Read the private key used for TLS from FILE.
3027 ** -P|--port TCPPORT listen to request on port TCPPORT
3028 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
3029 ** --scgi Accept SCGI rather than HTTP
3030 ** --skin LABEL Use override skin LABEL
 
3031 ** --th-trace trace TH1 execution (for debugging purposes)
 
 
3032 ** --usepidkey Use saved encryption key from parent process. This is
3033 ** only necessary when using SEE on Windows.
3034 **
3035 ** See also: [[cgi]], [[http]], [[winsrv]]
3036 */
@@ -3255,10 +3262,12 @@
3262 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
3263 db_close(1);
3264
3265 /* Start up an HTTP server
3266 */
3267 fossil_setenv("SERVER_SOFTWARE", "fossil version " RELEASE_VERSION
3268 " " MANIFEST_VERSION " " MANIFEST_DATE);
3269 #if !defined(_WIN32)
3270 /* Unix implementation */
3271 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
3272 fossil_fatal("unable to listen on TCP socket %d", iPort);
3273 }
3274
--- src/main.mk
+++ src/main.mk
@@ -635,21 +635,18 @@
635635
-DSQLITE_OMIT_DEPRECATED \
636636
-DSQLITE_OMIT_PROGRESS_CALLBACK \
637637
-DSQLITE_OMIT_SHARED_CACHE \
638638
-DSQLITE_OMIT_LOAD_EXTENSION \
639639
-DSQLITE_MAX_EXPR_DEPTH=0 \
640
- -DSQLITE_USE_ALLOCA \
641640
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
642641
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
643642
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
644643
-DSQLITE_ENABLE_FTS4 \
645644
-DSQLITE_ENABLE_DBSTAT_VTAB \
646
- -DSQLITE_ENABLE_JSON1 \
647645
-DSQLITE_ENABLE_FTS5 \
648646
-DSQLITE_ENABLE_STMTVTAB \
649647
-DSQLITE_HAVE_ZLIB \
650
- -DSQLITE_INTROSPECTION_PRAGMAS \
651648
-DSQLITE_ENABLE_DBPAGE_VTAB \
652649
-DSQLITE_TRUSTED_SCHEMA=0
653650
654651
# Setup the options used to compile the included SQLite shell.
655652
SHELL_OPTIONS = -DNDEBUG=1 \
@@ -662,21 +659,18 @@
662659
-DSQLITE_OMIT_DEPRECATED \
663660
-DSQLITE_OMIT_PROGRESS_CALLBACK \
664661
-DSQLITE_OMIT_SHARED_CACHE \
665662
-DSQLITE_OMIT_LOAD_EXTENSION \
666663
-DSQLITE_MAX_EXPR_DEPTH=0 \
667
- -DSQLITE_USE_ALLOCA \
668664
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
669665
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
670666
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
671667
-DSQLITE_ENABLE_FTS4 \
672668
-DSQLITE_ENABLE_DBSTAT_VTAB \
673
- -DSQLITE_ENABLE_JSON1 \
674669
-DSQLITE_ENABLE_FTS5 \
675670
-DSQLITE_ENABLE_STMTVTAB \
676671
-DSQLITE_HAVE_ZLIB \
677
- -DSQLITE_INTROSPECTION_PRAGMAS \
678672
-DSQLITE_ENABLE_DBPAGE_VTAB \
679673
-DSQLITE_TRUSTED_SCHEMA=0 \
680674
-Dmain=sqlite3_shell \
681675
-DSQLITE_SHELL_IS_UTF8=1 \
682676
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
683677
--- src/main.mk
+++ src/main.mk
@@ -635,21 +635,18 @@
635 -DSQLITE_OMIT_DEPRECATED \
636 -DSQLITE_OMIT_PROGRESS_CALLBACK \
637 -DSQLITE_OMIT_SHARED_CACHE \
638 -DSQLITE_OMIT_LOAD_EXTENSION \
639 -DSQLITE_MAX_EXPR_DEPTH=0 \
640 -DSQLITE_USE_ALLOCA \
641 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
642 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
643 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
644 -DSQLITE_ENABLE_FTS4 \
645 -DSQLITE_ENABLE_DBSTAT_VTAB \
646 -DSQLITE_ENABLE_JSON1 \
647 -DSQLITE_ENABLE_FTS5 \
648 -DSQLITE_ENABLE_STMTVTAB \
649 -DSQLITE_HAVE_ZLIB \
650 -DSQLITE_INTROSPECTION_PRAGMAS \
651 -DSQLITE_ENABLE_DBPAGE_VTAB \
652 -DSQLITE_TRUSTED_SCHEMA=0
653
654 # Setup the options used to compile the included SQLite shell.
655 SHELL_OPTIONS = -DNDEBUG=1 \
@@ -662,21 +659,18 @@
662 -DSQLITE_OMIT_DEPRECATED \
663 -DSQLITE_OMIT_PROGRESS_CALLBACK \
664 -DSQLITE_OMIT_SHARED_CACHE \
665 -DSQLITE_OMIT_LOAD_EXTENSION \
666 -DSQLITE_MAX_EXPR_DEPTH=0 \
667 -DSQLITE_USE_ALLOCA \
668 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
669 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
670 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
671 -DSQLITE_ENABLE_FTS4 \
672 -DSQLITE_ENABLE_DBSTAT_VTAB \
673 -DSQLITE_ENABLE_JSON1 \
674 -DSQLITE_ENABLE_FTS5 \
675 -DSQLITE_ENABLE_STMTVTAB \
676 -DSQLITE_HAVE_ZLIB \
677 -DSQLITE_INTROSPECTION_PRAGMAS \
678 -DSQLITE_ENABLE_DBPAGE_VTAB \
679 -DSQLITE_TRUSTED_SCHEMA=0 \
680 -Dmain=sqlite3_shell \
681 -DSQLITE_SHELL_IS_UTF8=1 \
682 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
683
--- src/main.mk
+++ src/main.mk
@@ -635,21 +635,18 @@
635 -DSQLITE_OMIT_DEPRECATED \
636 -DSQLITE_OMIT_PROGRESS_CALLBACK \
637 -DSQLITE_OMIT_SHARED_CACHE \
638 -DSQLITE_OMIT_LOAD_EXTENSION \
639 -DSQLITE_MAX_EXPR_DEPTH=0 \
 
640 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
641 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
642 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
643 -DSQLITE_ENABLE_FTS4 \
644 -DSQLITE_ENABLE_DBSTAT_VTAB \
 
645 -DSQLITE_ENABLE_FTS5 \
646 -DSQLITE_ENABLE_STMTVTAB \
647 -DSQLITE_HAVE_ZLIB \
 
648 -DSQLITE_ENABLE_DBPAGE_VTAB \
649 -DSQLITE_TRUSTED_SCHEMA=0
650
651 # Setup the options used to compile the included SQLite shell.
652 SHELL_OPTIONS = -DNDEBUG=1 \
@@ -662,21 +659,18 @@
659 -DSQLITE_OMIT_DEPRECATED \
660 -DSQLITE_OMIT_PROGRESS_CALLBACK \
661 -DSQLITE_OMIT_SHARED_CACHE \
662 -DSQLITE_OMIT_LOAD_EXTENSION \
663 -DSQLITE_MAX_EXPR_DEPTH=0 \
 
664 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
665 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
666 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
667 -DSQLITE_ENABLE_FTS4 \
668 -DSQLITE_ENABLE_DBSTAT_VTAB \
 
669 -DSQLITE_ENABLE_FTS5 \
670 -DSQLITE_ENABLE_STMTVTAB \
671 -DSQLITE_HAVE_ZLIB \
 
672 -DSQLITE_ENABLE_DBPAGE_VTAB \
673 -DSQLITE_TRUSTED_SCHEMA=0 \
674 -Dmain=sqlite3_shell \
675 -DSQLITE_SHELL_IS_UTF8=1 \
676 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
677
+14 -11
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
5454
> <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
5555
5656
> In format 8, then the URL becomes the display text. This is useful for
5757
> hyperlinks that refer to wiki pages and check-in and ticket hashes.
5858
59
-## Fonts ##
59
+## Text Style ##
6060
6161
> * _\*italic\*_
6262
> * *\_italic\_*
6363
> * __\*\*bold\*\*__
6464
> * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
6969
> The **\`code\`** construct disables HTML markup, so one can write, for
7070
> example, **\`\<html\>\`** to yield **`<html>`**.
7171
7272
## Lists ##
7373
74
->
75
- * bullet item
76
- + bullet item
77
- - bullet item
78
- 1. numbered item
79
- 2) numbered item
74
+> ~~~
75
+ * bullet item
76
+ + bullet item
77
+ - bullet item
78
+ 1. numbered item
79
+ 2) numbered item
80
+~~~
8081
8182
> A two-level list is created by placing additional whitespace before the
8283
> **\***/**+**/**-**/**1.** of the secondary items.
8384
84
->
85
- * top-level item
86
- * secondary item
85
+> ~~~
86
+ * top-level item
87
+ * second-level item
88
+~~~
8789
8890
## Block Quotes ##
8991
9092
> Begin each line of a paragraph with **>** to block quote that paragraph.
9193
@@ -159,12 +161,13 @@
159161
> * **\<!--** HTML-style comments **-->** are supported.
160162
> * Escape special characters (ex: **\[** **\(** **\|** **\***)
161163
> using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
162164
> * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
163165
> rule. Spaces and extra **-**/**\***/**_** are allowed.
166
+> * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
164167
> * See [daringfireball.net][] for additional information.
165
-> * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
168
+> * See this page's [Markdown source](/md_rules?txt=1) for more examples.
166169
167170
## Special Features For Fossil ##
168171
169172
> * In hyperlinks, if the URL begins with **/** then the root of the Fossil
170173
> repository is prepended. This allows for repository-relative hyperlinks.
171174
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Fonts ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 >
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
 
80
81 > A two-level list is created by placing additional whitespace before the
82 > **\***/**+**/**-**/**1.** of the secondary items.
83
84 >
85 * top-level item
86 * secondary item
 
87
88 ## Block Quotes ##
89
90 > Begin each line of a paragraph with **>** to block quote that paragraph.
91
@@ -159,12 +161,13 @@
159 > * **\<!--** HTML-style comments **-->** are supported.
160 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
161 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
162 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
163 > rule. Spaces and extra **-**/**\***/**_** are allowed.
 
164 > * See [daringfireball.net][] for additional information.
165 > * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
166
167 ## Special Features For Fossil ##
168
169 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
170 > repository is prepended. This allows for repository-relative hyperlinks.
171
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Text Style ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 > ~~~
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
80 ~~~
81
82 > A two-level list is created by placing additional whitespace before the
83 > **\***/**+**/**-**/**1.** of the secondary items.
84
85 > ~~~
86 * top-level item
87 * second-level item
88 ~~~
89
90 ## Block Quotes ##
91
92 > Begin each line of a paragraph with **>** to block quote that paragraph.
93
@@ -159,12 +161,13 @@
161 > * **\<!--** HTML-style comments **-->** are supported.
162 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
163 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
164 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
165 > rule. Spaces and extra **-**/**\***/**_** are allowed.
166 > * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
167 > * See [daringfireball.net][] for additional information.
168 > * See this page's [Markdown source](/md_rules?txt=1) for more examples.
169
170 ## Special Features For Fossil ##
171
172 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
173 > repository is prepended. This allows for repository-relative hyperlinks.
174
+20 -13
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157157
Stmt q;
158158
int rc;
159159
int ans = rid;
160160
char *zBr = branch_of_rid(rid);
161161
db_prepare(&q,
162
- "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163
- " WHERE tagid=%d AND tagtype>0"
164
- " AND value=%Q AND rid=plink.pid)"
165
- " FROM plink"
166
- " WHERE cid=:cid AND isprim",
167
- TAG_BRANCH, zBr
162
+ "WITH RECURSIVE"
163
+ " par(pid, ex, cnt) as ("
164
+ " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165
+ " WHERE tagid=%d AND tagtype>0"
166
+ " AND value=%Q AND rid=plink.pid), 1"
167
+ " FROM plink WHERE cid=%d AND isprim"
168
+ " UNION ALL "
169
+ " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170
+ " WHERE tagid=%d AND tagtype>0"
171
+ " AND value=%Q AND rid=plink.pid),"
172
+ " 1+par.cnt"
173
+ " FROM plink, par"
174
+ " WHERE cid=par.pid AND isprim AND par.ex "
175
+ " LIMIT 100000 "
176
+ " )"
177
+ " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178
+ TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
168179
);
169180
fossil_free(zBr);
170
- do{
171
- db_reset(&q);
172
- db_bind_int(&q, ":cid", ans);
173
- rc = db_step(&q);
174
- if( rc!=SQLITE_ROW ) break;
175
- if( eType==1 && db_column_int(&q,1)==0 ) break;
181
+ rc = db_step(&q);
182
+ if( rc==SQLITE_ROW ){
176183
ans = db_column_int(&q, 0);
177
- }while( db_column_int(&q, 1)==1 && ans>0 );
184
+ }
178185
db_finalize(&q);
179186
if( eType==2 && ans>0 ){
180187
zBr = branch_of_rid(ans);
181188
ans = compute_youngest_ancestor_in_branch(rid, zBr);
182189
fossil_free(zBr);
183190
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163 " WHERE tagid=%d AND tagtype>0"
164 " AND value=%Q AND rid=plink.pid)"
165 " FROM plink"
166 " WHERE cid=:cid AND isprim",
167 TAG_BRANCH, zBr
 
 
 
 
 
 
 
 
 
 
 
168 );
169 fossil_free(zBr);
170 do{
171 db_reset(&q);
172 db_bind_int(&q, ":cid", ans);
173 rc = db_step(&q);
174 if( rc!=SQLITE_ROW ) break;
175 if( eType==1 && db_column_int(&q,1)==0 ) break;
176 ans = db_column_int(&q, 0);
177 }while( db_column_int(&q, 1)==1 && ans>0 );
178 db_finalize(&q);
179 if( eType==2 && ans>0 ){
180 zBr = branch_of_rid(ans);
181 ans = compute_youngest_ancestor_in_branch(rid, zBr);
182 fossil_free(zBr);
183
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "WITH RECURSIVE"
163 " par(pid, ex, cnt) as ("
164 " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165 " WHERE tagid=%d AND tagtype>0"
166 " AND value=%Q AND rid=plink.pid), 1"
167 " FROM plink WHERE cid=%d AND isprim"
168 " UNION ALL "
169 " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170 " WHERE tagid=%d AND tagtype>0"
171 " AND value=%Q AND rid=plink.pid),"
172 " 1+par.cnt"
173 " FROM plink, par"
174 " WHERE cid=par.pid AND isprim AND par.ex "
175 " LIMIT 100000 "
176 " )"
177 " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178 TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
179 );
180 fossil_free(zBr);
181 rc = db_step(&q);
182 if( rc==SQLITE_ROW ){
 
 
 
 
183 ans = db_column_int(&q, 0);
184 }
185 db_finalize(&q);
186 if( eType==2 && ans>0 ){
187 zBr = branch_of_rid(ans);
188 ans = compute_youngest_ancestor_in_branch(rid, zBr);
189 fossil_free(zBr);
190
+12 -3
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174174
int nName = (int)strlen(zName);
175175
char *zUrl;
176176
char *zAge;
177177
char *zFull;
178178
RepoInfo x;
179
- int iAge;
179
+ sqlite3_int64 iAge;
180180
if( nName<7 ) continue;
181181
zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182182
if( zName[0]=='/'
183183
#ifdef _WIN32
184184
|| sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205205
if( x.isRepolistSkin==2 && !allRepo ){
206206
/* Repositories with repolist-skin==2 are omitted from directory
207207
** scan lists, but included in "fossil all ui" lists */
208208
continue;
209209
}
210
- iAge = (rNow - x.rMTime)*86400;
211
- if( iAge<0 ) x.rMTime = rNow;
210
+ if( rNow <= x.rMTime ){
211
+ x.rMTime = rNow;
212
+ }else if( x.rMTime<0.0 ){
213
+ x.rMTime = rNow;
214
+ }
215
+ iAge = (int)(rNow - x.rMTime)*86400;
212216
zAge = human_readable_age(rNow - x.rMTime);
217
+ if( x.rMTime==0.0 ){
218
+ /* This repository has no entry in the "event" table.
219
+ ** Its age will still be maximum, so data-sortkey will work. */
220
+ zAge = mprintf("unknown");
221
+ }
213222
blob_append_sql(&html, "<tr><td valign='top'>");
214223
if( sqlite3_strglob("*.fossil", zName)!=0 ){
215224
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
216225
** do not work for repositories whose names do not end in ".fossil".
217226
** So do not hyperlink those cases. */
218227
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174 int nName = (int)strlen(zName);
175 char *zUrl;
176 char *zAge;
177 char *zFull;
178 RepoInfo x;
179 int iAge;
180 if( nName<7 ) continue;
181 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182 if( zName[0]=='/'
183 #ifdef _WIN32
184 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205 if( x.isRepolistSkin==2 && !allRepo ){
206 /* Repositories with repolist-skin==2 are omitted from directory
207 ** scan lists, but included in "fossil all ui" lists */
208 continue;
209 }
210 iAge = (rNow - x.rMTime)*86400;
211 if( iAge<0 ) x.rMTime = rNow;
 
 
 
 
212 zAge = human_readable_age(rNow - x.rMTime);
 
 
 
 
 
213 blob_append_sql(&html, "<tr><td valign='top'>");
214 if( sqlite3_strglob("*.fossil", zName)!=0 ){
215 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
216 ** do not work for repositories whose names do not end in ".fossil".
217 ** So do not hyperlink those cases. */
218
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174 int nName = (int)strlen(zName);
175 char *zUrl;
176 char *zAge;
177 char *zFull;
178 RepoInfo x;
179 sqlite3_int64 iAge;
180 if( nName<7 ) continue;
181 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182 if( zName[0]=='/'
183 #ifdef _WIN32
184 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205 if( x.isRepolistSkin==2 && !allRepo ){
206 /* Repositories with repolist-skin==2 are omitted from directory
207 ** scan lists, but included in "fossil all ui" lists */
208 continue;
209 }
210 if( rNow <= x.rMTime ){
211 x.rMTime = rNow;
212 }else if( x.rMTime<0.0 ){
213 x.rMTime = rNow;
214 }
215 iAge = (int)(rNow - x.rMTime)*86400;
216 zAge = human_readable_age(rNow - x.rMTime);
217 if( x.rMTime==0.0 ){
218 /* This repository has no entry in the "event" table.
219 ** Its age will still be maximum, so data-sortkey will work. */
220 zAge = mprintf("unknown");
221 }
222 blob_append_sql(&html, "<tr><td valign='top'>");
223 if( sqlite3_strglob("*.fossil", zName)!=0 ){
224 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
225 ** do not work for repositories whose names do not end in ".fossil".
226 ** So do not hyperlink those cases. */
227
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144144
@ immediately! Or, at least remove the Setup and Admin privileges
145145
@ from the default permissions for new users.
146146
}else if( hasAnyCap(zAnonCap,"y") ){
147147
@ <li><p>This repository is <big><b>INSECURE</b></big> because
148148
@ it allows anonymous users to push unversioned files.
149
- @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
149
+ @ Fix this by <a href="takeitprivate">taking the repository private</a>
150150
@ or by removing the "y" permission from users "anonymous" and
151151
@ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152152
}else if( hasAnyCap(zSelfCap,"y") ){
153153
@ <li><p>This repository is <big><b>INSECURE</b></big> because
154154
@ it allows self-registered users to push unversioned files.
155
- @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
155
+ @ Fix this by <a href="takeitprivate">taking the repository private</a>
156156
@ or by removing the "y" permission from the default permissions or
157157
@ by disabling self-registration.
158158
}else if( hasAnyCap(zAnonCap,"goz") ){
159159
@ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160160
@ checked-in content can be accessed by anonymous users.
@@ -223,12 +223,12 @@
223223
}else{
224224
int nUrl = db_int(0, "SELECT count(*) FROM config"
225225
" WHERE name GLOB 'baseurl:*'");
226226
@ <li><p>This repository does not have a canonical access URL.
227227
if( nUrl==1 ){
228
- @ There 1
229
- @ <a href="urllist?urlonly">1 non-canonical URLs</a>
228
+ @ There is
229
+ @ <a href="urllist?urlonly">1 non-canonical URL</a>
230230
@ that has been used to access this repository.
231231
}else if( nUrl>=2 ){
232232
@ There are
233233
@ <a href="urllist?all&urlonly">%d(nUrl) non-canonical URLs</a>
234234
@ that have been used to access this repository.
@@ -240,11 +240,11 @@
240240
*/
241241
if( db_get_int("redirect-to-https",0)==0 ){
242242
@ <li><p><b>WARNING:</b>
243243
@ Sensitive material such as login passwords can be sent over an
244244
@ unencrypted connection.
245
- @ <p>Fix this by changing the "Redirect to HTTPS" setting on the
245
+ @ Fix this by changing the "Redirect to HTTPS" setting on the
246246
@ <a href="setup_access">Access Control</a> page. If you were using
247247
@ the old "Redirect to HTTPS on Login Page" setting, switch to the
248248
@ new setting: it has a more secure implementation.
249249
}
250250
@@ -282,11 +282,11 @@
282282
*/
283283
if( hasAnyCap(zAnonCap, "e") ){
284284
@ <li><p><b>WARNING:</b>
285285
@ Anonymous users can view email addresses and other personally
286286
@ identifiable information on tickets.
287
- @ <p>Fix this by removing the "Email" privilege
287
+ @ Fix this by removing the "Email" privilege
288288
@ (<a href="setup_ucap_list">capability "e"</a>) from users
289289
@ "anonymous" and "nobody" on the
290290
@ <a href="setup_ulist">User Configuration</a> page.
291291
}
292292
@@ -294,11 +294,11 @@
294294
** to the repository.
295295
*/
296296
if( hasAnyCap(zAnonCap, "i") ){
297297
@ <li><p><b>WARNING:</b>
298298
@ Anonymous users can push new check-ins into the repository.
299
- @ <p>Fix this by removing the "Check-in" privilege
299
+ @ Fix this by removing the "Check-in" privilege
300300
@ (<a href="setup_ucap_list">capability</a> "i") from users
301301
@ "anonymous" and "nobody" on the
302302
@ <a href="setup_ulist">User Configuration</a> page.
303303
}
304304
@@ -307,11 +307,11 @@
307307
*/
308308
if( hasAnyCap(zAnonCap, "lq5") ){
309309
@ <li><p><b>WARNING:</b>
310310
@ Anonymous users can act as moderators for wiki, tickets, or
311311
@ forum posts. This defeats the whole purpose of moderation.
312
- @ <p>Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
312
+ @ Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313313
@ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314314
@ from users "anonymous" and "nobody"
315315
@ on the <a href="setup_ulist">User Configuration</a> page.
316316
}
317317
@@ -470,37 +470,66 @@
470470
@ number of users (%d(n)).
471471
@ Ideally, the Write-Unver privilege should only
472472
@ be granted to one or two users.
473473
}
474474
}
475
+
476
+ /* Providing hyperlink capability to user "nobody" can lead to robots
477
+ ** making excessive requests resulting in DoS
478
+ */
479
+ if( db_exists("SELECT 1 FROM user WHERE login='nobody' AND cap GLOB '*h*'") ){
480
+ int nobodyId = db_int(0,"SELECT uid FROM user WHERE login='nobody'");
481
+ int anonId = db_int(0,
482
+ "SELECT uid FROM user WHERE login='anonymous' AND cap NOT GLOB '*h*'");
483
+ @ <li><p>
484
+ @ User "nobody" has "Hyperlink" privilege ('h') which can lead to
485
+ @ robots walking a nearly endless progression of pages on public-facing
486
+ @ repositories, causing excessive server load and possible DoS.
487
+ @ Suggested remediation:
488
+ @ <ol type="a">
489
+ @ <li>Remove the 'h' privilege from the
490
+ @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that
491
+ @ robots cannot see hyperlinks.
492
+ @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that
493
+ @ human readers can still see hyperlinks even if they are not logged in.
494
+ @ Set the delay to at least 50 milliseconds and require a mouse
495
+ @ event for maximum robot defense.
496
+ if( anonId>0 ){
497
+ @ <li>Perhaps set the 'h' privilege on the
498
+ @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so
499
+ @ that humans that have javascript disabled in their browsers can
500
+ @ still see hyperlinks if they will log in as "anonymous".
501
+ }
502
+ @ </ol>
503
+ }
475504
476505
/* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
477506
*/
478507
if( db_get_boolean("remote_user_ok", 0) ){
479
- @ <li><p>
508
+ @ <li><p><b>Caution:</b>
480509
@ This repository trusts that the REMOTE_USER environment variable set
481510
@ up by the webserver contains the name of an authenticated user.
482511
@ Fossil's built-in authentication mechanism is bypassed.
483
- @ <p>Fix this by deactivating the "Allow REMOTE_USER authentication"
512
+ @ Fix this by deactivating the "Allow REMOTE_USER authentication"
484513
@ checkbox on the <a href="setup_access">Access Control</a> page.
485514
}
486515
if( db_get_boolean("http_authentication_ok", 0) ){
487
- @ <li><p>
516
+ @ <li><p><b>Caution:</b>
488517
@ This repository trusts that the HTTP_AUTHENITICATION environment
489518
@ variable set up by the webserver contains the name of an
490519
@ authenticated user.
491520
@ Fossil's built-in authentication mechanism is bypassed.
492
- @ <p>Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
521
+ @ Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
493522
@ checkbox on the <a href="setup_access">Access Control</a> page.
494523
}
495524
496525
/* Logging should be turned on
497526
*/
498527
if( db_get_boolean("access-log",0)==0 ){
499528
@ <li><p>
500529
@ The <a href="access_log">User Log</a> is disabled. The user log
501
- @ keeps a record of successful and unsucessful login attempts and is
530
+ @ keeps a record of successful and unsuccessful login attempts and is
502531
@ useful for security monitoring.
503532
}
504533
if( db_get_boolean("admin-log",0)==0 ){
505534
@ <li><p>
506535
@ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
512541
/* Make sure that the load-average limiter is armed and working */
513542
if( load_average()==0.0 ){
514543
@ <li><p>
515544
@ Unable to get the system load average. This can prevent Fossil
516545
@ from throttling expensive operations during peak demand.
517
- @ <p>If running in a chroot jail on Linux, verify that the /proc
546
+ @ If running in a chroot jail on Linux, verify that the /proc
518547
@ filesystem is mounted within the jail, so that the load average
519548
@ can be obtained from the /proc/loadavg file.
520549
}else {
521550
double r = atof(db_get("max-loadavg", 0));
522551
if( r<=0.0 ){
523552
@ <li><p>
524553
@ Load average limiting is turned off. This can cause the server
525554
@ to bog down if many requests for expensive services (such as
526555
@ large diffs or tarballs) arrive at about the same time.
527
- @ <p>To fix this, set the "Server Load Average Limit" on the
528
- @ <a href="setup_access">Access Control</a> page to approximately
556
+ @ To fix this, set the
557
+ @ <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on the
558
+ @ <a href='%R/setup_access'>Access Control</a> page to the approximate
529559
@ the number of available cores on your server, or maybe just a little
530560
@ less.
531561
}else if( r>=8.0 ){
532562
@ <li><p>
533
- @ The "Server Load Average Limit" on the
534
- @ <a href="setup_access">Access Control</a> page is set to %g(r),
563
+ @ The <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on
564
+ @ the <a href="setup_access">Access Control</a> page is set to %g(r),
535565
@ which seems high. Is this server really a %d((int)r)-core machine?
536566
}
537567
}
538568
#endif
539569
540570
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144 @ immediately! Or, at least remove the Setup and Admin privileges
145 @ from the default permissions for new users.
146 }else if( hasAnyCap(zAnonCap,"y") ){
147 @ <li><p>This repository is <big><b>INSECURE</b></big> because
148 @ it allows anonymous users to push unversioned files.
149 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
150 @ or by removing the "y" permission from users "anonymous" and
151 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152 }else if( hasAnyCap(zSelfCap,"y") ){
153 @ <li><p>This repository is <big><b>INSECURE</b></big> because
154 @ it allows self-registered users to push unversioned files.
155 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
156 @ or by removing the "y" permission from the default permissions or
157 @ by disabling self-registration.
158 }else if( hasAnyCap(zAnonCap,"goz") ){
159 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160 @ checked-in content can be accessed by anonymous users.
@@ -223,12 +223,12 @@
223 }else{
224 int nUrl = db_int(0, "SELECT count(*) FROM config"
225 " WHERE name GLOB 'baseurl:*'");
226 @ <li><p>This repository does not have a canonical access URL.
227 if( nUrl==1 ){
228 @ There 1
229 @ <a href="urllist?urlonly">1 non-canonical URLs</a>
230 @ that has been used to access this repository.
231 }else if( nUrl>=2 ){
232 @ There are
233 @ <a href="urllist?all&urlonly">%d(nUrl) non-canonical URLs</a>
234 @ that have been used to access this repository.
@@ -240,11 +240,11 @@
240 */
241 if( db_get_int("redirect-to-https",0)==0 ){
242 @ <li><p><b>WARNING:</b>
243 @ Sensitive material such as login passwords can be sent over an
244 @ unencrypted connection.
245 @ <p>Fix this by changing the "Redirect to HTTPS" setting on the
246 @ <a href="setup_access">Access Control</a> page. If you were using
247 @ the old "Redirect to HTTPS on Login Page" setting, switch to the
248 @ new setting: it has a more secure implementation.
249 }
250
@@ -282,11 +282,11 @@
282 */
283 if( hasAnyCap(zAnonCap, "e") ){
284 @ <li><p><b>WARNING:</b>
285 @ Anonymous users can view email addresses and other personally
286 @ identifiable information on tickets.
287 @ <p>Fix this by removing the "Email" privilege
288 @ (<a href="setup_ucap_list">capability "e"</a>) from users
289 @ "anonymous" and "nobody" on the
290 @ <a href="setup_ulist">User Configuration</a> page.
291 }
292
@@ -294,11 +294,11 @@
294 ** to the repository.
295 */
296 if( hasAnyCap(zAnonCap, "i") ){
297 @ <li><p><b>WARNING:</b>
298 @ Anonymous users can push new check-ins into the repository.
299 @ <p>Fix this by removing the "Check-in" privilege
300 @ (<a href="setup_ucap_list">capability</a> "i") from users
301 @ "anonymous" and "nobody" on the
302 @ <a href="setup_ulist">User Configuration</a> page.
303 }
304
@@ -307,11 +307,11 @@
307 */
308 if( hasAnyCap(zAnonCap, "lq5") ){
309 @ <li><p><b>WARNING:</b>
310 @ Anonymous users can act as moderators for wiki, tickets, or
311 @ forum posts. This defeats the whole purpose of moderation.
312 @ <p>Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313 @ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314 @ from users "anonymous" and "nobody"
315 @ on the <a href="setup_ulist">User Configuration</a> page.
316 }
317
@@ -470,37 +470,66 @@
470 @ number of users (%d(n)).
471 @ Ideally, the Write-Unver privilege should only
472 @ be granted to one or two users.
473 }
474 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
476 /* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
477 */
478 if( db_get_boolean("remote_user_ok", 0) ){
479 @ <li><p>
480 @ This repository trusts that the REMOTE_USER environment variable set
481 @ up by the webserver contains the name of an authenticated user.
482 @ Fossil's built-in authentication mechanism is bypassed.
483 @ <p>Fix this by deactivating the "Allow REMOTE_USER authentication"
484 @ checkbox on the <a href="setup_access">Access Control</a> page.
485 }
486 if( db_get_boolean("http_authentication_ok", 0) ){
487 @ <li><p>
488 @ This repository trusts that the HTTP_AUTHENITICATION environment
489 @ variable set up by the webserver contains the name of an
490 @ authenticated user.
491 @ Fossil's built-in authentication mechanism is bypassed.
492 @ <p>Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
493 @ checkbox on the <a href="setup_access">Access Control</a> page.
494 }
495
496 /* Logging should be turned on
497 */
498 if( db_get_boolean("access-log",0)==0 ){
499 @ <li><p>
500 @ The <a href="access_log">User Log</a> is disabled. The user log
501 @ keeps a record of successful and unsucessful login attempts and is
502 @ useful for security monitoring.
503 }
504 if( db_get_boolean("admin-log",0)==0 ){
505 @ <li><p>
506 @ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
512 /* Make sure that the load-average limiter is armed and working */
513 if( load_average()==0.0 ){
514 @ <li><p>
515 @ Unable to get the system load average. This can prevent Fossil
516 @ from throttling expensive operations during peak demand.
517 @ <p>If running in a chroot jail on Linux, verify that the /proc
518 @ filesystem is mounted within the jail, so that the load average
519 @ can be obtained from the /proc/loadavg file.
520 }else {
521 double r = atof(db_get("max-loadavg", 0));
522 if( r<=0.0 ){
523 @ <li><p>
524 @ Load average limiting is turned off. This can cause the server
525 @ to bog down if many requests for expensive services (such as
526 @ large diffs or tarballs) arrive at about the same time.
527 @ <p>To fix this, set the "Server Load Average Limit" on the
528 @ <a href="setup_access">Access Control</a> page to approximately
 
529 @ the number of available cores on your server, or maybe just a little
530 @ less.
531 }else if( r>=8.0 ){
532 @ <li><p>
533 @ The "Server Load Average Limit" on the
534 @ <a href="setup_access">Access Control</a> page is set to %g(r),
535 @ which seems high. Is this server really a %d((int)r)-core machine?
536 }
537 }
538 #endif
539
540
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144 @ immediately! Or, at least remove the Setup and Admin privileges
145 @ from the default permissions for new users.
146 }else if( hasAnyCap(zAnonCap,"y") ){
147 @ <li><p>This repository is <big><b>INSECURE</b></big> because
148 @ it allows anonymous users to push unversioned files.
149 @ Fix this by <a href="takeitprivate">taking the repository private</a>
150 @ or by removing the "y" permission from users "anonymous" and
151 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152 }else if( hasAnyCap(zSelfCap,"y") ){
153 @ <li><p>This repository is <big><b>INSECURE</b></big> because
154 @ it allows self-registered users to push unversioned files.
155 @ Fix this by <a href="takeitprivate">taking the repository private</a>
156 @ or by removing the "y" permission from the default permissions or
157 @ by disabling self-registration.
158 }else if( hasAnyCap(zAnonCap,"goz") ){
159 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160 @ checked-in content can be accessed by anonymous users.
@@ -223,12 +223,12 @@
223 }else{
224 int nUrl = db_int(0, "SELECT count(*) FROM config"
225 " WHERE name GLOB 'baseurl:*'");
226 @ <li><p>This repository does not have a canonical access URL.
227 if( nUrl==1 ){
228 @ There is
229 @ <a href="urllist?urlonly">1 non-canonical URL</a>
230 @ that has been used to access this repository.
231 }else if( nUrl>=2 ){
232 @ There are
233 @ <a href="urllist?all&urlonly">%d(nUrl) non-canonical URLs</a>
234 @ that have been used to access this repository.
@@ -240,11 +240,11 @@
240 */
241 if( db_get_int("redirect-to-https",0)==0 ){
242 @ <li><p><b>WARNING:</b>
243 @ Sensitive material such as login passwords can be sent over an
244 @ unencrypted connection.
245 @ Fix this by changing the "Redirect to HTTPS" setting on the
246 @ <a href="setup_access">Access Control</a> page. If you were using
247 @ the old "Redirect to HTTPS on Login Page" setting, switch to the
248 @ new setting: it has a more secure implementation.
249 }
250
@@ -282,11 +282,11 @@
282 */
283 if( hasAnyCap(zAnonCap, "e") ){
284 @ <li><p><b>WARNING:</b>
285 @ Anonymous users can view email addresses and other personally
286 @ identifiable information on tickets.
287 @ Fix this by removing the "Email" privilege
288 @ (<a href="setup_ucap_list">capability "e"</a>) from users
289 @ "anonymous" and "nobody" on the
290 @ <a href="setup_ulist">User Configuration</a> page.
291 }
292
@@ -294,11 +294,11 @@
294 ** to the repository.
295 */
296 if( hasAnyCap(zAnonCap, "i") ){
297 @ <li><p><b>WARNING:</b>
298 @ Anonymous users can push new check-ins into the repository.
299 @ Fix this by removing the "Check-in" privilege
300 @ (<a href="setup_ucap_list">capability</a> "i") from users
301 @ "anonymous" and "nobody" on the
302 @ <a href="setup_ulist">User Configuration</a> page.
303 }
304
@@ -307,11 +307,11 @@
307 */
308 if( hasAnyCap(zAnonCap, "lq5") ){
309 @ <li><p><b>WARNING:</b>
310 @ Anonymous users can act as moderators for wiki, tickets, or
311 @ forum posts. This defeats the whole purpose of moderation.
312 @ Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313 @ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314 @ from users "anonymous" and "nobody"
315 @ on the <a href="setup_ulist">User Configuration</a> page.
316 }
317
@@ -470,37 +470,66 @@
470 @ number of users (%d(n)).
471 @ Ideally, the Write-Unver privilege should only
472 @ be granted to one or two users.
473 }
474 }
475
476 /* Providing hyperlink capability to user "nobody" can lead to robots
477 ** making excessive requests resulting in DoS
478 */
479 if( db_exists("SELECT 1 FROM user WHERE login='nobody' AND cap GLOB '*h*'") ){
480 int nobodyId = db_int(0,"SELECT uid FROM user WHERE login='nobody'");
481 int anonId = db_int(0,
482 "SELECT uid FROM user WHERE login='anonymous' AND cap NOT GLOB '*h*'");
483 @ <li><p>
484 @ User "nobody" has "Hyperlink" privilege ('h') which can lead to
485 @ robots walking a nearly endless progression of pages on public-facing
486 @ repositories, causing excessive server load and possible DoS.
487 @ Suggested remediation:
488 @ <ol type="a">
489 @ <li>Remove the 'h' privilege from the
490 @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that
491 @ robots cannot see hyperlinks.
492 @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that
493 @ human readers can still see hyperlinks even if they are not logged in.
494 @ Set the delay to at least 50 milliseconds and require a mouse
495 @ event for maximum robot defense.
496 if( anonId>0 ){
497 @ <li>Perhaps set the 'h' privilege on the
498 @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so
499 @ that humans that have javascript disabled in their browsers can
500 @ still see hyperlinks if they will log in as "anonymous".
501 }
502 @ </ol>
503 }
504
505 /* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
506 */
507 if( db_get_boolean("remote_user_ok", 0) ){
508 @ <li><p><b>Caution:</b>
509 @ This repository trusts that the REMOTE_USER environment variable set
510 @ up by the webserver contains the name of an authenticated user.
511 @ Fossil's built-in authentication mechanism is bypassed.
512 @ Fix this by deactivating the "Allow REMOTE_USER authentication"
513 @ checkbox on the <a href="setup_access">Access Control</a> page.
514 }
515 if( db_get_boolean("http_authentication_ok", 0) ){
516 @ <li><p><b>Caution:</b>
517 @ This repository trusts that the HTTP_AUTHENITICATION environment
518 @ variable set up by the webserver contains the name of an
519 @ authenticated user.
520 @ Fossil's built-in authentication mechanism is bypassed.
521 @ Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
522 @ checkbox on the <a href="setup_access">Access Control</a> page.
523 }
524
525 /* Logging should be turned on
526 */
527 if( db_get_boolean("access-log",0)==0 ){
528 @ <li><p>
529 @ The <a href="access_log">User Log</a> is disabled. The user log
530 @ keeps a record of successful and unsuccessful login attempts and is
531 @ useful for security monitoring.
532 }
533 if( db_get_boolean("admin-log",0)==0 ){
534 @ <li><p>
535 @ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
541 /* Make sure that the load-average limiter is armed and working */
542 if( load_average()==0.0 ){
543 @ <li><p>
544 @ Unable to get the system load average. This can prevent Fossil
545 @ from throttling expensive operations during peak demand.
546 @ If running in a chroot jail on Linux, verify that the /proc
547 @ filesystem is mounted within the jail, so that the load average
548 @ can be obtained from the /proc/loadavg file.
549 }else {
550 double r = atof(db_get("max-loadavg", 0));
551 if( r<=0.0 ){
552 @ <li><p>
553 @ Load average limiting is turned off. This can cause the server
554 @ to bog down if many requests for expensive services (such as
555 @ large diffs or tarballs) arrive at about the same time.
556 @ To fix this, set the
557 @ <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on the
558 @ <a href='%R/setup_access'>Access Control</a> page to the approximate
559 @ the number of available cores on your server, or maybe just a little
560 @ less.
561 }else if( r>=8.0 ){
562 @ <li><p>
563 @ The <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on
564 @ the <a href="setup_access">Access Control</a> page is set to %g(r),
565 @ which seems high. Is this server really a %d((int)r)-core machine?
566 }
567 }
568 #endif
569
570
+110 -42
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111111
"Configure the WWW components of the repository");
112112
}
113113
setup_menu_entry("Security-Audit", "secaudit0",
114114
"Analyze the current configuration for security problems");
115115
if( setup_user ){
116
+ setup_menu_entry("Robot-Defense", "setup_robot",
117
+ "Settings for configure defense against robots");
116118
setup_menu_entry("Settings", "setup_settings",
117119
"Web interface to the \"fossil settings\" command");
118120
}
119121
setup_menu_entry("Timeline", "setup_timeline",
120122
"Timeline display preferences");
@@ -208,11 +210,11 @@
208210
zVar, iQ ? "on" : "off");
209211
iVal = iQ;
210212
}
211213
}
212214
@ <label><input type="checkbox" name="%s(zQParm)" \
213
- @ aria-label="%s(zLabel[0]?zLabel:zQParm)" \
215
+ @ aria-label="%h(zLabel[0]?zLabel:zQParm)" \
214216
if( iVal ){
215217
@ checked="checked" \
216218
}
217219
if( disabled ){
218220
@ disabled="disabled" \
@@ -322,10 +324,105 @@
322324
@ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
323325
}
324326
@ </select> <b>%h(zLabel)</b>
325327
}
326328
329
+/*
330
+** Insert code into the current page that allows the user to configure
331
+** auto-hyperlink related robot defense settings.
332
+*/
333
+static void addAutoHyperlinkSettings(void){
334
+ static const char *const azDefenseOpts[] = {
335
+ "0", "Off",
336
+ "2", "UserAgent only",
337
+ "1", "UserAgent and Javascript",
338
+ };
339
+ multiple_choice_attribute(
340
+ "Enable hyperlinks base on User-Agent and/or Javascript",
341
+ "auto-hyperlink", "autohyperlink", "1",
342
+ count(azDefenseOpts)/2, azDefenseOpts);
343
+ @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
344
+ @ including user "nobody", as long as the User-Agent string in the
345
+ @ HTTP header indicates that the request is coming from an actual human
346
+ @ being. If this setting is "UserAgent only" (2) then the
347
+ @ UserAgent string is the only factor considered. If the value of this
348
+ @ setting is "UserAgent And Javascript" (1) then Javascript is added that
349
+ @ runs after the page loads and fills in the href= values of &lt;a&gt;
350
+ @ elements. In either case, &lt;a&gt; tags are only generated if the
351
+ @ UserAgent string indicates that the request is coming from a human and
352
+ @ not a robot.
353
+ @
354
+ @ <p>This setting is designed to give easy access to humans while
355
+ @ keeping out robots.
356
+ @ You do not normally want a robot to walk your entire repository because
357
+ @ if it does, your server will end up computing diffs and annotations for
358
+ @ every historical version of every file and creating ZIPs and tarballs of
359
+ @ every historical check-in, which can use a lot of CPU and bandwidth
360
+ @ even for relatively small projects.</p>
361
+ @
362
+ @ <p>The "UserAgent and Javascript" value for this setting provides
363
+ @ superior protection from robots. However, that setting also prevents
364
+ @ the visited/unvisited colors on hyperlinks from displaying correctly
365
+ @ on Safara-derived browsers. (Chrome and Firefox work fine.) Since
366
+ @ Safari is the underlying rendering engine on all iPhones and iPads,
367
+ @ this means that hyperlink visited/unvisited colors will not operate
368
+ @ on those platforms when "UserAgent and Javascript" is selected.</p>
369
+ @
370
+ @ <p>Additional parameters that control the behavior of Javascript:</p>
371
+ @ <blockquote>
372
+ entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
373
+ "auto-hyperlink-delay", "ah-delay", "50", 0);
374
+ @ <br />
375
+ onoff_attribute("Also require a mouse event before enabling hyperlinks",
376
+ "auto-hyperlink-mouseover", "ahmo", 0, 0);
377
+ @ </blockquote>
378
+ @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds
379
+ @ and "require a mouse event" should be turned on. These values only come
380
+ @ into play when the main auto-hyperlink settings is 2 ("UserAgent and
381
+ @ Javascript").</p>
382
+ @
383
+ @ <p>To see if Javascript-base hyperlink enabling mechanism is working,
384
+ @ visit the <a href="%R/test_env">/test_env</a> page (from a separate
385
+ @ web browser that is not logged in, even as "anonymous") and verify
386
+ @ that the "g.jsHref" value is "1".</p>
387
+ @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and
388
+ @ "auto-hyperlink-mouseover"")</p>
389
+}
390
+
391
+/*
392
+** WEBPAGE: setup_robot
393
+**
394
+** Settings associated with defense against robots. Requires setup privilege.
395
+*/
396
+void setup_robots(void){
397
+ login_check_credentials();
398
+ if( !g.perm.Setup ){
399
+ login_needed(0);
400
+ return;
401
+ }
402
+ style_set_current_feature("setup");
403
+ style_header("Robot Defense Settings");
404
+ db_begin_transaction();
405
+ @ <p>A Fossil website can have billions of pages in its tree, even for a
406
+ @ modest project. Many of those pages (examples: diffs and tarballs)
407
+ @ might be expensive to compute. A robot that tries to walk the entire
408
+ @ website can present a crippling CPU and bandwidth load.
409
+ @
410
+ @ <p>The settings on this page are intended to help site administrators
411
+ @ defend the site against robots.
412
+ @
413
+ @ <form action="%R/setup_robot" method="post"><div>
414
+ login_insert_csrf_secret();
415
+ @ <input type="submit" name="submit" value="Apply Changes" /></p>
416
+ @ <hr />
417
+ addAutoHyperlinkSettings();
418
+ @ <hr />
419
+ @ <p><input type="submit" name="submit" value="Apply Changes" /></p>
420
+ @ </div></form>
421
+ db_end_transaction(0);
422
+ style_finish_page();
423
+}
327424
328425
/*
329426
** WEBPAGE: setup_access
330427
**
331428
** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
447544
@ the out-bound data of sync, clone, and pull packets.
448545
@ If the client request takes longer, a partial reply is given similar
449546
@ to the download packet limit. 30s is a reasonable default.
450547
@ (Property: "max-download-time")</p>
451548
549
+ @ <a id="slal"></a>
452550
@ <hr />
453551
entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
454552
"0.0", 0);
455553
@ <p>Some expensive operations (such as computing tarballs, zip archives,
456554
@ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
459557
@ This limit is only enforced on Unix servers. On Linux systems,
460558
@ access to the /proc virtual filesystem is required, which means this limit
461559
@ might not work inside a chroot() jail.
462560
@ (Property: "max-loadavg")</p>
463561
562
+ /* Add the auto-hyperlink settings controls. These same controls
563
+ ** are also accessible from the /setup_robot page.
564
+ */
464565
@ <hr />
465
- onoff_attribute(
466
- "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
467
- "auto-hyperlink", "autohyperlink", 1, 0);
468
- @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
469
- @ including user "nobody", as long as
470
- @ <ol><li>the User-Agent string in the
471
- @ HTTP header indicates that the request is coming from an actual human
472
- @ being, and
473
- @ <li>the user agent is able to
474
- @ run Javascript in order to set the href= attribute of hyperlinks, and
475
- @ <li>mouse movement is detected (optional - see the checkbox below), and
476
- @ <li>a number of milliseconds have passed since the page loaded.</ol>
477
- @
478
- @ <p>This setting is designed to give easy access to humans while
479
- @ keeping out robots and spiders.
480
- @ You do not normally want a robot to walk your entire repository because
481
- @ if it does, your server will end up computing diffs and annotations for
482
- @ every historical version of every file and creating ZIPs and tarballs of
483
- @ every historical check-in, which can use a lot of CPU and bandwidth
484
- @ even for relatively small projects.</p>
485
- @
486
- @ <p>Additional parameters that control this behavior:</p>
487
- @ <blockquote>
488
- onoff_attribute("Require mouse movement before enabling hyperlinks",
489
- "auto-hyperlink-mouseover", "ahmo", 0, 0);
490
- @ <br />
491
- entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
492
- "auto-hyperlink-delay", "ah-delay", "50", 0);
493
- @ </blockquote>
494
- @ <p>For maximum robot defense, the "require mouse movement" should
495
- @ be turned on and the "Delay" should be at least 50 milliseconds.</p>
496
- @ (Properties: "auto-hyperlink",
497
- @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p>
566
+ addAutoHyperlinkSettings();
498567
499568
@ <hr />
500569
onoff_attribute("Require a CAPTCHA if not logged in",
501570
"require-captcha", "reqcapt", 1, 0);
502571
@ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
9621031
** * The second term is a hyperlink to take when a user clicks on the
9631032
** entry. Hyperlinks that start with "/" are relative to the
9641033
** repository root.
9651034
**
9661035
** * The third term is an argument to the TH1 "capexpr" command.
967
-** If capexpr evalutes to true, then the entry is shown. If not,
1036
+** If capexpr evaluates to true, then the entry is shown. If not,
9681037
** the entry is omitted. "*" is always true. "{}" is never true.
9691038
**
9701039
** * The fourth term is a list of extra class names to apply to the
9711040
** new menu entry. Some skins use classes "desktoponly" and
9721041
** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
9931062
** * The second term is a hyperlink to take when a user clicks on the
9941063
** entry. Hyperlinks that start with "/" are relative to the
9951064
** repository root.
9961065
**
9971066
** * The third term is an argument to the TH1 "capexpr" command.
998
-** If capexpr evalutes to true, then the entry is shown. If not,
1067
+** If capexpr evaluates to true, then the entry is shown. If not,
9991068
** the entry is omitted. "*" is always true.
10001069
**
10011070
** The default value is blank, meaning no added entries.
10021071
*/
10031072
@@ -1093,11 +1162,11 @@
10931162
@ <li> The first term is text that appears on the menu.
10941163
@ <li> The second term is a hyperlink to take when a user clicks on the
10951164
@ entry. Hyperlinks that start with "/" are relative to the
10961165
@ repository root.
10971166
@ <li> The third term is an argument to the TH1 "capexpr" command.
1098
- @ If capexpr evalutes to true, then the entry is shown. If not,
1167
+ @ If capexpr evaluates to true, then the entry is shown. If not,
10991168
@ the entry is omitted. "*" is always true. "{}" is never true.
11001169
@ <li> The fourth term is a list of extra class names to apply to the new
11011170
@ menu entry. Some skins use classes "desktoponly" and "wideonly"
11021171
@ to only show the entries when the web browser screen is wide or
11031172
@ very wide, respectively.
@@ -1131,11 +1200,11 @@
11311200
@ <li> The first term is the display name of the /sitemap entry
11321201
@ <li> The second term is a hyperlink to take when a user clicks on the
11331202
@ entry. Hyperlinks that start with "/" are relative to the
11341203
@ repository root.
11351204
@ <li> The third term is an argument to the TH1 "capexpr" command.
1136
- @ If capexpr evalutes to true, then the entry is shown. If not,
1205
+ @ If capexpr evaluates to true, then the entry is shown. If not,
11371206
@ the entry is omitted. "*" is always true.
11381207
@ </ol>
11391208
@
11401209
@ <p>The default value is blank, meaning no added entries.
11411210
@ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
17291798
zQ = sqlite3_mprintf(
17301799
"SELECT sql FROM repository.sqlite_schema"
17311800
" WHERE sql IS NOT NULL ORDER BY name");
17321801
go = 1;
17331802
}else if( P("tablelist") ){
1734
- zQ = sqlite3_mprintf(
1735
- "SELECT name FROM repository.sqlite_schema WHERE type='table'"
1736
- " ORDER BY name");
1803
+ zQ = sqlite3_mprintf("SELECT*FROM pragma_table_list ORDER BY schema, name");
17371804
go = 1;
17381805
}
17391806
if( go ){
17401807
sqlite3_stmt *pStmt;
17411808
int rc;
@@ -1744,10 +1811,11 @@
17441811
int nRow = 0;
17451812
int i;
17461813
@ <hr />
17471814
login_verify_csrf_secret();
17481815
sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
1816
+ search_sql_setup(g.db);
17491817
rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
17501818
if( rc!=SQLITE_OK ){
17511819
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
17521820
sqlite3_finalize(pStmt);
17531821
}else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
17571825
rc = sqlite3_finalize(pStmt);
17581826
if( rc ){
17591827
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
17601828
}
17611829
}else{
1762
- @ <table border=1>
1830
+ @ <table border="1" cellpadding="4" cellspacing="0">
17631831
while( sqlite3_step(pStmt)==SQLITE_ROW ){
17641832
if( nRow==0 ){
17651833
@ <tr>
17661834
for(i=0; i<nCol; i++){
17671835
@ <th>%h(sqlite3_column_name(pStmt, i))</th>
17681836
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111 "Configure the WWW components of the repository");
112 }
113 setup_menu_entry("Security-Audit", "secaudit0",
114 "Analyze the current configuration for security problems");
115 if( setup_user ){
 
 
116 setup_menu_entry("Settings", "setup_settings",
117 "Web interface to the \"fossil settings\" command");
118 }
119 setup_menu_entry("Timeline", "setup_timeline",
120 "Timeline display preferences");
@@ -208,11 +210,11 @@
208 zVar, iQ ? "on" : "off");
209 iVal = iQ;
210 }
211 }
212 @ <label><input type="checkbox" name="%s(zQParm)" \
213 @ aria-label="%s(zLabel[0]?zLabel:zQParm)" \
214 if( iVal ){
215 @ checked="checked" \
216 }
217 if( disabled ){
218 @ disabled="disabled" \
@@ -322,10 +324,105 @@
322 @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
323 }
324 @ </select> <b>%h(zLabel)</b>
325 }
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
328 /*
329 ** WEBPAGE: setup_access
330 **
331 ** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
447 @ the out-bound data of sync, clone, and pull packets.
448 @ If the client request takes longer, a partial reply is given similar
449 @ to the download packet limit. 30s is a reasonable default.
450 @ (Property: "max-download-time")</p>
451
 
452 @ <hr />
453 entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
454 "0.0", 0);
455 @ <p>Some expensive operations (such as computing tarballs, zip archives,
456 @ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
459 @ This limit is only enforced on Unix servers. On Linux systems,
460 @ access to the /proc virtual filesystem is required, which means this limit
461 @ might not work inside a chroot() jail.
462 @ (Property: "max-loadavg")</p>
463
 
 
 
464 @ <hr />
465 onoff_attribute(
466 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
467 "auto-hyperlink", "autohyperlink", 1, 0);
468 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
469 @ including user "nobody", as long as
470 @ <ol><li>the User-Agent string in the
471 @ HTTP header indicates that the request is coming from an actual human
472 @ being, and
473 @ <li>the user agent is able to
474 @ run Javascript in order to set the href= attribute of hyperlinks, and
475 @ <li>mouse movement is detected (optional - see the checkbox below), and
476 @ <li>a number of milliseconds have passed since the page loaded.</ol>
477 @
478 @ <p>This setting is designed to give easy access to humans while
479 @ keeping out robots and spiders.
480 @ You do not normally want a robot to walk your entire repository because
481 @ if it does, your server will end up computing diffs and annotations for
482 @ every historical version of every file and creating ZIPs and tarballs of
483 @ every historical check-in, which can use a lot of CPU and bandwidth
484 @ even for relatively small projects.</p>
485 @
486 @ <p>Additional parameters that control this behavior:</p>
487 @ <blockquote>
488 onoff_attribute("Require mouse movement before enabling hyperlinks",
489 "auto-hyperlink-mouseover", "ahmo", 0, 0);
490 @ <br />
491 entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
492 "auto-hyperlink-delay", "ah-delay", "50", 0);
493 @ </blockquote>
494 @ <p>For maximum robot defense, the "require mouse movement" should
495 @ be turned on and the "Delay" should be at least 50 milliseconds.</p>
496 @ (Properties: "auto-hyperlink",
497 @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p>
498
499 @ <hr />
500 onoff_attribute("Require a CAPTCHA if not logged in",
501 "require-captcha", "reqcapt", 1, 0);
502 @ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
962 ** * The second term is a hyperlink to take when a user clicks on the
963 ** entry. Hyperlinks that start with "/" are relative to the
964 ** repository root.
965 **
966 ** * The third term is an argument to the TH1 "capexpr" command.
967 ** If capexpr evalutes to true, then the entry is shown. If not,
968 ** the entry is omitted. "*" is always true. "{}" is never true.
969 **
970 ** * The fourth term is a list of extra class names to apply to the
971 ** new menu entry. Some skins use classes "desktoponly" and
972 ** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
993 ** * The second term is a hyperlink to take when a user clicks on the
994 ** entry. Hyperlinks that start with "/" are relative to the
995 ** repository root.
996 **
997 ** * The third term is an argument to the TH1 "capexpr" command.
998 ** If capexpr evalutes to true, then the entry is shown. If not,
999 ** the entry is omitted. "*" is always true.
1000 **
1001 ** The default value is blank, meaning no added entries.
1002 */
1003
@@ -1093,11 +1162,11 @@
1093 @ <li> The first term is text that appears on the menu.
1094 @ <li> The second term is a hyperlink to take when a user clicks on the
1095 @ entry. Hyperlinks that start with "/" are relative to the
1096 @ repository root.
1097 @ <li> The third term is an argument to the TH1 "capexpr" command.
1098 @ If capexpr evalutes to true, then the entry is shown. If not,
1099 @ the entry is omitted. "*" is always true. "{}" is never true.
1100 @ <li> The fourth term is a list of extra class names to apply to the new
1101 @ menu entry. Some skins use classes "desktoponly" and "wideonly"
1102 @ to only show the entries when the web browser screen is wide or
1103 @ very wide, respectively.
@@ -1131,11 +1200,11 @@
1131 @ <li> The first term is the display name of the /sitemap entry
1132 @ <li> The second term is a hyperlink to take when a user clicks on the
1133 @ entry. Hyperlinks that start with "/" are relative to the
1134 @ repository root.
1135 @ <li> The third term is an argument to the TH1 "capexpr" command.
1136 @ If capexpr evalutes to true, then the entry is shown. If not,
1137 @ the entry is omitted. "*" is always true.
1138 @ </ol>
1139 @
1140 @ <p>The default value is blank, meaning no added entries.
1141 @ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
1729 zQ = sqlite3_mprintf(
1730 "SELECT sql FROM repository.sqlite_schema"
1731 " WHERE sql IS NOT NULL ORDER BY name");
1732 go = 1;
1733 }else if( P("tablelist") ){
1734 zQ = sqlite3_mprintf(
1735 "SELECT name FROM repository.sqlite_schema WHERE type='table'"
1736 " ORDER BY name");
1737 go = 1;
1738 }
1739 if( go ){
1740 sqlite3_stmt *pStmt;
1741 int rc;
@@ -1744,10 +1811,11 @@
1744 int nRow = 0;
1745 int i;
1746 @ <hr />
1747 login_verify_csrf_secret();
1748 sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
 
1749 rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
1750 if( rc!=SQLITE_OK ){
1751 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1752 sqlite3_finalize(pStmt);
1753 }else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
1757 rc = sqlite3_finalize(pStmt);
1758 if( rc ){
1759 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1760 }
1761 }else{
1762 @ <table border=1>
1763 while( sqlite3_step(pStmt)==SQLITE_ROW ){
1764 if( nRow==0 ){
1765 @ <tr>
1766 for(i=0; i<nCol; i++){
1767 @ <th>%h(sqlite3_column_name(pStmt, i))</th>
1768
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111 "Configure the WWW components of the repository");
112 }
113 setup_menu_entry("Security-Audit", "secaudit0",
114 "Analyze the current configuration for security problems");
115 if( setup_user ){
116 setup_menu_entry("Robot-Defense", "setup_robot",
117 "Settings for configure defense against robots");
118 setup_menu_entry("Settings", "setup_settings",
119 "Web interface to the \"fossil settings\" command");
120 }
121 setup_menu_entry("Timeline", "setup_timeline",
122 "Timeline display preferences");
@@ -208,11 +210,11 @@
210 zVar, iQ ? "on" : "off");
211 iVal = iQ;
212 }
213 }
214 @ <label><input type="checkbox" name="%s(zQParm)" \
215 @ aria-label="%h(zLabel[0]?zLabel:zQParm)" \
216 if( iVal ){
217 @ checked="checked" \
218 }
219 if( disabled ){
220 @ disabled="disabled" \
@@ -322,10 +324,105 @@
324 @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
325 }
326 @ </select> <b>%h(zLabel)</b>
327 }
328
329 /*
330 ** Insert code into the current page that allows the user to configure
331 ** auto-hyperlink related robot defense settings.
332 */
333 static void addAutoHyperlinkSettings(void){
334 static const char *const azDefenseOpts[] = {
335 "0", "Off",
336 "2", "UserAgent only",
337 "1", "UserAgent and Javascript",
338 };
339 multiple_choice_attribute(
340 "Enable hyperlinks base on User-Agent and/or Javascript",
341 "auto-hyperlink", "autohyperlink", "1",
342 count(azDefenseOpts)/2, azDefenseOpts);
343 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
344 @ including user "nobody", as long as the User-Agent string in the
345 @ HTTP header indicates that the request is coming from an actual human
346 @ being. If this setting is "UserAgent only" (2) then the
347 @ UserAgent string is the only factor considered. If the value of this
348 @ setting is "UserAgent And Javascript" (1) then Javascript is added that
349 @ runs after the page loads and fills in the href= values of &lt;a&gt;
350 @ elements. In either case, &lt;a&gt; tags are only generated if the
351 @ UserAgent string indicates that the request is coming from a human and
352 @ not a robot.
353 @
354 @ <p>This setting is designed to give easy access to humans while
355 @ keeping out robots.
356 @ You do not normally want a robot to walk your entire repository because
357 @ if it does, your server will end up computing diffs and annotations for
358 @ every historical version of every file and creating ZIPs and tarballs of
359 @ every historical check-in, which can use a lot of CPU and bandwidth
360 @ even for relatively small projects.</p>
361 @
362 @ <p>The "UserAgent and Javascript" value for this setting provides
363 @ superior protection from robots. However, that setting also prevents
364 @ the visited/unvisited colors on hyperlinks from displaying correctly
365 @ on Safara-derived browsers. (Chrome and Firefox work fine.) Since
366 @ Safari is the underlying rendering engine on all iPhones and iPads,
367 @ this means that hyperlink visited/unvisited colors will not operate
368 @ on those platforms when "UserAgent and Javascript" is selected.</p>
369 @
370 @ <p>Additional parameters that control the behavior of Javascript:</p>
371 @ <blockquote>
372 entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
373 "auto-hyperlink-delay", "ah-delay", "50", 0);
374 @ <br />
375 onoff_attribute("Also require a mouse event before enabling hyperlinks",
376 "auto-hyperlink-mouseover", "ahmo", 0, 0);
377 @ </blockquote>
378 @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds
379 @ and "require a mouse event" should be turned on. These values only come
380 @ into play when the main auto-hyperlink settings is 2 ("UserAgent and
381 @ Javascript").</p>
382 @
383 @ <p>To see if Javascript-base hyperlink enabling mechanism is working,
384 @ visit the <a href="%R/test_env">/test_env</a> page (from a separate
385 @ web browser that is not logged in, even as "anonymous") and verify
386 @ that the "g.jsHref" value is "1".</p>
387 @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and
388 @ "auto-hyperlink-mouseover"")</p>
389 }
390
391 /*
392 ** WEBPAGE: setup_robot
393 **
394 ** Settings associated with defense against robots. Requires setup privilege.
395 */
396 void setup_robots(void){
397 login_check_credentials();
398 if( !g.perm.Setup ){
399 login_needed(0);
400 return;
401 }
402 style_set_current_feature("setup");
403 style_header("Robot Defense Settings");
404 db_begin_transaction();
405 @ <p>A Fossil website can have billions of pages in its tree, even for a
406 @ modest project. Many of those pages (examples: diffs and tarballs)
407 @ might be expensive to compute. A robot that tries to walk the entire
408 @ website can present a crippling CPU and bandwidth load.
409 @
410 @ <p>The settings on this page are intended to help site administrators
411 @ defend the site against robots.
412 @
413 @ <form action="%R/setup_robot" method="post"><div>
414 login_insert_csrf_secret();
415 @ <input type="submit" name="submit" value="Apply Changes" /></p>
416 @ <hr />
417 addAutoHyperlinkSettings();
418 @ <hr />
419 @ <p><input type="submit" name="submit" value="Apply Changes" /></p>
420 @ </div></form>
421 db_end_transaction(0);
422 style_finish_page();
423 }
424
425 /*
426 ** WEBPAGE: setup_access
427 **
428 ** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
544 @ the out-bound data of sync, clone, and pull packets.
545 @ If the client request takes longer, a partial reply is given similar
546 @ to the download packet limit. 30s is a reasonable default.
547 @ (Property: "max-download-time")</p>
548
549 @ <a id="slal"></a>
550 @ <hr />
551 entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
552 "0.0", 0);
553 @ <p>Some expensive operations (such as computing tarballs, zip archives,
554 @ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
557 @ This limit is only enforced on Unix servers. On Linux systems,
558 @ access to the /proc virtual filesystem is required, which means this limit
559 @ might not work inside a chroot() jail.
560 @ (Property: "max-loadavg")</p>
561
562 /* Add the auto-hyperlink settings controls. These same controls
563 ** are also accessible from the /setup_robot page.
564 */
565 @ <hr />
566 addAutoHyperlinkSettings();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
568 @ <hr />
569 onoff_attribute("Require a CAPTCHA if not logged in",
570 "require-captcha", "reqcapt", 1, 0);
571 @ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
1031 ** * The second term is a hyperlink to take when a user clicks on the
1032 ** entry. Hyperlinks that start with "/" are relative to the
1033 ** repository root.
1034 **
1035 ** * The third term is an argument to the TH1 "capexpr" command.
1036 ** If capexpr evaluates to true, then the entry is shown. If not,
1037 ** the entry is omitted. "*" is always true. "{}" is never true.
1038 **
1039 ** * The fourth term is a list of extra class names to apply to the
1040 ** new menu entry. Some skins use classes "desktoponly" and
1041 ** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
1062 ** * The second term is a hyperlink to take when a user clicks on the
1063 ** entry. Hyperlinks that start with "/" are relative to the
1064 ** repository root.
1065 **
1066 ** * The third term is an argument to the TH1 "capexpr" command.
1067 ** If capexpr evaluates to true, then the entry is shown. If not,
1068 ** the entry is omitted. "*" is always true.
1069 **
1070 ** The default value is blank, meaning no added entries.
1071 */
1072
@@ -1093,11 +1162,11 @@
1162 @ <li> The first term is text that appears on the menu.
1163 @ <li> The second term is a hyperlink to take when a user clicks on the
1164 @ entry. Hyperlinks that start with "/" are relative to the
1165 @ repository root.
1166 @ <li> The third term is an argument to the TH1 "capexpr" command.
1167 @ If capexpr evaluates to true, then the entry is shown. If not,
1168 @ the entry is omitted. "*" is always true. "{}" is never true.
1169 @ <li> The fourth term is a list of extra class names to apply to the new
1170 @ menu entry. Some skins use classes "desktoponly" and "wideonly"
1171 @ to only show the entries when the web browser screen is wide or
1172 @ very wide, respectively.
@@ -1131,11 +1200,11 @@
1200 @ <li> The first term is the display name of the /sitemap entry
1201 @ <li> The second term is a hyperlink to take when a user clicks on the
1202 @ entry. Hyperlinks that start with "/" are relative to the
1203 @ repository root.
1204 @ <li> The third term is an argument to the TH1 "capexpr" command.
1205 @ If capexpr evaluates to true, then the entry is shown. If not,
1206 @ the entry is omitted. "*" is always true.
1207 @ </ol>
1208 @
1209 @ <p>The default value is blank, meaning no added entries.
1210 @ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
1798 zQ = sqlite3_mprintf(
1799 "SELECT sql FROM repository.sqlite_schema"
1800 " WHERE sql IS NOT NULL ORDER BY name");
1801 go = 1;
1802 }else if( P("tablelist") ){
1803 zQ = sqlite3_mprintf("SELECT*FROM pragma_table_list ORDER BY schema, name");
 
 
1804 go = 1;
1805 }
1806 if( go ){
1807 sqlite3_stmt *pStmt;
1808 int rc;
@@ -1744,10 +1811,11 @@
1811 int nRow = 0;
1812 int i;
1813 @ <hr />
1814 login_verify_csrf_secret();
1815 sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
1816 search_sql_setup(g.db);
1817 rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
1818 if( rc!=SQLITE_OK ){
1819 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1820 sqlite3_finalize(pStmt);
1821 }else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
1825 rc = sqlite3_finalize(pStmt);
1826 if( rc ){
1827 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1828 }
1829 }else{
1830 @ <table border="1" cellpadding="4" cellspacing="0">
1831 while( sqlite3_step(pStmt)==SQLITE_ROW ){
1832 if( nRow==0 ){
1833 @ <tr>
1834 for(i=0; i<nCol; i++){
1835 @ <th>%h(sqlite3_column_name(pStmt, i))</th>
1836
+24 -1
--- src/setupuser.c
+++ src/setupuser.c
@@ -347,11 +347,11 @@
347347
if( P("delete") && cgi_csrf_safe(1) ){
348348
int n;
349349
if( P("verifydelete") ){
350350
/* Verified delete user request */
351351
db_unprotect(PROTECT_USER);
352
- if( db_table_exists("repository","subscriber") ){
352
+ if( alert_tables_exist() ){
353353
/* Also delete any subscriptions associated with this user */
354354
db_multi_exec("DELETE FROM subscriber WHERE suname="
355355
"(SELECT login FROM user WHERE uid=%d)", uid);
356356
}
357357
db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
@@ -447,10 +447,19 @@
447447
db_multi_exec(
448448
"REPLACE INTO user(uid,login,info,pw,cap,mtime) "
449449
"VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
450450
uid, zLogin, P("info"), zPw, zCap
451451
);
452
+ if( zOldLogin && fossil_strcmp(zLogin, zOldLogin)!=0 ){
453
+ if( alert_tables_exist() ){
454
+ /* Rename matching subscriber entry, else the user cannot
455
+ re-subscribe with their same email address. */
456
+ db_multi_exec("UPDATE subscriber SET suname=%Q WHERE suname=%Q",
457
+ zLogin, zOldLogin);
458
+ }
459
+ admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin );
460
+ }
452461
db_protect_pop();
453462
setup_incr_cfgcnt();
454463
admin_log( "Updated user [%q] with capabilities [%q].",
455464
zLogin, zCap );
456465
if( atoi(PD("all","0"))>0 ){
@@ -463,10 +472,24 @@
463472
" SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
464473
zLogin, zLogin
465474
);
466475
zOldLogin = zLogin;
467476
}
477
+#if 0
478
+ /* Problem: when renaming a user we need to update the subcriber
479
+ ** names to match but we cannot know from here if each member of
480
+ ** the login group has the subscriber tables, so we cannot blindly
481
+ ** include this SQL. */
482
+ else if( fossil_strcmp(zLogin, zOldLogin)!=0
483
+ && alert_tables_exist() ){
484
+ /* Rename matching subscriber entry, else the user cannot
485
+ re-subscribe with their same email address. */
486
+ blob_appendf(&sql,
487
+ "UPDATE subscriber SET suname=%Q WHERE suname=%Q;",
488
+ zLogin, zOldLogin);
489
+ }
490
+#endif
468491
blob_appendf(&sql,
469492
"UPDATE user SET login=%Q,"
470493
" pw=coalesce(shared_secret(%Q,%Q,"
471494
"(SELECT value FROM config WHERE name='project-code')),pw),"
472495
" info=%Q,"
473496
--- src/setupuser.c
+++ src/setupuser.c
@@ -347,11 +347,11 @@
347 if( P("delete") && cgi_csrf_safe(1) ){
348 int n;
349 if( P("verifydelete") ){
350 /* Verified delete user request */
351 db_unprotect(PROTECT_USER);
352 if( db_table_exists("repository","subscriber") ){
353 /* Also delete any subscriptions associated with this user */
354 db_multi_exec("DELETE FROM subscriber WHERE suname="
355 "(SELECT login FROM user WHERE uid=%d)", uid);
356 }
357 db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
@@ -447,10 +447,19 @@
447 db_multi_exec(
448 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
449 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
450 uid, zLogin, P("info"), zPw, zCap
451 );
 
 
 
 
 
 
 
 
 
452 db_protect_pop();
453 setup_incr_cfgcnt();
454 admin_log( "Updated user [%q] with capabilities [%q].",
455 zLogin, zCap );
456 if( atoi(PD("all","0"))>0 ){
@@ -463,10 +472,24 @@
463 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
464 zLogin, zLogin
465 );
466 zOldLogin = zLogin;
467 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468 blob_appendf(&sql,
469 "UPDATE user SET login=%Q,"
470 " pw=coalesce(shared_secret(%Q,%Q,"
471 "(SELECT value FROM config WHERE name='project-code')),pw),"
472 " info=%Q,"
473
--- src/setupuser.c
+++ src/setupuser.c
@@ -347,11 +347,11 @@
347 if( P("delete") && cgi_csrf_safe(1) ){
348 int n;
349 if( P("verifydelete") ){
350 /* Verified delete user request */
351 db_unprotect(PROTECT_USER);
352 if( alert_tables_exist() ){
353 /* Also delete any subscriptions associated with this user */
354 db_multi_exec("DELETE FROM subscriber WHERE suname="
355 "(SELECT login FROM user WHERE uid=%d)", uid);
356 }
357 db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
@@ -447,10 +447,19 @@
447 db_multi_exec(
448 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
449 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
450 uid, zLogin, P("info"), zPw, zCap
451 );
452 if( zOldLogin && fossil_strcmp(zLogin, zOldLogin)!=0 ){
453 if( alert_tables_exist() ){
454 /* Rename matching subscriber entry, else the user cannot
455 re-subscribe with their same email address. */
456 db_multi_exec("UPDATE subscriber SET suname=%Q WHERE suname=%Q",
457 zLogin, zOldLogin);
458 }
459 admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin );
460 }
461 db_protect_pop();
462 setup_incr_cfgcnt();
463 admin_log( "Updated user [%q] with capabilities [%q].",
464 zLogin, zCap );
465 if( atoi(PD("all","0"))>0 ){
@@ -463,10 +472,24 @@
472 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
473 zLogin, zLogin
474 );
475 zOldLogin = zLogin;
476 }
477 #if 0
478 /* Problem: when renaming a user we need to update the subcriber
479 ** names to match but we cannot know from here if each member of
480 ** the login group has the subscriber tables, so we cannot blindly
481 ** include this SQL. */
482 else if( fossil_strcmp(zLogin, zOldLogin)!=0
483 && alert_tables_exist() ){
484 /* Rename matching subscriber entry, else the user cannot
485 re-subscribe with their same email address. */
486 blob_appendf(&sql,
487 "UPDATE subscriber SET suname=%Q WHERE suname=%Q;",
488 zLogin, zOldLogin);
489 }
490 #endif
491 blob_appendf(&sql,
492 "UPDATE user SET login=%Q,"
493 " pw=coalesce(shared_secret(%Q,%Q,"
494 "(SELECT value FROM config WHERE name='project-code')),pw),"
495 " info=%Q,"
496
+3 -3
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
7474
if( P("popup")!=0 ){
7575
/* The "popup" query parameter
7676
** then disable anti-robot defenses */
7777
isPopup = 1;
7878
g.perm.Hyperlink = 1;
79
- g.javascriptHyperlink = 0;
79
+ g.jsHref = 0;
8080
}
8181
srchFlags = search_restrict(SRCH_ALL);
8282
if( !isPopup ){
8383
style_header("Site Map");
8484
style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312312
if( P("popup")!=0 && cgi_csrf_safe(0) ){
313313
/* If this is a POST from the same origin with the popup=1 parameter,
314314
** then disable anti-robot defenses */
315315
isPopup = 1;
316316
g.perm.Hyperlink = 1;
317
- g.javascriptHyperlink = 0;
317
+ g.jsHref = 0;
318318
}
319319
if( !isPopup ){
320320
style_header("Test Page Map");
321321
style_adunit_config(ADUNIT_RIGHT_OK);
322322
}
@@ -364,11 +364,11 @@
364364
if( P("popup")!=0 && cgi_csrf_safe(0) ){
365365
/* If this is a POST from the same origin with the popup=1 parameter,
366366
** then disable anti-robot defenses */
367367
isPopup = 1;
368368
g.perm.Hyperlink = 1;
369
- g.javascriptHyperlink = 0;
369
+ g.jsHref = 0;
370370
}
371371
if( !isPopup ){
372372
style_header("Timeline Examples");
373373
style_adunit_config(ADUNIT_RIGHT_OK);
374374
}
375375
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
74 if( P("popup")!=0 ){
75 /* The "popup" query parameter
76 ** then disable anti-robot defenses */
77 isPopup = 1;
78 g.perm.Hyperlink = 1;
79 g.javascriptHyperlink = 0;
80 }
81 srchFlags = search_restrict(SRCH_ALL);
82 if( !isPopup ){
83 style_header("Site Map");
84 style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312 if( P("popup")!=0 && cgi_csrf_safe(0) ){
313 /* If this is a POST from the same origin with the popup=1 parameter,
314 ** then disable anti-robot defenses */
315 isPopup = 1;
316 g.perm.Hyperlink = 1;
317 g.javascriptHyperlink = 0;
318 }
319 if( !isPopup ){
320 style_header("Test Page Map");
321 style_adunit_config(ADUNIT_RIGHT_OK);
322 }
@@ -364,11 +364,11 @@
364 if( P("popup")!=0 && cgi_csrf_safe(0) ){
365 /* If this is a POST from the same origin with the popup=1 parameter,
366 ** then disable anti-robot defenses */
367 isPopup = 1;
368 g.perm.Hyperlink = 1;
369 g.javascriptHyperlink = 0;
370 }
371 if( !isPopup ){
372 style_header("Timeline Examples");
373 style_adunit_config(ADUNIT_RIGHT_OK);
374 }
375
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
74 if( P("popup")!=0 ){
75 /* The "popup" query parameter
76 ** then disable anti-robot defenses */
77 isPopup = 1;
78 g.perm.Hyperlink = 1;
79 g.jsHref = 0;
80 }
81 srchFlags = search_restrict(SRCH_ALL);
82 if( !isPopup ){
83 style_header("Site Map");
84 style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312 if( P("popup")!=0 && cgi_csrf_safe(0) ){
313 /* If this is a POST from the same origin with the popup=1 parameter,
314 ** then disable anti-robot defenses */
315 isPopup = 1;
316 g.perm.Hyperlink = 1;
317 g.jsHref = 0;
318 }
319 if( !isPopup ){
320 style_header("Test Page Map");
321 style_adunit_config(ADUNIT_RIGHT_OK);
322 }
@@ -364,11 +364,11 @@
364 if( P("popup")!=0 && cgi_csrf_safe(0) ){
365 /* If this is a POST from the same origin with the popup=1 parameter,
366 ** then disable anti-robot defenses */
367 isPopup = 1;
368 g.perm.Hyperlink = 1;
369 g.jsHref = 0;
370 }
371 if( !isPopup ){
372 style_header("Timeline Examples");
373 style_adunit_config(ADUNIT_RIGHT_OK);
374 }
375
+7 -4
--- src/stat.c
+++ src/stat.c
@@ -999,14 +999,17 @@
999999
r = 0;
10001000
n = 0;
10011001
while( db_step(&q)==SQLITE_ROW ){
10021002
r += db_column_int(&q, 0);
10031003
if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004
- if( n==(nTotal+99)/100 ) sz1pct = r;
1005
- if( n==(nTotal+9)/10 ) sz10pct = r;
1006
- if( n==(nTotal+4)/5 ) sz25pct = r;
1007
- if( n==(nTotal+1)/2 ){ sz50pct = r; medCmpr = db_column_int(&q,0); }
1004
+ if( n==(nTotal+99)/100 ) sz1pct = (sqlite3_int64)r;
1005
+ if( n==(nTotal+9)/10 ) sz10pct = (sqlite3_int64)r;
1006
+ if( n==(nTotal+4)/5 ) sz25pct = (sqlite3_int64)r;
1007
+ if( n==(nTotal+1)/2 ){
1008
+ sz50pct = (sqlite3_int64)r;
1009
+ medCmpr = db_column_int(&q,0);
1010
+ }
10081011
n++;
10091012
}
10101013
db_finalize(&q);
10111014
10121015
@ <h1>Overall Artifact Size Statistics:</h1>
10131016
--- src/stat.c
+++ src/stat.c
@@ -999,14 +999,17 @@
999 r = 0;
1000 n = 0;
1001 while( db_step(&q)==SQLITE_ROW ){
1002 r += db_column_int(&q, 0);
1003 if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004 if( n==(nTotal+99)/100 ) sz1pct = r;
1005 if( n==(nTotal+9)/10 ) sz10pct = r;
1006 if( n==(nTotal+4)/5 ) sz25pct = r;
1007 if( n==(nTotal+1)/2 ){ sz50pct = r; medCmpr = db_column_int(&q,0); }
 
 
 
1008 n++;
1009 }
1010 db_finalize(&q);
1011
1012 @ <h1>Overall Artifact Size Statistics:</h1>
1013
--- src/stat.c
+++ src/stat.c
@@ -999,14 +999,17 @@
999 r = 0;
1000 n = 0;
1001 while( db_step(&q)==SQLITE_ROW ){
1002 r += db_column_int(&q, 0);
1003 if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004 if( n==(nTotal+99)/100 ) sz1pct = (sqlite3_int64)r;
1005 if( n==(nTotal+9)/10 ) sz10pct = (sqlite3_int64)r;
1006 if( n==(nTotal+4)/5 ) sz25pct = (sqlite3_int64)r;
1007 if( n==(nTotal+1)/2 ){
1008 sz50pct = (sqlite3_int64)r;
1009 medCmpr = db_column_int(&q,0);
1010 }
1011 n++;
1012 }
1013 db_finalize(&q);
1014
1015 @ <h1>Overall Artifact Size Statistics:</h1>
1016
+43 -28
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106106
** Generate and return a anchor tag like this:
107107
**
108108
** <a href="URL">
109109
** or <a id="ID">
110110
**
111
-** The form of the anchor tag is determined by the g.javascriptHyperlink
111
+** The form of the anchor tag is determined by the g.jsHref
112112
** and g.perm.Hyperlink variables.
113113
**
114
-** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115
-** ---------------- --------------------- ------------------------
116
-** 0 0 (empty string)
117
-** 0 1 (empty string)
118
-** 1 0 <a href="URL">
119
-** 1 1 <a id="ID">
114
+** g.perm.Hyperlink g.jsHref Returned anchor format
115
+** ---------------- -------- ------------------------
116
+** 0 0 (empty string)
117
+** 0 1 (empty string)
118
+** 1 0 <a href="URL">
119
+** 1 1 <a data-href="URL">
120120
**
121121
** No anchor tag is generated if g.perm.Hyperlink is false.
122
-** The href="URL" form is used if g.javascriptHyperlink is false.
123
-** If g.javascriptHyperlink is true then the id="ID" form is used and
124
-** javascript is generated in the footer to cause href values to be
125
-** inserted after the page has loaded. The use of the id="ID" form
122
+** The href="URL" form is used if g.jsHref is false.
123
+** If g.jsHref is true then the data-href="URL" and
124
+** href="/honeypot" is generated and javascript is added to the footer
125
+** to cause data-href values to be inserted into href
126
+** after the page has loaded. The use of the data-href="URL" form
126127
** instead of href="URL" is a defense against bots.
127128
**
128129
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129130
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130
-** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131
+** g.jsHref is set to 1 by login_check_credentials(). Thus
131132
** the g.perm.Hyperlink property will be true even if the user does not
132133
** have the "h" privilege if the "auto-hyperlink" setting is true.
133134
**
134
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
135136
** ------------ -------------- ---------------- ---------------------
136137
** 0 0 0 0
137138
** 1 0 1 0
138139
** 0 1 1 1
139140
** 1 1 1 0
@@ -142,12 +143,12 @@
142143
**
143144
** User has "h" auto-hyperlink Returned anchor format
144145
** ------------ -------------- ----------------------
145146
** 0 0 (empty string)
146147
** 1 0 <a href="URL">
147
-** 0 1 <a id="ID">
148
-** 1 1 (can't happen)
148
+** 0 1 <a data-href="URL">
149
+** 1 1 <a href="URL">
149150
**
150151
** The name of these routines are deliberately kept short so that can be
151152
** easily used within @-lines. Example:
152153
**
153154
** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172173
va_list ap;
173174
if( !g.perm.Hyperlink ) return fossil_strdup("");
174175
va_start(ap, zFormat);
175176
zUrl = vmprintf(zFormat, ap);
176177
va_end(ap);
177
- if( !g.javascriptHyperlink ){
178
+ if( !g.jsHref ){
178179
char *zHUrl;
179180
if( zExtra ){
180181
zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181182
}else{
182183
zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197198
va_list ap;
198199
if( !g.perm.Hyperlink ) return fossil_strdup("");
199200
va_start(ap, zFormat);
200201
zUrl = vmprintf(zFormat, ap);
201202
va_end(ap);
202
- if( !g.javascriptHyperlink ){
203
+ if( !g.jsHref ){
203204
char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204205
fossil_free(zUrl);
205206
return zHUrl;
206207
}
207208
needHrefJs = 1;
@@ -213,11 +214,11 @@
213214
va_list ap;
214215
if( !g.perm.Hyperlink ) return fossil_strdup("");
215216
va_start(ap, zFormat);
216217
zUrl = vmprintf(zFormat, ap);
217218
va_end(ap);
218
- if( !g.javascriptHyperlink ){
219
+ if( !g.jsHref ){
219220
char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220221
fossil_free(zUrl);
221222
return zHUrl;
222223
}
223224
needHrefJs = 1;
@@ -232,18 +233,18 @@
232233
** As a defense against robots, the action=ARG might instead by data-action=ARG
233234
** and javascript (href.js) added to the page so that the data-action= is
234235
** changed into action= after the page loads. Whether or not this happens
235236
** depends on if the user has the "h" privilege and whether or not the
236237
** auto-hyperlink setting is on. These setings determine the values of
237
-** variables g.perm.Hyperlink and g.javascriptHyperlink.
238
+** variables g.perm.Hyperlink and g.jsHref.
238239
**
239
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240
-** ------------ -------------- ---------------- ---------------------
241
-** 1: 0 0 0 0
242
-** 2: 1 0 1 0
243
-** 3: 0 1 1 1
244
-** 4: 1 1 1 0
240
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241
+** ------------ -------------- ---------------- --------
242
+** 1: 0 0 0 0
243
+** 2: 1 0 1 0
244
+** 3: 0 1 1 1
245
+** 4: 1 1 1 0
245246
**
246247
** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247248
** javascript is omitted and so the form is effectively disabled.
248249
*/
249250
void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -882,11 +883,12 @@
882883
** Generate code to load all required javascript files.
883884
*/
884885
static void style_load_all_js_files(void){
885886
if( needHrefJs && g.perm.Hyperlink ){
886887
int nDelay = db_get_int("auto-hyperlink-delay",0);
887
- int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
888
+ int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
889
+ && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
888890
@ <script id='href-data' type='application/json'>\
889891
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
890892
}
891893
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
892894
@ function debugMsg(msg){
@@ -1318,12 +1320,23 @@
13181320
/*
13191321
** WEBPAGE: honeypot
13201322
** This page is a honeypot for spiders and bots.
13211323
*/
13221324
void honeypot_page(void){
1323
- cgi_set_status(403, "Forbidden");
1324
- @ <p>Please enable javascript or log in to see this content</p>
1325
+ style_header("I think you are a robot");
1326
+ @ <p>You seem like a robot.</p>
1327
+ @
1328
+ @ <p>Is this wrong? Are you really a human? If so, please prove it
1329
+ @ by <a href="%R/login">logging in</a>.
1330
+ if( g.anon.Hyperlink ){
1331
+ @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1332
+ @ prefer.
1333
+ }
1334
+ @ <p>Sorry for the inconvenience. The point of this is to prevent
1335
+ @ robots from following the countless of hyperlinks in this site and
1336
+ @ soaking up all the available CPU time and network bandwidth.
1337
+ style_finish_page();
13251338
}
13261339
13271340
/*
13281341
** Webpages that encounter an error due to missing or incorrect
13291342
** query parameters can jump to this routine to render an error
@@ -1375,10 +1388,11 @@
13751388
@ g.zTop = %h(g.zTop)<br />
13761389
@ g.zPath = %h(g.zPath)<br />
13771390
@ g.userUid = %d(g.userUid)<br />
13781391
@ g.zLogin = %h(g.zLogin)<br />
13791392
@ g.isHuman = %d(g.isHuman)<br />
1393
+ @ g.jsHref = %d(g.jsHref)<br />
13801394
if( g.nRequest ){
13811395
@ g.nRequest = %d(g.nRequest)<br />
13821396
}
13831397
if( g.nPendingRequest>1 ){
13841398
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
@@ -1394,10 +1408,11 @@
13941408
#endif
13951409
@ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
13961410
@ fossil_exe_id() = %h(fossil_exe_id())<br />
13971411
@ <hr />
13981412
P("HTTP_USER_AGENT");
1413
+ P("SERVER_SOFTWARE");
13991414
cgi_print_all(showAll, 0);
14001415
if( showAll && blob_size(&g.httpHeader)>0 ){
14011416
@ <hr />
14021417
@ <pre>
14031418
@ %h(blob_str(&g.httpHeader))
14041419
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.javascriptHyperlink
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115 ** ---------------- --------------------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a id="ID">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.javascriptHyperlink is false.
123 ** If g.javascriptHyperlink is true then the id="ID" form is used and
124 ** javascript is generated in the footer to cause href values to be
125 ** inserted after the page has loaded. The use of the id="ID" form
 
126 ** instead of href="URL" is a defense against bots.
127 **
128 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130 ** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131 ** the g.perm.Hyperlink property will be true even if the user does not
132 ** have the "h" privilege if the "auto-hyperlink" setting is true.
133 **
134 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135 ** ------------ -------------- ---------------- ---------------------
136 ** 0 0 0 0
137 ** 1 0 1 0
138 ** 0 1 1 1
139 ** 1 1 1 0
@@ -142,12 +143,12 @@
142 **
143 ** User has "h" auto-hyperlink Returned anchor format
144 ** ------------ -------------- ----------------------
145 ** 0 0 (empty string)
146 ** 1 0 <a href="URL">
147 ** 0 1 <a id="ID">
148 ** 1 1 (can't happen)
149 **
150 ** The name of these routines are deliberately kept short so that can be
151 ** easily used within @-lines. Example:
152 **
153 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172 va_list ap;
173 if( !g.perm.Hyperlink ) return fossil_strdup("");
174 va_start(ap, zFormat);
175 zUrl = vmprintf(zFormat, ap);
176 va_end(ap);
177 if( !g.javascriptHyperlink ){
178 char *zHUrl;
179 if( zExtra ){
180 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181 }else{
182 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197 va_list ap;
198 if( !g.perm.Hyperlink ) return fossil_strdup("");
199 va_start(ap, zFormat);
200 zUrl = vmprintf(zFormat, ap);
201 va_end(ap);
202 if( !g.javascriptHyperlink ){
203 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204 fossil_free(zUrl);
205 return zHUrl;
206 }
207 needHrefJs = 1;
@@ -213,11 +214,11 @@
213 va_list ap;
214 if( !g.perm.Hyperlink ) return fossil_strdup("");
215 va_start(ap, zFormat);
216 zUrl = vmprintf(zFormat, ap);
217 va_end(ap);
218 if( !g.javascriptHyperlink ){
219 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220 fossil_free(zUrl);
221 return zHUrl;
222 }
223 needHrefJs = 1;
@@ -232,18 +233,18 @@
232 ** As a defense against robots, the action=ARG might instead by data-action=ARG
233 ** and javascript (href.js) added to the page so that the data-action= is
234 ** changed into action= after the page loads. Whether or not this happens
235 ** depends on if the user has the "h" privilege and whether or not the
236 ** auto-hyperlink setting is on. These setings determine the values of
237 ** variables g.perm.Hyperlink and g.javascriptHyperlink.
238 **
239 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240 ** ------------ -------------- ---------------- ---------------------
241 ** 1: 0 0 0 0
242 ** 2: 1 0 1 0
243 ** 3: 0 1 1 1
244 ** 4: 1 1 1 0
245 **
246 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247 ** javascript is omitted and so the form is effectively disabled.
248 */
249 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -882,11 +883,12 @@
882 ** Generate code to load all required javascript files.
883 */
884 static void style_load_all_js_files(void){
885 if( needHrefJs && g.perm.Hyperlink ){
886 int nDelay = db_get_int("auto-hyperlink-delay",0);
887 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
 
888 @ <script id='href-data' type='application/json'>\
889 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
890 }
891 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
892 @ function debugMsg(msg){
@@ -1318,12 +1320,23 @@
1318 /*
1319 ** WEBPAGE: honeypot
1320 ** This page is a honeypot for spiders and bots.
1321 */
1322 void honeypot_page(void){
1323 cgi_set_status(403, "Forbidden");
1324 @ <p>Please enable javascript or log in to see this content</p>
 
 
 
 
 
 
 
 
 
 
 
1325 }
1326
1327 /*
1328 ** Webpages that encounter an error due to missing or incorrect
1329 ** query parameters can jump to this routine to render an error
@@ -1375,10 +1388,11 @@
1375 @ g.zTop = %h(g.zTop)<br />
1376 @ g.zPath = %h(g.zPath)<br />
1377 @ g.userUid = %d(g.userUid)<br />
1378 @ g.zLogin = %h(g.zLogin)<br />
1379 @ g.isHuman = %d(g.isHuman)<br />
 
1380 if( g.nRequest ){
1381 @ g.nRequest = %d(g.nRequest)<br />
1382 }
1383 if( g.nPendingRequest>1 ){
1384 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
@@ -1394,10 +1408,11 @@
1394 #endif
1395 @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
1396 @ fossil_exe_id() = %h(fossil_exe_id())<br />
1397 @ <hr />
1398 P("HTTP_USER_AGENT");
 
1399 cgi_print_all(showAll, 0);
1400 if( showAll && blob_size(&g.httpHeader)>0 ){
1401 @ <hr />
1402 @ <pre>
1403 @ %h(blob_str(&g.httpHeader))
1404
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.jsHref
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.jsHref Returned anchor format
115 ** ---------------- -------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a data-href="URL">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.jsHref is false.
123 ** If g.jsHref is true then the data-href="URL" and
124 ** href="/honeypot" is generated and javascript is added to the footer
125 ** to cause data-href values to be inserted into href
126 ** after the page has loaded. The use of the data-href="URL" form
127 ** instead of href="URL" is a defense against bots.
128 **
129 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
130 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
131 ** g.jsHref is set to 1 by login_check_credentials(). Thus
132 ** the g.perm.Hyperlink property will be true even if the user does not
133 ** have the "h" privilege if the "auto-hyperlink" setting is true.
134 **
135 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
136 ** ------------ -------------- ---------------- ---------------------
137 ** 0 0 0 0
138 ** 1 0 1 0
139 ** 0 1 1 1
140 ** 1 1 1 0
@@ -142,12 +143,12 @@
143 **
144 ** User has "h" auto-hyperlink Returned anchor format
145 ** ------------ -------------- ----------------------
146 ** 0 0 (empty string)
147 ** 1 0 <a href="URL">
148 ** 0 1 <a data-href="URL">
149 ** 1 1 <a href="URL">
150 **
151 ** The name of these routines are deliberately kept short so that can be
152 ** easily used within @-lines. Example:
153 **
154 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
173 va_list ap;
174 if( !g.perm.Hyperlink ) return fossil_strdup("");
175 va_start(ap, zFormat);
176 zUrl = vmprintf(zFormat, ap);
177 va_end(ap);
178 if( !g.jsHref ){
179 char *zHUrl;
180 if( zExtra ){
181 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
182 }else{
183 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
198 va_list ap;
199 if( !g.perm.Hyperlink ) return fossil_strdup("");
200 va_start(ap, zFormat);
201 zUrl = vmprintf(zFormat, ap);
202 va_end(ap);
203 if( !g.jsHref ){
204 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
205 fossil_free(zUrl);
206 return zHUrl;
207 }
208 needHrefJs = 1;
@@ -213,11 +214,11 @@
214 va_list ap;
215 if( !g.perm.Hyperlink ) return fossil_strdup("");
216 va_start(ap, zFormat);
217 zUrl = vmprintf(zFormat, ap);
218 va_end(ap);
219 if( !g.jsHref ){
220 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
221 fossil_free(zUrl);
222 return zHUrl;
223 }
224 needHrefJs = 1;
@@ -232,18 +233,18 @@
233 ** As a defense against robots, the action=ARG might instead by data-action=ARG
234 ** and javascript (href.js) added to the page so that the data-action= is
235 ** changed into action= after the page loads. Whether or not this happens
236 ** depends on if the user has the "h" privilege and whether or not the
237 ** auto-hyperlink setting is on. These setings determine the values of
238 ** variables g.perm.Hyperlink and g.jsHref.
239 **
240 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241 ** ------------ -------------- ---------------- --------
242 ** 1: 0 0 0 0
243 ** 2: 1 0 1 0
244 ** 3: 0 1 1 1
245 ** 4: 1 1 1 0
246 **
247 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
248 ** javascript is omitted and so the form is effectively disabled.
249 */
250 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -882,11 +883,12 @@
883 ** Generate code to load all required javascript files.
884 */
885 static void style_load_all_js_files(void){
886 if( needHrefJs && g.perm.Hyperlink ){
887 int nDelay = db_get_int("auto-hyperlink-delay",0);
888 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
889 && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
890 @ <script id='href-data' type='application/json'>\
891 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
892 }
893 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
894 @ function debugMsg(msg){
@@ -1318,12 +1320,23 @@
1320 /*
1321 ** WEBPAGE: honeypot
1322 ** This page is a honeypot for spiders and bots.
1323 */
1324 void honeypot_page(void){
1325 style_header("I think you are a robot");
1326 @ <p>You seem like a robot.</p>
1327 @
1328 @ <p>Is this wrong? Are you really a human? If so, please prove it
1329 @ by <a href="%R/login">logging in</a>.
1330 if( g.anon.Hyperlink ){
1331 @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1332 @ prefer.
1333 }
1334 @ <p>Sorry for the inconvenience. The point of this is to prevent
1335 @ robots from following the countless of hyperlinks in this site and
1336 @ soaking up all the available CPU time and network bandwidth.
1337 style_finish_page();
1338 }
1339
1340 /*
1341 ** Webpages that encounter an error due to missing or incorrect
1342 ** query parameters can jump to this routine to render an error
@@ -1375,10 +1388,11 @@
1388 @ g.zTop = %h(g.zTop)<br />
1389 @ g.zPath = %h(g.zPath)<br />
1390 @ g.userUid = %d(g.userUid)<br />
1391 @ g.zLogin = %h(g.zLogin)<br />
1392 @ g.isHuman = %d(g.isHuman)<br />
1393 @ g.jsHref = %d(g.jsHref)<br />
1394 if( g.nRequest ){
1395 @ g.nRequest = %d(g.nRequest)<br />
1396 }
1397 if( g.nPendingRequest>1 ){
1398 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
@@ -1394,10 +1408,11 @@
1408 #endif
1409 @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
1410 @ fossil_exe_id() = %h(fossil_exe_id())<br />
1411 @ <hr />
1412 P("HTTP_USER_AGENT");
1413 P("SERVER_SOFTWARE");
1414 cgi_print_all(showAll, 0);
1415 if( showAll && blob_size(&g.httpHeader)>0 ){
1416 @ <hr />
1417 @ <pre>
1418 @ %h(blob_str(&g.httpHeader))
1419
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175175
body.chat #load-msg-toolbar > div > button {
176176
flex: 1 1 auto;
177177
}
178178
/* "Chat-only mode" hides the site header/footer, showing only
179179
the chat app. */
180
-body.chat.chat-only-mode{}
180
+body.chat.chat-only-mode{
181
+ padding: 0;
182
+}
181183
body.chat #chat-button-settings {}
182184
/** Popup widget for the /chat settings. */
183185
body.chat .chat-settings-popup {
184186
font-size: 0.8em;
185187
text-align: left;
@@ -271,10 +273,14 @@
271273
display: flex;
272274
flex-direction: row;
273275
align-items: stretch;
274276
flex-wrap: nowrap;
275277
}
278
+body.chat.chat-only-mode #chat-input-line-wrapper {
279
+ padding: 0 0.25em;
280
+}
281
+
276282
/*body.chat #chat-input-line-wrapper:not(.compact) {
277283
flex-wrap: nowrap;
278284
}*/
279285
body.chat #chat-input-line-wrapper.compact {
280286
/* "The problem" with wrapping, together with a contenteditable input
281287
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{}
 
 
181 body.chat #chat-button-settings {}
182 /** Popup widget for the /chat settings. */
183 body.chat .chat-settings-popup {
184 font-size: 0.8em;
185 text-align: left;
@@ -271,10 +273,14 @@
271 display: flex;
272 flex-direction: row;
273 align-items: stretch;
274 flex-wrap: nowrap;
275 }
 
 
 
 
276 /*body.chat #chat-input-line-wrapper:not(.compact) {
277 flex-wrap: nowrap;
278 }*/
279 body.chat #chat-input-line-wrapper.compact {
280 /* "The problem" with wrapping, together with a contenteditable input
281
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{
181 padding: 0;
182 }
183 body.chat #chat-button-settings {}
184 /** Popup widget for the /chat settings. */
185 body.chat .chat-settings-popup {
186 font-size: 0.8em;
187 text-align: left;
@@ -271,10 +273,14 @@
273 display: flex;
274 flex-direction: row;
275 align-items: stretch;
276 flex-wrap: nowrap;
277 }
278 body.chat.chat-only-mode #chat-input-line-wrapper {
279 padding: 0 0.25em;
280 }
281
282 /*body.chat #chat-input-line-wrapper:not(.compact) {
283 flex-wrap: nowrap;
284 }*/
285 body.chat #chat-input-line-wrapper.compact {
286 /* "The problem" with wrapping, together with a contenteditable input
287
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175175
body.chat #load-msg-toolbar > div > button {
176176
flex: 1 1 auto;
177177
}
178178
/* "Chat-only mode" hides the site header/footer, showing only
179179
the chat app. */
180
-body.chat.chat-only-mode{}
180
+body.chat.chat-only-mode{
181
+ padding: 0;
182
+}
181183
body.chat #chat-button-settings {}
182184
/** Popup widget for the /chat settings. */
183185
body.chat .chat-settings-popup {
184186
font-size: 0.8em;
185187
text-align: left;
@@ -271,10 +273,14 @@
271273
display: flex;
272274
flex-direction: row;
273275
align-items: stretch;
274276
flex-wrap: nowrap;
275277
}
278
+body.chat.chat-only-mode #chat-input-line-wrapper {
279
+ padding: 0 0.25em;
280
+}
281
+
276282
/*body.chat #chat-input-line-wrapper:not(.compact) {
277283
flex-wrap: nowrap;
278284
}*/
279285
body.chat #chat-input-line-wrapper.compact {
280286
/* "The problem" with wrapping, together with a contenteditable input
281287
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{}
 
 
181 body.chat #chat-button-settings {}
182 /** Popup widget for the /chat settings. */
183 body.chat .chat-settings-popup {
184 font-size: 0.8em;
185 text-align: left;
@@ -271,10 +273,14 @@
271 display: flex;
272 flex-direction: row;
273 align-items: stretch;
274 flex-wrap: nowrap;
275 }
 
 
 
 
276 /*body.chat #chat-input-line-wrapper:not(.compact) {
277 flex-wrap: nowrap;
278 }*/
279 body.chat #chat-input-line-wrapper.compact {
280 /* "The problem" with wrapping, together with a contenteditable input
281
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{
181 padding: 0;
182 }
183 body.chat #chat-button-settings {}
184 /** Popup widget for the /chat settings. */
185 body.chat .chat-settings-popup {
186 font-size: 0.8em;
187 text-align: left;
@@ -271,10 +273,14 @@
273 display: flex;
274 flex-direction: row;
275 align-items: stretch;
276 flex-wrap: nowrap;
277 }
278 body.chat.chat-only-mode #chat-input-line-wrapper {
279 padding: 0 0.25em;
280 }
281
282 /*body.chat #chat-input-line-wrapper:not(.compact) {
283 flex-wrap: nowrap;
284 }*/
285 body.chat #chat-input-line-wrapper.compact {
286 /* "The problem" with wrapping, together with a contenteditable input
287
+38 -31
--- src/sync.c
+++ src/sync.c
@@ -232,10 +232,13 @@
232232
*pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233233
}
234234
if( find_option("all",0,0)!=0 ){
235235
*pSyncFlags |= SYNC_ALLURL;
236236
}
237
+
238
+ /* Undocumented option to cause links transitive links to other
239
+ ** repositories to be shared */
237240
if( ((*pSyncFlags) & SYNC_PULL)!=0
238241
&& find_option("share-links",0,0)!=0
239242
){
240243
*pSyncFlags |= SYNC_SHARE_LINKS;
241244
}
@@ -319,11 +322,10 @@
319322
** --once Do not remember URL for subsequent syncs
320323
** --private Pull private branches too
321324
** --project-code CODE Use CODE as the project code
322325
** --proxy PROXY Use the specified HTTP proxy
323326
** -R|--repository REPO Local repository to pull into
324
-** --share-links Share links to mirror repos
325327
** --ssl-identity FILE Local SSL credentials, if requested by remote
326328
** --ssh-command SSH Use SSH as the "ssh" command
327329
** --transport-command CMD Use external command CMD to move messages
328330
** between client and server
329331
** -v|--verbose Additional (debugging) output
@@ -422,11 +424,10 @@
422424
** --no-http-compression Do not compress HTTP traffic
423425
** --once Do not remember URL for subsequent syncs
424426
** --proxy PROXY Use the specified HTTP proxy
425427
** --private Sync private branches too
426428
** -R|--repository REPO Local repository to sync with
427
-** --share-links Share links to mirror repos
428429
** --ssl-identity FILE Local SSL credentials, if requested by remote
429430
** --ssh-command SSH Use SSH as the "ssh" command
430431
** --transport-command CMD Use external command CMD to move message
431432
** between the client and the server
432433
** -u|--unversioned Also sync unversioned content
@@ -470,55 +471,55 @@
470471
** COMMAND: remote
471472
** COMMAND: remote-url*
472473
**
473474
** Usage: %fossil remote ?SUBCOMMAND ...?
474475
**
475
-** View or modify the set of remote repository sync URLs used as the
476
-** target in any command that uses the sync protocol: "sync", "push",
477
-** and "pull", plus all other commands that trigger Fossil's autosync
478
-** feature. (Collectively, "sync operations".)
479
-**
480
-** See "fossil help clone" for the format of these sync URLs.
481
-**
482
-** Fossil implicitly sets the default remote sync URL from the initial
483
-** "clone" or "open URL" command for a repository, then may subsequently
484
-** change it when given a URL in commands that take a sync URL, except
485
-** when given the --once flag. Fossil uses this new sync URL as its
486
-** default when not explicitly given one in subsequent sync operations.
487
-**
488
-** Named remotes added by "remote add" allow use of those names in place
489
-** of a sync URL in any command that takes one.
490
-**
491
-** The full name of this command is "remote-url", but we anticipate no
492
-** future collision from use of its shortened form "remote".
476
+** View or modify the URLs of remote repositories used for syncing.
477
+** The "default" remote is the URL used in the most recent "sync",
478
+** "push", "pull", "clone", or similar command. The default remote can
479
+** change with each sync command. Other named remotes are persistent.
493480
**
494481
** > fossil remote
495482
**
496483
** With no arguments, this command shows the current default remote
497484
** URL. If there is no default, it shows "off".
498485
**
499486
** > fossil remote add NAME URL
500487
**
501
-** Add a new named URL to the set of remote sync URLs for use in
502
-** place of a sync URL in commands that take one.
488
+** Add a new named URL. Afterwards, NAME can be used as a short
489
+** symbolic name for URL in contexts where a URL is required. The
490
+** URL argument can be "default" or a prior symbolic name, to make
491
+** a copy of an existing URL under a new name.
492
+**
493
+** > fossil remote config-data
494
+**
495
+** DEBUG USE ONLY - Show the name and value of every CONFIG table
496
+** entry in the repository that is associated with the remote URL store.
497
+** Passwords are obscured in the output.
503498
**
504499
** > fossil remote delete NAME
505500
**
506
-** Delete a sync URL previously added by the "add" subcommand.
501
+** Delete a named URL previously created by the "add" subcommand.
507502
**
508503
** > fossil remote list|ls
509504
**
510
-** Show all remote repository sync URLs.
505
+** Show all remote repository URLs.
511506
**
512507
** > fossil remote off
513508
**
514
-** Forget the default sync URL, disabling autosync. Combined with
515
-** named sync URLs, it allows canceling this "airplane mode" with
516
-** "fossil remote NAME" to select a previously-set named URL.
509
+** Forget the default URL. This disables autosync.
510
+**
511
+** This is a convenient way to enter "airplane mode". To enter
512
+** airplane mode, first save the current default URL, then turn the
513
+** default off. Perhaps like this:
514
+**
515
+** fossil remote add main default
516
+** fossil remote off
517
+**
518
+** To exit airplane mode and turn autosync back on again:
517519
**
518
-** To disable use of the default remote without forgetting its URL,
519
-** say "fossil set autosync 0" instead.
520
+** fossil remote main
520521
**
521522
** > fossil remote scrub
522523
**
523524
** Forget any saved passwords for remote repositories, but continue
524525
** to remember the URLs themselves. You will be prompted for the
@@ -607,12 +608,17 @@
607608
if( g.argc!=5 ) usage("add NAME URL");
608609
memset(&x, 0, sizeof(x));
609610
zName = g.argv[3];
610611
zUrl = g.argv[4];
611612
if( strcmp(zName,"default")==0 ) goto remote_add_default;
612
- url_parse_local(zUrl, URL_PROMPT_PW, &x);
613613
db_begin_write();
614
+ if( fossil_strcmp(zUrl,"default")==0 ){
615
+ x.canonical = db_get("last-sync-url",0);
616
+ x.passwd = unobscure(db_get("last-sync-pw",0));
617
+ }else{
618
+ url_parse_local(zUrl, URL_PROMPT_PW|URL_USE_CONFIG, &x);
619
+ }
614620
db_unprotect(PROTECT_CONFIG);
615621
db_multi_exec(
616622
"REPLACE INTO config(name, value, mtime)"
617623
" VALUES('sync-url:%q',%Q,now())",
618624
zName, x.canonical
@@ -685,11 +691,12 @@
685691
|| db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
686692
){
687693
remote_add_default:
688694
db_unset("last-sync-url", 0);
689695
db_unset("last-sync-pw", 0);
690
- url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
696
+ url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|
697
+ URL_USE_CONFIG|URL_ASK_REMEMBER_PW);
691698
url_remember();
692699
return;
693700
}
694701
fossil_fatal("unknown command \"%s\" - should be a URL or one of: "
695702
"add delete list off", zArg);
696703
--- src/sync.c
+++ src/sync.c
@@ -232,10 +232,13 @@
232 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233 }
234 if( find_option("all",0,0)!=0 ){
235 *pSyncFlags |= SYNC_ALLURL;
236 }
 
 
 
237 if( ((*pSyncFlags) & SYNC_PULL)!=0
238 && find_option("share-links",0,0)!=0
239 ){
240 *pSyncFlags |= SYNC_SHARE_LINKS;
241 }
@@ -319,11 +322,10 @@
319 ** --once Do not remember URL for subsequent syncs
320 ** --private Pull private branches too
321 ** --project-code CODE Use CODE as the project code
322 ** --proxy PROXY Use the specified HTTP proxy
323 ** -R|--repository REPO Local repository to pull into
324 ** --share-links Share links to mirror repos
325 ** --ssl-identity FILE Local SSL credentials, if requested by remote
326 ** --ssh-command SSH Use SSH as the "ssh" command
327 ** --transport-command CMD Use external command CMD to move messages
328 ** between client and server
329 ** -v|--verbose Additional (debugging) output
@@ -422,11 +424,10 @@
422 ** --no-http-compression Do not compress HTTP traffic
423 ** --once Do not remember URL for subsequent syncs
424 ** --proxy PROXY Use the specified HTTP proxy
425 ** --private Sync private branches too
426 ** -R|--repository REPO Local repository to sync with
427 ** --share-links Share links to mirror repos
428 ** --ssl-identity FILE Local SSL credentials, if requested by remote
429 ** --ssh-command SSH Use SSH as the "ssh" command
430 ** --transport-command CMD Use external command CMD to move message
431 ** between the client and the server
432 ** -u|--unversioned Also sync unversioned content
@@ -470,55 +471,55 @@
470 ** COMMAND: remote
471 ** COMMAND: remote-url*
472 **
473 ** Usage: %fossil remote ?SUBCOMMAND ...?
474 **
475 ** View or modify the set of remote repository sync URLs used as the
476 ** target in any command that uses the sync protocol: "sync", "push",
477 ** and "pull", plus all other commands that trigger Fossil's autosync
478 ** feature. (Collectively, "sync operations".)
479 **
480 ** See "fossil help clone" for the format of these sync URLs.
481 **
482 ** Fossil implicitly sets the default remote sync URL from the initial
483 ** "clone" or "open URL" command for a repository, then may subsequently
484 ** change it when given a URL in commands that take a sync URL, except
485 ** when given the --once flag. Fossil uses this new sync URL as its
486 ** default when not explicitly given one in subsequent sync operations.
487 **
488 ** Named remotes added by "remote add" allow use of those names in place
489 ** of a sync URL in any command that takes one.
490 **
491 ** The full name of this command is "remote-url", but we anticipate no
492 ** future collision from use of its shortened form "remote".
493 **
494 ** > fossil remote
495 **
496 ** With no arguments, this command shows the current default remote
497 ** URL. If there is no default, it shows "off".
498 **
499 ** > fossil remote add NAME URL
500 **
501 ** Add a new named URL to the set of remote sync URLs for use in
502 ** place of a sync URL in commands that take one.
 
 
 
 
 
 
 
 
503 **
504 ** > fossil remote delete NAME
505 **
506 ** Delete a sync URL previously added by the "add" subcommand.
507 **
508 ** > fossil remote list|ls
509 **
510 ** Show all remote repository sync URLs.
511 **
512 ** > fossil remote off
513 **
514 ** Forget the default sync URL, disabling autosync. Combined with
515 ** named sync URLs, it allows canceling this "airplane mode" with
516 ** "fossil remote NAME" to select a previously-set named URL.
 
 
 
 
 
 
 
517 **
518 ** To disable use of the default remote without forgetting its URL,
519 ** say "fossil set autosync 0" instead.
520 **
521 ** > fossil remote scrub
522 **
523 ** Forget any saved passwords for remote repositories, but continue
524 ** to remember the URLs themselves. You will be prompted for the
@@ -607,12 +608,17 @@
607 if( g.argc!=5 ) usage("add NAME URL");
608 memset(&x, 0, sizeof(x));
609 zName = g.argv[3];
610 zUrl = g.argv[4];
611 if( strcmp(zName,"default")==0 ) goto remote_add_default;
612 url_parse_local(zUrl, URL_PROMPT_PW, &x);
613 db_begin_write();
 
 
 
 
 
 
614 db_unprotect(PROTECT_CONFIG);
615 db_multi_exec(
616 "REPLACE INTO config(name, value, mtime)"
617 " VALUES('sync-url:%q',%Q,now())",
618 zName, x.canonical
@@ -685,11 +691,12 @@
685 || db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
686 ){
687 remote_add_default:
688 db_unset("last-sync-url", 0);
689 db_unset("last-sync-pw", 0);
690 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
 
691 url_remember();
692 return;
693 }
694 fossil_fatal("unknown command \"%s\" - should be a URL or one of: "
695 "add delete list off", zArg);
696
--- src/sync.c
+++ src/sync.c
@@ -232,10 +232,13 @@
232 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233 }
234 if( find_option("all",0,0)!=0 ){
235 *pSyncFlags |= SYNC_ALLURL;
236 }
237
238 /* Undocumented option to cause links transitive links to other
239 ** repositories to be shared */
240 if( ((*pSyncFlags) & SYNC_PULL)!=0
241 && find_option("share-links",0,0)!=0
242 ){
243 *pSyncFlags |= SYNC_SHARE_LINKS;
244 }
@@ -319,11 +322,10 @@
322 ** --once Do not remember URL for subsequent syncs
323 ** --private Pull private branches too
324 ** --project-code CODE Use CODE as the project code
325 ** --proxy PROXY Use the specified HTTP proxy
326 ** -R|--repository REPO Local repository to pull into
 
327 ** --ssl-identity FILE Local SSL credentials, if requested by remote
328 ** --ssh-command SSH Use SSH as the "ssh" command
329 ** --transport-command CMD Use external command CMD to move messages
330 ** between client and server
331 ** -v|--verbose Additional (debugging) output
@@ -422,11 +424,10 @@
424 ** --no-http-compression Do not compress HTTP traffic
425 ** --once Do not remember URL for subsequent syncs
426 ** --proxy PROXY Use the specified HTTP proxy
427 ** --private Sync private branches too
428 ** -R|--repository REPO Local repository to sync with
 
429 ** --ssl-identity FILE Local SSL credentials, if requested by remote
430 ** --ssh-command SSH Use SSH as the "ssh" command
431 ** --transport-command CMD Use external command CMD to move message
432 ** between the client and the server
433 ** -u|--unversioned Also sync unversioned content
@@ -470,55 +471,55 @@
471 ** COMMAND: remote
472 ** COMMAND: remote-url*
473 **
474 ** Usage: %fossil remote ?SUBCOMMAND ...?
475 **
476 ** View or modify the URLs of remote repositories used for syncing.
477 ** The "default" remote is the URL used in the most recent "sync",
478 ** "push", "pull", "clone", or similar command. The default remote can
479 ** change with each sync command. Other named remotes are persistent.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480 **
481 ** > fossil remote
482 **
483 ** With no arguments, this command shows the current default remote
484 ** URL. If there is no default, it shows "off".
485 **
486 ** > fossil remote add NAME URL
487 **
488 ** Add a new named URL. Afterwards, NAME can be used as a short
489 ** symbolic name for URL in contexts where a URL is required. The
490 ** URL argument can be "default" or a prior symbolic name, to make
491 ** a copy of an existing URL under a new name.
492 **
493 ** > fossil remote config-data
494 **
495 ** DEBUG USE ONLY - Show the name and value of every CONFIG table
496 ** entry in the repository that is associated with the remote URL store.
497 ** Passwords are obscured in the output.
498 **
499 ** > fossil remote delete NAME
500 **
501 ** Delete a named URL previously created by the "add" subcommand.
502 **
503 ** > fossil remote list|ls
504 **
505 ** Show all remote repository URLs.
506 **
507 ** > fossil remote off
508 **
509 ** Forget the default URL. This disables autosync.
510 **
511 ** This is a convenient way to enter "airplane mode". To enter
512 ** airplane mode, first save the current default URL, then turn the
513 ** default off. Perhaps like this:
514 **
515 ** fossil remote add main default
516 ** fossil remote off
517 **
518 ** To exit airplane mode and turn autosync back on again:
519 **
520 ** fossil remote main
 
521 **
522 ** > fossil remote scrub
523 **
524 ** Forget any saved passwords for remote repositories, but continue
525 ** to remember the URLs themselves. You will be prompted for the
@@ -607,12 +608,17 @@
608 if( g.argc!=5 ) usage("add NAME URL");
609 memset(&x, 0, sizeof(x));
610 zName = g.argv[3];
611 zUrl = g.argv[4];
612 if( strcmp(zName,"default")==0 ) goto remote_add_default;
 
613 db_begin_write();
614 if( fossil_strcmp(zUrl,"default")==0 ){
615 x.canonical = db_get("last-sync-url",0);
616 x.passwd = unobscure(db_get("last-sync-pw",0));
617 }else{
618 url_parse_local(zUrl, URL_PROMPT_PW|URL_USE_CONFIG, &x);
619 }
620 db_unprotect(PROTECT_CONFIG);
621 db_multi_exec(
622 "REPLACE INTO config(name, value, mtime)"
623 " VALUES('sync-url:%q',%Q,now())",
624 zName, x.canonical
@@ -685,11 +691,12 @@
691 || db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
692 ){
693 remote_add_default:
694 db_unset("last-sync-url", 0);
695 db_unset("last-sync-pw", 0);
696 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|
697 URL_USE_CONFIG|URL_ASK_REMEMBER_PW);
698 url_remember();
699 return;
700 }
701 fossil_fatal("unknown command \"%s\" - should be a URL or one of: "
702 "add delete list off", zArg);
703
+1 -2
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496496
nPrefix = blob_size(&filename);
497497
498498
pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499499
if( pManifest ){
500500
int flg, eflg = 0;
501
- mTime = (pManifest->rDate - 2440587.5)*86400.0;
501
+ mTime = (unsigned)((pManifest->rDate - 2440587.5)*86400.0);
502502
if( pTar ) tar_begin(mTime);
503503
flg = db_get_manifest_setting();
504504
if( flg ){
505505
/* eflg is the effective flags, taking include/exclude into account */
506506
if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -523,11 +523,10 @@
523523
if( eflg & MFESTFLG_RAW ){
524524
blob_append(&filename, "manifest", -1);
525525
zName = blob_str(&filename);
526526
if( listFlag ) fossil_print("%s\n", zName);
527527
if( pTar ){
528
- sterilize_manifest(&mfile, CFTYPE_MANIFEST);
529528
tar_add_file(zName, &mfile, 0, mTime);
530529
}
531530
}
532531
}
533532
blob_reset(&mfile);
534533
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496 nPrefix = blob_size(&filename);
497
498 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499 if( pManifest ){
500 int flg, eflg = 0;
501 mTime = (pManifest->rDate - 2440587.5)*86400.0;
502 if( pTar ) tar_begin(mTime);
503 flg = db_get_manifest_setting();
504 if( flg ){
505 /* eflg is the effective flags, taking include/exclude into account */
506 if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -523,11 +523,10 @@
523 if( eflg & MFESTFLG_RAW ){
524 blob_append(&filename, "manifest", -1);
525 zName = blob_str(&filename);
526 if( listFlag ) fossil_print("%s\n", zName);
527 if( pTar ){
528 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
529 tar_add_file(zName, &mfile, 0, mTime);
530 }
531 }
532 }
533 blob_reset(&mfile);
534
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496 nPrefix = blob_size(&filename);
497
498 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499 if( pManifest ){
500 int flg, eflg = 0;
501 mTime = (unsigned)((pManifest->rDate - 2440587.5)*86400.0);
502 if( pTar ) tar_begin(mTime);
503 flg = db_get_manifest_setting();
504 if( flg ){
505 /* eflg is the effective flags, taking include/exclude into account */
506 if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -523,11 +523,10 @@
523 if( eflg & MFESTFLG_RAW ){
524 blob_append(&filename, "manifest", -1);
525 zName = blob_str(&filename);
526 if( listFlag ) fossil_print("%s\n", zName);
527 if( pTar ){
 
528 tar_add_file(zName, &mfile, 0, mTime);
529 }
530 }
531 }
532 blob_reset(&mfile);
533
+5 -6
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911911
** Only exists if "mo" exists.
912912
** cu: Extend the mu merge arrow up to this row as a cherrypick
913913
** merge line, if this value exists.
914914
** u: Draw a thick child-line out of the top of this node and up to
915915
** the node with an id equal to this value. 0 if it is straight to
916
- ** the top of the page or just up a little wasy, -1 if there is
916
+ ** the top of the page or just up a little ways, -1 if there is
917917
** no thick-line riser (if the node is a leaf).
918918
** sb: Draw a dotted child-line out of the top of this node up to the
919919
** node with the id equal to the value. This is like "u" except
920920
** that the line is dotted instead of solid and has no arrow.
921921
** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925925
** is the rail on which the riser should run and the second integer
926926
** is the id of the node upto which the riser should run. If there
927927
** are no risers, this array does not exist.
928928
** mi: "merge-in". An array of integer rail positions from which
929929
** merge arrows should be drawn into this node. If the value is
930
- ** negative, then the rail position is the absolute value of mi[]
931
- ** and a thin merge-arrow descender is drawn to the bottom of
932
- ** the screen. This array is omitted if there are no inbound
933
- ** merges.
930
+ ** negative, then the rail position is -1-mi[] and a thin merge-arrow
931
+ ** descender is drawn to the bottom of the screen. This array is
932
+ ** omitted if there are no inbound merges.
934933
** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
935934
** omitted if there are no cherrypick merges.
936935
** h: The artifact hash of the object being graphed
937936
* br: The branch to which the artifact belongs
938937
*/
@@ -981,11 +980,11 @@
981980
}
982981
/* mi */
983982
for(i=k=0; i<GR_MAX_RAIL; i++){
984983
if( pRow->mergeIn[i]==1 ){
985984
int mi = aiMap[i];
986
- if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
985
+ if( (pRow->mergeDown >> i) & 1 ) mi = -1-mi;
987986
if( k==0 ){
988987
cgi_printf("\"mi\":");
989988
cSep = '[';
990989
}
991990
k++;
992991
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911 ** Only exists if "mo" exists.
912 ** cu: Extend the mu merge arrow up to this row as a cherrypick
913 ** merge line, if this value exists.
914 ** u: Draw a thick child-line out of the top of this node and up to
915 ** the node with an id equal to this value. 0 if it is straight to
916 ** the top of the page or just up a little wasy, -1 if there is
917 ** no thick-line riser (if the node is a leaf).
918 ** sb: Draw a dotted child-line out of the top of this node up to the
919 ** node with the id equal to the value. This is like "u" except
920 ** that the line is dotted instead of solid and has no arrow.
921 ** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925 ** is the rail on which the riser should run and the second integer
926 ** is the id of the node upto which the riser should run. If there
927 ** are no risers, this array does not exist.
928 ** mi: "merge-in". An array of integer rail positions from which
929 ** merge arrows should be drawn into this node. If the value is
930 ** negative, then the rail position is the absolute value of mi[]
931 ** and a thin merge-arrow descender is drawn to the bottom of
932 ** the screen. This array is omitted if there are no inbound
933 ** merges.
934 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
935 ** omitted if there are no cherrypick merges.
936 ** h: The artifact hash of the object being graphed
937 * br: The branch to which the artifact belongs
938 */
@@ -981,11 +980,11 @@
981 }
982 /* mi */
983 for(i=k=0; i<GR_MAX_RAIL; i++){
984 if( pRow->mergeIn[i]==1 ){
985 int mi = aiMap[i];
986 if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
987 if( k==0 ){
988 cgi_printf("\"mi\":");
989 cSep = '[';
990 }
991 k++;
992
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911 ** Only exists if "mo" exists.
912 ** cu: Extend the mu merge arrow up to this row as a cherrypick
913 ** merge line, if this value exists.
914 ** u: Draw a thick child-line out of the top of this node and up to
915 ** the node with an id equal to this value. 0 if it is straight to
916 ** the top of the page or just up a little ways, -1 if there is
917 ** no thick-line riser (if the node is a leaf).
918 ** sb: Draw a dotted child-line out of the top of this node up to the
919 ** node with the id equal to the value. This is like "u" except
920 ** that the line is dotted instead of solid and has no arrow.
921 ** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925 ** is the rail on which the riser should run and the second integer
926 ** is the id of the node upto which the riser should run. If there
927 ** are no risers, this array does not exist.
928 ** mi: "merge-in". An array of integer rail positions from which
929 ** merge arrows should be drawn into this node. If the value is
930 ** negative, then the rail position is -1-mi[] and a thin merge-arrow
931 ** descender is drawn to the bottom of the screen. This array is
932 ** omitted if there are no inbound merges.
 
933 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
934 ** omitted if there are no cherrypick merges.
935 ** h: The artifact hash of the object being graphed
936 * br: The branch to which the artifact belongs
937 */
@@ -981,11 +980,11 @@
980 }
981 /* mi */
982 for(i=k=0; i<GR_MAX_RAIL; i++){
983 if( pRow->mergeIn[i]==1 ){
984 int mi = aiMap[i];
985 if( (pRow->mergeDown >> i) & 1 ) mi = -1-mi;
986 if( k==0 ){
987 cgi_printf("\"mi\":");
988 cSep = '[';
989 }
990 k++;
991
--- src/update.c
+++ src/update.c
@@ -561,10 +561,13 @@
561561
fossil_print("%.79c\n",'-');
562562
if( nUpdate==0 ){
563563
show_common_info(tid, "checkout:", 1, 0);
564564
fossil_print("%-13s None. Already up-to-date\n", "changes:");
565565
}else{
566
+ fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
567
+ db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
568
+ " WHERE objid=%d", vid));
566569
show_common_info(tid, "updated-to:", 1, 0);
567570
fossil_print("%-13s %d file%s modified.\n", "changes:",
568571
nUpdate, nUpdate>1 ? "s" : "");
569572
}
570573
571574
--- src/update.c
+++ src/update.c
@@ -561,10 +561,13 @@
561 fossil_print("%.79c\n",'-');
562 if( nUpdate==0 ){
563 show_common_info(tid, "checkout:", 1, 0);
564 fossil_print("%-13s None. Already up-to-date\n", "changes:");
565 }else{
 
 
 
566 show_common_info(tid, "updated-to:", 1, 0);
567 fossil_print("%-13s %d file%s modified.\n", "changes:",
568 nUpdate, nUpdate>1 ? "s" : "");
569 }
570
571
--- src/update.c
+++ src/update.c
@@ -561,10 +561,13 @@
561 fossil_print("%.79c\n",'-');
562 if( nUpdate==0 ){
563 show_common_info(tid, "checkout:", 1, 0);
564 fossil_print("%-13s None. Already up-to-date\n", "changes:");
565 }else{
566 fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
567 db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
568 " WHERE objid=%d", vid));
569 show_common_info(tid, "updated-to:", 1, 0);
570 fossil_print("%-13s %d file%s modified.\n", "changes:",
571 nUpdate, nUpdate>1 ? "s" : "");
572 }
573
574
+17 -8
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363363
#endif
364364
}
365365
while( amt<szHdr ){
366366
if( sslConn ){
367367
#ifdef FOSSIL_ENABLE_SSL
368
- got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
368
+ got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369369
#endif
370370
}else{
371
- got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
371
+ got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372372
if( got==SOCKET_ERROR ) goto end_request;
373373
}
374374
if( got==0 ){
375375
wanted = 0;
376376
break;
@@ -394,11 +394,11 @@
394394
if( out==0 ) goto end_request;
395395
fwrite(zBuf, 1, amt, out);
396396
while( wanted>0 ){
397397
if( sslConn ){
398398
#ifdef FOSSIL_ENABLE_SSL
399
- got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
399
+ got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400400
#endif
401401
}else{
402402
got = recv(p->s, zBuf, sizeof(zBuf), 0);
403403
if( got==SOCKET_ERROR ) goto end_request;
404404
}
@@ -437,10 +437,13 @@
437437
g.httpUseSSL ? "" : " --nossl", p->zOptions
438438
);
439439
in = fossil_fopen(zReplyFName, "w+b");
440440
fflush(out);
441441
fflush(aux);
442
+ if( g.fHttpTrace ){
443
+ fossil_print("%s\n", zCmd);
444
+ }
442445
fossil_system(zCmd);
443446
if( in ){
444447
while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445448
if( sslConn ){
446449
#ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
465468
if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
466469
closesocket(p->s);
467470
/* Make multiple attempts to delete the temporary files. Sometimes AV
468471
** software keeps the files open for a few seconds, preventing the file
469472
** from being deleted on the first try. */
470
- for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
471
- for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
472
- for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
473
+ if( !g.fHttpTrace ){
474
+ for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
475
+ for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
476
+ for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
477
+ }
473478
fossil_free(p);
474479
}
475480
476481
/*
477482
** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
652657
}
653658
}
654659
if( !GetTempPathW(MAX_PATH, zTmpPath) ){
655660
fossil_panic("unable to get path to the temporary directory.");
656661
}
657
- zTempPrefix = mprintf("%sfossil_server_P%d",
658
- fossil_unicode_to_utf8(zTmpPath), iPort);
662
+ if( g.fHttpTrace ){
663
+ zTempPrefix = mprintf("httptrace");
664
+ }else{
665
+ zTempPrefix = mprintf("%sfossil_server_P%d",
666
+ fossil_unicode_to_utf8(zTmpPath), iPort);
667
+ }
659668
fossil_print("Temporary files: %s*\n", zTempPrefix);
660669
fossil_print("Listening for %s requests on TCP port %d\n",
661670
(flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662671
g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
663672
if( zBrowser ){
664673
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
374 if( got==0 ){
375 wanted = 0;
376 break;
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
@@ -437,10 +437,13 @@
437 g.httpUseSSL ? "" : " --nossl", p->zOptions
438 );
439 in = fossil_fopen(zReplyFName, "w+b");
440 fflush(out);
441 fflush(aux);
 
 
 
442 fossil_system(zCmd);
443 if( in ){
444 while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445 if( sslConn ){
446 #ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
465 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
466 closesocket(p->s);
467 /* Make multiple attempts to delete the temporary files. Sometimes AV
468 ** software keeps the files open for a few seconds, preventing the file
469 ** from being deleted on the first try. */
470 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
471 for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
472 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
 
 
473 fossil_free(p);
474 }
475
476 /*
477 ** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
652 }
653 }
654 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
655 fossil_panic("unable to get path to the temporary directory.");
656 }
657 zTempPrefix = mprintf("%sfossil_server_P%d",
658 fossil_unicode_to_utf8(zTmpPath), iPort);
 
 
 
 
659 fossil_print("Temporary files: %s*\n", zTempPrefix);
660 fossil_print("Listening for %s requests on TCP port %d\n",
661 (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662 g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
663 if( zBrowser ){
664
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
374 if( got==0 ){
375 wanted = 0;
376 break;
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
@@ -437,10 +437,13 @@
437 g.httpUseSSL ? "" : " --nossl", p->zOptions
438 );
439 in = fossil_fopen(zReplyFName, "w+b");
440 fflush(out);
441 fflush(aux);
442 if( g.fHttpTrace ){
443 fossil_print("%s\n", zCmd);
444 }
445 fossil_system(zCmd);
446 if( in ){
447 while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
448 if( sslConn ){
449 #ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
468 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
469 closesocket(p->s);
470 /* Make multiple attempts to delete the temporary files. Sometimes AV
471 ** software keeps the files open for a few seconds, preventing the file
472 ** from being deleted on the first try. */
473 if( !g.fHttpTrace ){
474 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
475 for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
476 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
477 }
478 fossil_free(p);
479 }
480
481 /*
482 ** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
657 }
658 }
659 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
660 fossil_panic("unable to get path to the temporary directory.");
661 }
662 if( g.fHttpTrace ){
663 zTempPrefix = mprintf("httptrace");
664 }else{
665 zTempPrefix = mprintf("%sfossil_server_P%d",
666 fossil_unicode_to_utf8(zTmpPath), iPort);
667 }
668 fossil_print("Temporary files: %s*\n", zTempPrefix);
669 fossil_print("Listening for %s requests on TCP port %d\n",
670 (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
671 g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
672 if( zBrowser ){
673
+2 -2
--- src/xfer.c
+++ src/xfer.c
@@ -2064,15 +2064,15 @@
20642064
** do not really need to be sent.
20652065
*/
20662066
if( (syncFlags & (SYNC_UNVERSIONED|SYNC_CLONE))!=0 ){
20672067
unversioned_schema();
20682068
db_multi_exec(
2069
- "CREATE TEMP TABLE uv_tosend("
2069
+ "CREATE TEMP TABLE IF NOT EXISTS uv_tosend("
20702070
" name TEXT PRIMARY KEY," /* Name of file to send client->server */
20712071
" mtimeOnly BOOLEAN" /* True to only send mtime, not content */
20722072
") WITHOUT ROWID;"
2073
- "INSERT INTO uv_toSend(name,mtimeOnly)"
2073
+ "REPLACE INTO uv_toSend(name,mtimeOnly)"
20742074
" SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
20752075
);
20762076
}
20772077
20782078
/*
20792079
--- src/xfer.c
+++ src/xfer.c
@@ -2064,15 +2064,15 @@
2064 ** do not really need to be sent.
2065 */
2066 if( (syncFlags & (SYNC_UNVERSIONED|SYNC_CLONE))!=0 ){
2067 unversioned_schema();
2068 db_multi_exec(
2069 "CREATE TEMP TABLE uv_tosend("
2070 " name TEXT PRIMARY KEY," /* Name of file to send client->server */
2071 " mtimeOnly BOOLEAN" /* True to only send mtime, not content */
2072 ") WITHOUT ROWID;"
2073 "INSERT INTO uv_toSend(name,mtimeOnly)"
2074 " SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
2075 );
2076 }
2077
2078 /*
2079
--- src/xfer.c
+++ src/xfer.c
@@ -2064,15 +2064,15 @@
2064 ** do not really need to be sent.
2065 */
2066 if( (syncFlags & (SYNC_UNVERSIONED|SYNC_CLONE))!=0 ){
2067 unversioned_schema();
2068 db_multi_exec(
2069 "CREATE TEMP TABLE IF NOT EXISTS uv_tosend("
2070 " name TEXT PRIMARY KEY," /* Name of file to send client->server */
2071 " mtimeOnly BOOLEAN" /* True to only send mtime, not content */
2072 ") WITHOUT ROWID;"
2073 "REPLACE INTO uv_toSend(name,mtimeOnly)"
2074 " SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
2075 );
2076 }
2077
2078 /*
2079
+1 -2
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236236
*/
237237
void zip_set_timedate(double rDate){
238238
char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239239
zip_set_timedate_from_str(zDate);
240240
fossil_free(zDate);
241
- unixTime = (rDate - 2440587.5)*86400.0;
241
+ unixTime = (int)((rDate - 2440587.5)*86400.0);
242242
}
243243
244244
/*
245245
** Append a single file to a growing ZIP archive.
246246
**
@@ -677,11 +677,10 @@
677677
blob_append(&filename, "manifest", -1);
678678
zName = blob_str(&filename);
679679
if( listFlag ) fossil_print("%s\n", zName);
680680
if( pZip ){
681681
zip_add_folders(&sArchive, zName);
682
- sterilize_manifest(&mfile, CFTYPE_MANIFEST);
683682
zip_add_file(&sArchive, zName, &mfile, 0);
684683
}
685684
}
686685
if( eflg & MFESTFLG_UUID ){
687686
blob_append(&hash, "\n", 1);
688687
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236 */
237 void zip_set_timedate(double rDate){
238 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239 zip_set_timedate_from_str(zDate);
240 fossil_free(zDate);
241 unixTime = (rDate - 2440587.5)*86400.0;
242 }
243
244 /*
245 ** Append a single file to a growing ZIP archive.
246 **
@@ -677,11 +677,10 @@
677 blob_append(&filename, "manifest", -1);
678 zName = blob_str(&filename);
679 if( listFlag ) fossil_print("%s\n", zName);
680 if( pZip ){
681 zip_add_folders(&sArchive, zName);
682 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
683 zip_add_file(&sArchive, zName, &mfile, 0);
684 }
685 }
686 if( eflg & MFESTFLG_UUID ){
687 blob_append(&hash, "\n", 1);
688
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236 */
237 void zip_set_timedate(double rDate){
238 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239 zip_set_timedate_from_str(zDate);
240 fossil_free(zDate);
241 unixTime = (int)((rDate - 2440587.5)*86400.0);
242 }
243
244 /*
245 ** Append a single file to a growing ZIP archive.
246 **
@@ -677,11 +677,10 @@
677 blob_append(&filename, "manifest", -1);
678 zName = blob_str(&filename);
679 if( listFlag ) fossil_print("%s\n", zName);
680 if( pZip ){
681 zip_add_folders(&sArchive, zName);
 
682 zip_add_file(&sArchive, zName, &mfile, 0);
683 }
684 }
685 if( eflg & MFESTFLG_UUID ){
686 blob_append(&hash, "\n", 1);
687
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572572
</p>
573573
574574
<p><li>
575575
Makeheaders generates an error message if it encounters a function or
576576
variable definition within a .h file.
577
-The .h files are suppose to contain only interface, not implementation.
577
+The .h files are supposed to contain only interface, not implementation.
578578
C compilers will not enforce this convention, but makeheaders does.
579579
</ul>
580580
581581
<p>
582582
As a final note, we observe that automatically generated declarations
583583
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572 </p>
573
574 <p><li>
575 Makeheaders generates an error message if it encounters a function or
576 variable definition within a .h file.
577 The .h files are suppose to contain only interface, not implementation.
578 C compilers will not enforce this convention, but makeheaders does.
579 </ul>
580
581 <p>
582 As a final note, we observe that automatically generated declarations
583
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572 </p>
573
574 <p><li>
575 Makeheaders generates an error message if it encounters a function or
576 variable definition within a .h file.
577 The .h files are supposed to contain only interface, not implementation.
578 C compilers will not enforce this convention, but makeheaders does.
579 </ul>
580
581 <p>
582 As a final note, we observe that automatically generated declarations
583
+53 -215
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -234,21 +234,18 @@
234234
-DSQLITE_OMIT_DEPRECATED
235235
-DSQLITE_OMIT_PROGRESS_CALLBACK
236236
-DSQLITE_OMIT_SHARED_CACHE
237237
-DSQLITE_OMIT_LOAD_EXTENSION
238238
-DSQLITE_MAX_EXPR_DEPTH=0
239
- -DSQLITE_USE_ALLOCA
240239
-DSQLITE_ENABLE_LOCKING_STYLE=0
241240
-DSQLITE_DEFAULT_FILE_FORMAT=4
242241
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
243242
-DSQLITE_ENABLE_FTS4
244243
-DSQLITE_ENABLE_DBSTAT_VTAB
245
- -DSQLITE_ENABLE_JSON1
246244
-DSQLITE_ENABLE_FTS5
247245
-DSQLITE_ENABLE_STMTVTAB
248246
-DSQLITE_HAVE_ZLIB
249
- -DSQLITE_INTROSPECTION_PRAGMAS
250247
-DSQLITE_ENABLE_DBPAGE_VTAB
251248
-DSQLITE_TRUSTED_SCHEMA=0
252249
}
253250
#lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
254251
#lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
@@ -1439,10 +1436,13 @@
14391436
14401437
writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
14411438
foreach s [lsort $src] {
14421439
writeln -nonewline "${s}_.c:$s.h "
14431440
}
1441
+foreach s [lsort $src_ext] {
1442
+ writeln -nonewline "\$(SRCDIR_extsrc)\\${s}.c:$s.h "
1443
+}
14441444
writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
14451445
writeln "\t@copy /Y nul: headers"
14461446
14471447
close $output_file
14481448
#
@@ -1574,11 +1574,10 @@
15741574
!if $(FOSSIL_DYNAMIC_BUILD)!=0
15751575
SSLLIBDIR = $(SSLDIR)
15761576
!else
15771577
SSLLIBDIR = $(SSLDIR)
15781578
!endif
1579
-SSLLFLAGS = /nologo /opt:ref /debug
15801579
SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
15811580
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
15821581
!message Using 'x64' platform for OpenSSL...
15831582
SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
15841583
!if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1631,11 +1630,11 @@
16311630
16321631
!if $(FOSSIL_ENABLE_TCL)!=0
16331632
INCL = $(INCL) /I"$(TCLINCDIR)"
16341633
!endif
16351634
1636
-CFLAGS = /nologo
1635
+CFLAGS = /nologo /W2 /WX /utf-8
16371636
LDFLAGS =
16381637
16391638
CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
16401639
CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
16411640
@@ -1646,16 +1645,27 @@
16461645
!endif
16471646
16481647
!if $(FOSSIL_ENABLE_WINXP)!=0
16491648
XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
16501649
CFLAGS = $(CFLAGS) $(XPCFLAGS)
1650
+#
1651
+# NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
1652
+# explicit initialization is redundant, but is required for post-built edits.
1653
+#
16511654
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1652
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1655
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
16531656
!else
1654
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1657
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
16551658
!endif
16561659
LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1660
+#
1661
+# NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
1662
+# is applied in a separate post-build step, see below for more information.
1663
+#
1664
+!if $(FOSSIL_ENABLE_SSL)!=0
1665
+SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
1666
+!endif
16571667
!endif
16581668
16591669
!if $(FOSSIL_DYNAMIC_BUILD)!=0
16601670
!if $(DEBUG)!=0
16611671
CRTFLAGS = /MDd
@@ -1762,10 +1772,15 @@
17621772
writeln " \\"
17631773
writeln -nonewline " "
17641774
}
17651775
writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
17661776
}
1777
+foreach s [lsort $src_ext] {
1778
+ writeln " \\"
1779
+ writeln -nonewline " "
1780
+ writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\""; incr i
1781
+}
17671782
writeln "\n"
17681783
writeln -nonewline "EXTRA_FILES = "
17691784
set i 0
17701785
foreach s [lsort $extra_files] {
17711786
if {$i > 0} {
@@ -1826,19 +1841,42 @@
18261841
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
18271842
18281843
!if $(FOSSIL_ENABLE_SSL)!=0
18291844
openssl:
18301845
@echo Building OpenSSL from "$(SSLDIR)"...
1846
+!if $(FOSSIL_ENABLE_WINXP)!=0
1847
+ @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
1848
+!endif
18311849
!ifdef PERLDIR
18321850
@pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
18331851
!else
18341852
@pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
18351853
!endif
1836
-!if $(FOSSIL_ENABLE_WINXP)!=0
1837
- @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1838
-!else
18391854
@pushd "$(SSLDIR)" && $(MAKE) && popd
1855
+!if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
1856
+#
1857
+# NOTE: Appending custom linker flags to the OpenSSL default linker flags is
1858
+# somewhat difficult, as summarized in this Fossil Forum post:
1859
+#
1860
+# https://fossil-scm.org/forum/forumpost/a9a2d6af28b
1861
+#
1862
+# Therefore the custom linker flags required for Windows XP dynamic builds are
1863
+# applied in a separate post-build step.
1864
+#
1865
+# If the build stops here, or if the custom linker flags are outside the scope
1866
+# of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
1867
+# the OpenSSL makefile by hand.
1868
+#
1869
+# Also note that this step changes the subsystem for the OpenSSL DLLs from
1870
+# WINDOWS to CONSOLE, but which has no effect on DLLs.
1871
+#
1872
+ @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
1873
+ @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) <<<NEXT_LINE>>>
1874
+ do @( <<<NEXT_LINE>>>
1875
+ echo %F & <<<NEXT_LINE>>>
1876
+ link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 <<<NEXT_LINE>>>
1877
+ )
18401878
!endif
18411879
18421880
clean-openssl:
18431881
@pushd "$(SSLDIR)" && $(MAKE) clean && popd
18441882
!endif
@@ -2005,10 +2043,15 @@
20052043
writeln " \\"
20062044
writeln -nonewline "\t\t\t"
20072045
}
20082046
writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
20092047
}
2048
+foreach s [lsort $src_ext] {
2049
+ writeln " \\"
2050
+ writeln -nonewline "\t\t\t"
2051
+ writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\":\"\$(OX)\\$s.h\""; incr i
2052
+}
20102053
writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
20112054
writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
20122055
writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
20132056
writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
20142057
writeln "\t@copy /Y nul: $@"
@@ -2017,210 +2060,5 @@
20172060
close $output_file
20182061
#
20192062
# End of the win/Makefile.msc output
20202063
##############################################################################
20212064
##############################################################################
2022
-##############################################################################
2023
-# Begin win/Makefile.PellesCGMake output
2024
-#
2025
-puts "building ../win/Makefile.PellesCGMake"
2026
-set output_file [open ../win/Makefile.PellesCGMake w]
2027
-fconfigure $output_file -translation binary
2028
-
2029
-writeln [string map [list \
2030
- <<<SQLITE_OPTIONS>>> [join $SQLITE_WIN32_OPTIONS { }] \
2031
- <<<SHELL_OPTIONS>>> [join $SHELL_WIN32_OPTIONS { }]] {#
2032
-##############################################################################
2033
-# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
2034
-##############################################################################
2035
-#
2036
-# This file is automatically generated. Instead of editing this
2037
-# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
2038
-# to regenerate this file.
2039
-#
2040
-# HowTo
2041
-# -----
2042
-#
2043
-# This is a Makefile to compile fossil with PellesC from
2044
-# http://www.smorgasbordet.com/pellesc/index.htm
2045
-# In addition to the Compiler envrionment, you need
2046
-# gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
2047
-# couldn't handle the complex dependencies in this build
2048
-# zlib sources
2049
-# Then you do
2050
-# 1. create a directory PellesC in the project root directory
2051
-# 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
2052
-# 3. open a dos prompt window and change working directory into PellesC (step 1)
2053
-# 4. run gmake -f ..\win\Makefile.PellesCGMake
2054
-#
2055
-# this file is tested with
2056
-# PellesC 5.00.13
2057
-# gmake 3.80
2058
-# zlib sources 1.2.5
2059
-# Windows XP SP 2
2060
-# and
2061
-# PellesC 6.00.4
2062
-# gmake 3.80
2063
-# zlib sources 1.2.5
2064
-# Windows 7 Home Premium
2065
-#
2066
-
2067
-#
2068
-PellesCDir=c:\Programme\PellesC
2069
-
2070
-# Select between 32/64 bit code, default is 32 bit
2071
-#TARGETVERSION=64
2072
-
2073
-ifeq ($(TARGETVERSION),64)
2074
-# 64 bit version
2075
-TARGETMACHINE_CC=amd64
2076
-TARGETMACHINE_LN=amd64
2077
-TARGETEXTEND=64
2078
-else
2079
-# 32 bit version
2080
-TARGETMACHINE_CC=x86
2081
-TARGETMACHINE_LN=ix86
2082
-TARGETEXTEND=
2083
-endif
2084
-
2085
-# define the project directories
2086
-B=..
2087
-SRCDIR=$(B)/src/
2088
-SRCDIR_extsrc=$(B)/extsrc/
2089
-SRCDIR_tools=$(B)/tools/
2090
-WINDIR=$(B)/win/
2091
-ZLIBSRCDIR=../../zlib/
2092
-
2093
-# define linker command and options
2094
-LINK=$(PellesCDir)/bin/polink.exe
2095
-LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
2096
-
2097
-# define standard C-compiler and flags, used to compile
2098
-# the fossil binary. Some special definitions follow for
2099
-# special files follow
2100
-CC=$(PellesCDir)\bin\pocc.exe
2101
-DEFINES=-D_pgmptr=g.argv[0]
2102
-CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
2103
-INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
2104
-
2105
-# define commands for building the windows resource files
2106
-RESOURCE=fossil.res
2107
-RC=$(PellesCDir)\bin\porc.exe
2108
-RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
2109
-
2110
-# define the special utilities files, needed to generate
2111
-# the automatically generated source files
2112
-UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
2113
-UTILS_OBJ=$(UTILS:.exe=.obj)
2114
-UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
2115
-
2116
-# define the SQLite files, which need special flags on compile
2117
-SQLITESRC=sqlite3.c
2118
-ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
2119
-SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
2120
-SQLITEDEFINES=<<<SQLITE_OPTIONS>>>
2121
-
2122
-# define the SQLite shell files, which need special flags on compile
2123
-SQLITESHELLSRC=shell.c
2124
-ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
2125
-SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
2126
-SQLITESHELLDEFINES=<<<SHELL_OPTIONS>>>
2127
-
2128
-# define the th scripting files, which need special flags on compile
2129
-THSRC=th.c th_lang.c
2130
-ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
2131
-THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
2132
-
2133
-# define the zlib files, needed by this compile
2134
-ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
2135
-ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
2136
-ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
2137
-
2138
-# define all fossil sources, using the standard compile and
2139
-# source generation. These are all files in SRCDIR, which are not
2140
-# mentioned as special files above:
2141
-ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
2142
-SRC=$(subst $(SRCDIR),,$(ORIGSRC))
2143
-TRANSLATEDSRC=$(SRC:.c=_.c)
2144
-TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
2145
-
2146
-# main target file is the application
2147
-APPLICATION=fossil.exe
2148
-
2149
-# define the standard make target
2150
-.PHONY: default
2151
-default: page_index.h builtin_data.h headers $(APPLICATION)
2152
-
2153
-# symbolic target to generate the source generate utils
2154
-.PHONY: utils
2155
-utils: $(UTILS)
2156
-
2157
-# link utils
2158
-$(UTILS) version.exe: %.exe: %.obj
2159
- $(LINK) $(LINKFLAGS) -out:"$@" $<
2160
-
2161
-# compiling standard fossil utils
2162
-$(UTILS_OBJ): %.obj: $(SRCDIR)%.c
2163
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2164
-
2165
-# compile special windows utils
2166
-version.obj: $(SRCDIR_tools)mkversion.c
2167
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2168
-
2169
-# generate the translated c-source files
2170
-$(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
2171
- translate.exe $< >$@
2172
-
2173
-# generate the index source, containing all web references,..
2174
-page_index.h: $(TRANSLATEDSRC) mkindex.exe
2175
- mkindex.exe $(TRANSLATEDSRC) >$@
2176
-
2177
-builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
2178
- mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
2179
-
2180
-# extracting version info from manifest
2181
-VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
2182
- version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
2183
-
2184
-# generate the simplified headers
2185
-headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
2186
- makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
2187
- echo Done >$@
2188
-
2189
-# compile C sources with relevant options
2190
-
2191
-$(TRANSLATEDOBJ): %_.obj: %_.c %.h
2192
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2193
-
2194
-$(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
2195
- $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
2196
-
2197
-$(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
2198
- $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
2199
-
2200
-$(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
2201
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2202
-
2203
-$(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
2204
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2205
-
2206
-# create the windows resource with icon and version info
2207
-$(RESOURCE): %.res: ../win/%.rc ../win/*.ico
2208
- $(RC) $(RCFLAGS) $< -Fo"$@"
2209
-
2210
-# link the application
2211
-$(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
2212
- $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
2213
-
2214
-# cleanup
2215
-
2216
-.PHONY: clean
2217
-clean:
2218
- -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
2219
- -del /F $(TRANSLATEDSRC)
2220
- -del /F *.h headers
2221
- -del /F $(RESOURCE)
2222
-
2223
-.PHONY: clobber
2224
-clobber: clean
2225
- -del /F *.exe
2226
-}]
22272065
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -234,21 +234,18 @@
234 -DSQLITE_OMIT_DEPRECATED
235 -DSQLITE_OMIT_PROGRESS_CALLBACK
236 -DSQLITE_OMIT_SHARED_CACHE
237 -DSQLITE_OMIT_LOAD_EXTENSION
238 -DSQLITE_MAX_EXPR_DEPTH=0
239 -DSQLITE_USE_ALLOCA
240 -DSQLITE_ENABLE_LOCKING_STYLE=0
241 -DSQLITE_DEFAULT_FILE_FORMAT=4
242 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
243 -DSQLITE_ENABLE_FTS4
244 -DSQLITE_ENABLE_DBSTAT_VTAB
245 -DSQLITE_ENABLE_JSON1
246 -DSQLITE_ENABLE_FTS5
247 -DSQLITE_ENABLE_STMTVTAB
248 -DSQLITE_HAVE_ZLIB
249 -DSQLITE_INTROSPECTION_PRAGMAS
250 -DSQLITE_ENABLE_DBPAGE_VTAB
251 -DSQLITE_TRUSTED_SCHEMA=0
252 }
253 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
254 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
@@ -1439,10 +1436,13 @@
1439
1440 writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
1441 foreach s [lsort $src] {
1442 writeln -nonewline "${s}_.c:$s.h "
1443 }
 
 
 
1444 writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
1445 writeln "\t@copy /Y nul: headers"
1446
1447 close $output_file
1448 #
@@ -1574,11 +1574,10 @@
1574 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1575 SSLLIBDIR = $(SSLDIR)
1576 !else
1577 SSLLIBDIR = $(SSLDIR)
1578 !endif
1579 SSLLFLAGS = /nologo /opt:ref /debug
1580 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1581 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1582 !message Using 'x64' platform for OpenSSL...
1583 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1584 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1631,11 +1630,11 @@
1631
1632 !if $(FOSSIL_ENABLE_TCL)!=0
1633 INCL = $(INCL) /I"$(TCLINCDIR)"
1634 !endif
1635
1636 CFLAGS = /nologo
1637 LDFLAGS =
1638
1639 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
1640 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
1641
@@ -1646,16 +1645,27 @@
1646 !endif
1647
1648 !if $(FOSSIL_ENABLE_WINXP)!=0
1649 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
1650 CFLAGS = $(CFLAGS) $(XPCFLAGS)
 
 
 
 
1651 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1652 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1653 !else
1654 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1655 !endif
1656 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
 
 
 
 
 
 
 
1657 !endif
1658
1659 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1660 !if $(DEBUG)!=0
1661 CRTFLAGS = /MDd
@@ -1762,10 +1772,15 @@
1762 writeln " \\"
1763 writeln -nonewline " "
1764 }
1765 writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
1766 }
 
 
 
 
 
1767 writeln "\n"
1768 writeln -nonewline "EXTRA_FILES = "
1769 set i 0
1770 foreach s [lsort $extra_files] {
1771 if {$i > 0} {
@@ -1826,19 +1841,42 @@
1826 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
1827
1828 !if $(FOSSIL_ENABLE_SSL)!=0
1829 openssl:
1830 @echo Building OpenSSL from "$(SSLDIR)"...
 
 
 
1831 !ifdef PERLDIR
1832 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
1833 !else
1834 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
1835 !endif
1836 !if $(FOSSIL_ENABLE_WINXP)!=0
1837 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1838 !else
1839 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1840 !endif
1841
1842 clean-openssl:
1843 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
1844 !endif
@@ -2005,10 +2043,15 @@
2005 writeln " \\"
2006 writeln -nonewline "\t\t\t"
2007 }
2008 writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
2009 }
 
 
 
 
 
2010 writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
2011 writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
2012 writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
2013 writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
2014 writeln "\t@copy /Y nul: $@"
@@ -2017,210 +2060,5 @@
2017 close $output_file
2018 #
2019 # End of the win/Makefile.msc output
2020 ##############################################################################
2021 ##############################################################################
2022 ##############################################################################
2023 # Begin win/Makefile.PellesCGMake output
2024 #
2025 puts "building ../win/Makefile.PellesCGMake"
2026 set output_file [open ../win/Makefile.PellesCGMake w]
2027 fconfigure $output_file -translation binary
2028
2029 writeln [string map [list \
2030 <<<SQLITE_OPTIONS>>> [join $SQLITE_WIN32_OPTIONS { }] \
2031 <<<SHELL_OPTIONS>>> [join $SHELL_WIN32_OPTIONS { }]] {#
2032 ##############################################################################
2033 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
2034 ##############################################################################
2035 #
2036 # This file is automatically generated. Instead of editing this
2037 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
2038 # to regenerate this file.
2039 #
2040 # HowTo
2041 # -----
2042 #
2043 # This is a Makefile to compile fossil with PellesC from
2044 # http://www.smorgasbordet.com/pellesc/index.htm
2045 # In addition to the Compiler envrionment, you need
2046 # gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
2047 # couldn't handle the complex dependencies in this build
2048 # zlib sources
2049 # Then you do
2050 # 1. create a directory PellesC in the project root directory
2051 # 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
2052 # 3. open a dos prompt window and change working directory into PellesC (step 1)
2053 # 4. run gmake -f ..\win\Makefile.PellesCGMake
2054 #
2055 # this file is tested with
2056 # PellesC 5.00.13
2057 # gmake 3.80
2058 # zlib sources 1.2.5
2059 # Windows XP SP 2
2060 # and
2061 # PellesC 6.00.4
2062 # gmake 3.80
2063 # zlib sources 1.2.5
2064 # Windows 7 Home Premium
2065 #
2066
2067 #
2068 PellesCDir=c:\Programme\PellesC
2069
2070 # Select between 32/64 bit code, default is 32 bit
2071 #TARGETVERSION=64
2072
2073 ifeq ($(TARGETVERSION),64)
2074 # 64 bit version
2075 TARGETMACHINE_CC=amd64
2076 TARGETMACHINE_LN=amd64
2077 TARGETEXTEND=64
2078 else
2079 # 32 bit version
2080 TARGETMACHINE_CC=x86
2081 TARGETMACHINE_LN=ix86
2082 TARGETEXTEND=
2083 endif
2084
2085 # define the project directories
2086 B=..
2087 SRCDIR=$(B)/src/
2088 SRCDIR_extsrc=$(B)/extsrc/
2089 SRCDIR_tools=$(B)/tools/
2090 WINDIR=$(B)/win/
2091 ZLIBSRCDIR=../../zlib/
2092
2093 # define linker command and options
2094 LINK=$(PellesCDir)/bin/polink.exe
2095 LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
2096
2097 # define standard C-compiler and flags, used to compile
2098 # the fossil binary. Some special definitions follow for
2099 # special files follow
2100 CC=$(PellesCDir)\bin\pocc.exe
2101 DEFINES=-D_pgmptr=g.argv[0]
2102 CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
2103 INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
2104
2105 # define commands for building the windows resource files
2106 RESOURCE=fossil.res
2107 RC=$(PellesCDir)\bin\porc.exe
2108 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
2109
2110 # define the special utilities files, needed to generate
2111 # the automatically generated source files
2112 UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
2113 UTILS_OBJ=$(UTILS:.exe=.obj)
2114 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
2115
2116 # define the SQLite files, which need special flags on compile
2117 SQLITESRC=sqlite3.c
2118 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
2119 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
2120 SQLITEDEFINES=<<<SQLITE_OPTIONS>>>
2121
2122 # define the SQLite shell files, which need special flags on compile
2123 SQLITESHELLSRC=shell.c
2124 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
2125 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
2126 SQLITESHELLDEFINES=<<<SHELL_OPTIONS>>>
2127
2128 # define the th scripting files, which need special flags on compile
2129 THSRC=th.c th_lang.c
2130 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
2131 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
2132
2133 # define the zlib files, needed by this compile
2134 ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
2135 ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
2136 ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
2137
2138 # define all fossil sources, using the standard compile and
2139 # source generation. These are all files in SRCDIR, which are not
2140 # mentioned as special files above:
2141 ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
2142 SRC=$(subst $(SRCDIR),,$(ORIGSRC))
2143 TRANSLATEDSRC=$(SRC:.c=_.c)
2144 TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
2145
2146 # main target file is the application
2147 APPLICATION=fossil.exe
2148
2149 # define the standard make target
2150 .PHONY: default
2151 default: page_index.h builtin_data.h headers $(APPLICATION)
2152
2153 # symbolic target to generate the source generate utils
2154 .PHONY: utils
2155 utils: $(UTILS)
2156
2157 # link utils
2158 $(UTILS) version.exe: %.exe: %.obj
2159 $(LINK) $(LINKFLAGS) -out:"$@" $<
2160
2161 # compiling standard fossil utils
2162 $(UTILS_OBJ): %.obj: $(SRCDIR)%.c
2163 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2164
2165 # compile special windows utils
2166 version.obj: $(SRCDIR_tools)mkversion.c
2167 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2168
2169 # generate the translated c-source files
2170 $(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
2171 translate.exe $< >$@
2172
2173 # generate the index source, containing all web references,..
2174 page_index.h: $(TRANSLATEDSRC) mkindex.exe
2175 mkindex.exe $(TRANSLATEDSRC) >$@
2176
2177 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
2178 mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
2179
2180 # extracting version info from manifest
2181 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
2182 version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
2183
2184 # generate the simplified headers
2185 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
2186 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
2187 echo Done >$@
2188
2189 # compile C sources with relevant options
2190
2191 $(TRANSLATEDOBJ): %_.obj: %_.c %.h
2192 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2193
2194 $(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
2195 $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
2196
2197 $(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
2198 $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
2199
2200 $(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
2201 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2202
2203 $(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
2204 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2205
2206 # create the windows resource with icon and version info
2207 $(RESOURCE): %.res: ../win/%.rc ../win/*.ico
2208 $(RC) $(RCFLAGS) $< -Fo"$@"
2209
2210 # link the application
2211 $(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
2212 $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
2213
2214 # cleanup
2215
2216 .PHONY: clean
2217 clean:
2218 -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
2219 -del /F $(TRANSLATEDSRC)
2220 -del /F *.h headers
2221 -del /F $(RESOURCE)
2222
2223 .PHONY: clobber
2224 clobber: clean
2225 -del /F *.exe
2226 }]
2227
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -234,21 +234,18 @@
234 -DSQLITE_OMIT_DEPRECATED
235 -DSQLITE_OMIT_PROGRESS_CALLBACK
236 -DSQLITE_OMIT_SHARED_CACHE
237 -DSQLITE_OMIT_LOAD_EXTENSION
238 -DSQLITE_MAX_EXPR_DEPTH=0
 
239 -DSQLITE_ENABLE_LOCKING_STYLE=0
240 -DSQLITE_DEFAULT_FILE_FORMAT=4
241 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
242 -DSQLITE_ENABLE_FTS4
243 -DSQLITE_ENABLE_DBSTAT_VTAB
 
244 -DSQLITE_ENABLE_FTS5
245 -DSQLITE_ENABLE_STMTVTAB
246 -DSQLITE_HAVE_ZLIB
 
247 -DSQLITE_ENABLE_DBPAGE_VTAB
248 -DSQLITE_TRUSTED_SCHEMA=0
249 }
250 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
251 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
@@ -1439,10 +1436,13 @@
1436
1437 writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
1438 foreach s [lsort $src] {
1439 writeln -nonewline "${s}_.c:$s.h "
1440 }
1441 foreach s [lsort $src_ext] {
1442 writeln -nonewline "\$(SRCDIR_extsrc)\\${s}.c:$s.h "
1443 }
1444 writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
1445 writeln "\t@copy /Y nul: headers"
1446
1447 close $output_file
1448 #
@@ -1574,11 +1574,10 @@
1574 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1575 SSLLIBDIR = $(SSLDIR)
1576 !else
1577 SSLLIBDIR = $(SSLDIR)
1578 !endif
 
1579 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1580 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1581 !message Using 'x64' platform for OpenSSL...
1582 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1583 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1631,11 +1630,11 @@
1630
1631 !if $(FOSSIL_ENABLE_TCL)!=0
1632 INCL = $(INCL) /I"$(TCLINCDIR)"
1633 !endif
1634
1635 CFLAGS = /nologo /W2 /WX /utf-8
1636 LDFLAGS =
1637
1638 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
1639 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
1640
@@ -1646,16 +1645,27 @@
1645 !endif
1646
1647 !if $(FOSSIL_ENABLE_WINXP)!=0
1648 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
1649 CFLAGS = $(CFLAGS) $(XPCFLAGS)
1650 #
1651 # NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
1652 # explicit initialization is redundant, but is required for post-built edits.
1653 #
1654 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1655 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
1656 !else
1657 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
1658 !endif
1659 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1660 #
1661 # NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
1662 # is applied in a separate post-build step, see below for more information.
1663 #
1664 !if $(FOSSIL_ENABLE_SSL)!=0
1665 SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
1666 !endif
1667 !endif
1668
1669 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1670 !if $(DEBUG)!=0
1671 CRTFLAGS = /MDd
@@ -1762,10 +1772,15 @@
1772 writeln " \\"
1773 writeln -nonewline " "
1774 }
1775 writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
1776 }
1777 foreach s [lsort $src_ext] {
1778 writeln " \\"
1779 writeln -nonewline " "
1780 writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\""; incr i
1781 }
1782 writeln "\n"
1783 writeln -nonewline "EXTRA_FILES = "
1784 set i 0
1785 foreach s [lsort $extra_files] {
1786 if {$i > 0} {
@@ -1826,19 +1841,42 @@
1841 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
1842
1843 !if $(FOSSIL_ENABLE_SSL)!=0
1844 openssl:
1845 @echo Building OpenSSL from "$(SSLDIR)"...
1846 !if $(FOSSIL_ENABLE_WINXP)!=0
1847 @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
1848 !endif
1849 !ifdef PERLDIR
1850 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
1851 !else
1852 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
1853 !endif
 
 
 
1854 @pushd "$(SSLDIR)" && $(MAKE) && popd
1855 !if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
1856 #
1857 # NOTE: Appending custom linker flags to the OpenSSL default linker flags is
1858 # somewhat difficult, as summarized in this Fossil Forum post:
1859 #
1860 # https://fossil-scm.org/forum/forumpost/a9a2d6af28b
1861 #
1862 # Therefore the custom linker flags required for Windows XP dynamic builds are
1863 # applied in a separate post-build step.
1864 #
1865 # If the build stops here, or if the custom linker flags are outside the scope
1866 # of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
1867 # the OpenSSL makefile by hand.
1868 #
1869 # Also note that this step changes the subsystem for the OpenSSL DLLs from
1870 # WINDOWS to CONSOLE, but which has no effect on DLLs.
1871 #
1872 @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
1873 @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) <<<NEXT_LINE>>>
1874 do @( <<<NEXT_LINE>>>
1875 echo %F & <<<NEXT_LINE>>>
1876 link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 <<<NEXT_LINE>>>
1877 )
1878 !endif
1879
1880 clean-openssl:
1881 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
1882 !endif
@@ -2005,10 +2043,15 @@
2043 writeln " \\"
2044 writeln -nonewline "\t\t\t"
2045 }
2046 writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
2047 }
2048 foreach s [lsort $src_ext] {
2049 writeln " \\"
2050 writeln -nonewline "\t\t\t"
2051 writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\":\"\$(OX)\\$s.h\""; incr i
2052 }
2053 writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
2054 writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
2055 writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
2056 writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
2057 writeln "\t@copy /Y nul: $@"
@@ -2017,210 +2060,5 @@
2060 close $output_file
2061 #
2062 # End of the win/Makefile.msc output
2063 ##############################################################################
2064 ##############################################################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2065
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200200
#elif defined(__POCC__) /* e.g. 700 */
201201
d = (__POCC__ / 100); /* major */
202202
x = (__POCC__ % 100); /* minor */
203203
printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204204
#elif defined(_MSC_VER) /* e.g. 1800 */
205
+ /* _MSC_FULL_VER also defined, e.g. 193030709 */
205206
d = (_MSC_VER / 100); /* major */
206207
x = (_MSC_VER % 100); /* minor */
207
- printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
208
+ printf("#define COMPILER_VERSION \"%d.%02d.", d, x);
209
+ printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */
208210
#endif
209211
return 0;
210212
}
211213
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200 #elif defined(__POCC__) /* e.g. 700 */
201 d = (__POCC__ / 100); /* major */
202 x = (__POCC__ % 100); /* minor */
203 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204 #elif defined(_MSC_VER) /* e.g. 1800 */
 
205 d = (_MSC_VER / 100); /* major */
206 x = (_MSC_VER % 100); /* minor */
207 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
 
208 #endif
209 return 0;
210 }
211
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200 #elif defined(__POCC__) /* e.g. 700 */
201 d = (__POCC__ / 100); /* major */
202 x = (__POCC__ % 100); /* minor */
203 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204 #elif defined(_MSC_VER) /* e.g. 1800 */
205 /* _MSC_FULL_VER also defined, e.g. 193030709 */
206 d = (_MSC_VER / 100); /* major */
207 x = (_MSC_VER % 100); /* minor */
208 printf("#define COMPILER_VERSION \"%d.%02d.", d, x);
209 printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */
210 #endif
211 return 0;
212 }
213
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
6262
version=(major*1000000)+(minor*1000)+release;
6363
6464
int i;
6565
static const char *zRequiredOpts[] = {
6666
"ENABLE_FTS4", /* Required for repository search */
67
- "ENABLE_JSON1", /* Required for the check-in locking protocol */
6867
"ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
6968
};
7069
7170
/* Check minimum SQLite version number */
7271
if( sqlite3_libversion_number()<version ){
7372
7473
DELETED win/Makefile.PellesCGMake
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
62 version=(major*1000000)+(minor*1000)+release;
63
64 int i;
65 static const char *zRequiredOpts[] = {
66 "ENABLE_FTS4", /* Required for repository search */
67 "ENABLE_JSON1", /* Required for the check-in locking protocol */
68 "ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
69 };
70
71 /* Check minimum SQLite version number */
72 if( sqlite3_libversion_number()<version ){
73
74 ELETED win/Makefile.PellesCGMake
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
62 version=(major*1000000)+(minor*1000)+release;
63
64 int i;
65 static const char *zRequiredOpts[] = {
66 "ENABLE_FTS4", /* Required for repository search */
 
67 "ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
68 };
69
70 /* Check minimum SQLite version number */
71 if( sqlite3_libversion_number()<version ){
72
73 ELETED win/Makefile.PellesCGMake
D win/Makefile.PellesCGMake
-211
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,211 +0,0 @@
1
-#
2
-##############################################################################
3
-# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
4
-##############################################################################
5
-#
6
-# This file is automatically generated. Instead of editing this
7
-# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
8
-# to regenerate this file.
9
-#
10
-# HowTo
11
-# -----
12
-#
13
-# This is a Makefile to compile fossil with PellesC from
14
-# http://www.smorgasbordet.com/pellesc/index.htm
15
-# In addition to the Compiler envrionment, you need
16
-# gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
17
-# couldn't handle the complex dependencies in this build
18
-# zlib sources
19
-# Then you do
20
-# 1. create a directory PellesC in the project root directory
21
-# 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
22
-# 3. open a dos prompt window and change working directory into PellesC (step 1)
23
-# 4. run gmake -f ..\win\Makefile.PellesCGMake
24
-#
25
-# this file is tested with
26
-# PellesC 5.00.13
27
-# gmake 3.80
28
-# zlib sources 1.2.5
29
-# Windows XP SP 2
30
-# and
31
-# PellesC 6.00.4
32
-# gmake 3.80
33
-# zlib sources 1.2.5
34
-# Windows 7 Home Premium
35
-#
36
-
37
-#
38
-PellesCDir=c:\Programme\PellesC
39
-
40
-# Select between 32/64 bit code, default is 32 bit
41
-#TARGETVERSION=64
42
-
43
-ifeq ($(TARGETVERSION),64)
44
-# 64 bit version
45
-TARGETMACHINE_CC=amd64
46
-TARGETMACHINE_LN=amd64
47
-TARGETEXTEND=64
48
-else
49
-# 32 bit version
50
-TARGETMACHINE_CC=x86
51
-TARGETMACHINE_LN=ix86
52
-TARGETEXTEND=
53
-endif
54
-
55
-# define the projecUSE_ALLOCAN -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DJSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -####################################################
56
-# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
57
-##############################################################################
58
-#
59
-# This file is automatically generated. Instead of editing this
60
-# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
61
-# to regenerate this file.
62
-#
63
-# HowTo
64
-# -----
65
-#
66
-# This is a Makefile to compile fossil with PellesC from
67
-# http://www.smorgasbordet.com/pellesc/index.htm
68
-# In addition to the Compiler envrionment, you need
69
-# gmake from http://sourceforge.net/pro#
70
-########N -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
71
-
72
-# define the th scripting files, which need special flags on compile
73
-THSRC=th.c th_lang.c
74
-ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
75
-THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
76
-
77
-# define the zlib files, needed by this compile
78
-ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
79
-ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
80
-ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
81
-
82
-# define all fossil sources, using the standard compile and
83
-# source generation. These are all files in SRCDIR, which are not
84
-# mentioned as special files above:
85
-ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
86
-SRC=$(subst $(SRCDIR),,$(ORIGSRC))
87
-TRANSLATEDSRC=$(SRC:.c=_.c)
88
-TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
89
-
90
-# main target file is the application
91
-APPLICATION=fossil.exe
92
-
93
-# define the standard make target
94
-.PHONY: default
95
-default: page_index.h builtin_data.h headers $(APPLICATION)
96
-
97
-# symbolic target to generate the source generate utils
98
-.PHONY: utils
99
-utils: $(UTILS)
100
-
101
-# link utils
102
-$(UTILS) version.exe: %.exe: %.obj
103
- $(LINK) $(LINKFLAGS) -out:"$@" $<
104
-
105
-# compiling standard fossil utils
106
-$(UTILS_OBJ): %.obj: $(SRCDIR)%.c
107
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
108
-
109
-# compile special windows utils
110
-version.obj: $(SRCDIR_tools)mkversion.c
111
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
112
-
113
-# generate the translated c-source files
114
-$(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
115
- translate.exe $< >$@
116
-
117
-# generate the index source, containing all web references,..
118
-page_index.h: $(TRANSLATEDSRC) mkindex.exe
119
- mkindex.exe $(TRANSLATEDSRC) >$@
120
-
121
-builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
122
- mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
123
-
124
-# extracting version info from manifest
125
-VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
126
- version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
127
-
128
-# generate the simplified headers
129
-headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
130
- makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
131
- echo Done >$@
132
-
133
-# compile C sources with relevant options
134
-
135
-$(TRANSLATEDOBJ): %_.obj: %_.c %.h
136
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
137
-
138
-$(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
139
- $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
140
-
141
-$(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
142
- $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
143
-
144
-$(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
145
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
146
-
147
-$(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
148
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
149
-
150
-# create the windows resource with icon and version info
151
-$(RESOURCE): %.res: ../win/%.rc ../win/*.ico
152
- $(RC) $(RCFLAGS) $< -Fo"$@"
153
-
154
-# link the application
155
-$(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
156
- $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
157
-
158
-# cleanup
159
-
160
-.PHONY: clean
161
-clean:
162
- -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
163
- -del /F $(TRANSLATEDSRC)
164
- -del /F *.h headers
165
- -del /F $(RESOURCE)
166
-
167
-.PHONY: clobber
168
-clobber: clean
169
- -del /F *.exe
170
-
171
-JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
172
-
173
-# define the th scripting files, which need special flags on compile
174
-THSRC=th.c th_lang.c
175
-ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
176
-THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
177
-
178
-# define the zlib files, needed by this compile
179
-ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
180
-ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
181
-ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
182
-
183
-# define all fossil sources, using the standard compile and
184
-# source generation. These are all files in SRCDIR, which are not
185
-# mentioned as special files above:
186
-ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
187
-SRC=$(subst $(SRCDIR),,$(ORIGSRC))
188
-TRANSLATEDSRC=$(SRC:.c=_.c)
189
-TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
190
-
191
-# main target file is the application
192
-APPLICATION=fossil.exe
193
-
194
-# define the standard make target
195
-.PHONY: default
196
-default: page_index.h builtin_data.h headers $(APPLICATION)
197
-
198
-# symbolic target to generate the source generate utils
199
-.PHONY: utils
200
-utils: $(UTILS)
201
-
202
-# link utils
203
-$(UTILS) version.exe: %.exe: %.obj
204
- $(LINK) $(LINKFLAGS) -out:"$@" $<
205
-
206
-# compiling standard fossil utils
207
-$(UTILS_OBJ): %.obj: $(SRCDIR)%.c
208
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
209
-
210
-# compile special windows utils
211
-version.o
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,211 +0,0 @@
1 #
2 ##############################################################################
3 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
4 ##############################################################################
5 #
6 # This file is automatically generated. Instead of editing this
7 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
8 # to regenerate this file.
9 #
10 # HowTo
11 # -----
12 #
13 # This is a Makefile to compile fossil with PellesC from
14 # http://www.smorgasbordet.com/pellesc/index.htm
15 # In addition to the Compiler envrionment, you need
16 # gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
17 # couldn't handle the complex dependencies in this build
18 # zlib sources
19 # Then you do
20 # 1. create a directory PellesC in the project root directory
21 # 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
22 # 3. open a dos prompt window and change working directory into PellesC (step 1)
23 # 4. run gmake -f ..\win\Makefile.PellesCGMake
24 #
25 # this file is tested with
26 # PellesC 5.00.13
27 # gmake 3.80
28 # zlib sources 1.2.5
29 # Windows XP SP 2
30 # and
31 # PellesC 6.00.4
32 # gmake 3.80
33 # zlib sources 1.2.5
34 # Windows 7 Home Premium
35 #
36
37 #
38 PellesCDir=c:\Programme\PellesC
39
40 # Select between 32/64 bit code, default is 32 bit
41 #TARGETVERSION=64
42
43 ifeq ($(TARGETVERSION),64)
44 # 64 bit version
45 TARGETMACHINE_CC=amd64
46 TARGETMACHINE_LN=amd64
47 TARGETEXTEND=64
48 else
49 # 32 bit version
50 TARGETMACHINE_CC=x86
51 TARGETMACHINE_LN=ix86
52 TARGETEXTEND=
53 endif
54
55 # define the projecUSE_ALLOCAN -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DJSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -####################################################
56 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
57 ##############################################################################
58 #
59 # This file is automatically generated. Instead of editing this
60 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
61 # to regenerate this file.
62 #
63 # HowTo
64 # -----
65 #
66 # This is a Makefile to compile fossil with PellesC from
67 # http://www.smorgasbordet.com/pellesc/index.htm
68 # In addition to the Compiler envrionment, you need
69 # gmake from http://sourceforge.net/pro#
70 ########N -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
71
72 # define the th scripting files, which need special flags on compile
73 THSRC=th.c th_lang.c
74 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
75 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
76
77 # define the zlib files, needed by this compile
78 ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
79 ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
80 ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
81
82 # define all fossil sources, using the standard compile and
83 # source generation. These are all files in SRCDIR, which are not
84 # mentioned as special files above:
85 ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
86 SRC=$(subst $(SRCDIR),,$(ORIGSRC))
87 TRANSLATEDSRC=$(SRC:.c=_.c)
88 TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
89
90 # main target file is the application
91 APPLICATION=fossil.exe
92
93 # define the standard make target
94 .PHONY: default
95 default: page_index.h builtin_data.h headers $(APPLICATION)
96
97 # symbolic target to generate the source generate utils
98 .PHONY: utils
99 utils: $(UTILS)
100
101 # link utils
102 $(UTILS) version.exe: %.exe: %.obj
103 $(LINK) $(LINKFLAGS) -out:"$@" $<
104
105 # compiling standard fossil utils
106 $(UTILS_OBJ): %.obj: $(SRCDIR)%.c
107 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
108
109 # compile special windows utils
110 version.obj: $(SRCDIR_tools)mkversion.c
111 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
112
113 # generate the translated c-source files
114 $(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
115 translate.exe $< >$@
116
117 # generate the index source, containing all web references,..
118 page_index.h: $(TRANSLATEDSRC) mkindex.exe
119 mkindex.exe $(TRANSLATEDSRC) >$@
120
121 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
122 mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
123
124 # extracting version info from manifest
125 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
126 version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
127
128 # generate the simplified headers
129 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
130 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
131 echo Done >$@
132
133 # compile C sources with relevant options
134
135 $(TRANSLATEDOBJ): %_.obj: %_.c %.h
136 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
137
138 $(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
139 $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
140
141 $(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
142 $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
143
144 $(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
145 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
146
147 $(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
148 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
149
150 # create the windows resource with icon and version info
151 $(RESOURCE): %.res: ../win/%.rc ../win/*.ico
152 $(RC) $(RCFLAGS) $< -Fo"$@"
153
154 # link the application
155 $(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
156 $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
157
158 # cleanup
159
160 .PHONY: clean
161 clean:
162 -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
163 -del /F $(TRANSLATEDSRC)
164 -del /F *.h headers
165 -del /F $(RESOURCE)
166
167 .PHONY: clobber
168 clobber: clean
169 -del /F *.exe
170
171 JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
172
173 # define the th scripting files, which need special flags on compile
174 THSRC=th.c th_lang.c
175 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
176 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
177
178 # define the zlib files, needed by this compile
179 ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
180 ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
181 ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
182
183 # define all fossil sources, using the standard compile and
184 # source generation. These are all files in SRCDIR, which are not
185 # mentioned as special files above:
186 ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
187 SRC=$(subst $(SRCDIR),,$(ORIGSRC))
188 TRANSLATEDSRC=$(SRC:.c=_.c)
189 TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
190
191 # main target file is the application
192 APPLICATION=fossil.exe
193
194 # define the standard make target
195 .PHONY: default
196 default: page_index.h builtin_data.h headers $(APPLICATION)
197
198 # symbolic target to generate the source generate utils
199 .PHONY: utils
200 utils: $(UTILS)
201
202 # link utils
203 $(UTILS) version.exe: %.exe: %.obj
204 $(LINK) $(LINKFLAGS) -out:"$@" $<
205
206 # compiling standard fossil utils
207 $(UTILS_OBJ): %.obj: $(SRCDIR)%.c
208 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
209
210 # compile special windows utils
211 version.o
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,211 +0,0 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
2626
CFLAGS = -o
2727
BCC = $(DMDIR)\bin\dmc $(CFLAGS)
2828
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2929
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
3030
31
-SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
31
+SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
3232
33
-SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
33
+SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
3434
3535
SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
3636
3737
OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3838
@@ -1007,7 +1007,7 @@
10071007
10081008
zip_.c : $(SRCDIR)\zip.c
10091009
+translate$E $** > $@
10101010
10111011
headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1012
- +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1012
+ +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
10131013
@copy /Y nul: headers
10141014
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 CFLAGS = -o
27 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
28 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
29 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
30
31 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
32
33 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
34
35 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
36
37 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
38
@@ -1007,7 +1007,7 @@
1007
1008 zip_.c : $(SRCDIR)\zip.c
1009 +translate$E $** > $@
1010
1011 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1012 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1013 @copy /Y nul: headers
1014
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 CFLAGS = -o
27 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
28 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
29 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
30
31 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
32
33 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
34
35 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
36
37 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
38
@@ -1007,7 +1007,7 @@
1007
1008 zip_.c : $(SRCDIR)\zip.c
1009 +translate$E $** > $@
1010
1011 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1012 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1013 @copy /Y nul: headers
1014
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2512,21 +2512,18 @@
25122512
-DSQLITE_OMIT_DEPRECATED \
25132513
-DSQLITE_OMIT_PROGRESS_CALLBACK \
25142514
-DSQLITE_OMIT_SHARED_CACHE \
25152515
-DSQLITE_OMIT_LOAD_EXTENSION \
25162516
-DSQLITE_MAX_EXPR_DEPTH=0 \
2517
- -DSQLITE_USE_ALLOCA \
25182517
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
25192518
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
25202519
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
25212520
-DSQLITE_ENABLE_FTS4 \
25222521
-DSQLITE_ENABLE_DBSTAT_VTAB \
2523
- -DSQLITE_ENABLE_JSON1 \
25242522
-DSQLITE_ENABLE_FTS5 \
25252523
-DSQLITE_ENABLE_STMTVTAB \
25262524
-DSQLITE_HAVE_ZLIB \
2527
- -DSQLITE_INTROSPECTION_PRAGMAS \
25282525
-DSQLITE_ENABLE_DBPAGE_VTAB \
25292526
-DSQLITE_TRUSTED_SCHEMA=0 \
25302527
-DSQLITE_WIN32_NO_ANSI \
25312528
$(MINGW_OPTIONS) \
25322529
-DSQLITE_USE_MALLOC_H \
@@ -2542,21 +2539,18 @@
25422539
-DSQLITE_OMIT_DEPRECATED \
25432540
-DSQLITE_OMIT_PROGRESS_CALLBACK \
25442541
-DSQLITE_OMIT_SHARED_CACHE \
25452542
-DSQLITE_OMIT_LOAD_EXTENSION \
25462543
-DSQLITE_MAX_EXPR_DEPTH=0 \
2547
- -DSQLITE_USE_ALLOCA \
25482544
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
25492545
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
25502546
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
25512547
-DSQLITE_ENABLE_FTS4 \
25522548
-DSQLITE_ENABLE_DBSTAT_VTAB \
2553
- -DSQLITE_ENABLE_JSON1 \
25542549
-DSQLITE_ENABLE_FTS5 \
25552550
-DSQLITE_ENABLE_STMTVTAB \
25562551
-DSQLITE_HAVE_ZLIB \
2557
- -DSQLITE_INTROSPECTION_PRAGMAS \
25582552
-DSQLITE_ENABLE_DBPAGE_VTAB \
25592553
-DSQLITE_TRUSTED_SCHEMA=0 \
25602554
-Dmain=sqlite3_shell \
25612555
-DSQLITE_SHELL_IS_UTF8=1 \
25622556
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
25632557
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2512,21 +2512,18 @@
2512 -DSQLITE_OMIT_DEPRECATED \
2513 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2514 -DSQLITE_OMIT_SHARED_CACHE \
2515 -DSQLITE_OMIT_LOAD_EXTENSION \
2516 -DSQLITE_MAX_EXPR_DEPTH=0 \
2517 -DSQLITE_USE_ALLOCA \
2518 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2519 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2520 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2521 -DSQLITE_ENABLE_FTS4 \
2522 -DSQLITE_ENABLE_DBSTAT_VTAB \
2523 -DSQLITE_ENABLE_JSON1 \
2524 -DSQLITE_ENABLE_FTS5 \
2525 -DSQLITE_ENABLE_STMTVTAB \
2526 -DSQLITE_HAVE_ZLIB \
2527 -DSQLITE_INTROSPECTION_PRAGMAS \
2528 -DSQLITE_ENABLE_DBPAGE_VTAB \
2529 -DSQLITE_TRUSTED_SCHEMA=0 \
2530 -DSQLITE_WIN32_NO_ANSI \
2531 $(MINGW_OPTIONS) \
2532 -DSQLITE_USE_MALLOC_H \
@@ -2542,21 +2539,18 @@
2542 -DSQLITE_OMIT_DEPRECATED \
2543 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2544 -DSQLITE_OMIT_SHARED_CACHE \
2545 -DSQLITE_OMIT_LOAD_EXTENSION \
2546 -DSQLITE_MAX_EXPR_DEPTH=0 \
2547 -DSQLITE_USE_ALLOCA \
2548 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2549 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2550 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2551 -DSQLITE_ENABLE_FTS4 \
2552 -DSQLITE_ENABLE_DBSTAT_VTAB \
2553 -DSQLITE_ENABLE_JSON1 \
2554 -DSQLITE_ENABLE_FTS5 \
2555 -DSQLITE_ENABLE_STMTVTAB \
2556 -DSQLITE_HAVE_ZLIB \
2557 -DSQLITE_INTROSPECTION_PRAGMAS \
2558 -DSQLITE_ENABLE_DBPAGE_VTAB \
2559 -DSQLITE_TRUSTED_SCHEMA=0 \
2560 -Dmain=sqlite3_shell \
2561 -DSQLITE_SHELL_IS_UTF8=1 \
2562 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2563
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2512,21 +2512,18 @@
2512 -DSQLITE_OMIT_DEPRECATED \
2513 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2514 -DSQLITE_OMIT_SHARED_CACHE \
2515 -DSQLITE_OMIT_LOAD_EXTENSION \
2516 -DSQLITE_MAX_EXPR_DEPTH=0 \
 
2517 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2518 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2519 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2520 -DSQLITE_ENABLE_FTS4 \
2521 -DSQLITE_ENABLE_DBSTAT_VTAB \
 
2522 -DSQLITE_ENABLE_FTS5 \
2523 -DSQLITE_ENABLE_STMTVTAB \
2524 -DSQLITE_HAVE_ZLIB \
 
2525 -DSQLITE_ENABLE_DBPAGE_VTAB \
2526 -DSQLITE_TRUSTED_SCHEMA=0 \
2527 -DSQLITE_WIN32_NO_ANSI \
2528 $(MINGW_OPTIONS) \
2529 -DSQLITE_USE_MALLOC_H \
@@ -2542,21 +2539,18 @@
2539 -DSQLITE_OMIT_DEPRECATED \
2540 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2541 -DSQLITE_OMIT_SHARED_CACHE \
2542 -DSQLITE_OMIT_LOAD_EXTENSION \
2543 -DSQLITE_MAX_EXPR_DEPTH=0 \
 
2544 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2545 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2546 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2547 -DSQLITE_ENABLE_FTS4 \
2548 -DSQLITE_ENABLE_DBSTAT_VTAB \
 
2549 -DSQLITE_ENABLE_FTS5 \
2550 -DSQLITE_ENABLE_STMTVTAB \
2551 -DSQLITE_HAVE_ZLIB \
 
2552 -DSQLITE_ENABLE_DBPAGE_VTAB \
2553 -DSQLITE_TRUSTED_SCHEMA=0 \
2554 -Dmain=sqlite3_shell \
2555 -DSQLITE_SHELL_IS_UTF8=1 \
2556 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2557
+43 -14
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116116
!if $(FOSSIL_DYNAMIC_BUILD)!=0
117117
SSLLIBDIR = $(SSLDIR)
118118
!else
119119
SSLLIBDIR = $(SSLDIR)
120120
!endif
121
-SSLLFLAGS = /nologo /opt:ref /debug
122121
SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
123122
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
124123
!message Using 'x64' platform for OpenSSL...
125124
SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
126125
!if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
173172
174173
!if $(FOSSIL_ENABLE_TCL)!=0
175174
INCL = $(INCL) /I"$(TCLINCDIR)"
176175
!endif
177176
178
-CFLAGS = /nologo
177
+CFLAGS = /nologo /W2 /WX /utf-8
179178
LDFLAGS =
180179
181180
CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
182181
CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
183182
@@ -188,16 +187,27 @@
188187
!endif
189188
190189
!if $(FOSSIL_ENABLE_WINXP)!=0
191190
XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
192191
CFLAGS = $(CFLAGS) $(XPCFLAGS)
192
+#
193
+# NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
194
+# explicit initialization is redundant, but is required for post-built edits.
195
+#
193196
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
194
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
197
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
195198
!else
196
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
199
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
197200
!endif
198201
LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
202
+#
203
+# NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
204
+# is applied in a separate post-build step, see below for more information.
205
+#
206
+!if $(FOSSIL_ENABLE_SSL)!=0
207
+SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
208
+!endif
199209
!endif
200210
201211
!if $(FOSSIL_DYNAMIC_BUILD)!=0
202212
!if $(DEBUG)!=0
203213
CRTFLAGS = /MDd
@@ -299,21 +309,18 @@
299309
/DSQLITE_OMIT_DEPRECATED \
300310
/DSQLITE_OMIT_PROGRESS_CALLBACK \
301311
/DSQLITE_OMIT_SHARED_CACHE \
302312
/DSQLITE_OMIT_LOAD_EXTENSION \
303313
/DSQLITE_MAX_EXPR_DEPTH=0 \
304
- /DSQLITE_USE_ALLOCA \
305314
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
306315
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
307316
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
308317
/DSQLITE_ENABLE_FTS4 \
309318
/DSQLITE_ENABLE_DBSTAT_VTAB \
310
- /DSQLITE_ENABLE_JSON1 \
311319
/DSQLITE_ENABLE_FTS5 \
312320
/DSQLITE_ENABLE_STMTVTAB \
313321
/DSQLITE_HAVE_ZLIB \
314
- /DSQLITE_INTROSPECTION_PRAGMAS \
315322
/DSQLITE_ENABLE_DBPAGE_VTAB \
316323
/DSQLITE_TRUSTED_SCHEMA=0 \
317324
/DSQLITE_WIN32_NO_ANSI
318325
319326
SHELL_OPTIONS = /DNDEBUG=1 \
@@ -326,21 +333,18 @@
326333
/DSQLITE_OMIT_DEPRECATED \
327334
/DSQLITE_OMIT_PROGRESS_CALLBACK \
328335
/DSQLITE_OMIT_SHARED_CACHE \
329336
/DSQLITE_OMIT_LOAD_EXTENSION \
330337
/DSQLITE_MAX_EXPR_DEPTH=0 \
331
- /DSQLITE_USE_ALLOCA \
332338
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
333339
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
334340
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
335341
/DSQLITE_ENABLE_FTS4 \
336342
/DSQLITE_ENABLE_DBSTAT_VTAB \
337
- /DSQLITE_ENABLE_JSON1 \
338343
/DSQLITE_ENABLE_FTS5 \
339344
/DSQLITE_ENABLE_STMTVTAB \
340345
/DSQLITE_HAVE_ZLIB \
341
- /DSQLITE_INTROSPECTION_PRAGMAS \
342346
/DSQLITE_ENABLE_DBPAGE_VTAB \
343347
/DSQLITE_TRUSTED_SCHEMA=0 \
344348
/Dmain=sqlite3_shell \
345349
/DSQLITE_SHELL_IS_UTF8=1 \
346350
/DSQLITE_OMIT_LOAD_EXTENSION=1 \
@@ -496,11 +500,12 @@
496500
"$(OX)\wikiformat_.c" \
497501
"$(OX)\winfile_.c" \
498502
"$(OX)\winhttp_.c" \
499503
"$(OX)\xfer_.c" \
500504
"$(OX)\xfersetup_.c" \
501
- "$(OX)\zip_.c"
505
+ "$(OX)\zip_.c" \
506
+ "$(SRCDIR_extsrc)\pikchr.c"
502507
503508
EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
504509
"$(SRCDIR)\..\skins\ardoise\details.txt" \
505510
"$(SRCDIR)\..\skins\ardoise\footer.txt" \
506511
"$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -800,19 +805,42 @@
800805
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
801806
802807
!if $(FOSSIL_ENABLE_SSL)!=0
803808
openssl:
804809
@echo Building OpenSSL from "$(SSLDIR)"...
810
+!if $(FOSSIL_ENABLE_WINXP)!=0
811
+ @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
812
+!endif
805813
!ifdef PERLDIR
806814
@pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
807815
!else
808816
@pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
809817
!endif
810
-!if $(FOSSIL_ENABLE_WINXP)!=0
811
- @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
812
-!else
813818
@pushd "$(SSLDIR)" && $(MAKE) && popd
819
+!if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
820
+#
821
+# NOTE: Appending custom linker flags to the OpenSSL default linker flags is
822
+# somewhat difficult, as summarized in this Fossil Forum post:
823
+#
824
+# https://fossil-scm.org/forum/forumpost/a9a2d6af28b
825
+#
826
+# Therefore the custom linker flags required for Windows XP dynamic builds are
827
+# applied in a separate post-build step.
828
+#
829
+# If the build stops here, or if the custom linker flags are outside the scope
830
+# of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
831
+# the OpenSSL makefile by hand.
832
+#
833
+# Also note that this step changes the subsystem for the OpenSSL DLLs from
834
+# WINDOWS to CONSOLE, but which has no effect on DLLs.
835
+#
836
+ @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
837
+ @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) \
838
+ do @( \
839
+ echo %F & \
840
+ link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 \
841
+ )
814842
!endif
815843
816844
clean-openssl:
817845
@pushd "$(SSLDIR)" && $(MAKE) clean && popd
818846
!endif
@@ -2240,10 +2268,11 @@
22402268
"$(OX)\winfile_.c":"$(OX)\winfile.h" \
22412269
"$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
22422270
"$(OX)\xfer_.c":"$(OX)\xfer.h" \
22432271
"$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
22442272
"$(OX)\zip_.c":"$(OX)\zip.h" \
2273
+ "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \
22452274
"$(SRCDIR_extsrc)\sqlite3.h" \
22462275
"$(SRCDIR)\th.h" \
22472276
"$(OX)\VERSION.h" \
22482277
"$(SRCDIR_extsrc)\cson_amalgamation.h"
22492278
@copy /Y nul: $@
22502279
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116 !if $(FOSSIL_DYNAMIC_BUILD)!=0
117 SSLLIBDIR = $(SSLDIR)
118 !else
119 SSLLIBDIR = $(SSLDIR)
120 !endif
121 SSLLFLAGS = /nologo /opt:ref /debug
122 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
123 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
124 !message Using 'x64' platform for OpenSSL...
125 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
126 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
173
174 !if $(FOSSIL_ENABLE_TCL)!=0
175 INCL = $(INCL) /I"$(TCLINCDIR)"
176 !endif
177
178 CFLAGS = /nologo
179 LDFLAGS =
180
181 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
182 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
183
@@ -188,16 +187,27 @@
188 !endif
189
190 !if $(FOSSIL_ENABLE_WINXP)!=0
191 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
192 CFLAGS = $(CFLAGS) $(XPCFLAGS)
 
 
 
 
193 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
194 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
195 !else
196 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
197 !endif
198 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
 
 
 
 
 
 
 
199 !endif
200
201 !if $(FOSSIL_DYNAMIC_BUILD)!=0
202 !if $(DEBUG)!=0
203 CRTFLAGS = /MDd
@@ -299,21 +309,18 @@
299 /DSQLITE_OMIT_DEPRECATED \
300 /DSQLITE_OMIT_PROGRESS_CALLBACK \
301 /DSQLITE_OMIT_SHARED_CACHE \
302 /DSQLITE_OMIT_LOAD_EXTENSION \
303 /DSQLITE_MAX_EXPR_DEPTH=0 \
304 /DSQLITE_USE_ALLOCA \
305 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
306 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
307 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
308 /DSQLITE_ENABLE_FTS4 \
309 /DSQLITE_ENABLE_DBSTAT_VTAB \
310 /DSQLITE_ENABLE_JSON1 \
311 /DSQLITE_ENABLE_FTS5 \
312 /DSQLITE_ENABLE_STMTVTAB \
313 /DSQLITE_HAVE_ZLIB \
314 /DSQLITE_INTROSPECTION_PRAGMAS \
315 /DSQLITE_ENABLE_DBPAGE_VTAB \
316 /DSQLITE_TRUSTED_SCHEMA=0 \
317 /DSQLITE_WIN32_NO_ANSI
318
319 SHELL_OPTIONS = /DNDEBUG=1 \
@@ -326,21 +333,18 @@
326 /DSQLITE_OMIT_DEPRECATED \
327 /DSQLITE_OMIT_PROGRESS_CALLBACK \
328 /DSQLITE_OMIT_SHARED_CACHE \
329 /DSQLITE_OMIT_LOAD_EXTENSION \
330 /DSQLITE_MAX_EXPR_DEPTH=0 \
331 /DSQLITE_USE_ALLOCA \
332 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
333 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
334 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
335 /DSQLITE_ENABLE_FTS4 \
336 /DSQLITE_ENABLE_DBSTAT_VTAB \
337 /DSQLITE_ENABLE_JSON1 \
338 /DSQLITE_ENABLE_FTS5 \
339 /DSQLITE_ENABLE_STMTVTAB \
340 /DSQLITE_HAVE_ZLIB \
341 /DSQLITE_INTROSPECTION_PRAGMAS \
342 /DSQLITE_ENABLE_DBPAGE_VTAB \
343 /DSQLITE_TRUSTED_SCHEMA=0 \
344 /Dmain=sqlite3_shell \
345 /DSQLITE_SHELL_IS_UTF8=1 \
346 /DSQLITE_OMIT_LOAD_EXTENSION=1 \
@@ -496,11 +500,12 @@
496 "$(OX)\wikiformat_.c" \
497 "$(OX)\winfile_.c" \
498 "$(OX)\winhttp_.c" \
499 "$(OX)\xfer_.c" \
500 "$(OX)\xfersetup_.c" \
501 "$(OX)\zip_.c"
 
502
503 EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
504 "$(SRCDIR)\..\skins\ardoise\details.txt" \
505 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
506 "$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -800,19 +805,42 @@
800 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
801
802 !if $(FOSSIL_ENABLE_SSL)!=0
803 openssl:
804 @echo Building OpenSSL from "$(SSLDIR)"...
 
 
 
805 !ifdef PERLDIR
806 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
807 !else
808 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
809 !endif
810 !if $(FOSSIL_ENABLE_WINXP)!=0
811 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
812 !else
813 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814 !endif
815
816 clean-openssl:
817 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
818 !endif
@@ -2240,10 +2268,11 @@
2240 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2241 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2242 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2243 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2244 "$(OX)\zip_.c":"$(OX)\zip.h" \
 
2245 "$(SRCDIR_extsrc)\sqlite3.h" \
2246 "$(SRCDIR)\th.h" \
2247 "$(OX)\VERSION.h" \
2248 "$(SRCDIR_extsrc)\cson_amalgamation.h"
2249 @copy /Y nul: $@
2250
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116 !if $(FOSSIL_DYNAMIC_BUILD)!=0
117 SSLLIBDIR = $(SSLDIR)
118 !else
119 SSLLIBDIR = $(SSLDIR)
120 !endif
 
121 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
122 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
123 !message Using 'x64' platform for OpenSSL...
124 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
125 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
172
173 !if $(FOSSIL_ENABLE_TCL)!=0
174 INCL = $(INCL) /I"$(TCLINCDIR)"
175 !endif
176
177 CFLAGS = /nologo /W2 /WX /utf-8
178 LDFLAGS =
179
180 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
181 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
182
@@ -188,16 +187,27 @@
187 !endif
188
189 !if $(FOSSIL_ENABLE_WINXP)!=0
190 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
191 CFLAGS = $(CFLAGS) $(XPCFLAGS)
192 #
193 # NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
194 # explicit initialization is redundant, but is required for post-built edits.
195 #
196 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
197 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
198 !else
199 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
200 !endif
201 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
202 #
203 # NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
204 # is applied in a separate post-build step, see below for more information.
205 #
206 !if $(FOSSIL_ENABLE_SSL)!=0
207 SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
208 !endif
209 !endif
210
211 !if $(FOSSIL_DYNAMIC_BUILD)!=0
212 !if $(DEBUG)!=0
213 CRTFLAGS = /MDd
@@ -299,21 +309,18 @@
309 /DSQLITE_OMIT_DEPRECATED \
310 /DSQLITE_OMIT_PROGRESS_CALLBACK \
311 /DSQLITE_OMIT_SHARED_CACHE \
312 /DSQLITE_OMIT_LOAD_EXTENSION \
313 /DSQLITE_MAX_EXPR_DEPTH=0 \
 
314 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
315 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
316 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
317 /DSQLITE_ENABLE_FTS4 \
318 /DSQLITE_ENABLE_DBSTAT_VTAB \
 
319 /DSQLITE_ENABLE_FTS5 \
320 /DSQLITE_ENABLE_STMTVTAB \
321 /DSQLITE_HAVE_ZLIB \
 
322 /DSQLITE_ENABLE_DBPAGE_VTAB \
323 /DSQLITE_TRUSTED_SCHEMA=0 \
324 /DSQLITE_WIN32_NO_ANSI
325
326 SHELL_OPTIONS = /DNDEBUG=1 \
@@ -326,21 +333,18 @@
333 /DSQLITE_OMIT_DEPRECATED \
334 /DSQLITE_OMIT_PROGRESS_CALLBACK \
335 /DSQLITE_OMIT_SHARED_CACHE \
336 /DSQLITE_OMIT_LOAD_EXTENSION \
337 /DSQLITE_MAX_EXPR_DEPTH=0 \
 
338 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
339 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
340 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
341 /DSQLITE_ENABLE_FTS4 \
342 /DSQLITE_ENABLE_DBSTAT_VTAB \
 
343 /DSQLITE_ENABLE_FTS5 \
344 /DSQLITE_ENABLE_STMTVTAB \
345 /DSQLITE_HAVE_ZLIB \
 
346 /DSQLITE_ENABLE_DBPAGE_VTAB \
347 /DSQLITE_TRUSTED_SCHEMA=0 \
348 /Dmain=sqlite3_shell \
349 /DSQLITE_SHELL_IS_UTF8=1 \
350 /DSQLITE_OMIT_LOAD_EXTENSION=1 \
@@ -496,11 +500,12 @@
500 "$(OX)\wikiformat_.c" \
501 "$(OX)\winfile_.c" \
502 "$(OX)\winhttp_.c" \
503 "$(OX)\xfer_.c" \
504 "$(OX)\xfersetup_.c" \
505 "$(OX)\zip_.c" \
506 "$(SRCDIR_extsrc)\pikchr.c"
507
508 EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
509 "$(SRCDIR)\..\skins\ardoise\details.txt" \
510 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
511 "$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -800,19 +805,42 @@
805 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
806
807 !if $(FOSSIL_ENABLE_SSL)!=0
808 openssl:
809 @echo Building OpenSSL from "$(SSLDIR)"...
810 !if $(FOSSIL_ENABLE_WINXP)!=0
811 @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
812 !endif
813 !ifdef PERLDIR
814 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
815 !else
816 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
817 !endif
 
 
 
818 @pushd "$(SSLDIR)" && $(MAKE) && popd
819 !if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
820 #
821 # NOTE: Appending custom linker flags to the OpenSSL default linker flags is
822 # somewhat difficult, as summarized in this Fossil Forum post:
823 #
824 # https://fossil-scm.org/forum/forumpost/a9a2d6af28b
825 #
826 # Therefore the custom linker flags required for Windows XP dynamic builds are
827 # applied in a separate post-build step.
828 #
829 # If the build stops here, or if the custom linker flags are outside the scope
830 # of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
831 # the OpenSSL makefile by hand.
832 #
833 # Also note that this step changes the subsystem for the OpenSSL DLLs from
834 # WINDOWS to CONSOLE, but which has no effect on DLLs.
835 #
836 @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
837 @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) \
838 do @( \
839 echo %F & \
840 link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 \
841 )
842 !endif
843
844 clean-openssl:
845 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
846 !endif
@@ -2240,10 +2268,11 @@
2268 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2269 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2270 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2271 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2272 "$(OX)\zip_.c":"$(OX)\zip.h" \
2273 "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \
2274 "$(SRCDIR_extsrc)\sqlite3.h" \
2275 "$(SRCDIR)\th.h" \
2276 "$(OX)\VERSION.h" \
2277 "$(SRCDIR_extsrc)\cson_amalgamation.h"
2278 @copy /Y nul: $@
2279
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189189
<a id="cgivar"></a>
190190
The web server sets many environment variables in step 2 in addition
191191
to just PATH_INFO. The following diagram shows a few of these variables
192192
and their relationship to the request URL:
193193
<pre>
194
- REQUEST_URI
195
- ______________|___________________
196
- / \
194
+ REQUEST_URI
195
+ ___________________|_______________________
196
+ / \
197197
http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198198
\_________/\____________/\____________________/ \______/
199199
| | | |
200200
HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201201
</pre>
202202
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189 <a id="cgivar"></a>
190 The web server sets many environment variables in step 2 in addition
191 to just PATH_INFO. The following diagram shows a few of these variables
192 and their relationship to the request URL:
193 <pre>
194 REQUEST_URI
195 ______________|___________________
196 / \
197 http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198 \_________/\____________/\____________________/ \______/
199 | | | |
200 HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201 </pre>
202
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189 <a id="cgivar"></a>
190 The web server sets many environment variables in step 2 in addition
191 to just PATH_INFO. The following diagram shows a few of these variables
192 and their relationship to the request URL:
193 <pre>
194 REQUEST_URI
195 ___________________|_______________________
196 / \
197 http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198 \_________/\____________/\____________________/ \______/
199 | | | |
200 HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201 </pre>
202
+65 -66
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1
-<title>Defense Against Spiders</title>
2
-
3
-The website presented by a Fossil server has many hyperlinks.
4
-Even a modest project can have millions of pages in its
5
-tree, and many of those pages (for example diffs and annotations
6
-and ZIP archives of older check-ins) can be expensive to compute.
7
-If a spider or bot tries to walk a website implemented by
8
-Fossil, it can present a crippling bandwidth and CPU load.
9
-
10
-The website presented by a Fossil server is intended to be used
11
-interactively by humans, not walked by spiders. This article
1
+<title>Defense Against Robots</title>
2
+
3
+A typical Fossil website can have millions of pages, and many of
4
+those pages (for example diffs and annotations and tarballs) can
5
+be expensive to compute.
6
+If a robot walks a Fossil-generated website,
7
+it can present a crippling bandwidth and CPU load.
8
+
9
+A Fossil website is intended to be used
10
+interactively by humans, not walked by robots. This article
1211
describes the techniques used by Fossil to try to welcome human
13
-users while keeping out spiders.
12
+users while keeping out robots.
1413
1514
<h2>The Hyperlink User Capability</h2>
1615
1716
Every Fossil web session has a "user". For random passers-by on the internet
18
-(and for spiders) that user is "nobody". The "anonymous" user is also
17
+(and for robots) that user is "nobody". The "anonymous" user is also
1918
available for humans who do not wish to identify themselves. The difference
2019
is that "anonymous" requires a login (using a password supplied via
2120
a CAPTCHA) whereas "nobody" does not require a login.
2221
The site administrator can also create logins with
2322
passwords for specific individuals.
2423
2524
Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
2625
do not see most Fossil-generated hyperlinks. This is
27
-a simple defense against spiders, since [./caps/#ucat | the "nobody"
26
+a simple defense against robots, since [./caps/#ucat | the "nobody"
2827
user category] does not have this capability by default.
2928
Users must log in (perhaps as
30
-"anonymous") before they can see any of the hyperlinks. A spider
29
+"anonymous") before they can see any of the hyperlinks. A robot
3130
that cannot log into your Fossil repository will be unable to walk
3231
its historical check-ins, create diffs between versions, pull zip
33
-archives, etc. by visiting links, because they aren't there.
32
+archives, etc. by visiting links, because there are no links.
3433
3534
A text message appears at the top of each page in this situation to
3635
invite humans to log in as anonymous in order to activate hyperlinks.
3736
38
-Because this required login step is annoying to some,
39
-Fossil provides other techniques for blocking spiders which
37
+But requiring a login, even an anonymous login, can be annoying.
38
+Fossil provides other techniques for blocking robots which
4039
are less cumbersome to humans.
4140
4241
<h2>Automatic Hyperlinks Based on UserAgent</h2>
4342
4443
Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
4544
that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
4645
HTTP request header and on the browsers ability to run Javascript.
4746
4847
The UserAgent string is a text identifier that is included in the header
4948
of most HTTP requests that identifies the specific maker and version of
50
-the browser (or spider) that generated the request. Typical UserAgent
49
+the browser (or robot) that generated the request. Typical UserAgent
5150
strings look like this:
5251
5352
<ul>
5453
<li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
5554
<li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
5756
<li> Wget/1.12 (openbsd4.9)
5857
</ul>
5958
6059
The first two UserAgent strings above identify Firefox 19 and
6160
Internet Explorer 8.0, both running on Windows NT. The third
62
-example is the spider used by Google to index the internet.
61
+example is the robot used by Google to index the internet.
6362
The fourth example is the "wget" utility running on OpenBSD.
6463
Thus the first two UserAgent strings above identify the requester
65
-as human whereas the second two identify the requester as a spider.
64
+as human whereas the second two identify the requester as a robot.
6665
Note that the UserAgent string is completely under the control
67
-of the requester and so a malicious spider can forge a UserAgent
68
-string that makes it look like a human. But most spiders truly
69
-seem to desire to "play nicely" on the internet and are quite open
70
-about the fact that they are a spider. And so the UserAgent string
66
+of the requester and so a malicious robot can forge a UserAgent
67
+string that makes it look like a human. But most robots want
68
+to "play nicely" on the internet and are quite open
69
+about the fact that they are a robot. And so the UserAgent string
7170
provides a good first-guess about whether or not a request originates
72
-from a human or a spider.
73
-
74
-In Fossil, under the Admin/Access menu, there is a setting entitled
75
-"<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>".
76
-If this setting is enabled, and if the UserAgent string looks like a
77
-human and not a spider, then Fossil will enable hyperlinks even if
78
-the <b>Hyperlink</b> capability is omitted from the user permissions. This setting
79
-gives humans easy access to the hyperlinks while preventing spiders
80
-from walking the millions of pages on a typical Fossil site.
81
-
82
-But the hyperlinks are not enabled directly with the setting above.
71
+from a human or a robot.
72
+
73
+In Fossil, under the Admin/Robot-Defense menu, there is a setting entitled
74
+"<b>Enable hyperlinks based on User-Agent and/or Javascript</b>".
75
+If this setting is set to "UserAgent only" or "UserAgent and Javascript",
76
+and if the UserAgent string looks like a human and not a robot, then
77
+Fossil will enable hyperlinks even if the <b>Hyperlink</b> capability
78
+is omitted from the user permissions. This settingn gives humans easy
79
+access to the hyperlinks while preventing robots
80
+from walking the billions of pages on a typical Fossil site.
81
+
82
+If the setting is "UserAgent only", then the hyperlinks are simply
83
+enabled and that is all. But if the setting is "UserAgent and Javascript",
84
+then the hyperlinks are not enabled directly .
8385
Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
84
-without "href=" attributes. Then, JavaScript code is added to the
85
-end of the page that goes back and fills in the "href=" attributes of
86
-the anchor tags with the hyperlink targets, thus enabling the hyperlinks.
86
+with "href=" attributes that point to [/honeypot] rather than the correct
87
+link. JavaScript code is added to the end of the page that goes back and
88
+fills in the correct "href=" attributes of
89
+the anchor tags with the true hyperlink targets, thus enabling the hyperlinks.
8790
This extra step of using JavaScript to enable the hyperlink targets
88
-is a security measure against spiders that forge a human-looking
89
-UserAgent string. Most spiders do not bother to run JavaScript and
90
-so to the spider the empty anchor tag will be useless. But all modern
91
+is a security measure against robots that forge a human-looking
92
+UserAgent string. Most robots do not bother to run JavaScript and
93
+so to the robot the empty anchor tag will be useless. But all modern
9194
web browsers implement JavaScript, so hyperlinks will show up
9295
normally for human users.
9396
9497
<h2>Further Defenses</h2>
9598
9699
Recently (as of this writing, in the spring of 2013) the Fossil server
97100
on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
98
-by Chinese spiders that use forged UserAgent strings to make them look
101
+by Chinese robots that use forged UserAgent strings to make them look
99102
like normal web browsers and which interpret JavaScript. We do not
100103
believe these attacks to be nefarious since SQLite is public domain
101104
and the attackers could obtain all information they ever wanted to
102105
know about SQLite simply by cloning the repository. Instead, we
103106
believe these "attacks" are coming from "script kiddies". But regardless
104107
of whether or not malice is involved, these attacks do present
105108
an unnecessary load on the server which reduces the responsiveness of
106109
the SQLite website for well-behaved and socially responsible users.
107110
For this reason, additional defenses against
108
-spiders have been put in place.
111
+robots have been put in place.
109112
110
-On the Admin/Access page of Fossil, just below the
111
-"<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
113
+On the Admin/Robot-Defense page of Fossil, just below the
114
+"<b>Enable hyperlinks using User-Agent and/or Javascript</b>"
112115
setting, there are now two additional sub-settings that can be optionally
113116
enabled to control hyperlinks.
114117
115
-The first sub-setting waits to run the
116
-JavaScript that sets the "href=" attributes on anchor tags until after
117
-at least one "mouseover" event has been detected on the &lt;body&gt;
118
-element of the page. The thinking here is that spiders will not be
119
-simulating mouse motion and so no mouseover events will ever occur and
120
-hence the hyperlinks will never become enabled for spiders.
121
-
122
-The second new sub-setting is a delay (in milliseconds) before setting
123
-the "href=" attributes on anchor tags. The default value for this
124
-delay is 10 milliseconds. The idea here is that a spider will try to
125
-render the page immediately, and will not wait for delayed scripts
126
-to be run, thus will never enable the hyperlinks.
127
-
128
-These two sub-settings can be used separately or together. If used together,
129
-then the delay timer does not start until after the first mouse movement
130
-is detected.
118
+The first new sub-setting is a delay (in milliseconds) before setting
119
+the "href=" attributes on anchor tags. The default value for this
120
+delay is 10 milliseconds. The idea here is that a robots will try to
121
+interpret the links on the page immediately, and will not wait for delayed
122
+scripts to be run, and thus will never enable the true links.
123
+
124
+The second sub-setting waits to run the
125
+JavaScript that sets the "href=" attributes on anchor tags until after
126
+at least one "mousedown" or "mousemove" event has been detected on the
127
+&lt;body&gt; element of the page. The thinking here is that robots will not be
128
+simulating mouse motion and so no mouse events will ever occur and
129
+hence the hyperlinks will never become enabled for robots.
131130
132131
See also [./loadmgmt.md|Managing Server Load] for a description
133132
of how expensive pages can be disabled when the server is under heavy
134133
load.
135134
136135
<h2>The Ongoing Struggle</h2>
137136
138137
Fossil currently does a very good job of providing easy access to humans
139
-while keeping out troublesome robots and spiders. However, spiders and
140
-bots continue to grow more sophisticated, requiring ever more advanced
138
+while keeping out troublesome robots. However, robots
139
+continue to grow more sophisticated, requiring ever more advanced
141140
defenses. This "arms race" is unlikely to ever end. The developers of
142
-Fossil will continue to try improve the spider defenses of Fossil so
141
+Fossil will continue to try improve the robot defenses of Fossil so
143142
check back from time to time for the latest releases and updates.
144143
145
-Readers of this page who have suggestions on how to improve the spider
144
+Readers of this page who have suggestions on how to improve the robot
146145
defenses in Fossil are invited to submit your ideas to the Fossil Users
147146
forum:
148147
[https://fossil-scm.org/forum].
149148
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1 <title>Defense Against Spiders</title>
2
3 The website presented by a Fossil server has many hyperlinks.
4 Even a modest project can have millions of pages in its
5 tree, and many of those pages (for example diffs and annotations
6 and ZIP archives of older check-ins) can be expensive to compute.
7 If a spider or bot tries to walk a website implemented by
8 Fossil, it can present a crippling bandwidth and CPU load.
9
10 The website presented by a Fossil server is intended to be used
11 interactively by humans, not walked by spiders. This article
12 describes the techniques used by Fossil to try to welcome human
13 users while keeping out spiders.
14
15 <h2>The Hyperlink User Capability</h2>
16
17 Every Fossil web session has a "user". For random passers-by on the internet
18 (and for spiders) that user is "nobody". The "anonymous" user is also
19 available for humans who do not wish to identify themselves. The difference
20 is that "anonymous" requires a login (using a password supplied via
21 a CAPTCHA) whereas "nobody" does not require a login.
22 The site administrator can also create logins with
23 passwords for specific individuals.
24
25 Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
26 do not see most Fossil-generated hyperlinks. This is
27 a simple defense against spiders, since [./caps/#ucat | the "nobody"
28 user category] does not have this capability by default.
29 Users must log in (perhaps as
30 "anonymous") before they can see any of the hyperlinks. A spider
31 that cannot log into your Fossil repository will be unable to walk
32 its historical check-ins, create diffs between versions, pull zip
33 archives, etc. by visiting links, because they aren't there.
34
35 A text message appears at the top of each page in this situation to
36 invite humans to log in as anonymous in order to activate hyperlinks.
37
38 Because this required login step is annoying to some,
39 Fossil provides other techniques for blocking spiders which
40 are less cumbersome to humans.
41
42 <h2>Automatic Hyperlinks Based on UserAgent</h2>
43
44 Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
45 that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
46 HTTP request header and on the browsers ability to run Javascript.
47
48 The UserAgent string is a text identifier that is included in the header
49 of most HTTP requests that identifies the specific maker and version of
50 the browser (or spider) that generated the request. Typical UserAgent
51 strings look like this:
52
53 <ul>
54 <li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
55 <li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
57 <li> Wget/1.12 (openbsd4.9)
58 </ul>
59
60 The first two UserAgent strings above identify Firefox 19 and
61 Internet Explorer 8.0, both running on Windows NT. The third
62 example is the spider used by Google to index the internet.
63 The fourth example is the "wget" utility running on OpenBSD.
64 Thus the first two UserAgent strings above identify the requester
65 as human whereas the second two identify the requester as a spider.
66 Note that the UserAgent string is completely under the control
67 of the requester and so a malicious spider can forge a UserAgent
68 string that makes it look like a human. But most spiders truly
69 seem to desire to "play nicely" on the internet and are quite open
70 about the fact that they are a spider. And so the UserAgent string
71 provides a good first-guess about whether or not a request originates
72 from a human or a spider.
73
74 In Fossil, under the Admin/Access menu, there is a setting entitled
75 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>".
76 If this setting is enabled, and if the UserAgent string looks like a
77 human and not a spider, then Fossil will enable hyperlinks even if
78 the <b>Hyperlink</b> capability is omitted from the user permissions. This setting
79 gives humans easy access to the hyperlinks while preventing spiders
80 from walking the millions of pages on a typical Fossil site.
81
82 But the hyperlinks are not enabled directly with the setting above.
 
 
 
83 Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
84 without "href=" attributes. Then, JavaScript code is added to the
85 end of the page that goes back and fills in the "href=" attributes of
86 the anchor tags with the hyperlink targets, thus enabling the hyperlinks.
 
87 This extra step of using JavaScript to enable the hyperlink targets
88 is a security measure against spiders that forge a human-looking
89 UserAgent string. Most spiders do not bother to run JavaScript and
90 so to the spider the empty anchor tag will be useless. But all modern
91 web browsers implement JavaScript, so hyperlinks will show up
92 normally for human users.
93
94 <h2>Further Defenses</h2>
95
96 Recently (as of this writing, in the spring of 2013) the Fossil server
97 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
98 by Chinese spiders that use forged UserAgent strings to make them look
99 like normal web browsers and which interpret JavaScript. We do not
100 believe these attacks to be nefarious since SQLite is public domain
101 and the attackers could obtain all information they ever wanted to
102 know about SQLite simply by cloning the repository. Instead, we
103 believe these "attacks" are coming from "script kiddies". But regardless
104 of whether or not malice is involved, these attacks do present
105 an unnecessary load on the server which reduces the responsiveness of
106 the SQLite website for well-behaved and socially responsible users.
107 For this reason, additional defenses against
108 spiders have been put in place.
109
110 On the Admin/Access page of Fossil, just below the
111 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
112 setting, there are now two additional sub-settings that can be optionally
113 enabled to control hyperlinks.
114
115 The first sub-setting waits to run the
116 JavaScript that sets the "href=" attributes on anchor tags until after
117 at least one "mouseover" event has been detected on the &lt;body&gt;
118 element of the page. The thinking here is that spiders will not be
119 simulating mouse motion and so no mouseover events will ever occur and
120 hence the hyperlinks will never become enabled for spiders.
121
122 The second new sub-setting is a delay (in milliseconds) before setting
123 the "href=" attributes on anchor tags. The default value for this
124 delay is 10 milliseconds. The idea here is that a spider will try to
125 render the page immediately, and will not wait for delayed scripts
126 to be run, thus will never enable the hyperlinks.
127
128 These two sub-settings can be used separately or together. If used together,
129 then the delay timer does not start until after the first mouse movement
130 is detected.
131
132 See also [./loadmgmt.md|Managing Server Load] for a description
133 of how expensive pages can be disabled when the server is under heavy
134 load.
135
136 <h2>The Ongoing Struggle</h2>
137
138 Fossil currently does a very good job of providing easy access to humans
139 while keeping out troublesome robots and spiders. However, spiders and
140 bots continue to grow more sophisticated, requiring ever more advanced
141 defenses. This "arms race" is unlikely to ever end. The developers of
142 Fossil will continue to try improve the spider defenses of Fossil so
143 check back from time to time for the latest releases and updates.
144
145 Readers of this page who have suggestions on how to improve the spider
146 defenses in Fossil are invited to submit your ideas to the Fossil Users
147 forum:
148 [https://fossil-scm.org/forum].
149
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1 <title>Defense Against Robots</title>
2
3 A typical Fossil website can have millions of pages, and many of
4 those pages (for example diffs and annotations and tarballs) can
5 be expensive to compute.
6 If a robot walks a Fossil-generated website,
7 it can present a crippling bandwidth and CPU load.
8
9 A Fossil website is intended to be used
10 interactively by humans, not walked by robots. This article
 
11 describes the techniques used by Fossil to try to welcome human
12 users while keeping out robots.
13
14 <h2>The Hyperlink User Capability</h2>
15
16 Every Fossil web session has a "user". For random passers-by on the internet
17 (and for robots) that user is "nobody". The "anonymous" user is also
18 available for humans who do not wish to identify themselves. The difference
19 is that "anonymous" requires a login (using a password supplied via
20 a CAPTCHA) whereas "nobody" does not require a login.
21 The site administrator can also create logins with
22 passwords for specific individuals.
23
24 Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
25 do not see most Fossil-generated hyperlinks. This is
26 a simple defense against robots, since [./caps/#ucat | the "nobody"
27 user category] does not have this capability by default.
28 Users must log in (perhaps as
29 "anonymous") before they can see any of the hyperlinks. A robot
30 that cannot log into your Fossil repository will be unable to walk
31 its historical check-ins, create diffs between versions, pull zip
32 archives, etc. by visiting links, because there are no links.
33
34 A text message appears at the top of each page in this situation to
35 invite humans to log in as anonymous in order to activate hyperlinks.
36
37 But requiring a login, even an anonymous login, can be annoying.
38 Fossil provides other techniques for blocking robots which
39 are less cumbersome to humans.
40
41 <h2>Automatic Hyperlinks Based on UserAgent</h2>
42
43 Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
44 that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
45 HTTP request header and on the browsers ability to run Javascript.
46
47 The UserAgent string is a text identifier that is included in the header
48 of most HTTP requests that identifies the specific maker and version of
49 the browser (or robot) that generated the request. Typical UserAgent
50 strings look like this:
51
52 <ul>
53 <li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
54 <li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
56 <li> Wget/1.12 (openbsd4.9)
57 </ul>
58
59 The first two UserAgent strings above identify Firefox 19 and
60 Internet Explorer 8.0, both running on Windows NT. The third
61 example is the robot used by Google to index the internet.
62 The fourth example is the "wget" utility running on OpenBSD.
63 Thus the first two UserAgent strings above identify the requester
64 as human whereas the second two identify the requester as a robot.
65 Note that the UserAgent string is completely under the control
66 of the requester and so a malicious robot can forge a UserAgent
67 string that makes it look like a human. But most robots want
68 to "play nicely" on the internet and are quite open
69 about the fact that they are a robot. And so the UserAgent string
70 provides a good first-guess about whether or not a request originates
71 from a human or a robot.
72
73 In Fossil, under the Admin/Robot-Defense menu, there is a setting entitled
74 "<b>Enable hyperlinks based on User-Agent and/or Javascript</b>".
75 If this setting is set to "UserAgent only" or "UserAgent and Javascript",
76 and if the UserAgent string looks like a human and not a robot, then
77 Fossil will enable hyperlinks even if the <b>Hyperlink</b> capability
78 is omitted from the user permissions. This settingn gives humans easy
79 access to the hyperlinks while preventing robots
80 from walking the billions of pages on a typical Fossil site.
81
82 If the setting is "UserAgent only", then the hyperlinks are simply
83 enabled and that is all. But if the setting is "UserAgent and Javascript",
84 then the hyperlinks are not enabled directly .
85 Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
86 with "href=" attributes that point to [/honeypot] rather than the correct
87 link. JavaScript code is added to the end of the page that goes back and
88 fills in the correct "href=" attributes of
89 the anchor tags with the true hyperlink targets, thus enabling the hyperlinks.
90 This extra step of using JavaScript to enable the hyperlink targets
91 is a security measure against robots that forge a human-looking
92 UserAgent string. Most robots do not bother to run JavaScript and
93 so to the robot the empty anchor tag will be useless. But all modern
94 web browsers implement JavaScript, so hyperlinks will show up
95 normally for human users.
96
97 <h2>Further Defenses</h2>
98
99 Recently (as of this writing, in the spring of 2013) the Fossil server
100 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
101 by Chinese robots that use forged UserAgent strings to make them look
102 like normal web browsers and which interpret JavaScript. We do not
103 believe these attacks to be nefarious since SQLite is public domain
104 and the attackers could obtain all information they ever wanted to
105 know about SQLite simply by cloning the repository. Instead, we
106 believe these "attacks" are coming from "script kiddies". But regardless
107 of whether or not malice is involved, these attacks do present
108 an unnecessary load on the server which reduces the responsiveness of
109 the SQLite website for well-behaved and socially responsible users.
110 For this reason, additional defenses against
111 robots have been put in place.
112
113 On the Admin/Robot-Defense page of Fossil, just below the
114 "<b>Enable hyperlinks using User-Agent and/or Javascript</b>"
115 setting, there are now two additional sub-settings that can be optionally
116 enabled to control hyperlinks.
117
118 The first new sub-setting is a delay (in milliseconds) before setting
119 the "href=" attributes on anchor tags. The default value for this
120 delay is 10 milliseconds. The idea here is that a robots will try to
121 interpret the links on the page immediately, and will not wait for delayed
122 scripts to be run, and thus will never enable the true links.
123
124 The second sub-setting waits to run the
125 JavaScript that sets the "href=" attributes on anchor tags until after
126 at least one "mousedown" or "mousemove" event has been detected on the
127 &lt;body&gt; element of the page. The thinking here is that robots will not be
128 simulating mouse motion and so no mouse events will ever occur and
129 hence the hyperlinks will never become enabled for robots.
 
 
 
 
130
131 See also [./loadmgmt.md|Managing Server Load] for a description
132 of how expensive pages can be disabled when the server is under heavy
133 load.
134
135 <h2>The Ongoing Struggle</h2>
136
137 Fossil currently does a very good job of providing easy access to humans
138 while keeping out troublesome robots. However, robots
139 continue to grow more sophisticated, requiring ever more advanced
140 defenses. This "arms race" is unlikely to ever end. The developers of
141 Fossil will continue to try improve the robot defenses of Fossil so
142 check back from time to time for the latest releases and updates.
143
144 Readers of this page who have suggestions on how to improve the robot
145 defenses in Fossil are invited to submit your ideas to the Fossil Users
146 forum:
147 [https://fossil-scm.org/forum].
148
+1 -1
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233233
won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234234
a different cipher algorithm; both changes are likely to weaken the
235235
encryption significantly, so you should install a newer version rather
236236
than work around the lack of these features.
237237
238
-At the time of this writing — 2021.02.26 — macOS 11 (BigSur) ships an
238
+At the time of this writing — 2022.03.28 — macOS 12 (Monterey) still ships an
239239
outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240240
capability. Until Apple redresses this lack, we recommend use of the
241241
[Homebrew][hb] OpenSSL package rather than give up on the security
242242
afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243243
later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244244
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233 won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234 a different cipher algorithm; both changes are likely to weaken the
235 encryption significantly, so you should install a newer version rather
236 than work around the lack of these features.
237
238 At the time of this writing — 2021.02.26 — macOS 11 (BigSur) ships an
239 outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240 capability. Until Apple redresses this lack, we recommend use of the
241 [Homebrew][hb] OpenSSL package rather than give up on the security
242 afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243 later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233 won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234 a different cipher algorithm; both changes are likely to weaken the
235 encryption significantly, so you should install a newer version rather
236 than work around the lack of these features.
237
238 At the time of this writing — 2022.03.28 — macOS 12 (Monterey) still ships an
239 outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240 capability. Until Apple redresses this lack, we recommend use of the
241 [Homebrew][hb] OpenSSL package rather than give up on the security
242 afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243 later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244
+45 -13
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,24 +1,56 @@
11
<title>Change Log</title>
22
3
-<h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
3
+<h2 id='v2_19'>Changes for version 2.19 (pending)</h2>
4
+ * On file listing pages, sort filenames using the "uintnocase" collating
5
+ sequence, so that filenames that contains embedded integers sort in
6
+ numeric order even if they contain a different number of digits.
7
+ (Example: "fossil_80_..." comes before "fossil_100.png" in the
8
+ [/dir?ci=92fd091703a28c07&name=skins/blitz|/skins/blitz] directory listing.)
9
+ * Enhancements to the graph layout algorithm design to improve readability
10
+ and promote better situational awareness.
11
+ * Performance enhancement for the
12
+ [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13
+ accomplished using a Common Table Expression in the underlying SQL.
14
+
15
+<h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
416
* Added support for [./ssl-server.md|SSL/TLS server mode] for commands
517
like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
6
- * Added the --share-links option to [/help?cmd=sync|fossil sync] and
7
- [/help?cmd=pull|fossil pull]. Enhance the
8
- [/doc/trunk/www/sync.wiki|sync protocol] so that it is able to support
9
- sharing of links to other clones.
10
- * Added the --transport-command option to [/help?cmd=sync|fossil sync]
11
- and similar.
12
- * [/help?cmd=/chat|The /chat page] input options have been reworked
13
- again for better cross-browser portability.
14
- * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
15
- immediately lost and sending may optionally be retried.
16
- * [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
17
- types directly into message bodies via an iframe.
1818
* The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
1919
[/help?cmd=merge|merge --cherrypick].
20
+ * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
21
+ of any file in a commit exceeds this size, a warning is issued.
22
+ * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
23
+ * The [/help?cmd=tar|tar] and [/help?cmd=zip|zip commands] no longer
24
+ sterilize the manifest file.
25
+ * Futher improvement to diff alignment in cases that involve both
26
+ edits and indentation changes.
27
+ * [/doc/trunk/www/chat.md|Chat] improvements:<ul>
28
+ <li> [/help?cmd=/chat|The /chat page] input options have been reworked
29
+ again for better cross-browser portability.
30
+ <li> When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
31
+ immediately lost and sending may optionally be retried.
32
+ <li> [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
33
+ types directly into message bodies via an iframe.
34
+ <li> Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
35
+ command.
36
+ <li> Added the "[/help?cmd=chat|fossil chat pull]" command, available to
37
+ administrators only, for backing up the chat conversation.
38
+ </ul>
39
+ * Promote the test-detach command into the [/help?cmd=detach|detach command].
40
+ * For "[/help?cmd=pull|fossil pull]" with the --from-parent-project option,
41
+ if no URL is specified then use the last URL from the most recent prior
42
+ "fossil pull --from-parent-project".
43
+ * Add options --project-name and --project-desc to the
44
+ "[/help?cmd=init|fossil init]" command.
45
+ * The [/help?cmd=/ext|/ext page] generates the SERVER_SOFTWARE environment
46
+ variable for clients.
47
+ * Fix the REQUEST_URI [/doc/trunk/www/aboutcgi.wiki#cgivar|CGI variable] such
48
+ that it includes the query string. This is how most other systems understand
49
+ REQUEST_URI.
50
+ * Added the --transport-command option to [/help?cmd=sync|fossil sync]
51
+ and similar.
2052
2153
<h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
2254
2355
* Major improvements to the "diff" subsystem, including: <ul>
2456
<li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
2557
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,24 +1,56 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
 
 
 
 
 
 
 
 
 
 
 
 
4 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
5 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
6 * Added the --share-links option to [/help?cmd=sync|fossil sync] and
7 [/help?cmd=pull|fossil pull]. Enhance the
8 [/doc/trunk/www/sync.wiki|sync protocol] so that it is able to support
9 sharing of links to other clones.
10 * Added the --transport-command option to [/help?cmd=sync|fossil sync]
11 and similar.
12 * [/help?cmd=/chat|The /chat page] input options have been reworked
13 again for better cross-browser portability.
14 * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
15 immediately lost and sending may optionally be retried.
16 * [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
17 types directly into message bodies via an iframe.
18 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
19 [/help?cmd=merge|merge --cherrypick].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
21 <h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
22
23 * Major improvements to the "diff" subsystem, including: <ul>
24 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
25
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,24 +1,56 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_19'>Changes for version 2.19 (pending)</h2>
4 * On file listing pages, sort filenames using the "uintnocase" collating
5 sequence, so that filenames that contains embedded integers sort in
6 numeric order even if they contain a different number of digits.
7 (Example: "fossil_80_..." comes before "fossil_100.png" in the
8 [/dir?ci=92fd091703a28c07&name=skins/blitz|/skins/blitz] directory listing.)
9 * Enhancements to the graph layout algorithm design to improve readability
10 and promote better situational awareness.
11 * Performance enhancement for the
12 [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13 accomplished using a Common Table Expression in the underlying SQL.
14
15 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
16 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
17 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
 
 
 
 
 
 
 
 
 
 
 
 
18 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
19 [/help?cmd=merge|merge --cherrypick].
20 * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
21 of any file in a commit exceeds this size, a warning is issued.
22 * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
23 * The [/help?cmd=tar|tar] and [/help?cmd=zip|zip commands] no longer
24 sterilize the manifest file.
25 * Futher improvement to diff alignment in cases that involve both
26 edits and indentation changes.
27 * [/doc/trunk/www/chat.md|Chat] improvements:<ul>
28 <li> [/help?cmd=/chat|The /chat page] input options have been reworked
29 again for better cross-browser portability.
30 <li> When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
31 immediately lost and sending may optionally be retried.
32 <li> [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
33 types directly into message bodies via an iframe.
34 <li> Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
35 command.
36 <li> Added the "[/help?cmd=chat|fossil chat pull]" command, available to
37 administrators only, for backing up the chat conversation.
38 </ul>
39 * Promote the test-detach command into the [/help?cmd=detach|detach command].
40 * For "[/help?cmd=pull|fossil pull]" with the --from-parent-project option,
41 if no URL is specified then use the last URL from the most recent prior
42 "fossil pull --from-parent-project".
43 * Add options --project-name and --project-desc to the
44 "[/help?cmd=init|fossil init]" command.
45 * The [/help?cmd=/ext|/ext page] generates the SERVER_SOFTWARE environment
46 variable for clients.
47 * Fix the REQUEST_URI [/doc/trunk/www/aboutcgi.wiki#cgivar|CGI variable] such
48 that it includes the query string. This is how most other systems understand
49 REQUEST_URI.
50 * Added the --transport-command option to [/help?cmd=sync|fossil sync]
51 and similar.
52
53 <h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
54
55 * Major improvements to the "diff" subsystem, including: <ul>
56 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
57
+1 -1
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136136
The [fossil chat send](/help?cmd=chat) can be used by project-specific
137137
robots to send notifications to the chatroom. For example, on the
138138
[SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139139
feature, and indeed all of Fossil, was invented) there are long-running
140140
fuzz servers that sometimes run across obscure problems. Whenever this
141
-happens, a message is sent to the SQLite developers chatroom altering
141
+happens, a message is sent to the SQLite developers chatroom alerting
142142
them to the problem.
143143
144144
The recommended way to allow robots to send chat messages is to create
145145
a new user on the server for each robot. Give each such robot account
146146
the "C" privilege only. That means that the robot user account will be
147147
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136 The [fossil chat send](/help?cmd=chat) can be used by project-specific
137 robots to send notifications to the chatroom. For example, on the
138 [SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139 feature, and indeed all of Fossil, was invented) there are long-running
140 fuzz servers that sometimes run across obscure problems. Whenever this
141 happens, a message is sent to the SQLite developers chatroom altering
142 them to the problem.
143
144 The recommended way to allow robots to send chat messages is to create
145 a new user on the server for each robot. Give each such robot account
146 the "C" privilege only. That means that the robot user account will be
147
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136 The [fossil chat send](/help?cmd=chat) can be used by project-specific
137 robots to send notifications to the chatroom. For example, on the
138 [SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139 feature, and indeed all of Fossil, was invented) there are long-running
140 fuzz servers that sometimes run across obscure problems. Whenever this
141 happens, a message is sent to the SQLite developers chatroom alerting
142 them to the problem.
143
144 The recommended way to allow robots to send chat messages is to create
145 a new user on the server for each robot. Give each such robot account
146 the "C" privilege only. That means that the robot user account will be
147
+1 -1
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
3030
style-src 'self' 'unsafe-inline';
3131
img-src * data:;
3232
</pre>
3333
3434
The default is recommended for most installations. However,
35
-the site administrators can overwrite this default DSP using the
35
+the site administrators can overwrite this default CSP using the
3636
[default-csp setting](/help?cmd=default-csp). For example,
3737
CSP restrictions can be completely disabled by setting the default-csp to:
3838
3939
<pre>
4040
default-src *;
4141
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default DSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 <pre>
40 default-src *;
41
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default CSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 <pre>
40 default-src *;
41
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
2626
file names: insensitive on Windows, sensitive on Unix. There are
2727
probably odd interactions possible if you mix case sensitive and case
2828
insensitive file systems on any single platform. This option or the
2929
global setting should be used to force the case sensitivity to the
3030
most sensible condition.
31
+
32
+`--cgitrace`: Active CGI tracing.
3133
3234
`--chdir DIRECTORY`: Change to the named directory before processing
3335
any commands.
3436
3537
@@ -229,10 +231,13 @@
229231
`REQUEST_URI`: If defined, included in error log messages.
230232
231233
`SCRIPT_NAME`: If defined, included in error log messages.
232234
233235
`SSH_CONNECTION`: Informs CGI processing if the remote client is SSH.
236
+
237
+`SSL_CERT_FILE`, `SSL_CERT_DIR`: Override the [`ssl-ca-location`]
238
+(/help?cmd=ssl-ca-location) setting.
234239
235240
`SQLITE_FORCE_PROXY_LOCKING`: From `sqlite3.c`, 1 means force always
236241
use proxy, 0 means never use proxy, and undefined means use proxy for
237242
non-local files only.
238243
239244
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
26 file names: insensitive on Windows, sensitive on Unix. There are
27 probably odd interactions possible if you mix case sensitive and case
28 insensitive file systems on any single platform. This option or the
29 global setting should be used to force the case sensitivity to the
30 most sensible condition.
 
 
31
32 `--chdir DIRECTORY`: Change to the named directory before processing
33 any commands.
34
35
@@ -229,10 +231,13 @@
229 `REQUEST_URI`: If defined, included in error log messages.
230
231 `SCRIPT_NAME`: If defined, included in error log messages.
232
233 `SSH_CONNECTION`: Informs CGI processing if the remote client is SSH.
 
 
 
234
235 `SQLITE_FORCE_PROXY_LOCKING`: From `sqlite3.c`, 1 means force always
236 use proxy, 0 means never use proxy, and undefined means use proxy for
237 non-local files only.
238
239
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
26 file names: insensitive on Windows, sensitive on Unix. There are
27 probably odd interactions possible if you mix case sensitive and case
28 insensitive file systems on any single platform. This option or the
29 global setting should be used to force the case sensitivity to the
30 most sensible condition.
31
32 `--cgitrace`: Active CGI tracing.
33
34 `--chdir DIRECTORY`: Change to the named directory before processing
35 any commands.
36
37
@@ -229,10 +231,13 @@
231 `REQUEST_URI`: If defined, included in error log messages.
232
233 `SCRIPT_NAME`: If defined, included in error log messages.
234
235 `SSH_CONNECTION`: Informs CGI processing if the remote client is SSH.
236
237 `SSL_CERT_FILE`, `SSL_CERT_DIR`: Override the [`ssl-ca-location`]
238 (/help?cmd=ssl-ca-location) setting.
239
240 `SQLITE_FORCE_PROXY_LOCKING`: From `sqlite3.c`, 1 means force always
241 use proxy, 0 means never use proxy, and undefined means use proxy for
242 non-local files only.
243
244
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -74,11 +74,11 @@
7474
<li> [#forum | Forum Posts] </li>
7575
</ul>
7676
7777
These eight structural artifact types are described in subsections below.
7878
79
-Structural artifacts are ASCII text. The artifact may be PGP clearsigned.
79
+Structural artifacts are UTF-8 text. The artifact may be PGP clearsigned.
8080
After removal of the PGP clearsign header and suffix (if any) a structural
8181
artifact consists of one or more "cards" separated by a single newline
8282
(ASCII: 0x0a) character. Each card begins with a single
8383
character "card type". Zero or more arguments may follow
8484
the card type. All arguments are separated from each other
8585
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -74,11 +74,11 @@
74 <li> [#forum | Forum Posts] </li>
75 </ul>
76
77 These eight structural artifact types are described in subsections below.
78
79 Structural artifacts are ASCII text. The artifact may be PGP clearsigned.
80 After removal of the PGP clearsign header and suffix (if any) a structural
81 artifact consists of one or more "cards" separated by a single newline
82 (ASCII: 0x0a) character. Each card begins with a single
83 character "card type". Zero or more arguments may follow
84 the card type. All arguments are separated from each other
85
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -74,11 +74,11 @@
74 <li> [#forum | Forum Posts] </li>
75 </ul>
76
77 These eight structural artifact types are described in subsections below.
78
79 Structural artifacts are UTF-8 text. The artifact may be PGP clearsigned.
80 After removal of the PGP clearsign header and suffix (if any) a structural
81 artifact consists of one or more "cards" separated by a single newline
82 (ASCII: 0x0a) character. Each card begins with a single
83 character "card type". Zero or more arguments may follow
84 the card type. All arguments are separated from each other
85
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
1
-
21
#-------------------------------------------------------------------------
32
# get_fossil_data()
43
#
54
# If the current directory is part of a fossil checkout, then populate
65
# a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
2625
#-------------------------------------------------------------------------
2726
# set_prompt()
2827
#
2928
# Set the PS1 variable. If the current directory is part of a fossil
3029
# checkout then the prompt contains information relating to the state
31
-# of the checkout.
30
+# of the checkout.
3231
#
3332
# Otherwise, if the current directory is not part of a fossil checkout, it
3433
# is set to a fairly standard bash prompt containing the host name, user
3534
# name and current directory.
3635
#
3736
function set_prompt() {
3837
get_fossil_data
39
- if [ -n "$fossil_info_project_name" ] ; then
40
- project=$fossil_info_project_name
41
- checkout=`echo $fossil_info_checkout | sed 's/^\(........\).*/\1/'`
42
- date=`echo $fossil_info_checkout | sed 's/^[^ ]* *..//' | sed 's/:[^:]*$//'`
43
- tags=$fossil_info_tags
44
- local_root=`echo $fossil_info_local_root | sed 's/\/$//'`
45
- local=`pwd | sed "s*${local_root}**" | sed "s/^$/\//"`
46
-
47
- # Color the first part of the prompt blue if this is a clean checkout.
38
+ if [ -n "$fossil_info_project_name" ] ; then
39
+ # Color the path part of the prompt blue if this is a clean checkout
4840
# Or red if it has been edited in any way at all. Set $c1 to the escape
4941
# sequence required to change the type to the required color. And $c2
5042
# to the sequence that changes it back.
5143
#
5244
if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
5345
c1="\[\033[1;31m\]" # red
5446
else
5547
c1="\[\033[1;34m\]" # blue
5648
fi
5749
c2="\[\033[0m\]"
58
-
59
- PS1="$c1${project}.${tags}$c2 ${checkout} (${date}):${local}$c1\$$c2 "
50
+ PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:$c1\w\$$c2 "
6051
else
61
- PS1="\u@\h:\w\$ "
52
+ PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\w\$ "
6253
fi
6354
}
6455
6556
PROMPT_COMMAND=set_prompt
6657
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
1
2 #-------------------------------------------------------------------------
3 # get_fossil_data()
4 #
5 # If the current directory is part of a fossil checkout, then populate
6 # a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
26 #-------------------------------------------------------------------------
27 # set_prompt()
28 #
29 # Set the PS1 variable. If the current directory is part of a fossil
30 # checkout then the prompt contains information relating to the state
31 # of the checkout.
32 #
33 # Otherwise, if the current directory is not part of a fossil checkout, it
34 # is set to a fairly standard bash prompt containing the host name, user
35 # name and current directory.
36 #
37 function set_prompt() {
38 get_fossil_data
39 if [ -n "$fossil_info_project_name" ] ; then
40 project=$fossil_info_project_name
41 checkout=`echo $fossil_info_checkout | sed 's/^\(........\).*/\1/'`
42 date=`echo $fossil_info_checkout | sed 's/^[^ ]* *..//' | sed 's/:[^:]*$//'`
43 tags=$fossil_info_tags
44 local_root=`echo $fossil_info_local_root | sed 's/\/$//'`
45 local=`pwd | sed "s*${local_root}**" | sed "s/^$/\//"`
46
47 # Color the first part of the prompt blue if this is a clean checkout.
48 # Or red if it has been edited in any way at all. Set $c1 to the escape
49 # sequence required to change the type to the required color. And $c2
50 # to the sequence that changes it back.
51 #
52 if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
53 c1="\[\033[1;31m\]" # red
54 else
55 c1="\[\033[1;34m\]" # blue
56 fi
57 c2="\[\033[0m\]"
58
59 PS1="$c1${project}.${tags}$c2 ${checkout} (${date}):${local}$c1\$$c2 "
60 else
61 PS1="\u@\h:\w\$ "
62 fi
63 }
64
65 PROMPT_COMMAND=set_prompt
66
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
 
1 #-------------------------------------------------------------------------
2 # get_fossil_data()
3 #
4 # If the current directory is part of a fossil checkout, then populate
5 # a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
25 #-------------------------------------------------------------------------
26 # set_prompt()
27 #
28 # Set the PS1 variable. If the current directory is part of a fossil
29 # checkout then the prompt contains information relating to the state
30 # of the checkout.
31 #
32 # Otherwise, if the current directory is not part of a fossil checkout, it
33 # is set to a fairly standard bash prompt containing the host name, user
34 # name and current directory.
35 #
36 function set_prompt() {
37 get_fossil_data
38 if [ -n "$fossil_info_project_name" ] ; then
39 # Color the path part of the prompt blue if this is a clean checkout
 
 
 
 
 
 
 
40 # Or red if it has been edited in any way at all. Set $c1 to the escape
41 # sequence required to change the type to the required color. And $c2
42 # to the sequence that changes it back.
43 #
44 if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
45 c1="\[\033[1;31m\]" # red
46 else
47 c1="\[\033[1;34m\]" # blue
48 fi
49 c2="\[\033[0m\]"
50 PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:$c1\w\$$c2 "
 
51 else
52 PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\w\$ "
53 fi
54 }
55
56 PROMPT_COMMAND=set_prompt
57
+6 -1
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
22
33
44
A [glob pattern][glob] is a text expression that matches one or more
55
file names using wild cards familiar to most users of a command line.
66
For example, `*` is a glob that matches any name at all and
7
-`Readme.txt` is a glob that matches exactly one file.
7
+`Readme.txt` is a glob that matches exactly one file. For purposes of
8
+Fossil's globs, a file name with a directory prefix is "just a string"
9
+and the globs do not apply any special meaning to the directory part
10
+of the name. Thus the glob `*` matches any name, including any
11
+directory prefix, and `*/*` matches a name with _one or more_
12
+directory components.
813
914
A glob should not be confused with a [regular expression][regexp] (RE),
1015
even though they use some of the same special characters for similar
1116
purposes, because [they are not fully compatible][greinc] pattern
1217
matching languages. Fossil uses globs when matching file names with the
1318
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
2
3
4 A [glob pattern][glob] is a text expression that matches one or more
5 file names using wild cards familiar to most users of a command line.
6 For example, `*` is a glob that matches any name at all and
7 `Readme.txt` is a glob that matches exactly one file.
 
 
 
 
 
8
9 A glob should not be confused with a [regular expression][regexp] (RE),
10 even though they use some of the same special characters for similar
11 purposes, because [they are not fully compatible][greinc] pattern
12 matching languages. Fossil uses globs when matching file names with the
13
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
2
3
4 A [glob pattern][glob] is a text expression that matches one or more
5 file names using wild cards familiar to most users of a command line.
6 For example, `*` is a glob that matches any name at all and
7 `Readme.txt` is a glob that matches exactly one file. For purposes of
8 Fossil's globs, a file name with a directory prefix is "just a string"
9 and the globs do not apply any special meaning to the directory part
10 of the name. Thus the glob `*` matches any name, including any
11 directory prefix, and `*/*` matches a name with _one or more_
12 directory components.
13
14 A glob should not be confused with a [regular expression][regexp] (RE),
15 even though they use some of the same special characters for similar
16 purposes, because [they are not fully compatible][greinc] pattern
17 matching languages. Fossil uses globs when matching file names with the
18
+4 -4
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
8383
the repository are consistent prior to each commit.
8484
8585
8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
8686
8787
<hr>
88
-<h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
88
+<h3>Latest Release: 2.18 ([/timeline?c=version-2.18|2022-02-23])</h3>
8989
9090
* [/uv/download.html|Download]
91
- * [./changes.wiki#v2_17|Change Summary]
92
- * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93
- * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
91
+ * [./changes.wiki#v2_18|Change Summary]
92
+ * [/timeline?p=version-2.18&bt=version-2.17&y=ci|Check-ins in version 2.18]
93
+ * [/timeline?df=version-2.18&y=ci|Check-ins derived from the 2.18 release]
9494
* [/timeline?t=release|Timeline of all past releases]
9595
9696
<hr>
9797
<h3>Quick Start</h3>
9898
9999
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_17|Change Summary]
92 * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93 * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.18 ([/timeline?c=version-2.18|2022-02-23])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_18|Change Summary]
92 * [/timeline?p=version-2.18&bt=version-2.17&y=ci|Check-ins in version 2.18]
93 * [/timeline?df=version-2.18&y=ci|Check-ins derived from the 2.18 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166166
- `name=string` specifies the page name.
167167
- `content=string` is the body text.\
168168
Content is required for save (unless `createIfNotExists` is true *and*
169169
the page does not exist), optional for create. It *may* be an empty
170170
string.
171
+- `mimetype=string` specifies the mimetype for the body, noting any any
172
+ unrecognized/unsupported mimetype is silently treated as
173
+ `text/x-fossil-wiki`.
171174
- Save (not create) supports a `createIfNotExists` boolean option which
172175
makes it a functional superset of the create/save features. i.e. it
173176
will create if needed, else it will update. If createIfNotExists is
174177
false (the default) then save will fail if given a page name which
175178
does not refer to an existing page.
@@ -179,10 +182,11 @@
179182
high-priority addition. See:\
180183
[](/doc/trunk/www/fileformat.wiki#wikichng)
181184
- **Potential TODO:** we *could* optionally also support
182185
multi-page saving using an array of pages in the request payload:\
183186
`[… page objects … ]`
187
+
184188
185189
186190
<a id="diffs"></a>
187191
# Wiki Diffs
188192
@@ -238,28 +242,29 @@
238242
239243
This command wiki-processes arbitrary text sent from the client. To help
240244
curb potential abuse, its use is restricted to those with "k" access
241245
rights.
242246
243
-The `POST.payload` property must be a string containing Fossil wiki
244
-markup. The response payload is also a string, but contains the
245
-HTML-processed form of the string. Whether or not "all HTML" is allowed
246
-depends on site-level configuration options, and that changes how the
247
-input is processed.
247
+The `POST.payload` property must be either:
248
+
249
+1) A string containing Fossil wiki markup.
250
+
251
+2) An Object with a `body` property holding the text to render and a
252
+ `mimetype` property describing the wiki format:
253
+ `text/x-fossil-wiki` (the default), `text/x-markdown`, or
254
+ `text/plain`. Any unknown type is treated as `text/x-fossil-wiki`.
255
+
256
+The response payload is a string containing the rendered page. Whether
257
+or not "all HTML" is allowed depends on site-level configuration
258
+options, and that changes how the input is processed.
248259
249260
Note that the links in the generated page are for the HTML interface,
250261
and will not work as-is for arbitrary JSON clients. In order to
251262
integrate the parsed content with JSON-based clients the HTML will
252263
probably need to be post-processed, e.g. using jQuery to fish out the
253264
links and re-map wiki page links to a JSON-capable page handler.
254265
255
-**TODO**: Update this to accept the other two wiki formats (which
256
-didn't exist when this API was implemented): markdown and plain text
257
-(which gets HTML-ized for preview purposes). That requires changing
258
-the payload to an object, perhaps simply submitting the same thing as
259
-`/json/save`. There's no reason we can't support both call forms.
260
-
261266
262267
<a id="todo"></a>
263268
# Notes and TODOs
264269
265270
- When server-parsing the wiki content, the generated
266271
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166 - `name=string` specifies the page name.
167 - `content=string` is the body text.\
168 Content is required for save (unless `createIfNotExists` is true *and*
169 the page does not exist), optional for create. It *may* be an empty
170 string.
 
 
 
171 - Save (not create) supports a `createIfNotExists` boolean option which
172 makes it a functional superset of the create/save features. i.e. it
173 will create if needed, else it will update. If createIfNotExists is
174 false (the default) then save will fail if given a page name which
175 does not refer to an existing page.
@@ -179,10 +182,11 @@
179 high-priority addition. See:\
180 [](/doc/trunk/www/fileformat.wiki#wikichng)
181 - **Potential TODO:** we *could* optionally also support
182 multi-page saving using an array of pages in the request payload:\
183 `[… page objects … ]`
 
184
185
186 <a id="diffs"></a>
187 # Wiki Diffs
188
@@ -238,28 +242,29 @@
238
239 This command wiki-processes arbitrary text sent from the client. To help
240 curb potential abuse, its use is restricted to those with "k" access
241 rights.
242
243 The `POST.payload` property must be a string containing Fossil wiki
244 markup. The response payload is also a string, but contains the
245 HTML-processed form of the string. Whether or not "all HTML" is allowed
246 depends on site-level configuration options, and that changes how the
247 input is processed.
 
 
 
 
 
 
 
248
249 Note that the links in the generated page are for the HTML interface,
250 and will not work as-is for arbitrary JSON clients. In order to
251 integrate the parsed content with JSON-based clients the HTML will
252 probably need to be post-processed, e.g. using jQuery to fish out the
253 links and re-map wiki page links to a JSON-capable page handler.
254
255 **TODO**: Update this to accept the other two wiki formats (which
256 didn't exist when this API was implemented): markdown and plain text
257 (which gets HTML-ized for preview purposes). That requires changing
258 the payload to an object, perhaps simply submitting the same thing as
259 `/json/save`. There's no reason we can't support both call forms.
260
261
262 <a id="todo"></a>
263 # Notes and TODOs
264
265 - When server-parsing the wiki content, the generated
266
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166 - `name=string` specifies the page name.
167 - `content=string` is the body text.\
168 Content is required for save (unless `createIfNotExists` is true *and*
169 the page does not exist), optional for create. It *may* be an empty
170 string.
171 - `mimetype=string` specifies the mimetype for the body, noting any any
172 unrecognized/unsupported mimetype is silently treated as
173 `text/x-fossil-wiki`.
174 - Save (not create) supports a `createIfNotExists` boolean option which
175 makes it a functional superset of the create/save features. i.e. it
176 will create if needed, else it will update. If createIfNotExists is
177 false (the default) then save will fail if given a page name which
178 does not refer to an existing page.
@@ -179,10 +182,11 @@
182 high-priority addition. See:\
183 [](/doc/trunk/www/fileformat.wiki#wikichng)
184 - **Potential TODO:** we *could* optionally also support
185 multi-page saving using an array of pages in the request payload:\
186 `[… page objects … ]`
187
188
189
190 <a id="diffs"></a>
191 # Wiki Diffs
192
@@ -238,28 +242,29 @@
242
243 This command wiki-processes arbitrary text sent from the client. To help
244 curb potential abuse, its use is restricted to those with "k" access
245 rights.
246
247 The `POST.payload` property must be either:
248
249 1) A string containing Fossil wiki markup.
250
251 2) An Object with a `body` property holding the text to render and a
252 `mimetype` property describing the wiki format:
253 `text/x-fossil-wiki` (the default), `text/x-markdown`, or
254 `text/plain`. Any unknown type is treated as `text/x-fossil-wiki`.
255
256 The response payload is a string containing the rendered page. Whether
257 or not "all HTML" is allowed depends on site-level configuration
258 options, and that changes how the input is processed.
259
260 Note that the links in the generated page are for the HTML interface,
261 and will not work as-is for arbitrary JSON clients. In order to
262 integrate the parsed content with JSON-based clients the HTML will
263 probably need to be post-processed, e.g. using jQuery to fish out the
264 links and re-map wiki page links to a JSON-capable page handler.
265
 
 
 
 
 
 
266
267 <a id="todo"></a>
268 # Notes and TODOs
269
270 - When server-parsing the wiki content, the generated
271
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
6262
files.
6363
6464
The VERSION.h header file is generated from other information sources
6565
using a small program called:
6666
67
- 11. [/file/src/mkversion.c | mkversion.c]
67
+ 11. [/file/tools/mkversion.c | mkversion.c]
6868
6969
The builtin_data.h header file contains the definitions of C-language
7070
byte-array constants that contain various resources such as scripts and
7171
images. The builtin_data.h header file is generate from the original
7272
resource files using a small program called:
7373
74
- 12 [/file/src/mkbuiltin.c | mkbuiltin.c]
74
+ 12 [/file/tools/mkbuiltin.c | mkbuiltin.c]
7575
7676
Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
7777
script used to implement the --tk option to [/help?cmd=diff| fossil diff],
7878
the [/file/src/markdown.md | markdown documentation], and the various
7979
CSS scripts, headers, and footers used to implement built-in skins. New
8080
resources files are added to the "extra_files" variable in
81
-[/file/src/makemake.tcl | makemake.tcl].
81
+[/file/tools/makemake.tcl | makemake.tcl].
8282
8383
The src/ subdirectory also contains documentation about the
8484
makeheaders preprocessor program:
8585
8686
13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
9191
14. makemake.tcl
9292
9393
Running this Tcl script will automatically regenerate all makefiles.
9494
In order to add a new source file to the Fossil implementation, simply
9595
edit makemake.tcl to add the new filename, then rerun the script, and
96
-all of the makefiles for all targets will be rebuild.
96
+all of the makefiles for all targets will be rebuilt.
9797
9898
There is an optional code verification step implemented using
9999
100
- 15. [/file/src/codecheck1.c | codecheck1.c]
100
+ 15. [/file/tools/codecheck1.c | codecheck1.c]
101101
102102
This file implements a small utility program ("codecheck1")
103103
that scans other Fossil source files looking for errors in printf-style
104104
format strings.
105105
The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141141
(The "manifest" and "manifest.uuid" files are automatically generated and
142142
updated by Fossil itself. See the [/help/setting | fossil set manifest]
143143
command for additional information.)
144144
145145
The VERSION.h header file is generated by
146
-a C program: src/mkversion.c.
147
-To run the VERSION.h generator, first compile the src/mkversion.c
146
+a C program: tools/mkversion.c.
147
+To run the VERSION.h generator, first compile the tools/mkversion.c
148148
source file into a command-line program (named "mkversion.exe")
149149
then run:
150150
151151
<blockquote><pre>
152152
mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156156
directories right. The point is that the manifest.uuid, manifest, and
157157
VERSION files
158158
in the root of the source tree are the three arguments and
159159
the generated VERSION.h file appears on standard output.
160160
161
-The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
161
+The builtin_data.h header file is generated by a C program: tools/mkbuiltin.c.
162162
The builtin_data.h file contains C-language byte-array definitions for
163163
the content of resource files used by Fossil. To generate the
164164
builtin_data.h file, first compile the mkbuiltin.c program, then run:
165165
166166
<blockquote><pre>
167167
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
62 files.
63
64 The VERSION.h header file is generated from other information sources
65 using a small program called:
66
67 11. [/file/src/mkversion.c | mkversion.c]
68
69 The builtin_data.h header file contains the definitions of C-language
70 byte-array constants that contain various resources such as scripts and
71 images. The builtin_data.h header file is generate from the original
72 resource files using a small program called:
73
74 12 [/file/src/mkbuiltin.c | mkbuiltin.c]
75
76 Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
77 script used to implement the --tk option to [/help?cmd=diff| fossil diff],
78 the [/file/src/markdown.md | markdown documentation], and the various
79 CSS scripts, headers, and footers used to implement built-in skins. New
80 resources files are added to the "extra_files" variable in
81 [/file/src/makemake.tcl | makemake.tcl].
82
83 The src/ subdirectory also contains documentation about the
84 makeheaders preprocessor program:
85
86 13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
91 14. makemake.tcl
92
93 Running this Tcl script will automatically regenerate all makefiles.
94 In order to add a new source file to the Fossil implementation, simply
95 edit makemake.tcl to add the new filename, then rerun the script, and
96 all of the makefiles for all targets will be rebuild.
97
98 There is an optional code verification step implemented using
99
100 15. [/file/src/codecheck1.c | codecheck1.c]
101
102 This file implements a small utility program ("codecheck1")
103 that scans other Fossil source files looking for errors in printf-style
104 format strings.
105 The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141 (The "manifest" and "manifest.uuid" files are automatically generated and
142 updated by Fossil itself. See the [/help/setting | fossil set manifest]
143 command for additional information.)
144
145 The VERSION.h header file is generated by
146 a C program: src/mkversion.c.
147 To run the VERSION.h generator, first compile the src/mkversion.c
148 source file into a command-line program (named "mkversion.exe")
149 then run:
150
151 <blockquote><pre>
152 mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156 directories right. The point is that the manifest.uuid, manifest, and
157 VERSION files
158 in the root of the source tree are the three arguments and
159 the generated VERSION.h file appears on standard output.
160
161 The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
162 The builtin_data.h file contains C-language byte-array definitions for
163 the content of resource files used by Fossil. To generate the
164 builtin_data.h file, first compile the mkbuiltin.c program, then run:
165
166 <blockquote><pre>
167
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
62 files.
63
64 The VERSION.h header file is generated from other information sources
65 using a small program called:
66
67 11. [/file/tools/mkversion.c | mkversion.c]
68
69 The builtin_data.h header file contains the definitions of C-language
70 byte-array constants that contain various resources such as scripts and
71 images. The builtin_data.h header file is generate from the original
72 resource files using a small program called:
73
74 12 [/file/tools/mkbuiltin.c | mkbuiltin.c]
75
76 Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
77 script used to implement the --tk option to [/help?cmd=diff| fossil diff],
78 the [/file/src/markdown.md | markdown documentation], and the various
79 CSS scripts, headers, and footers used to implement built-in skins. New
80 resources files are added to the "extra_files" variable in
81 [/file/tools/makemake.tcl | makemake.tcl].
82
83 The src/ subdirectory also contains documentation about the
84 makeheaders preprocessor program:
85
86 13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
91 14. makemake.tcl
92
93 Running this Tcl script will automatically regenerate all makefiles.
94 In order to add a new source file to the Fossil implementation, simply
95 edit makemake.tcl to add the new filename, then rerun the script, and
96 all of the makefiles for all targets will be rebuilt.
97
98 There is an optional code verification step implemented using
99
100 15. [/file/tools/codecheck1.c | codecheck1.c]
101
102 This file implements a small utility program ("codecheck1")
103 that scans other Fossil source files looking for errors in printf-style
104 format strings.
105 The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141 (The "manifest" and "manifest.uuid" files are automatically generated and
142 updated by Fossil itself. See the [/help/setting | fossil set manifest]
143 command for additional information.)
144
145 The VERSION.h header file is generated by
146 a C program: tools/mkversion.c.
147 To run the VERSION.h generator, first compile the tools/mkversion.c
148 source file into a command-line program (named "mkversion.exe")
149 then run:
150
151 <blockquote><pre>
152 mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156 directories right. The point is that the manifest.uuid, manifest, and
157 VERSION files
158 in the root of the source tree are the three arguments and
159 the generated VERSION.h file appears on standard output.
160
161 The builtin_data.h header file is generated by a C program: tools/mkbuiltin.c.
162 The builtin_data.h file contains C-language byte-array definitions for
163 the content of resource files used by Fossil. To generate the
164 builtin_data.h file, first compile the mkbuiltin.c program, then run:
165
166 <blockquote><pre>
167
+1 -1
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
1414
aboutcgi.wiki {How CGI Works In Fossil}
1515
aboutdownload.wiki {How The Download Page Works}
1616
adding_code.wiki {Adding New Features To Fossil}
1717
adding_code.wiki {Hacking Fossil}
1818
alerts.md {Email Alerts And Notifications}
19
- antibot.wiki {Defense against Spiders and Bots}
19
+ antibot.wiki {Defense against Spiders and Robots}
2020
backoffice.md {The "Backoffice" mechanism of Fossil}
2121
backup.md {Backing Up a Remote Fossil Repository}
2222
blame.wiki {The Annotate/Blame Algorithm Of Fossil}
2323
blockchain.md {Is Fossil A Blockchain?}
2424
branching.wiki {Branching, Forking, Merging, and Tagging}
2525
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
14 aboutcgi.wiki {How CGI Works In Fossil}
15 aboutdownload.wiki {How The Download Page Works}
16 adding_code.wiki {Adding New Features To Fossil}
17 adding_code.wiki {Hacking Fossil}
18 alerts.md {Email Alerts And Notifications}
19 antibot.wiki {Defense against Spiders and Bots}
20 backoffice.md {The "Backoffice" mechanism of Fossil}
21 backup.md {Backing Up a Remote Fossil Repository}
22 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
23 blockchain.md {Is Fossil A Blockchain?}
24 branching.wiki {Branching, Forking, Merging, and Tagging}
25
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
14 aboutcgi.wiki {How CGI Works In Fossil}
15 aboutdownload.wiki {How The Download Page Works}
16 adding_code.wiki {Adding New Features To Fossil}
17 adding_code.wiki {Hacking Fossil}
18 alerts.md {Email Alerts And Notifications}
19 antibot.wiki {Defense against Spiders and Robots}
20 backoffice.md {The "Backoffice" mechanism of Fossil}
21 backup.md {Backing Up a Remote Fossil Repository}
22 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
23 blockchain.md {Is Fossil A Blockchain?}
24 branching.wiki {Branching, Forking, Merging, and Tagging}
25
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
1616
However, we will still give two different configurations, just as in the
1717
`systemd` article: one for a standalone HTTP server, and one using
1818
socket activation.
1919
2020
For more information on `launchd`, the single best resource we’ve found
21
-is [](launchd.info). The next best is:
21
+is [launchd.info](https://launchd.info). The next best is:
2222
2323
$ man launchd.plist
2424
2525
[la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
2626
[ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
2727
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
16 However, we will still give two different configurations, just as in the
17 `systemd` article: one for a standalone HTTP server, and one using
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [](launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
16 However, we will still give two different configurations, just as in the
17 `systemd` article: one for a standalone HTTP server, and one using
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [launchd.info](https://launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -118,11 +118,11 @@
118118
technologies like Wapp.) The fileup1 script is a demo program that lets
119119
the user upload a file using a form, and then displays that file in the reply.
120120
There is a link on the page that causes the fileup1 script to return a copy
121121
of its own source-code, so you can see how it works.
122122
123
-<h2>3.0 CGI Inputs</h2>
123
+<h2 id="cgi-inputs">3.0 CGI Inputs</h2>
124124
125125
The /ext extension mechanism is an ordinary CGI interface. Parameters
126126
are passed to the CGI program using environment variables. The following
127127
standard CGI environment variables are supported:
128128
@@ -152,10 +152,11 @@
152152
* SCRIPT_FILENAME
153153
* SCRIPT_NAME
154154
* SERVER_NAME
155155
* SERVER_PORT
156156
* SERVER_PROTOCOL
157
+ * SERVER_SOFTWARE
157158
158159
Do a web search for
159160
"[https://duckduckgo.com/?q=cgi+environment_variables|cgi environment variables]"
160161
to find more detail about what each of the above variables mean and how
161162
they are used.
162163
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -118,11 +118,11 @@
118 technologies like Wapp.) The fileup1 script is a demo program that lets
119 the user upload a file using a form, and then displays that file in the reply.
120 There is a link on the page that causes the fileup1 script to return a copy
121 of its own source-code, so you can see how it works.
122
123 <h2>3.0 CGI Inputs</h2>
124
125 The /ext extension mechanism is an ordinary CGI interface. Parameters
126 are passed to the CGI program using environment variables. The following
127 standard CGI environment variables are supported:
128
@@ -152,10 +152,11 @@
152 * SCRIPT_FILENAME
153 * SCRIPT_NAME
154 * SERVER_NAME
155 * SERVER_PORT
156 * SERVER_PROTOCOL
 
157
158 Do a web search for
159 "[https://duckduckgo.com/?q=cgi+environment_variables|cgi environment variables]"
160 to find more detail about what each of the above variables mean and how
161 they are used.
162
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -118,11 +118,11 @@
118 technologies like Wapp.) The fileup1 script is a demo program that lets
119 the user upload a file using a form, and then displays that file in the reply.
120 There is a link on the page that causes the fileup1 script to return a copy
121 of its own source-code, so you can see how it works.
122
123 <h2 id="cgi-inputs">3.0 CGI Inputs</h2>
124
125 The /ext extension mechanism is an ordinary CGI interface. Parameters
126 are passed to the CGI program using environment variables. The following
127 standard CGI environment variables are supported:
128
@@ -152,10 +152,11 @@
152 * SCRIPT_FILENAME
153 * SCRIPT_NAME
154 * SERVER_NAME
155 * SERVER_PORT
156 * SERVER_PROTOCOL
157 * SERVER_SOFTWARE
158
159 Do a web search for
160 "[https://duckduckgo.com/?q=cgi+environment_variables|cgi environment variables]"
161 to find more detail about what each of the above variables mean and how
162 they are used.
163
+27 -42
--- www/ssl-server.md
+++ www/ssl-server.md
@@ -28,25 +28,27 @@
2828
obtaining a CA-signed certificate.
2929
3030
## Usage
3131
3232
To put any of the Fossil server commands into SSL/TLS mode, simply
33
-add the "--ssl" command-line option. (Or use "--tls" which is an
34
-alias.) Like this:
33
+add the "--cert" command-line option.
3534
3635
> ~~~
37
-fossil ui --ssl
36
+fossil ui --cert unsafe-builtin
3837
~~~
3938
40
-Since no certificate (or "cert") has been specified, Fossil will use
41
-a self-signed cert that is built into Fossil itself. The fact that the
42
-cert is self-signed, rather than being signed by a
39
+The --cert option is what tells Fossil to use TLS encryption.
40
+Normally, the argument to --cert is the name of a file containing
41
+the certificate (the "fullchain.pem" file) for the website. In this
42
+example, the magic name "unsafe-builtin" is used, which causes Fossil
43
+to use a self-signed cert rather than a real cert obtained from a
4344
[Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)
44
-or "CA", means that your web-browser will complain bitterly and will refuse
45
-to display the pages that Fossil returns. Some web browsers (ex: Firefox)
46
-will allow you to click an "I know the risks" button and continue. Other
47
-web browsers will stubornly refuse to display the page, under the theory
45
+or "CA". As the name implies, this self-signed cert is not secure and
46
+should only be used for testing. Your web-browser will complain bitterly
47
+and will refuse to display the pages using the "unsafe-builtin" cert.
48
+Firefox will allow you to click an "I know the risks" button and continue.
49
+Other web browsers will stubornly refuse to display the page, under the theory
4850
that weak encryption is worse than no encryption at all. Continue reading
4951
to see how to solve this.
5052
5153
## About Certs
5254
@@ -71,13 +73,13 @@
7173
can verify it. But the private key is kept strictly private and is never
7274
shared with anyone.
7375
7476
## How To Tell Fossil About Your Cert And Private Key
7577
76
-If you do not tell Fossil about a cert and private key, it uses a
77
-generic "private key" and self-signed cert that is built into Fossil.
78
-This is wildly insecure, since the private key is not really private -
78
+If you do not have your own cert and private key, you can ask Fossil
79
+to use "unsafe-builtin", which is a self-signed cert that is built into
80
+Fossil. This is wildly insecure, since the private key is not really private -
7981
it is [in plain sight](/info/c2a7b14c3f541edb96?ln=89-116) in the Fossil
8082
source tree for anybody to read. <b>Never add the private key that is
8183
built into Fossil to your OS's trust store</b> as doing so will severely
8284
compromise your computer. The built-in cert is only useful for testing.
8385
If you want actual security, you will need to come up with your own private
@@ -105,22 +107,32 @@
105107
certificate, you can concatenate the two into a single file and the
106108
individual components will still be easily accessible.
107109
108110
If you have a single file that holds both your private key and your
109111
cert, you can hand it off to the "[fossil server](/help?cmd=server)"
110
-command using the --tls-cert-file option. Like this:
112
+command using the --cert option. Like this:
111113
112114
> ~~~
113
-fossil server --port 443 --tls-cert-file mycert.pem /home/www/myproject.fossil
115
+fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil
114116
~~~
115117
116118
The command above is sufficient to run a fully-encrypted web site for
117119
the "myproject.fossil" Fossil repository. This command must be run as
118120
root, since it wants to listen on TCP port 443, and only root processes are
119121
allowed to do that. This is safe, however, since before reading any
120122
information off of the wire, Fossil will put itself inside a chroot jail
121123
at /home/www and drop all root privileges.
124
+
125
+### Keeping The Cert And Private Key In Separate Files
126
+
127
+If you do not want to combine your cert and private key into a single
128
+big PEM file, you can keep them separate using the --pkey option to
129
+Fossil.
130
+
131
+> ~~~
132
+fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil
133
+~~~
122134
123135
## The ACME Protocol
124136
125137
The [ACME Protocol][2] is used to prove to a CA that you control a
126138
website. CAs require proof that you control a domain before they
@@ -172,34 +184,7 @@
172184
named "/home/www/.well-known" and put token files there, which the CA
173185
will verify. Then certbot will store your new cert in a particular file.
174186
175187
Once certbot has obtained your cert, then you can concatenate that
176188
cert with your private key and run Fossil in SSL/TLS mode as shown above.
177
-
178
-## Separate Cert And Private Key Files Using Settings
179
-
180
-If you do not want to concatenate your cert and private key, you can
181
-tell Fossil about the files separately using settings. Run a command
182
-like this on your repository:
183
-
184
-> ~~~
185
-fossil ssl-config load-cert --filename CERT-FILE.pem PRIVATE-KEY.pem
186
-~~~
187
-
188
-Substitute whatever filenames are appropriate in the command above, of
189
-course. Run "[fossil ssl-config](/help?cmd=ssl-config)" by itself to see
190
-the resulting configuration. Once you have done this, you can then
191
-restart your TLS server using just:
192
-
193
-> ~~~
194
-fossil server --port 443 --tls /home/www/myproject.fossil
195
-~~~
196
-
197
-Note however that this technique only works if you are serving a single
198
-repository from your website. If the argument to your "fossil server" command
199
-is the name of a directory that contains many Fossil repositories, then
200
-there is no one repository in which to put this setting, and so you have
201
-to specify the location of the combined cert and private key file using
202
-the --tls-cert-file option on the command-line.
203
-
204189
205190
[2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
206191
--- www/ssl-server.md
+++ www/ssl-server.md
@@ -28,25 +28,27 @@
28 obtaining a CA-signed certificate.
29
30 ## Usage
31
32 To put any of the Fossil server commands into SSL/TLS mode, simply
33 add the "--ssl" command-line option. (Or use "--tls" which is an
34 alias.) Like this:
35
36 > ~~~
37 fossil ui --ssl
38 ~~~
39
40 Since no certificate (or "cert") has been specified, Fossil will use
41 a self-signed cert that is built into Fossil itself. The fact that the
42 cert is self-signed, rather than being signed by a
 
 
43 [Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)
44 or "CA", means that your web-browser will complain bitterly and will refuse
45 to display the pages that Fossil returns. Some web browsers (ex: Firefox)
46 will allow you to click an "I know the risks" button and continue. Other
47 web browsers will stubornly refuse to display the page, under the theory
 
48 that weak encryption is worse than no encryption at all. Continue reading
49 to see how to solve this.
50
51 ## About Certs
52
@@ -71,13 +73,13 @@
71 can verify it. But the private key is kept strictly private and is never
72 shared with anyone.
73
74 ## How To Tell Fossil About Your Cert And Private Key
75
76 If you do not tell Fossil about a cert and private key, it uses a
77 generic "private key" and self-signed cert that is built into Fossil.
78 This is wildly insecure, since the private key is not really private -
79 it is [in plain sight](/info/c2a7b14c3f541edb96?ln=89-116) in the Fossil
80 source tree for anybody to read. <b>Never add the private key that is
81 built into Fossil to your OS's trust store</b> as doing so will severely
82 compromise your computer. The built-in cert is only useful for testing.
83 If you want actual security, you will need to come up with your own private
@@ -105,22 +107,32 @@
105 certificate, you can concatenate the two into a single file and the
106 individual components will still be easily accessible.
107
108 If you have a single file that holds both your private key and your
109 cert, you can hand it off to the "[fossil server](/help?cmd=server)"
110 command using the --tls-cert-file option. Like this:
111
112 > ~~~
113 fossil server --port 443 --tls-cert-file mycert.pem /home/www/myproject.fossil
114 ~~~
115
116 The command above is sufficient to run a fully-encrypted web site for
117 the "myproject.fossil" Fossil repository. This command must be run as
118 root, since it wants to listen on TCP port 443, and only root processes are
119 allowed to do that. This is safe, however, since before reading any
120 information off of the wire, Fossil will put itself inside a chroot jail
121 at /home/www and drop all root privileges.
 
 
 
 
 
 
 
 
 
 
122
123 ## The ACME Protocol
124
125 The [ACME Protocol][2] is used to prove to a CA that you control a
126 website. CAs require proof that you control a domain before they
@@ -172,34 +184,7 @@
172 named "/home/www/.well-known" and put token files there, which the CA
173 will verify. Then certbot will store your new cert in a particular file.
174
175 Once certbot has obtained your cert, then you can concatenate that
176 cert with your private key and run Fossil in SSL/TLS mode as shown above.
177
178 ## Separate Cert And Private Key Files Using Settings
179
180 If you do not want to concatenate your cert and private key, you can
181 tell Fossil about the files separately using settings. Run a command
182 like this on your repository:
183
184 > ~~~
185 fossil ssl-config load-cert --filename CERT-FILE.pem PRIVATE-KEY.pem
186 ~~~
187
188 Substitute whatever filenames are appropriate in the command above, of
189 course. Run "[fossil ssl-config](/help?cmd=ssl-config)" by itself to see
190 the resulting configuration. Once you have done this, you can then
191 restart your TLS server using just:
192
193 > ~~~
194 fossil server --port 443 --tls /home/www/myproject.fossil
195 ~~~
196
197 Note however that this technique only works if you are serving a single
198 repository from your website. If the argument to your "fossil server" command
199 is the name of a directory that contains many Fossil repositories, then
200 there is no one repository in which to put this setting, and so you have
201 to specify the location of the combined cert and private key file using
202 the --tls-cert-file option on the command-line.
203
204
205 [2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
206
--- www/ssl-server.md
+++ www/ssl-server.md
@@ -28,25 +28,27 @@
28 obtaining a CA-signed certificate.
29
30 ## Usage
31
32 To put any of the Fossil server commands into SSL/TLS mode, simply
33 add the "--cert" command-line option.
 
34
35 > ~~~
36 fossil ui --cert unsafe-builtin
37 ~~~
38
39 The --cert option is what tells Fossil to use TLS encryption.
40 Normally, the argument to --cert is the name of a file containing
41 the certificate (the "fullchain.pem" file) for the website. In this
42 example, the magic name "unsafe-builtin" is used, which causes Fossil
43 to use a self-signed cert rather than a real cert obtained from a
44 [Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)
45 or "CA". As the name implies, this self-signed cert is not secure and
46 should only be used for testing. Your web-browser will complain bitterly
47 and will refuse to display the pages using the "unsafe-builtin" cert.
48 Firefox will allow you to click an "I know the risks" button and continue.
49 Other web browsers will stubornly refuse to display the page, under the theory
50 that weak encryption is worse than no encryption at all. Continue reading
51 to see how to solve this.
52
53 ## About Certs
54
@@ -71,13 +73,13 @@
73 can verify it. But the private key is kept strictly private and is never
74 shared with anyone.
75
76 ## How To Tell Fossil About Your Cert And Private Key
77
78 If you do not have your own cert and private key, you can ask Fossil
79 to use "unsafe-builtin", which is a self-signed cert that is built into
80 Fossil. This is wildly insecure, since the private key is not really private -
81 it is [in plain sight](/info/c2a7b14c3f541edb96?ln=89-116) in the Fossil
82 source tree for anybody to read. <b>Never add the private key that is
83 built into Fossil to your OS's trust store</b> as doing so will severely
84 compromise your computer. The built-in cert is only useful for testing.
85 If you want actual security, you will need to come up with your own private
@@ -105,22 +107,32 @@
107 certificate, you can concatenate the two into a single file and the
108 individual components will still be easily accessible.
109
110 If you have a single file that holds both your private key and your
111 cert, you can hand it off to the "[fossil server](/help?cmd=server)"
112 command using the --cert option. Like this:
113
114 > ~~~
115 fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil
116 ~~~
117
118 The command above is sufficient to run a fully-encrypted web site for
119 the "myproject.fossil" Fossil repository. This command must be run as
120 root, since it wants to listen on TCP port 443, and only root processes are
121 allowed to do that. This is safe, however, since before reading any
122 information off of the wire, Fossil will put itself inside a chroot jail
123 at /home/www and drop all root privileges.
124
125 ### Keeping The Cert And Private Key In Separate Files
126
127 If you do not want to combine your cert and private key into a single
128 big PEM file, you can keep them separate using the --pkey option to
129 Fossil.
130
131 > ~~~
132 fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil
133 ~~~
134
135 ## The ACME Protocol
136
137 The [ACME Protocol][2] is used to prove to a CA that you control a
138 website. CAs require proof that you control a domain before they
@@ -172,34 +184,7 @@
184 named "/home/www/.well-known" and put token files there, which the CA
185 will verify. Then certbot will store your new cert in a particular file.
186
187 Once certbot has obtained your cert, then you can concatenate that
188 cert with your private key and run Fossil in SSL/TLS mode as shown above.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
190 [2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
191
+6 -5
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227227
228228
229229
<h2 id="server">Fossil TLS Configuration: Server Side</h2>
230230
231231
Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232
-(a.k.a. HTTPS) until version 2.18 (2022). Prior to that, system administrators
233
-that wanted to add HTTPS support to a Fossil server had to put Fossil
234
-behind a web-server or reverse-proxy that would do the HTTPS to HTTP
235
-translation. [./server/ | Instructions for doing so] are found elsewhere
236
-in this documentation. A few of the most useful of these are:
232
+(a.k.a. HTTPS) until version 2.18 (early 2022). Prior to that, system
233
+administrators that wanted to add HTTPS support to a Fossil server had
234
+to put Fossil behind a web-server or reverse-proxy that would do the
235
+HTTPS to HTTP translation. [./server/ | Instructions for doing so]
236
+are found elsewhere in this documentation. A few of the most useful
237
+of these are:
237238
238239
* <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
239240
* <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
240241
* <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
241242
242243
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227
228
229 <h2 id="server">Fossil TLS Configuration: Server Side</h2>
230
231 Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232 (a.k.a. HTTPS) until version 2.18 (2022). Prior to that, system administrators
233 that wanted to add HTTPS support to a Fossil server had to put Fossil
234 behind a web-server or reverse-proxy that would do the HTTPS to HTTP
235 translation. [./server/ | Instructions for doing so] are found elsewhere
236 in this documentation. A few of the most useful of these are:
 
237
238 * <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
239 * <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
240 * <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
241
242
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227
228
229 <h2 id="server">Fossil TLS Configuration: Server Side</h2>
230
231 Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232 (a.k.a. HTTPS) until version 2.18 (early 2022). Prior to that, system
233 administrators that wanted to add HTTPS support to a Fossil server had
234 to put Fossil behind a web-server or reverse-proxy that would do the
235 HTTPS to HTTP translation. [./server/ | Instructions for doing so]
236 are found elsewhere in this documentation. A few of the most useful
237 of these are:
238
239 * <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
240 * <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
241 * <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
242
243
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -31,14 +31,10 @@
3131
* [./stats.wiki | Performance statistics] taken from real-world projects
3232
hosted on Fossil.
3333
* How to [./shunning.wiki | delete content] from a Fossil repository.
3434
* How Fossil does [./password.wiki | password management].
3535
* On-line [/help | help].
36
- * Documentation on the
37
- [http://www.sqliteconcepts.org/THManual.pdf | TH1 scripting language],
38
- used to customize [./custom_ticket.wiki | ticketing], and several other
39
- subsystems, including [./customskin.md | theming].
4036
* List of [./th1.md | TH1 commands provided by Fossil itself] that expose
4137
its key functionality to TH1 scripts.
4238
* List of [./th1-hooks.md | TH1 hooks exposed by Fossil] that enable
4339
customization of commands and web pages.
4440
* A free hosting server for Fossil repositories is available at
@@ -49,5 +45,6 @@
4945
* [./inout.wiki | Import and export] from and to Git.
5046
* [./fossil-v-git.wiki | Fossil versus Git].
5147
* [./fiveminutes.wiki | Up and running in 5 minutes as a single user]
5248
(contributed by Gilles Ganault on 2013-01-08).
5349
* [./antibot.wiki | How Fossil defends against abuse by spiders and bots].
50
+ * [./wsl_caveats.wiki | Using Fossil on WSL], caveats and guidance.
5451
5552
ADDED www/wsl_caveats.wiki
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -31,14 +31,10 @@
31 * [./stats.wiki | Performance statistics] taken from real-world projects
32 hosted on Fossil.
33 * How to [./shunning.wiki | delete content] from a Fossil repository.
34 * How Fossil does [./password.wiki | password management].
35 * On-line [/help | help].
36 * Documentation on the
37 [http://www.sqliteconcepts.org/THManual.pdf | TH1 scripting language],
38 used to customize [./custom_ticket.wiki | ticketing], and several other
39 subsystems, including [./customskin.md | theming].
40 * List of [./th1.md | TH1 commands provided by Fossil itself] that expose
41 its key functionality to TH1 scripts.
42 * List of [./th1-hooks.md | TH1 hooks exposed by Fossil] that enable
43 customization of commands and web pages.
44 * A free hosting server for Fossil repositories is available at
@@ -49,5 +45,6 @@
49 * [./inout.wiki | Import and export] from and to Git.
50 * [./fossil-v-git.wiki | Fossil versus Git].
51 * [./fiveminutes.wiki | Up and running in 5 minutes as a single user]
52 (contributed by Gilles Ganault on 2013-01-08).
53 * [./antibot.wiki | How Fossil defends against abuse by spiders and bots].
 
54
55 DDED www/wsl_caveats.wiki
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -31,14 +31,10 @@
31 * [./stats.wiki | Performance statistics] taken from real-world projects
32 hosted on Fossil.
33 * How to [./shunning.wiki | delete content] from a Fossil repository.
34 * How Fossil does [./password.wiki | password management].
35 * On-line [/help | help].
 
 
 
 
36 * List of [./th1.md | TH1 commands provided by Fossil itself] that expose
37 its key functionality to TH1 scripts.
38 * List of [./th1-hooks.md | TH1 hooks exposed by Fossil] that enable
39 customization of commands and web pages.
40 * A free hosting server for Fossil repositories is available at
@@ -49,5 +45,6 @@
45 * [./inout.wiki | Import and export] from and to Git.
46 * [./fossil-v-git.wiki | Fossil versus Git].
47 * [./fiveminutes.wiki | Up and running in 5 minutes as a single user]
48 (contributed by Gilles Ganault on 2013-01-08).
49 * [./antibot.wiki | How Fossil defends against abuse by spiders and bots].
50 * [./wsl_caveats.wiki | Using Fossil on WSL], caveats and guidance.
51
52 DDED www/wsl_caveats.wiki
--- a/www/wsl_caveats.wiki
+++ b/www/wsl_caveats.wiki
@@ -0,0 +1,176 @@
1
+<title>Caveats and Precautions for Fossil Usage with Windows Subsystem for Linux</title>
2
+
3
+<h2>When These Issues Matter</h2>
4
+
5
+The discussion following is relevant to those who:
6
+
7
+ * Are using the Windows Subsystem for Linux (aka "WSL");
8
+ * Create a Fossil checkout in a directory accessible from WSL and Windows;
9
+ * Use both Linux Fossil and Windows tools to modify files in a checkout;
10
+ * Desire to or must preserve execute permissions set for repository files;
11
+ * and Use Linux Fossil to commit changes made within the checkout.
12
+
13
+Note that these criteria apply conjunctively; if any are not met,
14
+then the consequences of the issues below are at worst annoying
15
+and otherwise harmless or absent.
16
+
17
+<h2>What Can Go Wrong (Why It Matters)</h2>
18
+
19
+The most readily seen manifestation of the problem occurs when
20
+"<tt>fossil status</tt>" or "<tt>fossil changes</tt>" is run,
21
+using Linux Fossil from WSL after Windows tools (including
22
+fossil.exe) have been used to modify files within a checkout.
23
+Unless filter options block it, those subcommands will tag
24
+some (and often many) checkout files with <b>EXECUTABLE</b>
25
+or <b>NOEXEC</b>, indicating that the file's user execute permission
26
+has been altered such that it differs from what is recorded
27
+in the repository for that version of the file.
28
+
29
+This "user execute permission" is referred to as "the X-bit"
30
+hereafter, referring to either the recorded version state
31
+or a checkout file attributes state.
32
+
33
+This is merely annoying and distracting if the altered X-bit
34
+will never be committed using Linux Fossil. It can be quite
35
+distracting because those tags tend to mask the presence or
36
+absence of other changes whose detection is the usual
37
+reason for using Fossil's changes or status subcommands.
38
+
39
+However, in the problematic usage scenario, those tags will
40
+most often represent inadvertant toggling of the X-bit on the
41
+affected file. The X-bit is kept in the repository for good
42
+reason (usually), and arbitrary changes to it by means of a
43
+commit when that change is not intended is virtually always
44
+a bad result. (At best, the change causes useless churn; at
45
+worst it frustrates the intended purpose of having an X-bit.)
46
+
47
+<h2>Technical Discusion of the Problem</h2>
48
+
49
+The genesis of altered X-bits, while not obvious at first glance,
50
+involves obvious facts. The Windows OS does not deal with the
51
+triple of user/group/other executable permissions the way that
52
+Unix and similar operating systems do. Hence, tools which run
53
+on Windows, including Fossil built for Windows, do not manage
54
+the X-bit; it may not even exist yet for files which have not
55
+had their permissions set by any Linux program running in WSL.
56
+When such tools modify a file which has had its X-bit set (or
57
+cleared) by a program in WSL, an existing X-bit value may not
58
+be preserved depending upon how the modification is effected.
59
+
60
+The WSL infrastructure (or virtual system) compensates for the
61
+absence of an X-bit in Windows filesystems with two stratagems:
62
+(1) Establishing a default for its value when no Linux program
63
+has yet set it; and (2) stashing Linux "mode" bits in a "special"
64
+place for each file once it has been subject to a chmod() call.
65
+That default's default can be changed by way of /etc/wsl.conf
66
+content. However, this default cannot be right for files which
67
+are tracked in a Fossil repository as having the other value.
68
+And Windows tools generally are not written to deal with "mode"
69
+bits in that "special" place. (They are kept in a NTFS extended
70
+file attribute named $LXMOD, not accessible through the WIN32
71
+API; the OS layer below WIN32 must be used to get at them.)
72
+Hence, inadvertant X-bit changes are unavoidable, or avoided
73
+only by luck, in the general usage case noted above.
74
+
75
+<h2>Problematic Usage Scenarios</h2>
76
+
77
+<h3>A Simple Example</h3>
78
+
79
+ * Open a checkout in Windows (using fossil.exe) from a project
80
+whose files have a mixture of executable and non-executable files.
81
+Use a checkout directory visible when running under WSL.
82
+
83
+ * Navigate to the same directory in a Linux shell on WSL, then
84
+run "fossil status".
85
+
86
+ * Depending upon /etc/wsl.conf content (or defaults in its absence),
87
+the status ouput will tag checkout files as EXECUTABLE or NOEXEC.
88
+
89
+<h3>Continuation of Simple Example</h3>
90
+
91
+ * In the same checkout as above "Simple Example", on WSL,
92
+run "fossil revert" to correct all those errant X-bit values.
93
+
94
+ * Run "fossil status" again in WSL to verify absence of toggled X-bits.
95
+
96
+ * Run "ls -l" from WSL to find two files, one with its X-bit set
97
+and the other with it clear.
98
+
99
+ * From Windows, perform these steps on each of those files:<br>
100
+&nbsp;&nbsp;(1) read the_file content into a buffer<br>
101
+&nbsp;&nbsp;(2) rename the_file the_file.bak<br>
102
+&nbsp;&nbsp;(3) write buffer content to new file, the_file<br>
103
+&nbsp;&nbsp;(4) del the_file.bak (or leave it)<br>
104
+&nbsp;&nbsp;(Note that this sequence is similar to what many editors do when
105
+a user modifies a file then uses undo to reverse the changes.)
106
+
107
+ * Run "fossil status" again in WSL and observe that one of the
108
+two files has had its X-bit toggled.
109
+
110
+<h3>A Fossil-Only Example</h3>
111
+
112
+ * In the another (different) checkout of the same version,
113
+somehow cause "legitimate" X-bit toggles of two files whose
114
+X-bits differ. (This "somehow" probably will involve WSL to
115
+toggle file bits and fossil on WSL to commit the toggles.)
116
+
117
+ * In the Simple Example checkout, use fossil.exe on Windows
118
+to update the checkout, ostensibly bringing the X-bit toggles
119
+into the affected checkout files.
120
+
121
+ * In the Simple Example checkout, use fossil on WSL to run
122
+"fossil status", and observe at least one X-bit discrepancy.
123
+
124
+<h2>Recommended Workflow</h2>
125
+
126
+There are two simple approaches for dealing with this issue when
127
+one wishes to continue using the same checkout directory from
128
+Windows and WSL. Either one is effective. These are:
129
+
130
+ * Do not use fossil on WSL for any operations which will modify
131
+the repository. Instead, block those operations in some manner.
132
+
133
+ * Do not use any tools on Windows, (including certain subcommands
134
+of fossil.exe,) which may modify the X-bits on files within the
135
+shared checkout, instead restricting use of Windows tools to those
136
+which are known to only (and actually) modify file content in place
137
+while preserving X-bit values. (The "actually" proviso emphasizes
138
+that tools which only simulate in-place file modification, but do
139
+so via create combined with delete and rename, are to be avoided.
140
+A simulation which works flawlessly on Windows may not preserve
141
+the WSL X-bit.)
142
+
143
+There are more complex ways to deal with this issue, involving
144
+use of fossil on WSL to fix (or revert) toggled X-bits prior
145
+to any commit, together with actions needed to preserve all
146
+intended changes to the checkout as fossil revert is done.
147
+Such methods are overly clever or fragile for elaboration here.
148
+
149
+Another way to deal with this issue is to correct any toggled
150
+X-bits within a checkout before using "fossil commit" on WSL
151
+by means other than "fossil revert".
152
+
153
+<h2>Corrective Measures or Mitigation</h2>
154
+
155
+It is possible, by either manual or automated means, to perform
156
+a pre-commit check and/or correction for mis-toggled X-bits.
157
+
158
+The X-bit states are available from the repository for whatever
159
+versions it has stored. And several Linux tools are able to read
160
+or alter the X-bit state of files. With these components, a tool
161
+can be readily built to aid avoidance of a commit (via fossil on
162
+WSL) that would record mis-toggled X-bits into the repository.
163
+
164
+Fossil itself on WSL will detect mis-toggled X-bits for files
165
+which have not been otherise modified, but altered file content
166
+masks such detection, and it is just such modification that is
167
+among the problematic scenarios. So Fossil alone cannot yet
168
+reliably do the detection or correction needed to avoid or
169
+remedy the mis-toggled X-bit commit problem.
170
+
171
+It is also feasible to detect or correct the mis-toggled X-bit
172
+problem within Windows with a special-purpose tool which can
173
+read, create or modify the X-bits stored by WSL for any file
174
+which has been subject to the Linux chmod(...) system call.
175
+
176
+Creation of these tools is beyond the scope of this document.
--- a/www/wsl_caveats.wiki
+++ b/www/wsl_caveats.wiki
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/www/wsl_caveats.wiki
+++ b/www/wsl_caveats.wiki
@@ -0,0 +1,176 @@
1 <title>Caveats and Precautions for Fossil Usage with Windows Subsystem for Linux</title>
2
3 <h2>When These Issues Matter</h2>
4
5 The discussion following is relevant to those who:
6
7 * Are using the Windows Subsystem for Linux (aka "WSL");
8 * Create a Fossil checkout in a directory accessible from WSL and Windows;
9 * Use both Linux Fossil and Windows tools to modify files in a checkout;
10 * Desire to or must preserve execute permissions set for repository files;
11 * and Use Linux Fossil to commit changes made within the checkout.
12
13 Note that these criteria apply conjunctively; if any are not met,
14 then the consequences of the issues below are at worst annoying
15 and otherwise harmless or absent.
16
17 <h2>What Can Go Wrong (Why It Matters)</h2>
18
19 The most readily seen manifestation of the problem occurs when
20 "<tt>fossil status</tt>" or "<tt>fossil changes</tt>" is run,
21 using Linux Fossil from WSL after Windows tools (including
22 fossil.exe) have been used to modify files within a checkout.
23 Unless filter options block it, those subcommands will tag
24 some (and often many) checkout files with <b>EXECUTABLE</b>
25 or <b>NOEXEC</b>, indicating that the file's user execute permission
26 has been altered such that it differs from what is recorded
27 in the repository for that version of the file.
28
29 This "user execute permission" is referred to as "the X-bit"
30 hereafter, referring to either the recorded version state
31 or a checkout file attributes state.
32
33 This is merely annoying and distracting if the altered X-bit
34 will never be committed using Linux Fossil. It can be quite
35 distracting because those tags tend to mask the presence or
36 absence of other changes whose detection is the usual
37 reason for using Fossil's changes or status subcommands.
38
39 However, in the problematic usage scenario, those tags will
40 most often represent inadvertant toggling of the X-bit on the
41 affected file. The X-bit is kept in the repository for good
42 reason (usually), and arbitrary changes to it by means of a
43 commit when that change is not intended is virtually always
44 a bad result. (At best, the change causes useless churn; at
45 worst it frustrates the intended purpose of having an X-bit.)
46
47 <h2>Technical Discusion of the Problem</h2>
48
49 The genesis of altered X-bits, while not obvious at first glance,
50 involves obvious facts. The Windows OS does not deal with the
51 triple of user/group/other executable permissions the way that
52 Unix and similar operating systems do. Hence, tools which run
53 on Windows, including Fossil built for Windows, do not manage
54 the X-bit; it may not even exist yet for files which have not
55 had their permissions set by any Linux program running in WSL.
56 When such tools modify a file which has had its X-bit set (or
57 cleared) by a program in WSL, an existing X-bit value may not
58 be preserved depending upon how the modification is effected.
59
60 The WSL infrastructure (or virtual system) compensates for the
61 absence of an X-bit in Windows filesystems with two stratagems:
62 (1) Establishing a default for its value when no Linux program
63 has yet set it; and (2) stashing Linux "mode" bits in a "special"
64 place for each file once it has been subject to a chmod() call.
65 That default's default can be changed by way of /etc/wsl.conf
66 content. However, this default cannot be right for files which
67 are tracked in a Fossil repository as having the other value.
68 And Windows tools generally are not written to deal with "mode"
69 bits in that "special" place. (They are kept in a NTFS extended
70 file attribute named $LXMOD, not accessible through the WIN32
71 API; the OS layer below WIN32 must be used to get at them.)
72 Hence, inadvertant X-bit changes are unavoidable, or avoided
73 only by luck, in the general usage case noted above.
74
75 <h2>Problematic Usage Scenarios</h2>
76
77 <h3>A Simple Example</h3>
78
79 * Open a checkout in Windows (using fossil.exe) from a project
80 whose files have a mixture of executable and non-executable files.
81 Use a checkout directory visible when running under WSL.
82
83 * Navigate to the same directory in a Linux shell on WSL, then
84 run "fossil status".
85
86 * Depending upon /etc/wsl.conf content (or defaults in its absence),
87 the status ouput will tag checkout files as EXECUTABLE or NOEXEC.
88
89 <h3>Continuation of Simple Example</h3>
90
91 * In the same checkout as above "Simple Example", on WSL,
92 run "fossil revert" to correct all those errant X-bit values.
93
94 * Run "fossil status" again in WSL to verify absence of toggled X-bits.
95
96 * Run "ls -l" from WSL to find two files, one with its X-bit set
97 and the other with it clear.
98
99 * From Windows, perform these steps on each of those files:<br>
100 &nbsp;&nbsp;(1) read the_file content into a buffer<br>
101 &nbsp;&nbsp;(2) rename the_file the_file.bak<br>
102 &nbsp;&nbsp;(3) write buffer content to new file, the_file<br>
103 &nbsp;&nbsp;(4) del the_file.bak (or leave it)<br>
104 &nbsp;&nbsp;(Note that this sequence is similar to what many editors do when
105 a user modifies a file then uses undo to reverse the changes.)
106
107 * Run "fossil status" again in WSL and observe that one of the
108 two files has had its X-bit toggled.
109
110 <h3>A Fossil-Only Example</h3>
111
112 * In the another (different) checkout of the same version,
113 somehow cause "legitimate" X-bit toggles of two files whose
114 X-bits differ. (This "somehow" probably will involve WSL to
115 toggle file bits and fossil on WSL to commit the toggles.)
116
117 * In the Simple Example checkout, use fossil.exe on Windows
118 to update the checkout, ostensibly bringing the X-bit toggles
119 into the affected checkout files.
120
121 * In the Simple Example checkout, use fossil on WSL to run
122 "fossil status", and observe at least one X-bit discrepancy.
123
124 <h2>Recommended Workflow</h2>
125
126 There are two simple approaches for dealing with this issue when
127 one wishes to continue using the same checkout directory from
128 Windows and WSL. Either one is effective. These are:
129
130 * Do not use fossil on WSL for any operations which will modify
131 the repository. Instead, block those operations in some manner.
132
133 * Do not use any tools on Windows, (including certain subcommands
134 of fossil.exe,) which may modify the X-bits on files within the
135 shared checkout, instead restricting use of Windows tools to those
136 which are known to only (and actually) modify file content in place
137 while preserving X-bit values. (The "actually" proviso emphasizes
138 that tools which only simulate in-place file modification, but do
139 so via create combined with delete and rename, are to be avoided.
140 A simulation which works flawlessly on Windows may not preserve
141 the WSL X-bit.)
142
143 There are more complex ways to deal with this issue, involving
144 use of fossil on WSL to fix (or revert) toggled X-bits prior
145 to any commit, together with actions needed to preserve all
146 intended changes to the checkout as fossil revert is done.
147 Such methods are overly clever or fragile for elaboration here.
148
149 Another way to deal with this issue is to correct any toggled
150 X-bits within a checkout before using "fossil commit" on WSL
151 by means other than "fossil revert".
152
153 <h2>Corrective Measures or Mitigation</h2>
154
155 It is possible, by either manual or automated means, to perform
156 a pre-commit check and/or correction for mis-toggled X-bits.
157
158 The X-bit states are available from the repository for whatever
159 versions it has stored. And several Linux tools are able to read
160 or alter the X-bit state of files. With these components, a tool
161 can be readily built to aid avoidance of a commit (via fossil on
162 WSL) that would record mis-toggled X-bits into the repository.
163
164 Fossil itself on WSL will detect mis-toggled X-bits for files
165 which have not been otherise modified, but altered file content
166 masks such detection, and it is just such modification that is
167 among the problematic scenarios. So Fossil alone cannot yet
168 reliably do the detection or correction needed to avoid or
169 remedy the mis-toggled X-bit commit problem.
170
171 It is also feasible to detect or correct the mis-toggled X-bit
172 problem within Windows with a special-purpose tool which can
173 read, create or modify the X-bits stored by WSL for any file
174 which has been subject to the Linux chmod(...) system call.
175
176 Creation of these tools is beyond the scope of this document.

Keyboard Shortcuts

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