Fossil SCM

Update the built-in SQLite to the latest version 3.47.0 alpha.

stephan 2024-08-24 08:52 trunk
Commit e17b8da85584d6086e60c5e6fe2c99996748cf766a16cd7ab2f8dc6458ef9085
3 files changed +364 -49 +2283 -682 +124 -9
+364 -49
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1519,10 +1519,18 @@
15191519
size_t i;
15201520
for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
15211521
dest[i] = 0;
15221522
return dest;
15231523
}
1524
+
1525
+/*
1526
+** strcpy() workalike to squelch an unwarranted link-time warning
1527
+** from OpenBSD.
1528
+*/
1529
+static void shell_strcpy(char *dest, const char *src){
1530
+ while( (*(dest++) = *(src++))!=0 ){}
1531
+}
15241532
15251533
/*
15261534
** Optionally disable dynamic continuation prompt.
15271535
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
15281536
** or open parentheses level if non-zero, or continuation prompt as set.
@@ -1585,11 +1593,11 @@
15851593
}else{
15861594
if( dynPrompt.zScannerAwaits ){
15871595
size_t ncp = strlen(continuePrompt);
15881596
size_t ndp = strlen(dynPrompt.zScannerAwaits);
15891597
if( ndp > ncp-3 ) return continuePrompt;
1590
- strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
1598
+ shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
15911599
while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
15921600
shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
15931601
PROMPT_LEN_MAX-4);
15941602
}else{
15951603
if( dynPrompt.inParenLevel>9 ){
@@ -6132,10 +6140,30 @@
61326140
** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step.
61336141
** xBestIndex returns a small cost when both start and stop are available,
61346142
** and a very large cost if either start or stop are unavailable. This
61356143
** encourages the query planner to order joins such that the bounds of the
61366144
** series are well-defined.
6145
+**
6146
+** Update on 2024-08-22:
6147
+** xBestIndex now also looks for equality and inequality constraints against
6148
+** the value column and uses those constraints as additional bounds against
6149
+** the sequence range. Thus, a query like this:
6150
+**
6151
+** SELECT value FROM generate_series($SA,$EA)
6152
+** WHERE value BETWEEN $SB AND $EB;
6153
+**
6154
+** Is logically the same as:
6155
+**
6156
+** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB));
6157
+**
6158
+** Constraints on the value column can server as substitutes for constraints
6159
+** on the hidden start and stop columns. So, the following two queries
6160
+** are equivalent:
6161
+**
6162
+** SELECT value FROM generate_series($S,$E);
6163
+** SELECT value FROM generate_series WHERE value BETWEEN $S and $E;
6164
+**
61376165
*/
61386166
/* #include "sqlite3ext.h" */
61396167
SQLITE_EXTENSION_INIT1
61406168
#include <assert.h>
61416169
#include <string.h>
@@ -6173,12 +6201,14 @@
61736201
}
61746202
61756203
/* typedef unsigned char u8; */
61766204
61776205
typedef struct SequenceSpec {
6178
- sqlite3_int64 iBase; /* Starting value ("start") */
6179
- sqlite3_int64 iTerm; /* Given terminal value ("stop") */
6206
+ sqlite3_int64 iOBase; /* Original starting value ("start") */
6207
+ sqlite3_int64 iOTerm; /* Original terminal value ("stop") */
6208
+ sqlite3_int64 iBase; /* Starting value to actually use */
6209
+ sqlite3_int64 iTerm; /* Terminal value to actually use */
61806210
sqlite3_int64 iStep; /* Increment ("step") */
61816211
sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
61826212
sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
61836213
sqlite3_int64 iValueNow; /* Current value during generation */
61846214
u8 isNotEOF; /* Sequence generation not exhausted */
@@ -6367,21 +6397,23 @@
63676397
int i /* Which column to return */
63686398
){
63696399
series_cursor *pCur = (series_cursor*)cur;
63706400
sqlite3_int64 x = 0;
63716401
switch( i ){
6372
- case SERIES_COLUMN_START: x = pCur->ss.iBase; break;
6373
- case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break;
6374
- case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
6402
+ case SERIES_COLUMN_START: x = pCur->ss.iOBase; break;
6403
+ case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break;
6404
+ case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
63756405
default: x = pCur->ss.iValueNow; break;
63766406
}
63776407
sqlite3_result_int64(ctx, x);
63786408
return SQLITE_OK;
63796409
}
63806410
63816411
#ifndef LARGEST_UINT64
6412
+#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
63826413
#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32))
6414
+#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
63836415
#endif
63846416
63856417
/*
63866418
** Return the rowid for the current row, logically equivalent to n+1 where
63876419
** "n" is the ascending integer in the aforesaid production definition.
@@ -6418,17 +6450,22 @@
64186450
**
64196451
** The query plan selected by seriesBestIndex is passed in the idxNum
64206452
** parameter. (idxStr is not used in this implementation.) idxNum
64216453
** is a bitmask showing which constraints are available:
64226454
**
6423
-** 0x01: start=VALUE
6424
-** 0x02: stop=VALUE
6425
-** 0x04: step=VALUE
6426
-** 0x08: descending order
6427
-** 0x10: ascending order
6428
-** 0x20: LIMIT VALUE
6429
-** 0x40: OFFSET VALUE
6455
+** 0x0001: start=VALUE
6456
+** 0x0002: stop=VALUE
6457
+** 0x0004: step=VALUE
6458
+** 0x0008: descending order
6459
+** 0x0010: ascending order
6460
+** 0x0020: LIMIT VALUE
6461
+** 0x0040: OFFSET VALUE
6462
+** 0x0080: value=VALUE
6463
+** 0x0100: value>=VALUE
6464
+** 0x0200: value>VALUE
6465
+** 0x1000: value<=VALUE
6466
+** 0x2000: value<VALUE
64306467
**
64316468
** This routine should initialize the cursor and position it so that it
64326469
** is pointing at the first row, or pointing off the end of the table
64336470
** (so that seriesEof() will return true) if the table is empty.
64346471
*/
@@ -6437,10 +6474,16 @@
64376474
int idxNum, const char *idxStrUnused,
64386475
int argc, sqlite3_value **argv
64396476
){
64406477
series_cursor *pCur = (series_cursor *)pVtabCursor;
64416478
int i = 0;
6479
+ int returnNoRows = 0;
6480
+ sqlite3_int64 iMin = SMALLEST_INT64;
6481
+ sqlite3_int64 iMax = LARGEST_INT64;
6482
+ sqlite3_int64 iLimit = 0;
6483
+ sqlite3_int64 iOffset = 0;
6484
+
64426485
(void)idxStrUnused;
64436486
if( idxNum & 0x01 ){
64446487
pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
64456488
}else{
64466489
pCur->ss.iBase = 0;
@@ -6458,38 +6501,125 @@
64586501
if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
64596502
}
64606503
}else{
64616504
pCur->ss.iStep = 1;
64626505
}
6506
+
6507
+ /* If there are constraints on the value column but there are
6508
+ ** no constraints on the start, stop, and step columns, then
6509
+ ** initialize the default range to be the entire range of 64-bit signed
6510
+ ** integers. This range will contracted by the value column constraints
6511
+ ** further below.
6512
+ */
6513
+ if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){
6514
+ pCur->ss.iBase = SMALLEST_INT64;
6515
+ }
6516
+ if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){
6517
+ pCur->ss.iTerm = LARGEST_INT64;
6518
+ }
6519
+ pCur->ss.iOBase = pCur->ss.iBase;
6520
+ pCur->ss.iOTerm = pCur->ss.iTerm;
6521
+
6522
+ /* Extract the LIMIT and OFFSET values, but do not apply them yet.
6523
+ ** The range must first be constrained by the limits on value.
6524
+ */
64636525
if( idxNum & 0x20 ){
6464
- sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]);
6465
- sqlite3_int64 iTerm;
6526
+ iLimit = sqlite3_value_int64(argv[i++]);
64666527
if( idxNum & 0x40 ){
6467
- sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]);
6468
- if( iOffset>0 ){
6469
- pCur->ss.iBase += pCur->ss.iStep*iOffset;
6528
+ iOffset = sqlite3_value_int64(argv[i++]);
6529
+ }
6530
+ }
6531
+
6532
+ if( idxNum & 0x3380 ){
6533
+ /* Extract the maximum range of output values determined by
6534
+ ** constraints on the "value" column.
6535
+ */
6536
+ if( idxNum & 0x0080 ){
6537
+ iMin = iMax = sqlite3_value_int64(argv[i++]);
6538
+ }else{
6539
+ if( idxNum & 0x0300 ){
6540
+ iMin = sqlite3_value_int64(argv[i++]);
6541
+ if( idxNum & 0x0200 ){
6542
+ if( iMin==LARGEST_INT64 ){
6543
+ returnNoRows = 1;
6544
+ }else{
6545
+ iMin++;
6546
+ }
6547
+ }
64706548
}
6549
+ if( idxNum & 0x3000 ){
6550
+ iMax = sqlite3_value_int64(argv[i++]);
6551
+ if( idxNum & 0x2000 ){
6552
+ if( iMax==SMALLEST_INT64 ){
6553
+ returnNoRows = 1;
6554
+ }else{
6555
+ iMax--;
6556
+ }
6557
+ }
6558
+ }
6559
+ if( iMin>iMax ){
6560
+ returnNoRows = 1;
6561
+ }
6562
+ }
6563
+
6564
+ /* Try to reduce the range of values to be generated based on
6565
+ ** constraints on the "value" column.
6566
+ */
6567
+ if( pCur->ss.iStep>0 ){
6568
+ sqlite3_int64 szStep = pCur->ss.iStep;
6569
+ if( pCur->ss.iBase<iMin ){
6570
+ sqlite3_uint64 d = iMin - pCur->ss.iBase;
6571
+ pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
6572
+ }
6573
+ if( pCur->ss.iTerm>iMax ){
6574
+ sqlite3_uint64 d = pCur->ss.iTerm - iMax;
6575
+ pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep;
6576
+ }
6577
+ }else{
6578
+ sqlite3_int64 szStep = -pCur->ss.iStep;
6579
+ assert( szStep>0 );
6580
+ if( pCur->ss.iBase>iMax ){
6581
+ sqlite3_uint64 d = pCur->ss.iBase - iMax;
6582
+ pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
6583
+ }
6584
+ if( pCur->ss.iTerm<iMin ){
6585
+ sqlite3_uint64 d = iMin - pCur->ss.iTerm;
6586
+ pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep;
6587
+ }
6588
+ }
6589
+ }
6590
+
6591
+ /* Apply LIMIT and OFFSET constraints, if any */
6592
+ if( idxNum & 0x20 ){
6593
+ if( iOffset>0 ){
6594
+ pCur->ss.iBase += pCur->ss.iStep*iOffset;
64716595
}
64726596
if( iLimit>=0 ){
6597
+ sqlite3_int64 iTerm;
64736598
iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
64746599
if( pCur->ss.iStep<0 ){
64756600
if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
64766601
}else{
64776602
if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
64786603
}
64796604
}
64806605
}
6606
+
6607
+
64816608
for(i=0; i<argc; i++){
64826609
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
64836610
/* If any of the constraints have a NULL value, then return no rows.
64846611
** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
6485
- pCur->ss.iBase = 1;
6486
- pCur->ss.iTerm = 0;
6487
- pCur->ss.iStep = 1;
6612
+ returnNoRows = 1;
64886613
break;
64896614
}
64906615
}
6616
+ if( returnNoRows ){
6617
+ pCur->ss.iBase = 1;
6618
+ pCur->ss.iTerm = 0;
6619
+ pCur->ss.iStep = 1;
6620
+ }
64916621
if( idxNum & 0x08 ){
64926622
pCur->ss.isReversing = pCur->ss.iStep > 0;
64936623
}else{
64946624
pCur->ss.isReversing = pCur->ss.iStep < 0;
64956625
}
@@ -6506,17 +6636,39 @@
65066636
** In this implementation idxNum is used to represent the
65076637
** query plan. idxStr is unused.
65086638
**
65096639
** The query plan is represented by bits in idxNum:
65106640
**
6511
-** 0x01 start = $value -- constraint exists
6512
-** 0x02 stop = $value -- constraint exists
6513
-** 0x04 step = $value -- constraint exists
6514
-** 0x08 output is in descending order
6515
-** 0x10 output is in ascending order
6516
-** 0x20 LIMIT $value -- constraint exists
6517
-** 0x40 OFFSET $value -- constraint exists
6641
+** 0x0001 start = $num
6642
+** 0x0002 stop = $num
6643
+** 0x0004 step = $num
6644
+** 0x0008 output is in descending order
6645
+** 0x0010 output is in ascending order
6646
+** 0x0020 LIMIT $num
6647
+** 0x0040 OFFSET $num
6648
+** 0x0080 value = $num
6649
+** 0x0100 value >= $num
6650
+** 0x0200 value > $num
6651
+** 0x1000 value <= $num
6652
+** 0x2000 value < $num
6653
+**
6654
+** Only one of 0x0100 or 0x0200 will be returned. Similarly, only
6655
+** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then
6656
+** none of the 0xff00 bits will be set.
6657
+**
6658
+** The order of parameters passed to xFilter is as follows:
6659
+**
6660
+** * The argument to start= if bit 0x0001 is in the idxNum mask
6661
+** * The argument to stop= if bit 0x0002 is in the idxNum mask
6662
+** * The argument to step= if bit 0x0004 is in the idxNum mask
6663
+** * The argument to LIMIT if bit 0x0020 is in the idxNum mask
6664
+** * The argument to OFFSET if bit 0x0040 is in the idxNum mask
6665
+** * The argument to value=, or value>= or value> if any of
6666
+** bits 0x0380 are in the idxNum mask
6667
+** * The argument to value<= or value< if either of bits 0x3000
6668
+** are in the mask
6669
+**
65186670
*/
65196671
static int seriesBestIndex(
65206672
sqlite3_vtab *pVTab,
65216673
sqlite3_index_info *pIdxInfo
65226674
){
@@ -6525,19 +6677,21 @@
65256677
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
65266678
int bStartSeen = 0; /* EQ constraint seen on the START column */
65276679
#endif
65286680
int unusableMask = 0; /* Mask of unusable constraints */
65296681
int nArg = 0; /* Number of arguments that seriesFilter() expects */
6530
- int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */
6682
+ int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET,
6683
+ ** and value. aIdx[5] covers value=, value>=, and
6684
+ ** value>, aIdx[6] covers value<= and value< */
65316685
const struct sqlite3_index_constraint *pConstraint;
65326686
65336687
/* This implementation assumes that the start, stop, and step columns
65346688
** are the last three columns in the virtual table. */
65356689
assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
65366690
assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
65376691
6538
- aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1;
6692
+ aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1;
65396693
pConstraint = pIdxInfo->aConstraint;
65406694
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
65416695
int iCol; /* 0 for start, 1 for stop, 2 for step */
65426696
int iMask; /* bitmask for those column */
65436697
int op = pConstraint->op;
@@ -6554,11 +6708,54 @@
65546708
aIdx[4] = i;
65556709
idxNum |= 0x40;
65566710
}
65576711
continue;
65586712
}
6559
- if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
6713
+ if( pConstraint->iColumn==SERIES_COLUMN_VALUE ){
6714
+ switch( op ){
6715
+ case SQLITE_INDEX_CONSTRAINT_EQ:
6716
+ case SQLITE_INDEX_CONSTRAINT_IS: {
6717
+ idxNum |= 0x0080;
6718
+ idxNum &= ~0x3300;
6719
+ aIdx[5] = i;
6720
+ aIdx[6] = -1;
6721
+ bStartSeen = 1;
6722
+ break;
6723
+ }
6724
+ case SQLITE_INDEX_CONSTRAINT_GE: {
6725
+ if( idxNum & 0x0080 ) break;
6726
+ idxNum |= 0x0100;
6727
+ idxNum &= ~0x0200;
6728
+ aIdx[5] = i;
6729
+ bStartSeen = 1;
6730
+ break;
6731
+ }
6732
+ case SQLITE_INDEX_CONSTRAINT_GT: {
6733
+ if( idxNum & 0x0080 ) break;
6734
+ idxNum |= 0x0200;
6735
+ idxNum &= ~0x0100;
6736
+ aIdx[5] = i;
6737
+ bStartSeen = 1;
6738
+ break;
6739
+ }
6740
+ case SQLITE_INDEX_CONSTRAINT_LE: {
6741
+ if( idxNum & 0x0080 ) break;
6742
+ idxNum |= 0x1000;
6743
+ idxNum &= ~0x2000;
6744
+ aIdx[6] = i;
6745
+ break;
6746
+ }
6747
+ case SQLITE_INDEX_CONSTRAINT_LT: {
6748
+ if( idxNum & 0x0080 ) break;
6749
+ idxNum |= 0x2000;
6750
+ idxNum &= ~0x1000;
6751
+ aIdx[6] = i;
6752
+ break;
6753
+ }
6754
+ }
6755
+ continue;
6756
+ }
65606757
iCol = pConstraint->iColumn - SERIES_COLUMN_START;
65616758
assert( iCol>=0 && iCol<=2 );
65626759
iMask = 1 << iCol;
65636760
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
65646761
if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){
@@ -6576,11 +6773,11 @@
65766773
if( aIdx[3]==0 ){
65776774
/* Ignore OFFSET if LIMIT is omitted */
65786775
idxNum &= ~0x60;
65796776
aIdx[4] = 0;
65806777
}
6581
- for(i=0; i<5; i++){
6778
+ for(i=0; i<7; i++){
65826779
if( (j = aIdx[i])>=0 ){
65836780
pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
65846781
pIdxInfo->aConstraintUsage[j].omit =
65856782
!SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3;
65866783
}
@@ -6624,10 +6821,13 @@
66246821
** of numbers. Make this case very expensive so that the query
66256822
** planner will work hard to avoid it. */
66266823
pIdxInfo->estimatedRows = 2147483647;
66276824
}
66286825
pIdxInfo->idxNum = idxNum;
6826
+#ifdef SQLITE_INDEX_SCAN_HEX
6827
+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX;
6828
+#endif
66296829
return SQLITE_OK;
66306830
}
66316831
66326832
/*
66336833
** This following structure defines all the methods for the
@@ -24970,16 +25170,21 @@
2497025170
oputf("%-20s %u\n", "data version", iDataVersion);
2497125171
return 0;
2497225172
}
2497325173
#endif /* SQLITE_SHELL_HAVE_RECOVER */
2497425174
25175
+/*
25176
+** Print the given string as an error message.
25177
+*/
25178
+static void shellEmitError(const char *zErr){
25179
+ eputf("Error: %s\n", zErr);
25180
+}
2497525181
/*
2497625182
** Print the current sqlite3_errmsg() value to stderr and return 1.
2497725183
*/
2497825184
static int shellDatabaseError(sqlite3 *db){
24979
- const char *zErr = sqlite3_errmsg(db);
24980
- eputf("Error: %s\n", zErr);
25185
+ shellEmitError(sqlite3_errmsg(db));
2498125186
return 1;
2498225187
}
2498325188
2498425189
/*
2498525190
** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
@@ -25520,11 +25725,11 @@
2552025725
va_list ap;
2552125726
char *z;
2552225727
va_start(ap, zFmt);
2552325728
z = sqlite3_vmprintf(zFmt, ap);
2552425729
va_end(ap);
25525
- eputf("Error: %s\n", z);
25730
+ shellEmitError(z);
2552625731
if( pAr->fromCmdLine ){
2552725732
eputz("Use \"-A\" for more help\n");
2552825733
}else{
2552925734
eputz("Use \".archive --help\" for more help\n");
2553025735
}
@@ -26751,20 +26956,20 @@
2675126956
0, 0, 0);
2675226957
}
2675326958
open_db(p, 0);
2675426959
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2675526960
if( pBackup==0 ){
26756
- eputf("Error: %s\n", sqlite3_errmsg(pDest));
26961
+ shellDatabaseError(pDest);
2675726962
close_db(pDest);
2675826963
return 1;
2675926964
}
2676026965
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2676126966
sqlite3_backup_finish(pBackup);
2676226967
if( rc==SQLITE_DONE ){
2676326968
rc = 0;
2676426969
}else{
26765
- eputf("Error: %s\n", sqlite3_errmsg(pDest));
26970
+ shellDatabaseError(pDest);
2676626971
rc = 1;
2676726972
}
2676826973
close_db(pDest);
2676926974
}else
2677026975
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -26936,11 +27141,11 @@
2693627141
sqlite3_stmt *pStmt;
2693727142
int i;
2693827143
open_db(p, 0);
2693927144
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2694027145
if( rc ){
26941
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
27146
+ shellDatabaseError(p->db);
2694227147
rc = 1;
2694327148
}else{
2694427149
while( sqlite3_step(pStmt)==SQLITE_ROW ){
2694527150
const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
2694627151
const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
@@ -27632,11 +27837,11 @@
2763227837
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2763327838
sqlite3_free(zSql);
2763427839
zSql = 0;
2763527840
if( rc ){
2763627841
if (pStmt) sqlite3_finalize(pStmt);
27637
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
27842
+ shellDatabaseError(p->db);
2763827843
import_cleanup(&sCtx);
2763927844
rc = 1;
2764027845
goto meta_command_exit;
2764127846
}
2764227847
if( sqlite3_step(pStmt)==SQLITE_ROW ){
@@ -27676,11 +27881,11 @@
2767627881
}
2767727882
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2767827883
sqlite3_free(zSql);
2767927884
zSql = 0;
2768027885
if( rc ){
27681
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
27886
+ shellDatabaseError(p->db);
2768227887
if (pStmt) sqlite3_finalize(pStmt);
2768327888
import_cleanup(&sCtx);
2768427889
rc = 1;
2768527890
goto meta_command_exit;
2768627891
}
@@ -27970,11 +28175,11 @@
2797028175
zFile = azArg[1];
2797128176
zProc = nArg>=3 ? azArg[2] : 0;
2797228177
open_db(p, 0);
2797328178
rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2797428179
if( rc!=SQLITE_OK ){
27975
- eputf("Error: %s\n", zErrMsg);
28180
+ shellEmitError(zErrMsg);
2797628181
sqlite3_free(zErrMsg);
2797728182
rc = 1;
2797828183
}
2797928184
}else
2798028185
#endif
@@ -28592,11 +28797,11 @@
2859228797
return 1;
2859328798
}
2859428799
open_db(p, 0);
2859528800
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2859628801
if( pBackup==0 ){
28597
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
28802
+ shellDatabaseError(p->db);
2859828803
close_db(pSrc);
2859928804
return 1;
2860028805
}
2860128806
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2860228807
|| rc==SQLITE_BUSY ){
@@ -28610,11 +28815,11 @@
2861028815
rc = 0;
2861128816
}else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2861228817
eputz("Error: source database is busy\n");
2861328818
rc = 1;
2861428819
}else{
28615
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
28820
+ shellDatabaseError(p->db);
2861628821
rc = 1;
2861728822
}
2861828823
close_db(pSrc);
2861928824
}else
2862028825
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28707,11 +28912,11 @@
2870728912
if( zDiv ){
2870828913
sqlite3_stmt *pStmt = 0;
2870928914
rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
2871028915
-1, &pStmt, 0);
2871128916
if( rc ){
28712
- eputf("Error: %s\n", sqlite3_errmsg(p->db));
28917
+ shellDatabaseError(p->db);
2871328918
sqlite3_finalize(pStmt);
2871428919
rc = 1;
2871528920
goto meta_command_exit;
2871628921
}
2871728922
appendText(&sSelect, "SELECT sql FROM", 0);
@@ -28776,11 +28981,11 @@
2877628981
rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
2877728982
}
2877828983
freeText(&sSelect);
2877928984
}
2878028985
if( zErrMsg ){
28781
- eputf("Error: %s\n", zErrMsg);
28986
+ shellEmitError(zErrMsg);
2878228987
sqlite3_free(zErrMsg);
2878328988
rc = 1;
2878428989
}else if( rc != SQLITE_OK ){
2878528990
eputz("Error: querying schema information\n");
2878628991
rc = 1;
@@ -29547,11 +29752,11 @@
2954729752
{"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
2954829753
{"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
2954929754
{"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
2955029755
{"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
2955129756
{"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
29552
- {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
29757
+ {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK ..."},
2955329758
#ifdef YYCOVERAGE
2955429759
{"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
2955529760
#endif
2955629761
{"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,1, "OFFSET " },
2955729762
{"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
@@ -29610,13 +29815,123 @@
2961029815
if( testctrl<0 ){
2961129816
eputf("Error: unknown test-control: %s\n"
2961229817
"Use \".testctrl --help\" for help\n", zCmd);
2961329818
}else{
2961429819
switch(testctrl){
29820
+
29821
+ /* Special processing for .testctrl opt MASK ...
29822
+ ** Each MASK argument can be one of:
29823
+ **
29824
+ ** +LABEL Enable the named optimization
29825
+ **
29826
+ ** -LABEL Disable the named optimization
29827
+ **
29828
+ ** INTEGER Mask of optimizations to disable
29829
+ */
29830
+ case SQLITE_TESTCTRL_OPTIMIZATIONS: {
29831
+ static const struct {
29832
+ unsigned int mask; /* Mask for this optimization */
29833
+ unsigned int bDsply; /* Display this on output */
29834
+ const char *zLabel; /* Name of optimization */
29835
+ } aLabel[] = {
29836
+ { 0x00000001, 1, "QueryFlattener" },
29837
+ { 0x00000001, 0, "Flatten" },
29838
+ { 0x00000002, 1, "WindowFunc" },
29839
+ { 0x00000004, 1, "GroupByOrder" },
29840
+ { 0x00000008, 1, "FactorOutConst" },
29841
+ { 0x00000010, 1, "DistinctOpt" },
29842
+ { 0x00000020, 1, "CoverIdxScan" },
29843
+ { 0x00000040, 1, "OrderByIdxJoin" },
29844
+ { 0x00000080, 1, "Transitive" },
29845
+ { 0x00000100, 1, "OmitNoopJoin" },
29846
+ { 0x00000200, 1, "CountOfView" },
29847
+ { 0x00000400, 1, "CurosrHints" },
29848
+ { 0x00000800, 1, "Stat4" },
29849
+ { 0x00001000, 1, "PushDown" },
29850
+ { 0x00002000, 1, "SimplifyJoin" },
29851
+ { 0x00004000, 1, "SkipScan" },
29852
+ { 0x00008000, 1, "PropagateConst" },
29853
+ { 0x00010000, 1, "MinMaxOpt" },
29854
+ { 0x00020000, 1, "SeekScan" },
29855
+ { 0x00040000, 1, "OmitOrderBy" },
29856
+ { 0x00080000, 1, "BloomFilter" },
29857
+ { 0x00100000, 1, "BloomPulldown" },
29858
+ { 0x00200000, 1, "BalancedMerge" },
29859
+ { 0x00400000, 1, "ReleaseReg" },
29860
+ { 0x00800000, 1, "FlttnUnionAll" },
29861
+ { 0x01000000, 1, "IndexedEXpr" },
29862
+ { 0x02000000, 1, "Coroutines" },
29863
+ { 0x04000000, 1, "NullUnusedCols" },
29864
+ { 0x08000000, 1, "OnePass" },
29865
+ { 0x10000000, 1, "OrderBySubq" },
29866
+ { 0xffffffff, 0, "All" },
29867
+ };
29868
+ unsigned int curOpt;
29869
+ unsigned int newOpt;
29870
+ int ii;
29871
+ sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
29872
+ newOpt = curOpt;
29873
+ for(ii=2; ii<nArg; ii++){
29874
+ const char *z = azArg[ii];
29875
+ int useLabel = 0;
29876
+ const char *zLabel;
29877
+ if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
29878
+ useLabel = z[0];
29879
+ zLabel = &z[1];
29880
+ }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){
29881
+ useLabel = '+';
29882
+ zLabel = z;
29883
+ }else{
29884
+ newOpt = (unsigned int)strtol(z,0,0);
29885
+ }
29886
+ if( useLabel ){
29887
+ int jj;
29888
+ for(jj=0; jj<ArraySize(aLabel); jj++){
29889
+ if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
29890
+ }
29891
+ if( jj>=ArraySize(aLabel) ){
29892
+ eputf("Error: no such optimization: \"%s\"\n", zLabel);
29893
+ eputf("Should be one of:");
29894
+ for(jj=0; jj<ArraySize(aLabel); jj++){
29895
+ eputf(" %s", aLabel[jj].zLabel);
29896
+ }
29897
+ eputf("\n");
29898
+ rc = 1;
29899
+ goto meta_command_exit;
29900
+ }
29901
+ if( useLabel=='+' ){
29902
+ newOpt &= ~aLabel[jj].mask;
29903
+ }else{
29904
+ newOpt |= aLabel[jj].mask;
29905
+ }
29906
+ }
29907
+ }
29908
+ if( curOpt!=newOpt ){
29909
+ sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
29910
+ }else if( nArg<3 ){
29911
+ curOpt = ~newOpt;
29912
+ }
29913
+ if( newOpt==0 ){
29914
+ oputf("+All\n");
29915
+ }else if( newOpt==0xffffffff ){
29916
+ oputf("-All\n");
29917
+ }else{
29918
+ int jj;
29919
+ for(jj=0; jj<ArraySize(aLabel); jj++){
29920
+ unsigned int m = aLabel[jj].mask;
29921
+ if( !aLabel[jj].bDsply ) continue;
29922
+ if( (curOpt&m)!=(newOpt&m) ){
29923
+ oputf("%c%s\n", (newOpt & m)==0 ? '+' : '-',
29924
+ aLabel[jj].zLabel);
29925
+ }
29926
+ }
29927
+ }
29928
+ rc2 = isOk = 3;
29929
+ break;
29930
+ }
2961529931
2961629932
/* sqlite3_test_control(int, db, int) */
29617
- case SQLITE_TESTCTRL_OPTIMIZATIONS:
2961829933
case SQLITE_TESTCTRL_FK_NO_ACTION:
2961929934
if( nArg==3 ){
2962029935
unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
2962129936
rc2 = sqlite3_test_control(testctrl, p->db, opt);
2962229937
isOk = 3;
@@ -31355,11 +31670,11 @@
3135531670
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
3135631671
}else{
3135731672
open_db(&data, 0);
3135831673
rc = shell_exec(&data, z, &zErrMsg);
3135931674
if( zErrMsg!=0 ){
31360
- eputf("Error: %s\n", zErrMsg);
31675
+ shellEmitError(zErrMsg);
3136131676
if( bail_on_error ) return rc!=0 ? rc : 1;
3136231677
}else if( rc!=0 ){
3136331678
eputf("Error: unable to process SQL \"%s\"\n", z);
3136431679
if( bail_on_error ) return rc;
3136531680
}
@@ -31409,11 +31724,11 @@
3140931724
open_db(&data, 0);
3141031725
echo_group_input(&data, azCmd[i]);
3141131726
rc = shell_exec(&data, azCmd[i], &zErrMsg);
3141231727
if( zErrMsg || rc ){
3141331728
if( zErrMsg!=0 ){
31414
- eputf("Error: %s\n", zErrMsg);
31729
+ shellEmitError(zErrMsg);
3141531730
}else{
3141631731
eputf("Error: unable to process SQL: %s\n", azCmd[i]);
3141731732
}
3141831733
sqlite3_free(zErrMsg);
3141931734
if( rc==0 ) rc = 1;
3142031735
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1519,10 +1519,18 @@
1519 size_t i;
1520 for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
1521 dest[i] = 0;
1522 return dest;
1523 }
 
 
 
 
 
 
 
 
1524
1525 /*
1526 ** Optionally disable dynamic continuation prompt.
1527 ** Unless disabled, the continuation prompt shows open SQL lexemes if any,
1528 ** or open parentheses level if non-zero, or continuation prompt as set.
@@ -1585,11 +1593,11 @@
1585 }else{
1586 if( dynPrompt.zScannerAwaits ){
1587 size_t ncp = strlen(continuePrompt);
1588 size_t ndp = strlen(dynPrompt.zScannerAwaits);
1589 if( ndp > ncp-3 ) return continuePrompt;
1590 strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
1591 while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
1592 shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
1593 PROMPT_LEN_MAX-4);
1594 }else{
1595 if( dynPrompt.inParenLevel>9 ){
@@ -6132,10 +6140,30 @@
6132 ** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step.
6133 ** xBestIndex returns a small cost when both start and stop are available,
6134 ** and a very large cost if either start or stop are unavailable. This
6135 ** encourages the query planner to order joins such that the bounds of the
6136 ** series are well-defined.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6137 */
6138 /* #include "sqlite3ext.h" */
6139 SQLITE_EXTENSION_INIT1
6140 #include <assert.h>
6141 #include <string.h>
@@ -6173,12 +6201,14 @@
6173 }
6174
6175 /* typedef unsigned char u8; */
6176
6177 typedef struct SequenceSpec {
6178 sqlite3_int64 iBase; /* Starting value ("start") */
6179 sqlite3_int64 iTerm; /* Given terminal value ("stop") */
 
 
6180 sqlite3_int64 iStep; /* Increment ("step") */
6181 sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
6182 sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
6183 sqlite3_int64 iValueNow; /* Current value during generation */
6184 u8 isNotEOF; /* Sequence generation not exhausted */
@@ -6367,21 +6397,23 @@
6367 int i /* Which column to return */
6368 ){
6369 series_cursor *pCur = (series_cursor*)cur;
6370 sqlite3_int64 x = 0;
6371 switch( i ){
6372 case SERIES_COLUMN_START: x = pCur->ss.iBase; break;
6373 case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break;
6374 case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
6375 default: x = pCur->ss.iValueNow; break;
6376 }
6377 sqlite3_result_int64(ctx, x);
6378 return SQLITE_OK;
6379 }
6380
6381 #ifndef LARGEST_UINT64
 
6382 #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32))
 
6383 #endif
6384
6385 /*
6386 ** Return the rowid for the current row, logically equivalent to n+1 where
6387 ** "n" is the ascending integer in the aforesaid production definition.
@@ -6418,17 +6450,22 @@
6418 **
6419 ** The query plan selected by seriesBestIndex is passed in the idxNum
6420 ** parameter. (idxStr is not used in this implementation.) idxNum
6421 ** is a bitmask showing which constraints are available:
6422 **
6423 ** 0x01: start=VALUE
6424 ** 0x02: stop=VALUE
6425 ** 0x04: step=VALUE
6426 ** 0x08: descending order
6427 ** 0x10: ascending order
6428 ** 0x20: LIMIT VALUE
6429 ** 0x40: OFFSET VALUE
 
 
 
 
 
6430 **
6431 ** This routine should initialize the cursor and position it so that it
6432 ** is pointing at the first row, or pointing off the end of the table
6433 ** (so that seriesEof() will return true) if the table is empty.
6434 */
@@ -6437,10 +6474,16 @@
6437 int idxNum, const char *idxStrUnused,
6438 int argc, sqlite3_value **argv
6439 ){
6440 series_cursor *pCur = (series_cursor *)pVtabCursor;
6441 int i = 0;
 
 
 
 
 
 
6442 (void)idxStrUnused;
6443 if( idxNum & 0x01 ){
6444 pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
6445 }else{
6446 pCur->ss.iBase = 0;
@@ -6458,38 +6501,125 @@
6458 if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
6459 }
6460 }else{
6461 pCur->ss.iStep = 1;
6462 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6463 if( idxNum & 0x20 ){
6464 sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]);
6465 sqlite3_int64 iTerm;
6466 if( idxNum & 0x40 ){
6467 sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]);
6468 if( iOffset>0 ){
6469 pCur->ss.iBase += pCur->ss.iStep*iOffset;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6470 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6471 }
6472 if( iLimit>=0 ){
 
6473 iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
6474 if( pCur->ss.iStep<0 ){
6475 if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6476 }else{
6477 if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6478 }
6479 }
6480 }
 
 
6481 for(i=0; i<argc; i++){
6482 if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
6483 /* If any of the constraints have a NULL value, then return no rows.
6484 ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
6485 pCur->ss.iBase = 1;
6486 pCur->ss.iTerm = 0;
6487 pCur->ss.iStep = 1;
6488 break;
6489 }
6490 }
 
 
 
 
 
6491 if( idxNum & 0x08 ){
6492 pCur->ss.isReversing = pCur->ss.iStep > 0;
6493 }else{
6494 pCur->ss.isReversing = pCur->ss.iStep < 0;
6495 }
@@ -6506,17 +6636,39 @@
6506 ** In this implementation idxNum is used to represent the
6507 ** query plan. idxStr is unused.
6508 **
6509 ** The query plan is represented by bits in idxNum:
6510 **
6511 ** 0x01 start = $value -- constraint exists
6512 ** 0x02 stop = $value -- constraint exists
6513 ** 0x04 step = $value -- constraint exists
6514 ** 0x08 output is in descending order
6515 ** 0x10 output is in ascending order
6516 ** 0x20 LIMIT $value -- constraint exists
6517 ** 0x40 OFFSET $value -- constraint exists
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6518 */
6519 static int seriesBestIndex(
6520 sqlite3_vtab *pVTab,
6521 sqlite3_index_info *pIdxInfo
6522 ){
@@ -6525,19 +6677,21 @@
6525 #ifndef ZERO_ARGUMENT_GENERATE_SERIES
6526 int bStartSeen = 0; /* EQ constraint seen on the START column */
6527 #endif
6528 int unusableMask = 0; /* Mask of unusable constraints */
6529 int nArg = 0; /* Number of arguments that seriesFilter() expects */
6530 int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */
 
 
6531 const struct sqlite3_index_constraint *pConstraint;
6532
6533 /* This implementation assumes that the start, stop, and step columns
6534 ** are the last three columns in the virtual table. */
6535 assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
6536 assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
6537
6538 aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1;
6539 pConstraint = pIdxInfo->aConstraint;
6540 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
6541 int iCol; /* 0 for start, 1 for stop, 2 for step */
6542 int iMask; /* bitmask for those column */
6543 int op = pConstraint->op;
@@ -6554,11 +6708,54 @@
6554 aIdx[4] = i;
6555 idxNum |= 0x40;
6556 }
6557 continue;
6558 }
6559 if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6560 iCol = pConstraint->iColumn - SERIES_COLUMN_START;
6561 assert( iCol>=0 && iCol<=2 );
6562 iMask = 1 << iCol;
6563 #ifndef ZERO_ARGUMENT_GENERATE_SERIES
6564 if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){
@@ -6576,11 +6773,11 @@
6576 if( aIdx[3]==0 ){
6577 /* Ignore OFFSET if LIMIT is omitted */
6578 idxNum &= ~0x60;
6579 aIdx[4] = 0;
6580 }
6581 for(i=0; i<5; i++){
6582 if( (j = aIdx[i])>=0 ){
6583 pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
6584 pIdxInfo->aConstraintUsage[j].omit =
6585 !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3;
6586 }
@@ -6624,10 +6821,13 @@
6624 ** of numbers. Make this case very expensive so that the query
6625 ** planner will work hard to avoid it. */
6626 pIdxInfo->estimatedRows = 2147483647;
6627 }
6628 pIdxInfo->idxNum = idxNum;
 
 
 
6629 return SQLITE_OK;
6630 }
6631
6632 /*
6633 ** This following structure defines all the methods for the
@@ -24970,16 +25170,21 @@
24970 oputf("%-20s %u\n", "data version", iDataVersion);
24971 return 0;
24972 }
24973 #endif /* SQLITE_SHELL_HAVE_RECOVER */
24974
 
 
 
 
 
 
24975 /*
24976 ** Print the current sqlite3_errmsg() value to stderr and return 1.
24977 */
24978 static int shellDatabaseError(sqlite3 *db){
24979 const char *zErr = sqlite3_errmsg(db);
24980 eputf("Error: %s\n", zErr);
24981 return 1;
24982 }
24983
24984 /*
24985 ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
@@ -25520,11 +25725,11 @@
25520 va_list ap;
25521 char *z;
25522 va_start(ap, zFmt);
25523 z = sqlite3_vmprintf(zFmt, ap);
25524 va_end(ap);
25525 eputf("Error: %s\n", z);
25526 if( pAr->fromCmdLine ){
25527 eputz("Use \"-A\" for more help\n");
25528 }else{
25529 eputz("Use \".archive --help\" for more help\n");
25530 }
@@ -26751,20 +26956,20 @@
26751 0, 0, 0);
26752 }
26753 open_db(p, 0);
26754 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
26755 if( pBackup==0 ){
26756 eputf("Error: %s\n", sqlite3_errmsg(pDest));
26757 close_db(pDest);
26758 return 1;
26759 }
26760 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
26761 sqlite3_backup_finish(pBackup);
26762 if( rc==SQLITE_DONE ){
26763 rc = 0;
26764 }else{
26765 eputf("Error: %s\n", sqlite3_errmsg(pDest));
26766 rc = 1;
26767 }
26768 close_db(pDest);
26769 }else
26770 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -26936,11 +27141,11 @@
26936 sqlite3_stmt *pStmt;
26937 int i;
26938 open_db(p, 0);
26939 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
26940 if( rc ){
26941 eputf("Error: %s\n", sqlite3_errmsg(p->db));
26942 rc = 1;
26943 }else{
26944 while( sqlite3_step(pStmt)==SQLITE_ROW ){
26945 const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
26946 const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
@@ -27632,11 +27837,11 @@
27632 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
27633 sqlite3_free(zSql);
27634 zSql = 0;
27635 if( rc ){
27636 if (pStmt) sqlite3_finalize(pStmt);
27637 eputf("Error: %s\n", sqlite3_errmsg(p->db));
27638 import_cleanup(&sCtx);
27639 rc = 1;
27640 goto meta_command_exit;
27641 }
27642 if( sqlite3_step(pStmt)==SQLITE_ROW ){
@@ -27676,11 +27881,11 @@
27676 }
27677 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
27678 sqlite3_free(zSql);
27679 zSql = 0;
27680 if( rc ){
27681 eputf("Error: %s\n", sqlite3_errmsg(p->db));
27682 if (pStmt) sqlite3_finalize(pStmt);
27683 import_cleanup(&sCtx);
27684 rc = 1;
27685 goto meta_command_exit;
27686 }
@@ -27970,11 +28175,11 @@
27970 zFile = azArg[1];
27971 zProc = nArg>=3 ? azArg[2] : 0;
27972 open_db(p, 0);
27973 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
27974 if( rc!=SQLITE_OK ){
27975 eputf("Error: %s\n", zErrMsg);
27976 sqlite3_free(zErrMsg);
27977 rc = 1;
27978 }
27979 }else
27980 #endif
@@ -28592,11 +28797,11 @@
28592 return 1;
28593 }
28594 open_db(p, 0);
28595 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
28596 if( pBackup==0 ){
28597 eputf("Error: %s\n", sqlite3_errmsg(p->db));
28598 close_db(pSrc);
28599 return 1;
28600 }
28601 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
28602 || rc==SQLITE_BUSY ){
@@ -28610,11 +28815,11 @@
28610 rc = 0;
28611 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
28612 eputz("Error: source database is busy\n");
28613 rc = 1;
28614 }else{
28615 eputf("Error: %s\n", sqlite3_errmsg(p->db));
28616 rc = 1;
28617 }
28618 close_db(pSrc);
28619 }else
28620 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28707,11 +28912,11 @@
28707 if( zDiv ){
28708 sqlite3_stmt *pStmt = 0;
28709 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
28710 -1, &pStmt, 0);
28711 if( rc ){
28712 eputf("Error: %s\n", sqlite3_errmsg(p->db));
28713 sqlite3_finalize(pStmt);
28714 rc = 1;
28715 goto meta_command_exit;
28716 }
28717 appendText(&sSelect, "SELECT sql FROM", 0);
@@ -28776,11 +28981,11 @@
28776 rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
28777 }
28778 freeText(&sSelect);
28779 }
28780 if( zErrMsg ){
28781 eputf("Error: %s\n", zErrMsg);
28782 sqlite3_free(zErrMsg);
28783 rc = 1;
28784 }else if( rc != SQLITE_OK ){
28785 eputz("Error: querying schema information\n");
28786 rc = 1;
@@ -29547,11 +29752,11 @@
29547 {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
29548 {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
29549 {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
29550 {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
29551 {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
29552 {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
29553 #ifdef YYCOVERAGE
29554 {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
29555 #endif
29556 {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,1, "OFFSET " },
29557 {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
@@ -29610,13 +29815,123 @@
29610 if( testctrl<0 ){
29611 eputf("Error: unknown test-control: %s\n"
29612 "Use \".testctrl --help\" for help\n", zCmd);
29613 }else{
29614 switch(testctrl){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29615
29616 /* sqlite3_test_control(int, db, int) */
29617 case SQLITE_TESTCTRL_OPTIMIZATIONS:
29618 case SQLITE_TESTCTRL_FK_NO_ACTION:
29619 if( nArg==3 ){
29620 unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
29621 rc2 = sqlite3_test_control(testctrl, p->db, opt);
29622 isOk = 3;
@@ -31355,11 +31670,11 @@
31355 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
31356 }else{
31357 open_db(&data, 0);
31358 rc = shell_exec(&data, z, &zErrMsg);
31359 if( zErrMsg!=0 ){
31360 eputf("Error: %s\n", zErrMsg);
31361 if( bail_on_error ) return rc!=0 ? rc : 1;
31362 }else if( rc!=0 ){
31363 eputf("Error: unable to process SQL \"%s\"\n", z);
31364 if( bail_on_error ) return rc;
31365 }
@@ -31409,11 +31724,11 @@
31409 open_db(&data, 0);
31410 echo_group_input(&data, azCmd[i]);
31411 rc = shell_exec(&data, azCmd[i], &zErrMsg);
31412 if( zErrMsg || rc ){
31413 if( zErrMsg!=0 ){
31414 eputf("Error: %s\n", zErrMsg);
31415 }else{
31416 eputf("Error: unable to process SQL: %s\n", azCmd[i]);
31417 }
31418 sqlite3_free(zErrMsg);
31419 if( rc==0 ) rc = 1;
31420
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1519,10 +1519,18 @@
1519 size_t i;
1520 for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
1521 dest[i] = 0;
1522 return dest;
1523 }
1524
1525 /*
1526 ** strcpy() workalike to squelch an unwarranted link-time warning
1527 ** from OpenBSD.
1528 */
1529 static void shell_strcpy(char *dest, const char *src){
1530 while( (*(dest++) = *(src++))!=0 ){}
1531 }
1532
1533 /*
1534 ** Optionally disable dynamic continuation prompt.
1535 ** Unless disabled, the continuation prompt shows open SQL lexemes if any,
1536 ** or open parentheses level if non-zero, or continuation prompt as set.
@@ -1585,11 +1593,11 @@
1593 }else{
1594 if( dynPrompt.zScannerAwaits ){
1595 size_t ncp = strlen(continuePrompt);
1596 size_t ndp = strlen(dynPrompt.zScannerAwaits);
1597 if( ndp > ncp-3 ) return continuePrompt;
1598 shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
1599 while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
1600 shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
1601 PROMPT_LEN_MAX-4);
1602 }else{
1603 if( dynPrompt.inParenLevel>9 ){
@@ -6132,10 +6140,30 @@
6140 ** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step.
6141 ** xBestIndex returns a small cost when both start and stop are available,
6142 ** and a very large cost if either start or stop are unavailable. This
6143 ** encourages the query planner to order joins such that the bounds of the
6144 ** series are well-defined.
6145 **
6146 ** Update on 2024-08-22:
6147 ** xBestIndex now also looks for equality and inequality constraints against
6148 ** the value column and uses those constraints as additional bounds against
6149 ** the sequence range. Thus, a query like this:
6150 **
6151 ** SELECT value FROM generate_series($SA,$EA)
6152 ** WHERE value BETWEEN $SB AND $EB;
6153 **
6154 ** Is logically the same as:
6155 **
6156 ** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB));
6157 **
6158 ** Constraints on the value column can server as substitutes for constraints
6159 ** on the hidden start and stop columns. So, the following two queries
6160 ** are equivalent:
6161 **
6162 ** SELECT value FROM generate_series($S,$E);
6163 ** SELECT value FROM generate_series WHERE value BETWEEN $S and $E;
6164 **
6165 */
6166 /* #include "sqlite3ext.h" */
6167 SQLITE_EXTENSION_INIT1
6168 #include <assert.h>
6169 #include <string.h>
@@ -6173,12 +6201,14 @@
6201 }
6202
6203 /* typedef unsigned char u8; */
6204
6205 typedef struct SequenceSpec {
6206 sqlite3_int64 iOBase; /* Original starting value ("start") */
6207 sqlite3_int64 iOTerm; /* Original terminal value ("stop") */
6208 sqlite3_int64 iBase; /* Starting value to actually use */
6209 sqlite3_int64 iTerm; /* Terminal value to actually use */
6210 sqlite3_int64 iStep; /* Increment ("step") */
6211 sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
6212 sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
6213 sqlite3_int64 iValueNow; /* Current value during generation */
6214 u8 isNotEOF; /* Sequence generation not exhausted */
@@ -6367,21 +6397,23 @@
6397 int i /* Which column to return */
6398 ){
6399 series_cursor *pCur = (series_cursor*)cur;
6400 sqlite3_int64 x = 0;
6401 switch( i ){
6402 case SERIES_COLUMN_START: x = pCur->ss.iOBase; break;
6403 case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break;
6404 case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
6405 default: x = pCur->ss.iValueNow; break;
6406 }
6407 sqlite3_result_int64(ctx, x);
6408 return SQLITE_OK;
6409 }
6410
6411 #ifndef LARGEST_UINT64
6412 #define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
6413 #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32))
6414 #define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
6415 #endif
6416
6417 /*
6418 ** Return the rowid for the current row, logically equivalent to n+1 where
6419 ** "n" is the ascending integer in the aforesaid production definition.
@@ -6418,17 +6450,22 @@
6450 **
6451 ** The query plan selected by seriesBestIndex is passed in the idxNum
6452 ** parameter. (idxStr is not used in this implementation.) idxNum
6453 ** is a bitmask showing which constraints are available:
6454 **
6455 ** 0x0001: start=VALUE
6456 ** 0x0002: stop=VALUE
6457 ** 0x0004: step=VALUE
6458 ** 0x0008: descending order
6459 ** 0x0010: ascending order
6460 ** 0x0020: LIMIT VALUE
6461 ** 0x0040: OFFSET VALUE
6462 ** 0x0080: value=VALUE
6463 ** 0x0100: value>=VALUE
6464 ** 0x0200: value>VALUE
6465 ** 0x1000: value<=VALUE
6466 ** 0x2000: value<VALUE
6467 **
6468 ** This routine should initialize the cursor and position it so that it
6469 ** is pointing at the first row, or pointing off the end of the table
6470 ** (so that seriesEof() will return true) if the table is empty.
6471 */
@@ -6437,10 +6474,16 @@
6474 int idxNum, const char *idxStrUnused,
6475 int argc, sqlite3_value **argv
6476 ){
6477 series_cursor *pCur = (series_cursor *)pVtabCursor;
6478 int i = 0;
6479 int returnNoRows = 0;
6480 sqlite3_int64 iMin = SMALLEST_INT64;
6481 sqlite3_int64 iMax = LARGEST_INT64;
6482 sqlite3_int64 iLimit = 0;
6483 sqlite3_int64 iOffset = 0;
6484
6485 (void)idxStrUnused;
6486 if( idxNum & 0x01 ){
6487 pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
6488 }else{
6489 pCur->ss.iBase = 0;
@@ -6458,38 +6501,125 @@
6501 if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
6502 }
6503 }else{
6504 pCur->ss.iStep = 1;
6505 }
6506
6507 /* If there are constraints on the value column but there are
6508 ** no constraints on the start, stop, and step columns, then
6509 ** initialize the default range to be the entire range of 64-bit signed
6510 ** integers. This range will contracted by the value column constraints
6511 ** further below.
6512 */
6513 if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){
6514 pCur->ss.iBase = SMALLEST_INT64;
6515 }
6516 if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){
6517 pCur->ss.iTerm = LARGEST_INT64;
6518 }
6519 pCur->ss.iOBase = pCur->ss.iBase;
6520 pCur->ss.iOTerm = pCur->ss.iTerm;
6521
6522 /* Extract the LIMIT and OFFSET values, but do not apply them yet.
6523 ** The range must first be constrained by the limits on value.
6524 */
6525 if( idxNum & 0x20 ){
6526 iLimit = sqlite3_value_int64(argv[i++]);
 
6527 if( idxNum & 0x40 ){
6528 iOffset = sqlite3_value_int64(argv[i++]);
6529 }
6530 }
6531
6532 if( idxNum & 0x3380 ){
6533 /* Extract the maximum range of output values determined by
6534 ** constraints on the "value" column.
6535 */
6536 if( idxNum & 0x0080 ){
6537 iMin = iMax = sqlite3_value_int64(argv[i++]);
6538 }else{
6539 if( idxNum & 0x0300 ){
6540 iMin = sqlite3_value_int64(argv[i++]);
6541 if( idxNum & 0x0200 ){
6542 if( iMin==LARGEST_INT64 ){
6543 returnNoRows = 1;
6544 }else{
6545 iMin++;
6546 }
6547 }
6548 }
6549 if( idxNum & 0x3000 ){
6550 iMax = sqlite3_value_int64(argv[i++]);
6551 if( idxNum & 0x2000 ){
6552 if( iMax==SMALLEST_INT64 ){
6553 returnNoRows = 1;
6554 }else{
6555 iMax--;
6556 }
6557 }
6558 }
6559 if( iMin>iMax ){
6560 returnNoRows = 1;
6561 }
6562 }
6563
6564 /* Try to reduce the range of values to be generated based on
6565 ** constraints on the "value" column.
6566 */
6567 if( pCur->ss.iStep>0 ){
6568 sqlite3_int64 szStep = pCur->ss.iStep;
6569 if( pCur->ss.iBase<iMin ){
6570 sqlite3_uint64 d = iMin - pCur->ss.iBase;
6571 pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
6572 }
6573 if( pCur->ss.iTerm>iMax ){
6574 sqlite3_uint64 d = pCur->ss.iTerm - iMax;
6575 pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep;
6576 }
6577 }else{
6578 sqlite3_int64 szStep = -pCur->ss.iStep;
6579 assert( szStep>0 );
6580 if( pCur->ss.iBase>iMax ){
6581 sqlite3_uint64 d = pCur->ss.iBase - iMax;
6582 pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
6583 }
6584 if( pCur->ss.iTerm<iMin ){
6585 sqlite3_uint64 d = iMin - pCur->ss.iTerm;
6586 pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep;
6587 }
6588 }
6589 }
6590
6591 /* Apply LIMIT and OFFSET constraints, if any */
6592 if( idxNum & 0x20 ){
6593 if( iOffset>0 ){
6594 pCur->ss.iBase += pCur->ss.iStep*iOffset;
6595 }
6596 if( iLimit>=0 ){
6597 sqlite3_int64 iTerm;
6598 iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
6599 if( pCur->ss.iStep<0 ){
6600 if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6601 }else{
6602 if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
6603 }
6604 }
6605 }
6606
6607
6608 for(i=0; i<argc; i++){
6609 if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
6610 /* If any of the constraints have a NULL value, then return no rows.
6611 ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
6612 returnNoRows = 1;
 
 
6613 break;
6614 }
6615 }
6616 if( returnNoRows ){
6617 pCur->ss.iBase = 1;
6618 pCur->ss.iTerm = 0;
6619 pCur->ss.iStep = 1;
6620 }
6621 if( idxNum & 0x08 ){
6622 pCur->ss.isReversing = pCur->ss.iStep > 0;
6623 }else{
6624 pCur->ss.isReversing = pCur->ss.iStep < 0;
6625 }
@@ -6506,17 +6636,39 @@
6636 ** In this implementation idxNum is used to represent the
6637 ** query plan. idxStr is unused.
6638 **
6639 ** The query plan is represented by bits in idxNum:
6640 **
6641 ** 0x0001 start = $num
6642 ** 0x0002 stop = $num
6643 ** 0x0004 step = $num
6644 ** 0x0008 output is in descending order
6645 ** 0x0010 output is in ascending order
6646 ** 0x0020 LIMIT $num
6647 ** 0x0040 OFFSET $num
6648 ** 0x0080 value = $num
6649 ** 0x0100 value >= $num
6650 ** 0x0200 value > $num
6651 ** 0x1000 value <= $num
6652 ** 0x2000 value < $num
6653 **
6654 ** Only one of 0x0100 or 0x0200 will be returned. Similarly, only
6655 ** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then
6656 ** none of the 0xff00 bits will be set.
6657 **
6658 ** The order of parameters passed to xFilter is as follows:
6659 **
6660 ** * The argument to start= if bit 0x0001 is in the idxNum mask
6661 ** * The argument to stop= if bit 0x0002 is in the idxNum mask
6662 ** * The argument to step= if bit 0x0004 is in the idxNum mask
6663 ** * The argument to LIMIT if bit 0x0020 is in the idxNum mask
6664 ** * The argument to OFFSET if bit 0x0040 is in the idxNum mask
6665 ** * The argument to value=, or value>= or value> if any of
6666 ** bits 0x0380 are in the idxNum mask
6667 ** * The argument to value<= or value< if either of bits 0x3000
6668 ** are in the mask
6669 **
6670 */
6671 static int seriesBestIndex(
6672 sqlite3_vtab *pVTab,
6673 sqlite3_index_info *pIdxInfo
6674 ){
@@ -6525,19 +6677,21 @@
6677 #ifndef ZERO_ARGUMENT_GENERATE_SERIES
6678 int bStartSeen = 0; /* EQ constraint seen on the START column */
6679 #endif
6680 int unusableMask = 0; /* Mask of unusable constraints */
6681 int nArg = 0; /* Number of arguments that seriesFilter() expects */
6682 int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET,
6683 ** and value. aIdx[5] covers value=, value>=, and
6684 ** value>, aIdx[6] covers value<= and value< */
6685 const struct sqlite3_index_constraint *pConstraint;
6686
6687 /* This implementation assumes that the start, stop, and step columns
6688 ** are the last three columns in the virtual table. */
6689 assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
6690 assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
6691
6692 aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1;
6693 pConstraint = pIdxInfo->aConstraint;
6694 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
6695 int iCol; /* 0 for start, 1 for stop, 2 for step */
6696 int iMask; /* bitmask for those column */
6697 int op = pConstraint->op;
@@ -6554,11 +6708,54 @@
6708 aIdx[4] = i;
6709 idxNum |= 0x40;
6710 }
6711 continue;
6712 }
6713 if( pConstraint->iColumn==SERIES_COLUMN_VALUE ){
6714 switch( op ){
6715 case SQLITE_INDEX_CONSTRAINT_EQ:
6716 case SQLITE_INDEX_CONSTRAINT_IS: {
6717 idxNum |= 0x0080;
6718 idxNum &= ~0x3300;
6719 aIdx[5] = i;
6720 aIdx[6] = -1;
6721 bStartSeen = 1;
6722 break;
6723 }
6724 case SQLITE_INDEX_CONSTRAINT_GE: {
6725 if( idxNum & 0x0080 ) break;
6726 idxNum |= 0x0100;
6727 idxNum &= ~0x0200;
6728 aIdx[5] = i;
6729 bStartSeen = 1;
6730 break;
6731 }
6732 case SQLITE_INDEX_CONSTRAINT_GT: {
6733 if( idxNum & 0x0080 ) break;
6734 idxNum |= 0x0200;
6735 idxNum &= ~0x0100;
6736 aIdx[5] = i;
6737 bStartSeen = 1;
6738 break;
6739 }
6740 case SQLITE_INDEX_CONSTRAINT_LE: {
6741 if( idxNum & 0x0080 ) break;
6742 idxNum |= 0x1000;
6743 idxNum &= ~0x2000;
6744 aIdx[6] = i;
6745 break;
6746 }
6747 case SQLITE_INDEX_CONSTRAINT_LT: {
6748 if( idxNum & 0x0080 ) break;
6749 idxNum |= 0x2000;
6750 idxNum &= ~0x1000;
6751 aIdx[6] = i;
6752 break;
6753 }
6754 }
6755 continue;
6756 }
6757 iCol = pConstraint->iColumn - SERIES_COLUMN_START;
6758 assert( iCol>=0 && iCol<=2 );
6759 iMask = 1 << iCol;
6760 #ifndef ZERO_ARGUMENT_GENERATE_SERIES
6761 if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){
@@ -6576,11 +6773,11 @@
6773 if( aIdx[3]==0 ){
6774 /* Ignore OFFSET if LIMIT is omitted */
6775 idxNum &= ~0x60;
6776 aIdx[4] = 0;
6777 }
6778 for(i=0; i<7; i++){
6779 if( (j = aIdx[i])>=0 ){
6780 pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
6781 pIdxInfo->aConstraintUsage[j].omit =
6782 !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3;
6783 }
@@ -6624,10 +6821,13 @@
6821 ** of numbers. Make this case very expensive so that the query
6822 ** planner will work hard to avoid it. */
6823 pIdxInfo->estimatedRows = 2147483647;
6824 }
6825 pIdxInfo->idxNum = idxNum;
6826 #ifdef SQLITE_INDEX_SCAN_HEX
6827 pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX;
6828 #endif
6829 return SQLITE_OK;
6830 }
6831
6832 /*
6833 ** This following structure defines all the methods for the
@@ -24970,16 +25170,21 @@
25170 oputf("%-20s %u\n", "data version", iDataVersion);
25171 return 0;
25172 }
25173 #endif /* SQLITE_SHELL_HAVE_RECOVER */
25174
25175 /*
25176 ** Print the given string as an error message.
25177 */
25178 static void shellEmitError(const char *zErr){
25179 eputf("Error: %s\n", zErr);
25180 }
25181 /*
25182 ** Print the current sqlite3_errmsg() value to stderr and return 1.
25183 */
25184 static int shellDatabaseError(sqlite3 *db){
25185 shellEmitError(sqlite3_errmsg(db));
 
25186 return 1;
25187 }
25188
25189 /*
25190 ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
@@ -25520,11 +25725,11 @@
25725 va_list ap;
25726 char *z;
25727 va_start(ap, zFmt);
25728 z = sqlite3_vmprintf(zFmt, ap);
25729 va_end(ap);
25730 shellEmitError(z);
25731 if( pAr->fromCmdLine ){
25732 eputz("Use \"-A\" for more help\n");
25733 }else{
25734 eputz("Use \".archive --help\" for more help\n");
25735 }
@@ -26751,20 +26956,20 @@
26956 0, 0, 0);
26957 }
26958 open_db(p, 0);
26959 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
26960 if( pBackup==0 ){
26961 shellDatabaseError(pDest);
26962 close_db(pDest);
26963 return 1;
26964 }
26965 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
26966 sqlite3_backup_finish(pBackup);
26967 if( rc==SQLITE_DONE ){
26968 rc = 0;
26969 }else{
26970 shellDatabaseError(pDest);
26971 rc = 1;
26972 }
26973 close_db(pDest);
26974 }else
26975 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -26936,11 +27141,11 @@
27141 sqlite3_stmt *pStmt;
27142 int i;
27143 open_db(p, 0);
27144 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
27145 if( rc ){
27146 shellDatabaseError(p->db);
27147 rc = 1;
27148 }else{
27149 while( sqlite3_step(pStmt)==SQLITE_ROW ){
27150 const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
27151 const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
@@ -27632,11 +27837,11 @@
27837 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
27838 sqlite3_free(zSql);
27839 zSql = 0;
27840 if( rc ){
27841 if (pStmt) sqlite3_finalize(pStmt);
27842 shellDatabaseError(p->db);
27843 import_cleanup(&sCtx);
27844 rc = 1;
27845 goto meta_command_exit;
27846 }
27847 if( sqlite3_step(pStmt)==SQLITE_ROW ){
@@ -27676,11 +27881,11 @@
27881 }
27882 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
27883 sqlite3_free(zSql);
27884 zSql = 0;
27885 if( rc ){
27886 shellDatabaseError(p->db);
27887 if (pStmt) sqlite3_finalize(pStmt);
27888 import_cleanup(&sCtx);
27889 rc = 1;
27890 goto meta_command_exit;
27891 }
@@ -27970,11 +28175,11 @@
28175 zFile = azArg[1];
28176 zProc = nArg>=3 ? azArg[2] : 0;
28177 open_db(p, 0);
28178 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
28179 if( rc!=SQLITE_OK ){
28180 shellEmitError(zErrMsg);
28181 sqlite3_free(zErrMsg);
28182 rc = 1;
28183 }
28184 }else
28185 #endif
@@ -28592,11 +28797,11 @@
28797 return 1;
28798 }
28799 open_db(p, 0);
28800 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
28801 if( pBackup==0 ){
28802 shellDatabaseError(p->db);
28803 close_db(pSrc);
28804 return 1;
28805 }
28806 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
28807 || rc==SQLITE_BUSY ){
@@ -28610,11 +28815,11 @@
28815 rc = 0;
28816 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
28817 eputz("Error: source database is busy\n");
28818 rc = 1;
28819 }else{
28820 shellDatabaseError(p->db);
28821 rc = 1;
28822 }
28823 close_db(pSrc);
28824 }else
28825 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
@@ -28707,11 +28912,11 @@
28912 if( zDiv ){
28913 sqlite3_stmt *pStmt = 0;
28914 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
28915 -1, &pStmt, 0);
28916 if( rc ){
28917 shellDatabaseError(p->db);
28918 sqlite3_finalize(pStmt);
28919 rc = 1;
28920 goto meta_command_exit;
28921 }
28922 appendText(&sSelect, "SELECT sql FROM", 0);
@@ -28776,11 +28981,11 @@
28981 rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
28982 }
28983 freeText(&sSelect);
28984 }
28985 if( zErrMsg ){
28986 shellEmitError(zErrMsg);
28987 sqlite3_free(zErrMsg);
28988 rc = 1;
28989 }else if( rc != SQLITE_OK ){
28990 eputz("Error: querying schema information\n");
28991 rc = 1;
@@ -29547,11 +29752,11 @@
29752 {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
29753 {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
29754 {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
29755 {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
29756 {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
29757 {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK ..."},
29758 #ifdef YYCOVERAGE
29759 {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
29760 #endif
29761 {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,1, "OFFSET " },
29762 {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
@@ -29610,13 +29815,123 @@
29815 if( testctrl<0 ){
29816 eputf("Error: unknown test-control: %s\n"
29817 "Use \".testctrl --help\" for help\n", zCmd);
29818 }else{
29819 switch(testctrl){
29820
29821 /* Special processing for .testctrl opt MASK ...
29822 ** Each MASK argument can be one of:
29823 **
29824 ** +LABEL Enable the named optimization
29825 **
29826 ** -LABEL Disable the named optimization
29827 **
29828 ** INTEGER Mask of optimizations to disable
29829 */
29830 case SQLITE_TESTCTRL_OPTIMIZATIONS: {
29831 static const struct {
29832 unsigned int mask; /* Mask for this optimization */
29833 unsigned int bDsply; /* Display this on output */
29834 const char *zLabel; /* Name of optimization */
29835 } aLabel[] = {
29836 { 0x00000001, 1, "QueryFlattener" },
29837 { 0x00000001, 0, "Flatten" },
29838 { 0x00000002, 1, "WindowFunc" },
29839 { 0x00000004, 1, "GroupByOrder" },
29840 { 0x00000008, 1, "FactorOutConst" },
29841 { 0x00000010, 1, "DistinctOpt" },
29842 { 0x00000020, 1, "CoverIdxScan" },
29843 { 0x00000040, 1, "OrderByIdxJoin" },
29844 { 0x00000080, 1, "Transitive" },
29845 { 0x00000100, 1, "OmitNoopJoin" },
29846 { 0x00000200, 1, "CountOfView" },
29847 { 0x00000400, 1, "CurosrHints" },
29848 { 0x00000800, 1, "Stat4" },
29849 { 0x00001000, 1, "PushDown" },
29850 { 0x00002000, 1, "SimplifyJoin" },
29851 { 0x00004000, 1, "SkipScan" },
29852 { 0x00008000, 1, "PropagateConst" },
29853 { 0x00010000, 1, "MinMaxOpt" },
29854 { 0x00020000, 1, "SeekScan" },
29855 { 0x00040000, 1, "OmitOrderBy" },
29856 { 0x00080000, 1, "BloomFilter" },
29857 { 0x00100000, 1, "BloomPulldown" },
29858 { 0x00200000, 1, "BalancedMerge" },
29859 { 0x00400000, 1, "ReleaseReg" },
29860 { 0x00800000, 1, "FlttnUnionAll" },
29861 { 0x01000000, 1, "IndexedEXpr" },
29862 { 0x02000000, 1, "Coroutines" },
29863 { 0x04000000, 1, "NullUnusedCols" },
29864 { 0x08000000, 1, "OnePass" },
29865 { 0x10000000, 1, "OrderBySubq" },
29866 { 0xffffffff, 0, "All" },
29867 };
29868 unsigned int curOpt;
29869 unsigned int newOpt;
29870 int ii;
29871 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
29872 newOpt = curOpt;
29873 for(ii=2; ii<nArg; ii++){
29874 const char *z = azArg[ii];
29875 int useLabel = 0;
29876 const char *zLabel;
29877 if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
29878 useLabel = z[0];
29879 zLabel = &z[1];
29880 }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){
29881 useLabel = '+';
29882 zLabel = z;
29883 }else{
29884 newOpt = (unsigned int)strtol(z,0,0);
29885 }
29886 if( useLabel ){
29887 int jj;
29888 for(jj=0; jj<ArraySize(aLabel); jj++){
29889 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
29890 }
29891 if( jj>=ArraySize(aLabel) ){
29892 eputf("Error: no such optimization: \"%s\"\n", zLabel);
29893 eputf("Should be one of:");
29894 for(jj=0; jj<ArraySize(aLabel); jj++){
29895 eputf(" %s", aLabel[jj].zLabel);
29896 }
29897 eputf("\n");
29898 rc = 1;
29899 goto meta_command_exit;
29900 }
29901 if( useLabel=='+' ){
29902 newOpt &= ~aLabel[jj].mask;
29903 }else{
29904 newOpt |= aLabel[jj].mask;
29905 }
29906 }
29907 }
29908 if( curOpt!=newOpt ){
29909 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
29910 }else if( nArg<3 ){
29911 curOpt = ~newOpt;
29912 }
29913 if( newOpt==0 ){
29914 oputf("+All\n");
29915 }else if( newOpt==0xffffffff ){
29916 oputf("-All\n");
29917 }else{
29918 int jj;
29919 for(jj=0; jj<ArraySize(aLabel); jj++){
29920 unsigned int m = aLabel[jj].mask;
29921 if( !aLabel[jj].bDsply ) continue;
29922 if( (curOpt&m)!=(newOpt&m) ){
29923 oputf("%c%s\n", (newOpt & m)==0 ? '+' : '-',
29924 aLabel[jj].zLabel);
29925 }
29926 }
29927 }
29928 rc2 = isOk = 3;
29929 break;
29930 }
29931
29932 /* sqlite3_test_control(int, db, int) */
 
29933 case SQLITE_TESTCTRL_FK_NO_ACTION:
29934 if( nArg==3 ){
29935 unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
29936 rc2 = sqlite3_test_control(testctrl, p->db, opt);
29937 isOk = 3;
@@ -31355,11 +31670,11 @@
31670 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
31671 }else{
31672 open_db(&data, 0);
31673 rc = shell_exec(&data, z, &zErrMsg);
31674 if( zErrMsg!=0 ){
31675 shellEmitError(zErrMsg);
31676 if( bail_on_error ) return rc!=0 ? rc : 1;
31677 }else if( rc!=0 ){
31678 eputf("Error: unable to process SQL \"%s\"\n", z);
31679 if( bail_on_error ) return rc;
31680 }
@@ -31409,11 +31724,11 @@
31724 open_db(&data, 0);
31725 echo_group_input(&data, azCmd[i]);
31726 rc = shell_exec(&data, azCmd[i], &zErrMsg);
31727 if( zErrMsg || rc ){
31728 if( zErrMsg!=0 ){
31729 shellEmitError(zErrMsg);
31730 }else{
31731 eputf("Error: unable to process SQL: %s\n", azCmd[i]);
31732 }
31733 sqlite3_free(zErrMsg);
31734 if( rc==0 ) rc = 1;
31735
+2283 -682
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,13 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 7a0cdc7edb704a88a77b748cd28f6e00c498.
21
+** 9a9d0f6301faefe324261f03543023ffb6a9 with changes in files:
22
+**
23
+** src/shell.c.in
2224
*/
2325
#define SQLITE_CORE 1
2426
#define SQLITE_AMALGAMATION 1
2527
#ifndef SQLITE_PRIVATE
2628
# define SQLITE_PRIVATE static
@@ -462,11 +464,11 @@
462464
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463465
** [sqlite_version()] and [sqlite_source_id()].
464466
*/
465467
#define SQLITE_VERSION "3.47.0"
466468
#define SQLITE_VERSION_NUMBER 3047000
467
-#define SQLITE_SOURCE_ID "2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9"
469
+#define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
468470
469471
/*
470472
** CAPI3REF: Run-Time Library Version Numbers
471473
** KEYWORDS: sqlite3_version sqlite3_sourceid
472474
**
@@ -7741,13 +7743,15 @@
77417743
**
77427744
** ^The estimatedRows value is an estimate of the number of rows that
77437745
** will be returned by the strategy.
77447746
**
77457747
** The xBestIndex method may optionally populate the idxFlags field with a
7746
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
7747
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
7748
-** assumes that the strategy may visit at most one row.
7748
+** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
7749
+** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
7750
+** output to show the idxNum has hex instead of as decimal. Another flag is
7751
+** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
7752
+** return at most one row.
77497753
**
77507754
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
77517755
** SQLite also assumes that if a call to the xUpdate() method is made as
77527756
** part of the same statement to delete or update a virtual table row and the
77537757
** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7807,11 +7811,13 @@
78077811
**
78087812
** Virtual table implementations are allowed to set the
78097813
** [sqlite3_index_info].idxFlags field to some combination of
78107814
** these bits.
78117815
*/
7812
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
7816
+#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
7817
+#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
7818
+ /* in EXPLAIN QUERY PLAN */
78137819
78147820
/*
78157821
** CAPI3REF: Virtual Table Constraint Operator Codes
78167822
**
78177823
** These macros define the allowed values for the
@@ -8644,10 +8650,11 @@
86448650
#define SQLITE_TESTCTRL_ALWAYS 13
86458651
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
86468652
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
86478653
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
86488654
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8655
+#define SQLITE_TESTCTRL_GETOPT 16
86498656
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
86508657
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
86518658
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
86528659
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
86538660
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13418,13 +13425,36 @@
1341813425
** It is the output of the tokenizer module. For tokendata=1 tables, this
1341913426
** includes any embedded 0x00 and trailing data.
1342013427
**
1342113428
** This API can be quite slow if used with an FTS5 table created with the
1342213429
** "detail=none" or "detail=column" option.
13430
+**
13431
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13432
+** If parameter iCol is less than zero, or greater than or equal to the
13433
+** number of columns in the table, SQLITE_RANGE is returned.
13434
+**
13435
+** Otherwise, this function attempts to retrieve the locale associated
13436
+** with column iCol of the current row. Usually, there is no associated
13437
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
13438
+** to NULL and 0, respectively. However, if the fts5_locale() function
13439
+** was used to associate a locale with the value when it was inserted
13440
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
13441
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
13442
+** is set to the size in bytes of the buffer, not including the
13443
+** nul-terminator.
13444
+**
13445
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
13446
+** SQLite error code is returned. The final value of the output parameters
13447
+** is undefined in this case.
13448
+**
13449
+** xTokenize_v2:
13450
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
13451
+** API is the same as the xTokenize() API, except that it allows a tokenizer
13452
+** locale to be specified.
1342313453
*/
1342413454
struct Fts5ExtensionApi {
13425
- int iVersion; /* Currently always set to 3 */
13455
+ int iVersion; /* Currently always set to 4 */
1342613456
1342713457
void *(*xUserData)(Fts5Context*);
1342813458
1342913459
int (*xColumnCount)(Fts5Context*);
1343013460
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13462,10 +13492,19 @@
1346213492
int (*xQueryToken)(Fts5Context*,
1346313493
int iPhrase, int iToken,
1346413494
const char **ppToken, int *pnToken
1346513495
);
1346613496
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13497
+
13498
+ /* Below this point are iVersion>=4 only */
13499
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
13500
+ int (*xTokenize_v2)(Fts5Context*,
13501
+ const char *pText, int nText, /* Text to tokenize */
13502
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
13503
+ void *pCtx, /* Context passed to xToken() */
13504
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
13505
+ );
1346713506
};
1346813507
1346913508
/*
1347013509
** CUSTOM AUXILIARY FUNCTIONS
1347113510
*************************************************************************/
@@ -13474,19 +13513,20 @@
1347413513
** CUSTOM TOKENIZERS
1347513514
**
1347613515
** Applications may also register custom tokenizer types. A tokenizer
1347713516
** is registered by providing fts5 with a populated instance of the
1347813517
** following structure. All structure methods must be defined, setting
13518
+**
1347913519
** any member of the fts5_tokenizer struct to NULL leads to undefined
1348013520
** behaviour. The structure methods are expected to function as follows:
1348113521
**
1348213522
** xCreate:
1348313523
** This function is used to allocate and initialize a tokenizer instance.
1348413524
** A tokenizer instance is required to actually tokenize text.
1348513525
**
1348613526
** The first argument passed to this function is a copy of the (void*)
13487
-** pointer provided by the application when the fts5_tokenizer object
13527
+** pointer provided by the application when the fts5_tokenizer_v2 object
1348813528
** was registered with FTS5 (the third argument to xCreateTokenizer()).
1348913529
** The second and third arguments are an array of nul-terminated strings
1349013530
** containing the tokenizer arguments, if any, specified following the
1349113531
** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
1349213532
** to create the FTS5 table.
@@ -13506,11 +13546,11 @@
1350613546
** This function is expected to tokenize the nText byte string indicated
1350713547
** by argument pText. pText may or may not be nul-terminated. The first
1350813548
** argument passed to this function is a pointer to an Fts5Tokenizer object
1350913549
** returned by an earlier call to xCreate().
1351013550
**
13511
-** The second argument indicates the reason that FTS5 is requesting
13551
+** The third argument indicates the reason that FTS5 is requesting
1351213552
** tokenization of the supplied text. This is always one of the following
1351313553
** four values:
1351413554
**
1351513555
** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
1351613556
** or removed from the FTS table. The tokenizer is being invoked to
@@ -13529,10 +13569,17 @@
1352913569
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
1353013570
** satisfy an fts5_api.xTokenize() request made by an auxiliary
1353113571
** function. Or an fts5_api.xColumnSize() request made by the same
1353213572
** on a columnsize=0 database.
1353313573
** </ul>
13574
+**
13575
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
13576
+** nLocale - are a pointer to a buffer containing the locale to use for
13577
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
13578
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
13579
+** which case nLocale is always 0) to indicate that the tokenizer should
13580
+** use its default locale.
1353413581
**
1353513582
** For each token in the input string, the supplied callback xToken() must
1353613583
** be invoked. The first argument to it should be a copy of the pointer
1353713584
** passed as the second argument to xTokenize(). The third and fourth
1353813585
** arguments are a pointer to a buffer containing the token text, and the
@@ -13552,10 +13599,33 @@
1355213599
** immediately return a copy of the xToken() return value. Or, if the
1355313600
** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
1355413601
** if an error occurs with the xTokenize() implementation itself, it
1355513602
** may abandon the tokenization and return any error code other than
1355613603
** SQLITE_OK or SQLITE_DONE.
13604
+**
13605
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
13606
+** then the xTokenize() method has two additional arguments - pLocale
13607
+** and nLocale. These specify the locale that the tokenizer should use
13608
+** for the current request. If pLocale and nLocale are both 0, then the
13609
+** tokenizer should use its default locale. Otherwise, pLocale points to
13610
+** an nLocale byte buffer containing the name of the locale to use as utf-8
13611
+** text. pLocale is not nul-terminated.
13612
+**
13613
+** FTS5_TOKENIZER
13614
+**
13615
+** There is also an fts5_tokenizer object. This is an older version of
13616
+** fts5_tokenizer_v2. It is similar except that:
13617
+**
13618
+** <ul>
13619
+** <li> There is no "iVersion" field, and
13620
+** <li> The xTokenize() method does not take a locale argument.
13621
+** </ul>
13622
+**
13623
+** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13624
+** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13625
+** registered using either API may be retrieved using both xFindTokenizer()
13626
+** and xFindTokenizer_v2().
1355713627
**
1355813628
** SYNONYM SUPPORT
1355913629
**
1356013630
** Custom tokenizers may also support synonyms. Consider a case in which a
1356113631
** user wishes to query for a phrase such as "first place". Using the
@@ -13661,10 +13731,37 @@
1366113731
** provide synonyms when tokenizing document text (method (3)) or query
1366213732
** text (method (2)), not both. Doing so will not cause any errors, but is
1366313733
** inefficient.
1366413734
*/
1366513735
typedef struct Fts5Tokenizer Fts5Tokenizer;
13736
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
13737
+struct fts5_tokenizer_v2 {
13738
+ int iVersion; /* Currently always 2 */
13739
+
13740
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13741
+ void (*xDelete)(Fts5Tokenizer*);
13742
+ int (*xTokenize)(Fts5Tokenizer*,
13743
+ void *pCtx,
13744
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
13745
+ const char *pText, int nText,
13746
+ const char *pLocale, int nLocale,
13747
+ int (*xToken)(
13748
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
13749
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
13750
+ const char *pToken, /* Pointer to buffer containing token */
13751
+ int nToken, /* Size of token in bytes */
13752
+ int iStart, /* Byte offset of token within input text */
13753
+ int iEnd /* Byte offset of end of token within input text */
13754
+ )
13755
+ );
13756
+};
13757
+
13758
+/*
13759
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
13760
+** implementations. The following type is included for legacy applications
13761
+** that still use it.
13762
+*/
1366613763
typedef struct fts5_tokenizer fts5_tokenizer;
1366713764
struct fts5_tokenizer {
1366813765
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
1366913766
void (*xDelete)(Fts5Tokenizer*);
1367013767
int (*xTokenize)(Fts5Tokenizer*,
@@ -13679,10 +13776,11 @@
1367913776
int iStart, /* Byte offset of token within input text */
1368013777
int iEnd /* Byte offset of end of token within input text */
1368113778
)
1368213779
);
1368313780
};
13781
+
1368413782
1368513783
/* Flags that may be passed as the third argument to xTokenize() */
1368613784
#define FTS5_TOKENIZE_QUERY 0x0001
1368713785
#define FTS5_TOKENIZE_PREFIX 0x0002
1368813786
#define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13699,11 +13797,11 @@
1369913797
/*************************************************************************
1370013798
** FTS5 EXTENSION REGISTRATION API
1370113799
*/
1370213800
typedef struct fts5_api fts5_api;
1370313801
struct fts5_api {
13704
- int iVersion; /* Currently always set to 2 */
13802
+ int iVersion; /* Currently always set to 3 */
1370513803
1370613804
/* Create a new tokenizer */
1370713805
int (*xCreateTokenizer)(
1370813806
fts5_api *pApi,
1370913807
const char *zName,
@@ -13726,10 +13824,29 @@
1372613824
const char *zName,
1372713825
void *pUserData,
1372813826
fts5_extension_function xFunction,
1372913827
void (*xDestroy)(void*)
1373013828
);
13829
+
13830
+ /* APIs below this point are only available if iVersion>=3 */
13831
+
13832
+ /* Create a new tokenizer */
13833
+ int (*xCreateTokenizer_v2)(
13834
+ fts5_api *pApi,
13835
+ const char *zName,
13836
+ void *pUserData,
13837
+ fts5_tokenizer_v2 *pTokenizer,
13838
+ void (*xDestroy)(void*)
13839
+ );
13840
+
13841
+ /* Find an existing tokenizer */
13842
+ int (*xFindTokenizer_v2)(
13843
+ fts5_api *pApi,
13844
+ const char *zName,
13845
+ void **ppUserData,
13846
+ fts5_tokenizer_v2 **ppTokenizer
13847
+ );
1373113848
};
1373213849
1373313850
/*
1373413851
** END OF REGISTRATION API
1373513852
*************************************************************************/
@@ -15380,10 +15497,11 @@
1538015497
typedef struct RowSet RowSet;
1538115498
typedef struct Savepoint Savepoint;
1538215499
typedef struct Select Select;
1538315500
typedef struct SQLiteThread SQLiteThread;
1538415501
typedef struct SelectDest SelectDest;
15502
+typedef struct Subquery Subquery;
1538515503
typedef struct SrcItem SrcItem;
1538615504
typedef struct SrcList SrcList;
1538715505
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
1538815506
typedef struct Table Table;
1538915507
typedef struct TableLock TableLock;
@@ -19263,10 +19381,20 @@
1926319381
*/
1926419382
#define EU4_NONE 0 /* Does not use IdList.a.u4 */
1926519383
#define EU4_IDX 1 /* Uses IdList.a.u4.idx */
1926619384
#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
1926719385
19386
+/*
19387
+** Details of the implementation of a subquery.
19388
+*/
19389
+struct Subquery {
19390
+ Select *pSelect; /* A SELECT statement used in place of a table name */
19391
+ int addrFillSub; /* Address of subroutine to initialize a subquery */
19392
+ int regReturn; /* Register holding return address of addrFillSub */
19393
+ int regResult; /* Registers holding results of a co-routine */
19394
+};
19395
+
1926819396
/*
1926919397
** The SrcItem object represents a single term in the FROM clause of a query.
1927019398
** The SrcList object is mostly an array of SrcItems.
1927119399
**
1927219400
** The jointype starts out showing the join type between the current table
@@ -19275,33 +19403,44 @@
1927519403
** jointype expresses the join between the table and the previous table.
1927619404
**
1927719405
** In the colUsed field, the high-order bit (bit 63) is set if the table
1927819406
** contains more than 63 columns and the 64-th or later column is used.
1927919407
**
19280
-** Union member validity:
19408
+** Aggressive use of "union" helps keep the size of the object small. This
19409
+** has been shown to boost performance, in addition to saving memory.
19410
+** Access to union elements is gated by the following rules which should
19411
+** always be checked, either by an if-statement or by an assert().
1928119412
**
19282
-** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
19283
-** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
19413
+** Field Only access if this is true
19414
+** --------------- -----------------------------------
19415
+** u1.zIndexedBy fg.isIndexedBy
19416
+** u1.pFuncArg fg.isTabFunc
1928419417
** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
1928519418
**
19286
-** u2.pIBIndex fg.isIndexedBy && !fg.isCte
19287
-** u2.pCteUse fg.isCte && !fg.isIndexedBy
19419
+** u2.pIBIndex fg.isIndexedBy
19420
+** u2.pCteUse fg.isCte
19421
+**
19422
+** u3.pOn !fg.isUsing
19423
+** u3.pUsing fg.isUsing
19424
+**
19425
+** u4.zDatabase !fg.fixedSchema && !fg.isSubquery
19426
+** u4.pSchema fg.fixedSchema
19427
+** u4.pSubq fg.isSubquery
19428
+**
19429
+** See also the sqlite3SrcListDelete() routine for assert() statements that
19430
+** check invariants on the fields of this object, especially the flags
19431
+** inside the fg struct.
1928819432
*/
1928919433
struct SrcItem {
19290
- Schema *pSchema; /* Schema to which this item is fixed */
19291
- char *zDatabase; /* Name of database holding this table */
1929219434
char *zName; /* Name of the table */
1929319435
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
19294
- Table *pTab; /* An SQL table corresponding to zName */
19295
- Select *pSelect; /* A SELECT statement used in place of a table name */
19296
- int addrFillSub; /* Address of subroutine to manifest a subquery */
19297
- int regReturn; /* Register holding return address of addrFillSub */
19298
- int regResult; /* Registers holding results of a co-routine */
19436
+ Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */
1929919437
struct {
1930019438
u8 jointype; /* Type of join between this table and the previous */
1930119439
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
1930219440
unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
19441
+ unsigned isSubquery :1; /* True if this term is a subquery */
1930319442
unsigned isTabFunc :1; /* True if table-valued-function syntax */
1930419443
unsigned isCorrelated :1; /* True if sub-query is correlated */
1930519444
unsigned isMaterialized:1; /* This is a materialized view */
1930619445
unsigned viaCoroutine :1; /* Implemented as a co-routine */
1930719446
unsigned isRecursive :1; /* True for recursive reference in WITH */
@@ -19311,16 +19450,14 @@
1931119450
unsigned isUsing :1; /* u3.pUsing is valid */
1931219451
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
1931319452
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
1931419453
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
1931519454
unsigned rowidUsed :1; /* The ROWID of this table is referenced */
19455
+ unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
19456
+ unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
1931619457
} fg;
1931719458
int iCursor; /* The VDBE cursor number used to access this table */
19318
- union {
19319
- Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
19320
- IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
19321
- } u3;
1932219459
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
1932319460
union {
1932419461
char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
1932519462
ExprList *pFuncArg; /* Arguments to table-valued-function */
1932619463
u32 nRow; /* Number of rows in a VALUES clause */
@@ -19327,10 +19464,19 @@
1932719464
} u1;
1932819465
union {
1932919466
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
1933019467
CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
1933119468
} u2;
19469
+ union {
19470
+ Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
19471
+ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
19472
+ } u3;
19473
+ union {
19474
+ Schema *pSchema; /* Schema to which this item is fixed */
19475
+ char *zDatabase; /* Name of database holding this table */
19476
+ Subquery *pSubq; /* Description of a subquery */
19477
+ } u4;
1933219478
};
1933319479
1933419480
/*
1933519481
** The OnOrUsing object represents either an ON clause or a USING clause.
1933619482
** It can never be both at the same time, but it can be neither.
@@ -19586,12 +19732,14 @@
1958619732
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
1958719733
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
1958819734
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
1958919735
#define SF_Correlated 0x20000000 /* True if references the outer context */
1959019736
19591
-/* True if S exists and has SF_NestedFrom */
19592
-#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
19737
+/* True if SrcItem X is a subquery that has SF_NestedFrom */
19738
+#define IsNestedFrom(X) \
19739
+ ((X)->fg.isSubquery && \
19740
+ ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
1959319741
1959419742
/*
1959519743
** The results of a SELECT can be distributed in several ways, as defined
1959619744
** by one of the following macros. The "SRT" prefix means "SELECT Result
1959719745
** Type".
@@ -20979,10 +21127,13 @@
2097921127
SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
2098021128
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
2098121129
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
2098221130
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
2098321131
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
21132
+SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*);
21133
+SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*);
21134
+SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int);
2098421135
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
2098521136
Token*, Select*, OnOrUsing*);
2098621137
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
2098721138
SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
2098821139
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
@@ -24521,12 +24672,12 @@
2452124672
}
2452224673
if( M<=2 ){
2452324674
Y--;
2452424675
M += 12;
2452524676
}
24526
- A = Y/100;
24527
- B = 2 - A + (A/4);
24677
+ A = (Y+4800)/100;
24678
+ B = 38 - A + (A/4);
2452824679
X1 = 36525*(Y+4716)/100;
2452924680
X2 = 306001*(M+1)/10000;
2453024681
p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
2453124682
p->validJD = 1;
2453224683
if( p->validHMS ){
@@ -24706,11 +24857,11 @@
2470624857
2470724858
/*
2470824859
** Compute the Year, Month, and Day from the julian day number.
2470924860
*/
2471024861
static void computeYMD(DateTime *p){
24711
- int Z, A, B, C, D, E, X1;
24862
+ int Z, alpha, A, B, C, D, E, X1;
2471224863
if( p->validYMD ) return;
2471324864
if( !p->validJD ){
2471424865
p->Y = 2000;
2471524866
p->M = 1;
2471624867
p->D = 1;
@@ -24717,12 +24868,12 @@
2471724868
}else if( !validJulianDay(p->iJD) ){
2471824869
datetimeError(p);
2471924870
return;
2472024871
}else{
2472124872
Z = (int)((p->iJD + 43200000)/86400000);
24722
- A = (int)((Z - 1867216.25)/36524.25);
24723
- A = Z + 1 + A - (A/4);
24873
+ alpha = (int)((Z + 32044.75)/36524.25) - 52;
24874
+ A = Z + 1 + alpha - ((alpha+100)/4) + 25;
2472424875
B = A + 1524;
2472524876
C = (int)((B - 122.1)/365.25);
2472624877
D = (36525*(C&32767))/100;
2472724878
E = (int)((B-D)/30.6001);
2472824879
X1 = (int)(30.6001*E);
@@ -32017,20 +32168,23 @@
3201732168
pItem = va_arg(ap, SrcItem*);
3201832169
assert( bArgList==0 );
3201932170
if( pItem->zAlias && !flag_altform2 ){
3202032171
sqlite3_str_appendall(pAccum, pItem->zAlias);
3202132172
}else if( pItem->zName ){
32022
- if( pItem->zDatabase ){
32023
- sqlite3_str_appendall(pAccum, pItem->zDatabase);
32173
+ if( pItem->fg.fixedSchema==0
32174
+ && pItem->fg.isSubquery==0
32175
+ && pItem->u4.zDatabase!=0
32176
+ ){
32177
+ sqlite3_str_appendall(pAccum, pItem->u4.zDatabase);
3202432178
sqlite3_str_append(pAccum, ".", 1);
3202532179
}
3202632180
sqlite3_str_appendall(pAccum, pItem->zName);
3202732181
}else if( pItem->zAlias ){
3202832182
sqlite3_str_appendall(pAccum, pItem->zAlias);
32029
- }else{
32030
- Select *pSel = pItem->pSelect;
32031
- assert( pSel!=0 ); /* Because of tag-20240424-1 */
32183
+ }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */
32184
+ Select *pSel = pItem->u4.pSubq->pSelect;
32185
+ assert( pSel!=0 );
3203232186
if( pSel->selFlags & SF_NestedFrom ){
3203332187
sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
3203432188
}else if( pSel->selFlags & SF_MultiValue ){
3203532189
assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
3203632190
sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
@@ -32808,13 +32962,13 @@
3280832962
int n = 0;
3280932963
char zLine[1000];
3281032964
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
3281132965
x.printfFlags |= SQLITE_PRINTF_INTERNAL;
3281232966
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
32813
- if( pItem->pTab ){
32967
+ if( pItem->pSTab ){
3281432968
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
32815
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab,
32969
+ pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab,
3281632970
pItem->colUsed,
3281732971
pItem->fg.rowidUsed ? "+rowid" : "");
3281832972
}
3281932973
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
3282032974
sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
@@ -32841,27 +32995,34 @@
3284132995
if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
3284232996
if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
3284332997
if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
3284432998
if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte");
3284532999
if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom");
33000
+ if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema");
33001
+ if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema");
33002
+ if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery");
3284633003
3284733004
sqlite3StrAccumFinish(&x);
3284833005
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
3284933006
n = 0;
32850
- if( pItem->pSelect ) n++;
33007
+ if( pItem->fg.isSubquery ) n++;
3285133008
if( pItem->fg.isTabFunc ) n++;
3285233009
if( pItem->fg.isUsing ) n++;
3285333010
if( pItem->fg.isUsing ){
3285433011
sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
3285533012
}
32856
- if( pItem->pSelect ){
32857
- if( pItem->pTab ){
32858
- Table *pTab = pItem->pTab;
33013
+ if( pItem->fg.isSubquery ){
33014
+ assert( n==1 );
33015
+ if( pItem->pSTab ){
33016
+ Table *pTab = pItem->pSTab;
3285933017
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
3286033018
}
32861
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
32862
- sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
33019
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
33020
+ sqlite3TreeViewPush(&pView, 0);
33021
+ sqlite3TreeViewLine(pView, "SUBQUERY");
33022
+ sqlite3TreeViewPop(&pView);
33023
+ sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
3286333024
}
3286433025
if( pItem->fg.isTabFunc ){
3286533026
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
3286633027
}
3286733028
sqlite3TreeViewPop(&pView);
@@ -38721,11 +38882,11 @@
3872138882
** Allowed values for the unixFile.ctrlFlags bitmask:
3872238883
*/
3872338884
#define UNIXFILE_EXCL 0x01 /* Connections from one process only */
3872438885
#define UNIXFILE_RDONLY 0x02 /* Connection is read only */
3872538886
#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
38726
-#ifndef SQLITE_DISABLE_DIRSYNC
38887
+#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX)
3872738888
# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
3872838889
#else
3872938890
# define UNIXFILE_DIRSYNC 0x00
3873038891
#endif
3873138892
#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
@@ -95267,11 +95428,11 @@
9526795428
}
9526895429
break;
9526995430
}
9527095431
#endif
9527195432
95272
-#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE)
95433
+#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE)
9527395434
/* Opcode: Cast P1 P2 * * *
9527495435
** Synopsis: affinity(r[P1])
9527595436
**
9527695437
** Force the value in register P1 to be the type defined by P2.
9527795438
**
@@ -106731,11 +106892,13 @@
106731106892
SrcItem *pItem;
106732106893
106733106894
pSrc = p->pSrc;
106734106895
if( ALWAYS(pSrc) ){
106735106896
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
106736
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
106897
+ if( pItem->fg.isSubquery
106898
+ && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect)
106899
+ ){
106737106900
return WRC_Abort;
106738106901
}
106739106902
if( pItem->fg.isTabFunc
106740106903
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
106741106904
){
@@ -107037,11 +107200,11 @@
107037107200
){
107038107201
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
107039107202
if( pNew ){
107040107203
pNew->iTable = pMatch->iCursor;
107041107204
pNew->iColumn = iColumn;
107042
- pNew->y.pTab = pMatch->pTab;
107205
+ pNew->y.pTab = pMatch->pSTab;
107043107206
assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
107044107207
ExprSetProperty(pNew, EP_CanBeNull);
107045107208
*ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
107046107209
}
107047107210
}
@@ -107168,24 +107331,28 @@
107168107331
SrcList *pSrcList = pNC->pSrcList;
107169107332
107170107333
if( pSrcList ){
107171107334
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
107172107335
u8 hCol;
107173
- pTab = pItem->pTab;
107336
+ pTab = pItem->pSTab;
107174107337
assert( pTab!=0 && pTab->zName!=0 );
107175107338
assert( pTab->nCol>0 || pParse->nErr );
107176
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
107339
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem));
107177107340
if( pItem->fg.isNestedFrom ){
107178107341
/* In this case, pItem is a subquery that has been formed from a
107179107342
** parenthesized subset of the FROM clause terms. Example:
107180107343
** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
107181107344
** \_________________________/
107182107345
** This pItem -------------^
107183107346
*/
107184107347
int hit = 0;
107185
- assert( pItem->pSelect!=0 );
107186
- pEList = pItem->pSelect->pEList;
107348
+ Select *pSel;
107349
+ assert( pItem->fg.isSubquery );
107350
+ assert( pItem->u4.pSubq!=0 );
107351
+ pSel = pItem->u4.pSubq->pSelect;
107352
+ assert( pSel!=0 );
107353
+ pEList = pSel->pEList;
107187107354
assert( pEList!=0 );
107188107355
assert( pEList->nExpr==pTab->nCol );
107189107356
for(j=0; j<pEList->nExpr; j++){
107190107357
int bRowid = 0; /* True if possible rowid match */
107191107358
if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
@@ -107305,12 +107472,12 @@
107305107472
** words non-VIEW candidate terms take precedence over VIEWs.
107306107473
*/
107307107474
if( cntTab==0
107308107475
|| (cntTab==1
107309107476
&& ALWAYS(pMatch!=0)
107310
- && ALWAYS(pMatch->pTab!=0)
107311
- && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0
107477
+ && ALWAYS(pMatch->pSTab!=0)
107478
+ && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0
107312107479
&& (pTab->tabFlags & TF_Ephemeral)==0)
107313107480
){
107314107481
cntTab = 1;
107315107482
pMatch = pItem;
107316107483
}else{
@@ -107327,11 +107494,11 @@
107327107494
}
107328107495
}
107329107496
if( pMatch ){
107330107497
pExpr->iTable = pMatch->iCursor;
107331107498
assert( ExprUseYTab(pExpr) );
107332
- pExpr->y.pTab = pMatch->pTab;
107499
+ pExpr->y.pTab = pMatch->pSTab;
107333107500
if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
107334107501
ExprSetProperty(pExpr, EP_CanBeNull);
107335107502
}
107336107503
pSchema = pExpr->y.pTab->pSchema;
107337107504
}
@@ -107369,11 +107536,11 @@
107369107536
#endif /* SQLITE_OMIT_TRIGGER */
107370107537
#ifndef SQLITE_OMIT_UPSERT
107371107538
if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){
107372107539
Upsert *pUpsert = pNC->uNC.pUpsert;
107373107540
if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
107374
- pTab = pUpsert->pUpsertSrc->a[0].pTab;
107541
+ pTab = pUpsert->pUpsertSrc->a[0].pSTab;
107375107542
pExpr->iTable = EXCLUDED_TABLE_NUMBER;
107376107543
}
107377107544
}
107378107545
#endif /* SQLITE_OMIT_UPSERT */
107379107546
@@ -107452,15 +107619,15 @@
107452107619
if( cnt==0
107453107620
&& cntTab>=1
107454107621
&& pMatch
107455107622
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
107456107623
&& sqlite3IsRowid(zCol)
107457
- && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
107624
+ && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom)
107458107625
){
107459107626
cnt = cntTab;
107460107627
#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
107461
- if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){
107628
+ if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){
107462107629
eNewExprOp = TK_NULL;
107463107630
}
107464107631
#endif
107465107632
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
107466107633
pExpr->affExpr = SQLITE_AFF_INTEGER;
@@ -107693,11 +107860,11 @@
107693107860
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
107694107861
if( p ){
107695107862
SrcItem *pItem = &pSrc->a[iSrc];
107696107863
Table *pTab;
107697107864
assert( ExprUseYTab(p) );
107698
- pTab = p->y.pTab = pItem->pTab;
107865
+ pTab = p->y.pTab = pItem->pSTab;
107699107866
p->iTable = pItem->iCursor;
107700107867
if( p->y.pTab->iPKey==iCol ){
107701107868
p->iColumn = -1;
107702107869
}else{
107703107870
p->iColumn = (ynVar)iCol;
@@ -107812,11 +107979,11 @@
107812107979
SrcItem *pItem;
107813107980
assert( pSrcList && pSrcList->nSrc>=1 );
107814107981
pItem = pSrcList->a;
107815107982
pExpr->op = TK_COLUMN;
107816107983
assert( ExprUseYTab(pExpr) );
107817
- pExpr->y.pTab = pItem->pTab;
107984
+ pExpr->y.pTab = pItem->pSTab;
107818107985
pExpr->iTable = pItem->iCursor;
107819107986
pExpr->iColumn--;
107820107987
pExpr->affExpr = SQLITE_AFF_INTEGER;
107821107988
break;
107822107989
}
@@ -108702,11 +108869,15 @@
108702108869
** In this case the ORDER BY clause (p->pOrderBy) should be resolved
108703108870
** as if it were part of the sub-query, not the parent. This block
108704108871
** moves the pOrderBy down to the sub-query. It will be moved back
108705108872
** after the names have been resolved. */
108706108873
if( p->selFlags & SF_Converted ){
108707
- Select *pSub = p->pSrc->a[0].pSelect;
108874
+ Select *pSub;
108875
+ assert( p->pSrc->a[0].fg.isSubquery );
108876
+ assert( p->pSrc->a[0].u4.pSubq!=0 );
108877
+ pSub = p->pSrc->a[0].u4.pSubq->pSelect;
108878
+ assert( pSub!=0 );
108708108879
assert( p->pSrc->nSrc==1 && p->pOrderBy );
108709108880
assert( pSub->pPrior && pSub->pOrderBy==0 );
108710108881
pSub->pOrderBy = p->pOrderBy;
108711108882
p->pOrderBy = 0;
108712108883
}
@@ -108714,17 +108885,20 @@
108714108885
/* Recursively resolve names in all subqueries in the FROM clause
108715108886
*/
108716108887
if( pOuterNC ) pOuterNC->nNestedSelect++;
108717108888
for(i=0; i<p->pSrc->nSrc; i++){
108718108889
SrcItem *pItem = &p->pSrc->a[i];
108719
- assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/
108720
- if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
108890
+ assert( pItem->zName!=0
108891
+ || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/
108892
+ if( pItem->fg.isSubquery
108893
+ && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0
108894
+ ){
108721108895
int nRef = pOuterNC ? pOuterNC->nRef : 0;
108722108896
const char *zSavedContext = pParse->zAuthContext;
108723108897
108724108898
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
108725
- sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
108899
+ sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC);
108726108900
pParse->zAuthContext = zSavedContext;
108727108901
if( pParse->nErr ) return WRC_Abort;
108728108902
assert( db->mallocFailed==0 );
108729108903
108730108904
/* If the number of references to the outer context changed when
@@ -108822,11 +108996,14 @@
108822108996
** the sub-query back to the parent query. At this point each term
108823108997
** within the ORDER BY clause has been transformed to an integer value.
108824108998
** These integers will be replaced by copies of the corresponding result
108825108999
** set expressions by the call to resolveOrderGroupBy() below. */
108826109000
if( p->selFlags & SF_Converted ){
108827
- Select *pSub = p->pSrc->a[0].pSelect;
109001
+ Select *pSub;
109002
+ assert( p->pSrc->a[0].fg.isSubquery );
109003
+ pSub = p->pSrc->a[0].u4.pSubq->pSelect;
109004
+ assert( pSub!=0 );
108828109005
p->pOrderBy = pSub->pOrderBy;
108829109006
pSub->pOrderBy = 0;
108830109007
}
108831109008
108832109009
/* Process the ORDER BY clause for singleton SELECT statements.
@@ -109089,11 +109266,11 @@
109089109266
memset(&sNC, 0, sizeof(sNC));
109090109267
memset(&sSrc, 0, sizeof(sSrc));
109091109268
if( pTab ){
109092109269
sSrc.nSrc = 1;
109093109270
sSrc.a[0].zName = pTab->zName;
109094
- sSrc.a[0].pTab = pTab;
109271
+ sSrc.a[0].pSTab = pTab;
109095109272
sSrc.a[0].iCursor = -1;
109096109273
if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
109097109274
/* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
109098109275
** schema elements */
109099109276
type |= NC_FromDDL;
@@ -110986,19 +111163,34 @@
110986111163
pNew->nSrc = pNew->nAlloc = p->nSrc;
110987111164
for(i=0; i<p->nSrc; i++){
110988111165
SrcItem *pNewItem = &pNew->a[i];
110989111166
const SrcItem *pOldItem = &p->a[i];
110990111167
Table *pTab;
110991
- pNewItem->pSchema = pOldItem->pSchema;
110992
- pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
111168
+ pNewItem->fg = pOldItem->fg;
111169
+ if( pOldItem->fg.isSubquery ){
111170
+ Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery));
111171
+ if( pNewSubq==0 ){
111172
+ assert( db->mallocFailed );
111173
+ pNewItem->fg.isSubquery = 0;
111174
+ }else{
111175
+ memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq));
111176
+ pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags);
111177
+ if( pNewSubq->pSelect==0 ){
111178
+ sqlite3DbFree(db, pNewSubq);
111179
+ pNewSubq = 0;
111180
+ pNewItem->fg.isSubquery = 0;
111181
+ }
111182
+ }
111183
+ pNewItem->u4.pSubq = pNewSubq;
111184
+ }else if( pOldItem->fg.fixedSchema ){
111185
+ pNewItem->u4.pSchema = pOldItem->u4.pSchema;
111186
+ }else{
111187
+ pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase);
111188
+ }
110993111189
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
110994111190
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
110995
- pNewItem->fg = pOldItem->fg;
110996111191
pNewItem->iCursor = pOldItem->iCursor;
110997
- pNewItem->addrFillSub = pOldItem->addrFillSub;
110998
- pNewItem->regReturn = pOldItem->regReturn;
110999
- pNewItem->regResult = pOldItem->regResult;
111000111192
if( pNewItem->fg.isIndexedBy ){
111001111193
pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
111002111194
}else if( pNewItem->fg.isTabFunc ){
111003111195
pNewItem->u1.pFuncArg =
111004111196
sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
@@ -111007,15 +111199,14 @@
111007111199
}
111008111200
pNewItem->u2 = pOldItem->u2;
111009111201
if( pNewItem->fg.isCte ){
111010111202
pNewItem->u2.pCteUse->nUse++;
111011111203
}
111012
- pTab = pNewItem->pTab = pOldItem->pTab;
111204
+ pTab = pNewItem->pSTab = pOldItem->pSTab;
111013111205
if( pTab ){
111014111206
pTab->nTabRef++;
111015111207
}
111016
- pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
111017111208
if( pOldItem->fg.isUsing ){
111018111209
assert( pNewItem->fg.isUsing );
111019111210
pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
111020111211
}else{
111021111212
pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
@@ -111085,11 +111276,10 @@
111085111276
}
111086111277
*pp = pNew;
111087111278
pp = &pNew->pPrior;
111088111279
pNext = pNew;
111089111280
}
111090
-
111091111281
return pRet;
111092111282
}
111093111283
#else
111094111284
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
111095111285
assert( p==0 );
@@ -112105,12 +112295,12 @@
112105112295
if( p->pLimit ) return 0; /* Has no LIMIT clause */
112106112296
if( p->pWhere ) return 0; /* Has no WHERE clause */
112107112297
pSrc = p->pSrc;
112108112298
assert( pSrc!=0 );
112109112299
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
112110
- if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
112111
- pTab = pSrc->a[0].pTab;
112300
+ if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */
112301
+ pTab = pSrc->a[0].pSTab;
112112112302
assert( pTab!=0 );
112113112303
assert( !IsView(pTab) ); /* FROM clause is not a view */
112114112304
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
112115112305
pEList = p->pEList;
112116112306
assert( pEList!=0 );
@@ -112289,11 +112479,11 @@
112289112479
int nExpr = pEList->nExpr;
112290112480
112291112481
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
112292112482
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
112293112483
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
112294
- pTab = p->pSrc->a[0].pTab;
112484
+ pTab = p->pSrc->a[0].pSTab;
112295112485
112296112486
/* Code an OP_Transaction and OP_TableLock for <table>. */
112297112487
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
112298112488
assert( iDb>=0 && iDb<SQLITE_MAX_DB );
112299112489
sqlite3CodeVerifySchema(pParse, iDb);
@@ -117727,12 +117917,13 @@
117727117917
}
117728117918
if( pStep->pFrom ){
117729117919
int i;
117730117920
for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
117731117921
SrcItem *p = &pStep->pFrom->a[i];
117732
- if( p->pSelect ){
117733
- sqlite3SelectPrep(pParse, p->pSelect, 0);
117922
+ if( p->fg.isSubquery ){
117923
+ assert( p->u4.pSubq!=0 );
117924
+ sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0);
117734117925
}
117735117926
}
117736117927
}
117737117928
117738117929
if( db->mallocFailed ){
@@ -117796,12 +117987,16 @@
117796117987
sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
117797117988
sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
117798117989
}
117799117990
if( pStep->pFrom ){
117800117991
int i;
117801
- for(i=0; i<pStep->pFrom->nSrc; i++){
117802
- sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect);
117992
+ SrcList *pFrom = pStep->pFrom;
117993
+ for(i=0; i<pFrom->nSrc; i++){
117994
+ if( pFrom->a[i].fg.isSubquery ){
117995
+ assert( pFrom->a[i].u4.pSubq!=0 );
117996
+ sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect);
117997
+ }
117803117998
}
117804117999
}
117805118000
}
117806118001
}
117807118002
@@ -118044,11 +118239,11 @@
118044118239
assert( pWalker->pParse->db->mallocFailed );
118045118240
return WRC_Abort;
118046118241
}
118047118242
for(i=0; i<pSrc->nSrc; i++){
118048118243
SrcItem *pItem = &pSrc->a[i];
118049
- if( pItem->pTab==p->pTab ){
118244
+ if( pItem->pSTab==p->pTab ){
118050118245
renameTokenFind(pWalker->pParse, p, pItem->zName);
118051118246
}
118052118247
}
118053118248
renameWalkWith(pWalker, pSelect);
118054118249
@@ -121178,24 +121373,25 @@
121178121373
int iDb = sqlite3FindDbName(db, pFix->zDb);
121179121374
SrcList *pList = pSelect->pSrc;
121180121375
121181121376
if( NEVER(pList==0) ) return WRC_Continue;
121182121377
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
121183
- if( pFix->bTemp==0 ){
121184
- if( pItem->zDatabase ){
121185
- if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
121378
+ if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){
121379
+ if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
121380
+ if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){
121186121381
sqlite3ErrorMsg(pFix->pParse,
121187121382
"%s %T cannot reference objects in database %s",
121188
- pFix->zType, pFix->pName, pItem->zDatabase);
121383
+ pFix->zType, pFix->pName, pItem->u4.zDatabase);
121189121384
return WRC_Abort;
121190121385
}
121191
- sqlite3DbFree(db, pItem->zDatabase);
121192
- pItem->zDatabase = 0;
121386
+ sqlite3DbFree(db, pItem->u4.zDatabase);
121193121387
pItem->fg.notCte = 1;
121388
+ pItem->fg.hadSchema = 1;
121194121389
}
121195
- pItem->pSchema = pFix->pSchema;
121390
+ pItem->u4.pSchema = pFix->pSchema;
121196121391
pItem->fg.fromDDL = 1;
121392
+ pItem->fg.fixedSchema = 1;
121197121393
}
121198121394
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
121199121395
if( pList->a[i].fg.isUsing==0
121200121396
&& sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
121201121397
){
@@ -121484,11 +121680,11 @@
121484121680
pTab = pParse->pTriggerTab;
121485121681
}else{
121486121682
assert( pTabList );
121487121683
for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
121488121684
if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
121489
- pTab = pTabList->a[iSrc].pTab;
121685
+ pTab = pTabList->a[iSrc].pSTab;
121490121686
break;
121491121687
}
121492121688
}
121493121689
}
121494121690
iCol = pExpr->iColumn;
@@ -122087,16 +122283,16 @@
122087122283
Parse *pParse,
122088122284
u32 flags,
122089122285
SrcItem *p
122090122286
){
122091122287
const char *zDb;
122092
- assert( p->pSchema==0 || p->zDatabase==0 );
122093
- if( p->pSchema ){
122094
- int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
122288
+ if( p->fg.fixedSchema ){
122289
+ int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema);
122095122290
zDb = pParse->db->aDb[iDb].zDbSName;
122096122291
}else{
122097
- zDb = p->zDatabase;
122292
+ assert( !p->fg.isSubquery );
122293
+ zDb = p->u4.zDatabase;
122098122294
}
122099122295
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
122100122296
}
122101122297
122102122298
/*
@@ -125077,19 +125273,21 @@
125077125273
if( db->mallocFailed ){
125078125274
goto exit_drop_table;
125079125275
}
125080125276
assert( pParse->nErr==0 );
125081125277
assert( pName->nSrc==1 );
125278
+ assert( pName->a[0].fg.fixedSchema==0 );
125279
+ assert( pName->a[0].fg.isSubquery==0 );
125082125280
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
125083125281
if( noErr ) db->suppressErr++;
125084125282
assert( isView==0 || isView==LOCATE_VIEW );
125085125283
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
125086125284
if( noErr ) db->suppressErr--;
125087125285
125088125286
if( pTab==0 ){
125089125287
if( noErr ){
125090
- sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
125288
+ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
125091125289
sqlite3ForceNotReadOnly(pParse);
125092125290
}
125093125291
goto exit_drop_table;
125094125292
}
125095125293
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -126176,19 +126374,21 @@
126176126374
if( db->mallocFailed ){
126177126375
goto exit_drop_index;
126178126376
}
126179126377
assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
126180126378
assert( pName->nSrc==1 );
126379
+ assert( pName->a[0].fg.fixedSchema==0 );
126380
+ assert( pName->a[0].fg.isSubquery==0 );
126181126381
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
126182126382
goto exit_drop_index;
126183126383
}
126184
- pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
126384
+ pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase);
126185126385
if( pIndex==0 ){
126186126386
if( !ifExists ){
126187126387
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
126188126388
}else{
126189
- sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
126389
+ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
126190126390
sqlite3ForceNotReadOnly(pParse);
126191126391
}
126192126392
pParse->checkSchema = 1;
126193126393
goto exit_drop_index;
126194126394
}
@@ -126481,16 +126681,18 @@
126481126681
}
126482126682
pItem = &pList->a[pList->nSrc-1];
126483126683
if( pDatabase && pDatabase->z==0 ){
126484126684
pDatabase = 0;
126485126685
}
126686
+ assert( pItem->fg.fixedSchema==0 );
126687
+ assert( pItem->fg.isSubquery==0 );
126486126688
if( pDatabase ){
126487126689
pItem->zName = sqlite3NameFromToken(db, pDatabase);
126488
- pItem->zDatabase = sqlite3NameFromToken(db, pTable);
126690
+ pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable);
126489126691
}else{
126490126692
pItem->zName = sqlite3NameFromToken(db, pTable);
126491
- pItem->zDatabase = 0;
126693
+ pItem->u4.zDatabase = 0;
126492126694
}
126493126695
return pList;
126494126696
}
126495126697
126496126698
/*
@@ -126502,16 +126704,43 @@
126502126704
assert( pList || pParse->db->mallocFailed );
126503126705
if( ALWAYS(pList) ){
126504126706
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
126505126707
if( pItem->iCursor>=0 ) continue;
126506126708
pItem->iCursor = pParse->nTab++;
126507
- if( pItem->pSelect ){
126508
- sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
126709
+ if( pItem->fg.isSubquery ){
126710
+ assert( pItem->u4.pSubq!=0 );
126711
+ assert( pItem->u4.pSubq->pSelect!=0 );
126712
+ assert( pItem->u4.pSubq->pSelect->pSrc!=0 );
126713
+ sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc);
126509126714
}
126510126715
}
126511126716
}
126512126717
}
126718
+
126719
+/*
126720
+** Delete a Subquery object and its substructure.
126721
+*/
126722
+SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){
126723
+ assert( pSubq!=0 && pSubq->pSelect!=0 );
126724
+ sqlite3SelectDelete(db, pSubq->pSelect);
126725
+ sqlite3DbFree(db, pSubq);
126726
+}
126727
+
126728
+/*
126729
+** Remove a Subquery from a SrcItem. Return the associated Select object.
126730
+** The returned Select becomes the responsibility of the caller.
126731
+*/
126732
+SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){
126733
+ Select *pSel;
126734
+ assert( pItem!=0 );
126735
+ assert( pItem->fg.isSubquery );
126736
+ pSel = pItem->u4.pSubq->pSelect;
126737
+ sqlite3DbFree(db, pItem->u4.pSubq);
126738
+ pItem->u4.pSubq = 0;
126739
+ pItem->fg.isSubquery = 0;
126740
+ return pSel;
126741
+}
126513126742
126514126743
/*
126515126744
** Delete an entire SrcList including all its substructure.
126516126745
*/
126517126746
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
@@ -126518,25 +126747,84 @@
126518126747
int i;
126519126748
SrcItem *pItem;
126520126749
assert( db!=0 );
126521126750
if( pList==0 ) return;
126522126751
for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
126523
- if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase);
126752
+
126753
+ /* Check invariants on SrcItem */
126754
+ assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc );
126755
+ assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy );
126756
+ assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery );
126757
+ assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 &&
126758
+ pItem->u4.pSubq->pSelect!=0) );
126759
+
126524126760
if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName);
126525126761
if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias);
126762
+ if( pItem->fg.isSubquery ){
126763
+ sqlite3SubqueryDelete(db, pItem->u4.pSubq);
126764
+ }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
126765
+ sqlite3DbNNFreeNN(db, pItem->u4.zDatabase);
126766
+ }
126526126767
if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
126527126768
if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
126528
- sqlite3DeleteTable(db, pItem->pTab);
126529
- if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
126769
+ sqlite3DeleteTable(db, pItem->pSTab);
126530126770
if( pItem->fg.isUsing ){
126531126771
sqlite3IdListDelete(db, pItem->u3.pUsing);
126532126772
}else if( pItem->u3.pOn ){
126533126773
sqlite3ExprDelete(db, pItem->u3.pOn);
126534126774
}
126535126775
}
126536126776
sqlite3DbNNFreeNN(db, pList);
126537126777
}
126778
+
126779
+/*
126780
+** Attach a Subquery object to pItem->uv.pSubq. Set the
126781
+** pSelect value but leave all the other values initialized
126782
+** to zero.
126783
+**
126784
+** A copy of the Select object is made if dupSelect is true, and the
126785
+** SrcItem takes responsibility for deleting the copy. If dupSelect is
126786
+** false, ownership of the Select passes to the SrcItem. Either way,
126787
+** the SrcItem will take responsibility for deleting the Select.
126788
+**
126789
+** When dupSelect is zero, that means the Select might get deleted right
126790
+** away if there is an OOM error. Beware.
126791
+**
126792
+** Return non-zero on success. Return zero on an OOM error.
126793
+*/
126794
+SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(
126795
+ Parse *pParse, /* Parsing context */
126796
+ SrcItem *pItem, /* Item to which the subquery is to be attached */
126797
+ Select *pSelect, /* The subquery SELECT. Must be non-NULL */
126798
+ int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/
126799
+){
126800
+ Subquery *p;
126801
+ assert( pSelect!=0 );
126802
+ assert( pItem->fg.isSubquery==0 );
126803
+ if( pItem->fg.fixedSchema ){
126804
+ pItem->u4.pSchema = 0;
126805
+ pItem->fg.fixedSchema = 0;
126806
+ }else if( pItem->u4.zDatabase!=0 ){
126807
+ sqlite3DbFree(pParse->db, pItem->u4.zDatabase);
126808
+ pItem->u4.zDatabase = 0;
126809
+ }
126810
+ if( dupSelect ){
126811
+ pSelect = sqlite3SelectDup(pParse->db, pSelect, 0);
126812
+ if( pSelect==0 ) return 0;
126813
+ }
126814
+ p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery));
126815
+ if( p==0 ){
126816
+ sqlite3SelectDelete(pParse->db, pSelect);
126817
+ return 0;
126818
+ }
126819
+ pItem->fg.isSubquery = 1;
126820
+ p->pSelect = pSelect;
126821
+ assert( offsetof(Subquery, pSelect)==0 );
126822
+ memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect));
126823
+ return 1;
126824
+}
126825
+
126538126826
126539126827
/*
126540126828
** This routine is called by the parser to add a new term to the
126541126829
** end of a growing FROM clause. The "p" parameter is the part of
126542126830
** the FROM clause that has already been constructed. "p" is NULL
@@ -126583,14 +126871,16 @@
126583126871
}
126584126872
assert( pAlias!=0 );
126585126873
if( pAlias->n ){
126586126874
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
126587126875
}
126876
+ assert( pSubquery==0 || pDatabase==0 );
126588126877
if( pSubquery ){
126589
- pItem->pSelect = pSubquery;
126590
- if( pSubquery->selFlags & SF_NestedFrom ){
126591
- pItem->fg.isNestedFrom = 1;
126878
+ if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){
126879
+ if( pSubquery->selFlags & SF_NestedFrom ){
126880
+ pItem->fg.isNestedFrom = 1;
126881
+ }
126592126882
}
126593126883
}
126594126884
assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
126595126885
assert( pItem->fg.isUsing==0 );
126596126886
if( pOnUsing==0 ){
@@ -127864,21 +128154,21 @@
127864128154
** return a pointer. Set an error message and return NULL if the table
127865128155
** name is not found or if any other error occurs.
127866128156
**
127867128157
** The following fields are initialized appropriate in pSrc:
127868128158
**
127869
-** pSrc->a[0].pTab Pointer to the Table object
127870
-** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
128159
+** pSrc->a[0].spTab Pointer to the Table object
128160
+** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one
127871128161
**
127872128162
*/
127873128163
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
127874128164
SrcItem *pItem = pSrc->a;
127875128165
Table *pTab;
127876128166
assert( pItem && pSrc->nSrc>=1 );
127877128167
pTab = sqlite3LocateTableItem(pParse, 0, pItem);
127878
- if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab);
127879
- pItem->pTab = pTab;
128168
+ if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab);
128169
+ pItem->pSTab = pTab;
127880128170
pItem->fg.notCte = 1;
127881128171
if( pTab ){
127882128172
pTab->nTabRef++;
127883128173
if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){
127884128174
pTab = 0;
@@ -127996,11 +128286,12 @@
127996128286
pWhere = sqlite3ExprDup(db, pWhere, 0);
127997128287
pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
127998128288
if( pFrom ){
127999128289
assert( pFrom->nSrc==1 );
128000128290
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
128001
- pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
128291
+ assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 );
128292
+ pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
128002128293
assert( pFrom->a[0].fg.isUsing==0 );
128003128294
assert( pFrom->a[0].u3.pOn==0 );
128004128295
}
128005128296
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
128006128297
SF_IncludeHidden, pLimit);
@@ -128058,11 +128349,11 @@
128058128349
** DELETE FROM table_a WHERE rowid IN (
128059128350
** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
128060128351
** );
128061128352
*/
128062128353
128063
- pTab = pSrc->a[0].pTab;
128354
+ pTab = pSrc->a[0].pSTab;
128064128355
if( HasRowid(pTab) ){
128065128356
pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
128066128357
pEList = sqlite3ExprListAppend(
128067128358
pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
128068128359
);
@@ -128091,13 +128382,13 @@
128091128382
}
128092128383
}
128093128384
128094128385
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
128095128386
** and the SELECT subtree. */
128096
- pSrc->a[0].pTab = 0;
128387
+ pSrc->a[0].pSTab = 0;
128097128388
pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
128098
- pSrc->a[0].pTab = pTab;
128389
+ pSrc->a[0].pSTab = pTab;
128099128390
if( pSrc->a[0].fg.isIndexedBy ){
128100128391
assert( pSrc->a[0].fg.isCte==0 );
128101128392
pSrc->a[0].u2.pIBIndex = 0;
128102128393
pSrc->a[0].fg.isIndexedBy = 0;
128103128394
sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
@@ -132675,13 +132966,13 @@
132675132966
/* Create a SrcList structure containing the child table. We need the
132676132967
** child table as a SrcList for sqlite3WhereBegin() */
132677132968
pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
132678132969
if( pSrc ){
132679132970
SrcItem *pItem = pSrc->a;
132680
- pItem->pTab = pFKey->pFrom;
132971
+ pItem->pSTab = pFKey->pFrom;
132681132972
pItem->zName = pFKey->pFrom->zName;
132682
- pItem->pTab->nTabRef++;
132973
+ pItem->pSTab->nTabRef++;
132683132974
pItem->iCursor = pParse->nTab++;
132684132975
132685132976
if( regNew!=0 ){
132686132977
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
132687132978
}
@@ -132969,11 +133260,12 @@
132969133260
}
132970133261
pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
132971133262
if( pSrc ){
132972133263
assert( pSrc->nSrc==1 );
132973133264
pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom);
132974
- pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
133265
+ assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 );
133266
+ pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
132975133267
}
132976133268
pSelect = sqlite3SelectNew(pParse,
132977133269
sqlite3ExprListAppend(pParse, 0, pRaise),
132978133270
pSrc,
132979133271
pWhere,
@@ -133703,12 +133995,15 @@
133703133995
** co-routine.
133704133996
*/
133705133997
SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){
133706133998
if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){
133707133999
SrcItem *pItem = &pVal->pSrc->a[0];
133708
- sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn);
133709
- sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1);
134000
+ assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr );
134001
+ if( pItem->fg.isSubquery ){
134002
+ sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn);
134003
+ sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1);
134004
+ }
133710134005
}
133711134006
}
133712134007
133713134008
/*
133714134009
** Return true if all expressions in the expression-list passed as the
@@ -133832,56 +134127,67 @@
133832134127
sqlite3ReadSchema(pParse);
133833134128
}
133834134129
133835134130
if( pRet ){
133836134131
SelectDest dest;
134132
+ Subquery *pSubq;
133837134133
pRet->pSrc->nSrc = 1;
133838134134
pRet->pPrior = pLeft->pPrior;
133839134135
pRet->op = pLeft->op;
133840134136
if( pRet->pPrior ) pRet->selFlags |= SF_Values;
133841134137
pLeft->pPrior = 0;
133842134138
pLeft->op = TK_SELECT;
133843134139
assert( pLeft->pNext==0 );
133844134140
assert( pRet->pNext==0 );
133845134141
p = &pRet->pSrc->a[0];
133846
- p->pSelect = pLeft;
133847134142
p->fg.viaCoroutine = 1;
133848
- p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
133849
- p->regReturn = ++pParse->nMem;
133850134143
p->iCursor = -1;
134144
+ assert( !p->fg.isIndexedBy && !p->fg.isTabFunc );
133851134145
p->u1.nRow = 2;
133852
- sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub);
133853
- sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn);
133854
-
133855
- /* Allocate registers for the output of the co-routine. Do so so
133856
- ** that there are two unused registers immediately before those
133857
- ** used by the co-routine. This allows the code in sqlite3Insert()
133858
- ** to use these registers directly, instead of copying the output
133859
- ** of the co-routine to a separate array for processing. */
133860
- dest.iSdst = pParse->nMem + 3;
133861
- dest.nSdst = pLeft->pEList->nExpr;
133862
- pParse->nMem += 2 + dest.nSdst;
133863
-
133864
- pLeft->selFlags |= SF_MultiValue;
133865
- sqlite3Select(pParse, pLeft, &dest);
133866
- p->regResult = dest.iSdst;
133867
- assert( pParse->nErr || dest.iSdst>0 );
134146
+ if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){
134147
+ pSubq = p->u4.pSubq;
134148
+ pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
134149
+ pSubq->regReturn = ++pParse->nMem;
134150
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine,
134151
+ pSubq->regReturn, 0, pSubq->addrFillSub);
134152
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
134153
+
134154
+ /* Allocate registers for the output of the co-routine. Do so so
134155
+ ** that there are two unused registers immediately before those
134156
+ ** used by the co-routine. This allows the code in sqlite3Insert()
134157
+ ** to use these registers directly, instead of copying the output
134158
+ ** of the co-routine to a separate array for processing. */
134159
+ dest.iSdst = pParse->nMem + 3;
134160
+ dest.nSdst = pLeft->pEList->nExpr;
134161
+ pParse->nMem += 2 + dest.nSdst;
134162
+
134163
+ pLeft->selFlags |= SF_MultiValue;
134164
+ sqlite3Select(pParse, pLeft, &dest);
134165
+ pSubq->regResult = dest.iSdst;
134166
+ assert( pParse->nErr || dest.iSdst>0 );
134167
+ }
133868134168
pLeft = pRet;
133869134169
}
133870134170
}else{
133871134171
p = &pLeft->pSrc->a[0];
133872134172
assert( !p->fg.isTabFunc && !p->fg.isIndexedBy );
133873134173
p->u1.nRow++;
133874134174
}
133875134175
133876134176
if( pParse->nErr==0 ){
134177
+ Subquery *pSubq;
133877134178
assert( p!=0 );
133878
- if( p->pSelect->pEList->nExpr!=pRow->nExpr ){
133879
- sqlite3SelectWrongNumTermsError(pParse, p->pSelect);
134179
+ assert( p->fg.isSubquery );
134180
+ pSubq = p->u4.pSubq;
134181
+ assert( pSubq!=0 );
134182
+ assert( pSubq->pSelect!=0 );
134183
+ assert( pSubq->pSelect->pEList!=0 );
134184
+ if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){
134185
+ sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect);
133880134186
}else{
133881
- sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0);
133882
- sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn);
134187
+ sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0);
134188
+ sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn);
133883134189
}
133884134190
}
133885134191
sqlite3ExprListDelete(pParse->db, pRow);
133886134192
}
133887134193
@@ -134228,13 +134534,18 @@
134228134534
if( pSelect->pSrc->nSrc==1
134229134535
&& pSelect->pSrc->a[0].fg.viaCoroutine
134230134536
&& pSelect->pPrior==0
134231134537
){
134232134538
SrcItem *pItem = &pSelect->pSrc->a[0];
134233
- dest.iSDParm = pItem->regReturn;
134234
- regFromSelect = pItem->regResult;
134235
- nColumn = pItem->pSelect->pEList->nExpr;
134539
+ Subquery *pSubq;
134540
+ assert( pItem->fg.isSubquery );
134541
+ pSubq = pItem->u4.pSubq;
134542
+ dest.iSDParm = pSubq->regReturn;
134543
+ regFromSelect = pSubq->regResult;
134544
+ assert( pSubq->pSelect!=0 );
134545
+ assert( pSubq->pSelect->pEList!=0 );
134546
+ nColumn = pSubq->pSelect->pEList->nExpr;
134236134547
ExplainQueryPlan((pParse, 0, "SCAN %S", pItem));
134237134548
if( bIdListInOrder && nColumn==pTab->nCol ){
134238134549
regData = regFromSelect;
134239134550
regRowid = regData - 1;
134240134551
regIns = regRowid - (IsVirtual(pTab) ? 1 : 0);
@@ -136150,11 +136461,11 @@
136150136461
}
136151136462
assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
136152136463
if( pSelect->pSrc->nSrc!=1 ){
136153136464
return 0; /* FROM clause must have exactly one term */
136154136465
}
136155
- if( pSelect->pSrc->a[0].pSelect ){
136466
+ if( pSelect->pSrc->a[0].fg.isSubquery ){
136156136467
return 0; /* FROM clause cannot contain a subquery */
136157136468
}
136158136469
if( pSelect->pWhere ){
136159136470
return 0; /* SELECT may not have a WHERE clause */
136160136471
}
@@ -143448,15 +143759,17 @@
143448143759
/*
143449143760
** Mark a subquery result column as having been used.
143450143761
*/
143451143762
SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
143452143763
assert( pItem!=0 );
143453
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
143764
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
143454143765
if( pItem->fg.isNestedFrom ){
143455143766
ExprList *pResults;
143456
- assert( pItem->pSelect!=0 );
143457
- pResults = pItem->pSelect->pEList;
143767
+ assert( pItem->fg.isSubquery );
143768
+ assert( pItem->u4.pSubq!=0 );
143769
+ assert( pItem->u4.pSubq->pSelect!=0 );
143770
+ pResults = pItem->u4.pSubq->pSelect->pEList;
143458143771
assert( pResults!=0 );
143459143772
assert( iCol>=0 && iCol<pResults->nExpr );
143460143773
pResults->a[iCol].fg.bUsed = 1;
143461143774
}
143462143775
}
@@ -143486,13 +143799,13 @@
143486143799
assert( iEnd<pSrc->nSrc );
143487143800
assert( iStart>=0 );
143488143801
assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
143489143802
143490143803
for(i=iStart; i<=iEnd; i++){
143491
- iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
143804
+ iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol);
143492143805
if( iCol>=0
143493
- && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
143806
+ && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0)
143494143807
){
143495143808
if( piTab ){
143496143809
sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
143497143810
*piTab = i;
143498143811
*piCol = iCol;
@@ -143617,14 +143930,14 @@
143617143930
143618143931
pSrc = p->pSrc;
143619143932
pLeft = &pSrc->a[0];
143620143933
pRight = &pLeft[1];
143621143934
for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
143622
- Table *pRightTab = pRight->pTab;
143935
+ Table *pRightTab = pRight->pSTab;
143623143936
u32 joinType;
143624143937
143625
- if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
143938
+ if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue;
143626143939
joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
143627143940
143628143941
/* If this is a NATURAL join, synthesize an appropriate USING clause
143629143942
** to specify which columns should be joined.
143630143943
*/
@@ -145046,12 +145359,16 @@
145046145359
int iCol = pExpr->iColumn; /* Index of column in pTab */
145047145360
while( pNC && !pTab ){
145048145361
SrcList *pTabList = pNC->pSrcList;
145049145362
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
145050145363
if( j<pTabList->nSrc ){
145051
- pTab = pTabList->a[j].pTab;
145052
- pS = pTabList->a[j].pSelect;
145364
+ pTab = pTabList->a[j].pSTab;
145365
+ if( pTabList->a[j].fg.isSubquery ){
145366
+ pS = pTabList->a[j].u4.pSubq->pSelect;
145367
+ }else{
145368
+ pS = 0;
145369
+ }
145053145370
}else{
145054145371
pNC = pNC->pNext;
145055145372
}
145056145373
}
145057145374
@@ -147099,11 +147416,13 @@
147099147416
p->pHaving = substExpr(pSubst, p->pHaving);
147100147417
p->pWhere = substExpr(pSubst, p->pWhere);
147101147418
pSrc = p->pSrc;
147102147419
assert( pSrc!=0 );
147103147420
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
147104
- substSelect(pSubst, pItem->pSelect, 1);
147421
+ if( pItem->fg.isSubquery ){
147422
+ substSelect(pSubst, pItem->u4.pSubq->pSelect, 1);
147423
+ }
147105147424
if( pItem->fg.isTabFunc ){
147106147425
substExprList(pSubst, pItem->u1.pFuncArg);
147107147426
}
147108147427
}
147109147428
}while( doPrior && (p = p->pPrior)!=0 );
@@ -147130,11 +147449,11 @@
147130147449
static void recomputeColumnsUsed(
147131147450
Select *pSelect, /* The complete SELECT statement */
147132147451
SrcItem *pSrcItem /* Which FROM clause item to recompute */
147133147452
){
147134147453
Walker w;
147135
- if( NEVER(pSrcItem->pTab==0) ) return;
147454
+ if( NEVER(pSrcItem->pSTab==0) ) return;
147136147455
memset(&w, 0, sizeof(w));
147137147456
w.xExprCallback = recomputeColumnsUsedExpr;
147138147457
w.xSelectCallback = sqlite3SelectWalkNoop;
147139147458
w.u.pSrcItem = pSrcItem;
147140147459
pSrcItem->colUsed = 0;
@@ -147170,12 +147489,14 @@
147170147489
assert( pItem->iCursor < aCsrMap[0] );
147171147490
if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){
147172147491
aCsrMap[pItem->iCursor+1] = pParse->nTab++;
147173147492
}
147174147493
pItem->iCursor = aCsrMap[pItem->iCursor+1];
147175
- for(p=pItem->pSelect; p; p=p->pPrior){
147176
- srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
147494
+ if( pItem->fg.isSubquery ){
147495
+ for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){
147496
+ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
147497
+ }
147177147498
}
147178147499
}
147179147500
}
147180147501
}
147181147502
@@ -147482,11 +147803,12 @@
147482147803
if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
147483147804
pSrc = p->pSrc;
147484147805
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
147485147806
pSubitem = &pSrc->a[iFrom];
147486147807
iParent = pSubitem->iCursor;
147487
- pSub = pSubitem->pSelect;
147808
+ assert( pSubitem->fg.isSubquery );
147809
+ pSub = pSubitem->u4.pSubq->pSelect;
147488147810
assert( pSub!=0 );
147489147811
147490147812
#ifndef SQLITE_OMIT_WINDOWFUNC
147491147813
if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */
147492147814
#endif
@@ -147535,11 +147857,11 @@
147535147857
**
147536147858
** See also tickets #306, #350, and #3300.
147537147859
*/
147538147860
if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
147539147861
if( pSubSrc->nSrc>1 /* (3a) */
147540
- || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */
147862
+ || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */
147541147863
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
147542147864
|| (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
147543147865
){
147544147866
return 0;
147545147867
}
@@ -147621,18 +147943,22 @@
147621147943
TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
147622147944
testcase( i==SQLITE_DENY );
147623147945
pParse->zAuthContext = zSavedAuthContext;
147624147946
147625147947
/* Delete the transient structures associated with the subquery */
147626
- pSub1 = pSubitem->pSelect;
147627
- sqlite3DbFree(db, pSubitem->zDatabase);
147948
+
147949
+ if( ALWAYS(pSubitem->fg.isSubquery) ){
147950
+ pSub1 = sqlite3SubqueryDetach(db, pSubitem);
147951
+ }else{
147952
+ pSub1 = 0;
147953
+ }
147954
+ assert( pSubitem->fg.isSubquery==0 );
147955
+ assert( pSubitem->fg.fixedSchema==0 );
147628147956
sqlite3DbFree(db, pSubitem->zName);
147629147957
sqlite3DbFree(db, pSubitem->zAlias);
147630
- pSubitem->zDatabase = 0;
147631147958
pSubitem->zName = 0;
147632147959
pSubitem->zAlias = 0;
147633
- pSubitem->pSelect = 0;
147634147960
assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
147635147961
147636147962
/* If the sub-query is a compound SELECT statement, then (by restrictions
147637147963
** 17 and 18 above) it must be a UNION ALL and the parent query must
147638147964
** be of the form:
@@ -147669,20 +147995,20 @@
147669147995
for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
147670147996
Select *pNew;
147671147997
ExprList *pOrderBy = p->pOrderBy;
147672147998
Expr *pLimit = p->pLimit;
147673147999
Select *pPrior = p->pPrior;
147674
- Table *pItemTab = pSubitem->pTab;
147675
- pSubitem->pTab = 0;
148000
+ Table *pItemTab = pSubitem->pSTab;
148001
+ pSubitem->pSTab = 0;
147676148002
p->pOrderBy = 0;
147677148003
p->pPrior = 0;
147678148004
p->pLimit = 0;
147679148005
pNew = sqlite3SelectDup(db, p, 0);
147680148006
p->pLimit = pLimit;
147681148007
p->pOrderBy = pOrderBy;
147682148008
p->op = TK_ALL;
147683
- pSubitem->pTab = pItemTab;
148009
+ pSubitem->pSTab = pItemTab;
147684148010
if( pNew==0 ){
147685148011
p->pPrior = pPrior;
147686148012
}else{
147687148013
pNew->selId = ++pParse->nSelect;
147688148014
if( aCsrMap && ALWAYS(db->mallocFailed==0) ){
@@ -147693,15 +148019,18 @@
147693148019
pNew->pNext = p;
147694148020
p->pPrior = pNew;
147695148021
TREETRACE(0x4,pParse,p,("compound-subquery flattener"
147696148022
" creates %u as peer\n",pNew->selId));
147697148023
}
147698
- assert( pSubitem->pSelect==0 );
148024
+ assert( pSubitem->fg.isSubquery==0 );
147699148025
}
147700148026
sqlite3DbFree(db, aCsrMap);
147701148027
if( db->mallocFailed ){
147702
- pSubitem->pSelect = pSub1;
148028
+ assert( pSubitem->fg.fixedSchema==0 );
148029
+ assert( pSubitem->fg.isSubquery==0 );
148030
+ assert( pSubitem->u4.zDatabase==0 );
148031
+ sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0);
147703148032
return 1;
147704148033
}
147705148034
147706148035
/* Defer deleting the Table object associated with the
147707148036
** subquery until code generation is
@@ -147708,20 +148037,20 @@
147708148037
** complete, since there may still exist Expr.pTab entries that
147709148038
** refer to the subquery even after flattening. Ticket #3346.
147710148039
**
147711148040
** pSubitem->pTab is always non-NULL by test restrictions and tests above.
147712148041
*/
147713
- if( ALWAYS(pSubitem->pTab!=0) ){
147714
- Table *pTabToDel = pSubitem->pTab;
148042
+ if( ALWAYS(pSubitem->pSTab!=0) ){
148043
+ Table *pTabToDel = pSubitem->pSTab;
147715148044
if( pTabToDel->nTabRef==1 ){
147716148045
Parse *pToplevel = sqlite3ParseToplevel(pParse);
147717148046
sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
147718148047
testcase( pToplevel->earlyCleanup );
147719148048
}else{
147720148049
pTabToDel->nTabRef--;
147721148050
}
147722
- pSubitem->pTab = 0;
148051
+ pSubitem->pSTab = 0;
147723148052
}
147724148053
147725148054
/* The following loop runs once for each term in a compound-subquery
147726148055
** flattening (as described above). If we are doing a different kind
147727148056
** of flattening - a flattening other than a compound-subquery flattening -
@@ -147773,12 +148102,15 @@
147773148102
/* Transfer the FROM clause terms from the subquery into the
147774148103
** outer query.
147775148104
*/
147776148105
for(i=0; i<nSubSrc; i++){
147777148106
SrcItem *pItem = &pSrc->a[i+iFrom];
147778
- if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
147779148107
assert( pItem->fg.isTabFunc==0 );
148108
+ assert( pItem->fg.isSubquery
148109
+ || pItem->fg.fixedSchema
148110
+ || pItem->u4.zDatabase==0 );
148111
+ if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
147780148112
*pItem = pSubSrc->a[i];
147781148113
pItem->fg.jointype |= ltorj;
147782148114
iNewParent = pSubSrc->a[i].iCursor;
147783148115
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
147784148116
}
@@ -148458,14 +148790,14 @@
148458148790
148459148791
assert( pItem!=0 );
148460148792
if( pItem->fg.isCorrelated || pItem->fg.isCte ){
148461148793
return 0;
148462148794
}
148463
- assert( pItem->pTab!=0 );
148464
- pTab = pItem->pTab;
148465
- assert( pItem->pSelect!=0 );
148466
- pSub = pItem->pSelect;
148795
+ assert( pItem->pSTab!=0 );
148796
+ pTab = pItem->pSTab;
148797
+ assert( pItem->fg.isSubquery );
148798
+ pSub = pItem->u4.pSubq->pSelect;
148467148799
assert( pSub->pEList->nExpr==pTab->nCol );
148468148800
for(pX=pSub; pX; pX=pX->pPrior){
148469148801
if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
148470148802
testcase( pX->selFlags & SF_Distinct );
148471148803
testcase( pX->selFlags & SF_Aggregate );
@@ -148590,17 +148922,17 @@
148590148922
assert( !p->pGroupBy );
148591148923
148592148924
if( p->pWhere
148593148925
|| p->pEList->nExpr!=1
148594148926
|| p->pSrc->nSrc!=1
148595
- || p->pSrc->a[0].pSelect
148927
+ || p->pSrc->a[0].fg.isSubquery
148596148928
|| pAggInfo->nFunc!=1
148597148929
|| p->pHaving
148598148930
){
148599148931
return 0;
148600148932
}
148601
- pTab = p->pSrc->a[0].pTab;
148933
+ pTab = p->pSrc->a[0].pSTab;
148602148934
assert( pTab!=0 );
148603148935
assert( !IsView(pTab) );
148604148936
if( !IsOrdinaryTable(pTab) ) return 0;
148605148937
pExpr = p->pEList->a[0].pExpr;
148606148938
assert( pExpr!=0 );
@@ -148621,11 +148953,11 @@
148621148953
** was such a clause and the named index cannot be found, return
148622148954
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
148623148955
** pFrom->pIndex and return SQLITE_OK.
148624148956
*/
148625148957
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){
148626
- Table *pTab = pFrom->pTab;
148958
+ Table *pTab = pFrom->pSTab;
148627148959
char *zIndexedBy = pFrom->u1.zIndexedBy;
148628148960
Index *pIdx;
148629148961
assert( pTab!=0 );
148630148962
assert( pFrom->fg.isIndexedBy!=0 );
148631148963
@@ -148698,11 +149030,15 @@
148698149030
db = pParse->db;
148699149031
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
148700149032
if( pNew==0 ) return WRC_Abort;
148701149033
memset(&dummy, 0, sizeof(dummy));
148702149034
pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
148703
- if( pNewSrc==0 ) return WRC_Abort;
149035
+ assert( pNewSrc!=0 || pParse->nErr );
149036
+ if( pParse->nErr ){
149037
+ sqlite3SrcListDelete(db, pNewSrc);
149038
+ return WRC_Abort;
149039
+ }
148704149040
*pNew = *p;
148705149041
p->pSrc = pNewSrc;
148706149042
p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
148707149043
p->op = TK_SELECT;
148708149044
p->pWhere = 0;
@@ -148753,11 +149089,11 @@
148753149089
SrcItem *pItem, /* FROM clause element to resolve */
148754149090
With **ppContext /* OUT: WITH clause return value belongs to */
148755149091
){
148756149092
const char *zName = pItem->zName;
148757149093
With *p;
148758
- assert( pItem->zDatabase==0 );
149094
+ assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 );
148759149095
assert( zName!=0 );
148760149096
for(p=pWith; p; p=p->pOuter){
148761149097
int i;
148762149098
for(i=0; i<p->nCte; i++){
148763149099
if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
@@ -148823,21 +149159,22 @@
148823149159
SrcItem *pFrom /* The FROM clause term to check */
148824149160
){
148825149161
Cte *pCte; /* Matched CTE (or NULL if no match) */
148826149162
With *pWith; /* The matching WITH */
148827149163
148828
- assert( pFrom->pTab==0 );
149164
+ assert( pFrom->pSTab==0 );
148829149165
if( pParse->pWith==0 ){
148830149166
/* There are no WITH clauses in the stack. No match is possible */
148831149167
return 0;
148832149168
}
148833149169
if( pParse->nErr ){
148834149170
/* Prior errors might have left pParse->pWith in a goofy state, so
148835149171
** go no further. */
148836149172
return 0;
148837149173
}
148838
- if( pFrom->zDatabase!=0 ){
149174
+ assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 );
149175
+ if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){
148839149176
/* The FROM term contains a schema qualifier (ex: main.t1) and so
148840149177
** it cannot possibly be a CTE reference. */
148841149178
return 0;
148842149179
}
148843149180
if( pFrom->fg.notCte ){
@@ -148869,11 +149206,11 @@
148869149206
sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
148870149207
return 2;
148871149208
}
148872149209
if( cannotBeFunction(pParse, pFrom) ) return 2;
148873149210
148874
- assert( pFrom->pTab==0 );
149211
+ assert( pFrom->pSTab==0 );
148875149212
pTab = sqlite3DbMallocZero(db, sizeof(Table));
148876149213
if( pTab==0 ) return 2;
148877149214
pCteUse = pCte->pUse;
148878149215
if( pCteUse==0 ){
148879149216
pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0]));
@@ -148883,42 +149220,47 @@
148883149220
sqlite3DbFree(db, pTab);
148884149221
return 2;
148885149222
}
148886149223
pCteUse->eM10d = pCte->eM10d;
148887149224
}
148888
- pFrom->pTab = pTab;
149225
+ pFrom->pSTab = pTab;
148889149226
pTab->nTabRef = 1;
148890149227
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
148891149228
pTab->iPKey = -1;
148892149229
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
148893149230
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
148894
- pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
149231
+ sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1);
148895149232
if( db->mallocFailed ) return 2;
148896
- pFrom->pSelect->selFlags |= SF_CopyCte;
148897
- assert( pFrom->pSelect );
149233
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
149234
+ pSel = pFrom->u4.pSubq->pSelect;
149235
+ assert( pSel!=0 );
149236
+ pSel->selFlags |= SF_CopyCte;
148898149237
if( pFrom->fg.isIndexedBy ){
148899149238
sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
148900149239
return 2;
148901149240
}
149241
+ assert( !pFrom->fg.isIndexedBy );
148902149242
pFrom->fg.isCte = 1;
148903149243
pFrom->u2.pCteUse = pCteUse;
148904149244
pCteUse->nUse++;
148905149245
148906149246
/* Check if this is a recursive CTE. */
148907
- pRecTerm = pSel = pFrom->pSelect;
149247
+ pRecTerm = pSel;
148908149248
bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
148909149249
while( bMayRecursive && pRecTerm->op==pSel->op ){
148910149250
int i;
148911149251
SrcList *pSrc = pRecTerm->pSrc;
148912149252
assert( pRecTerm->pPrior!=0 );
148913149253
for(i=0; i<pSrc->nSrc; i++){
148914149254
SrcItem *pItem = &pSrc->a[i];
148915
- if( pItem->zDatabase==0
148916
- && pItem->zName!=0
149255
+ if( pItem->zName!=0
149256
+ && !pItem->fg.hadSchema
149257
+ && ALWAYS( !pItem->fg.isSubquery )
149258
+ && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0)
148917149259
&& 0==sqlite3StrICmp(pItem->zName, pCte->zName)
148918149260
){
148919
- pItem->pTab = pTab;
149261
+ pItem->pSTab = pTab;
148920149262
pTab->nTabRef++;
148921149263
pItem->fg.isRecursive = 1;
148922149264
if( pRecTerm->selFlags & SF_Recursive ){
148923149265
sqlite3ErrorMsg(pParse,
148924149266
"multiple references to recursive table: %s", pCte->zName
@@ -149016,15 +149358,18 @@
149016149358
** allocates and populates the SrcItem.pTab object. If successful,
149017149359
** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
149018149360
** SQLITE_NOMEM.
149019149361
*/
149020149362
SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
149021
- Select *pSel = pFrom->pSelect;
149363
+ Select *pSel;
149022149364
Table *pTab;
149023149365
149366
+ assert( pFrom->fg.isSubquery );
149367
+ assert( pFrom->u4.pSubq!=0 );
149368
+ pSel = pFrom->u4.pSubq->pSelect;
149024149369
assert( pSel );
149025
- pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
149370
+ pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
149026149371
if( pTab==0 ) return SQLITE_NOMEM;
149027149372
pTab->nTabRef = 1;
149028149373
if( pFrom->zAlias ){
149029149374
pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
149030149375
}else{
@@ -149140,37 +149485,39 @@
149140149485
** an entry of the FROM clause is a subquery instead of a table or view,
149141149486
** then create a transient table structure to describe the subquery.
149142149487
*/
149143149488
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149144149489
Table *pTab;
149145
- assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
149146
- if( pFrom->pTab ) continue;
149490
+ assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 );
149491
+ if( pFrom->pSTab ) continue;
149147149492
assert( pFrom->fg.isRecursive==0 );
149148149493
if( pFrom->zName==0 ){
149149149494
#ifndef SQLITE_OMIT_SUBQUERY
149150
- Select *pSel = pFrom->pSelect;
149495
+ Select *pSel;
149496
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 );
149497
+ pSel = pFrom->u4.pSubq->pSelect;
149151149498
/* A sub-query in the FROM clause of a SELECT */
149152149499
assert( pSel!=0 );
149153
- assert( pFrom->pTab==0 );
149500
+ assert( pFrom->pSTab==0 );
149154149501
if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
149155149502
if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
149156149503
#endif
149157149504
#ifndef SQLITE_OMIT_CTE
149158149505
}else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){
149159149506
if( rc>1 ) return WRC_Abort;
149160
- pTab = pFrom->pTab;
149507
+ pTab = pFrom->pSTab;
149161149508
assert( pTab!=0 );
149162149509
#endif
149163149510
}else{
149164149511
/* An ordinary table or view name in the FROM clause */
149165
- assert( pFrom->pTab==0 );
149166
- pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
149512
+ assert( pFrom->pSTab==0 );
149513
+ pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
149167149514
if( pTab==0 ) return WRC_Abort;
149168149515
if( pTab->nTabRef>=0xffff ){
149169149516
sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
149170149517
pTab->zName);
149171
- pFrom->pTab = 0;
149518
+ pFrom->pSTab = 0;
149172149519
return WRC_Abort;
149173149520
}
149174149521
pTab->nTabRef++;
149175149522
if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
149176149523
return WRC_Abort;
@@ -149178,19 +149525,19 @@
149178149525
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
149179149526
if( !IsOrdinaryTable(pTab) ){
149180149527
i16 nCol;
149181149528
u8 eCodeOrig = pWalker->eCode;
149182149529
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
149183
- assert( pFrom->pSelect==0 );
149530
+ assert( pFrom->fg.isSubquery==0 );
149184149531
if( IsView(pTab) ){
149185149532
if( (db->flags & SQLITE_EnableView)==0
149186149533
&& pTab->pSchema!=db->aDb[1].pSchema
149187149534
){
149188149535
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
149189149536
pTab->zName);
149190149537
}
149191
- pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);
149538
+ sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1);
149192149539
}
149193149540
#ifndef SQLITE_OMIT_VIRTUALTABLE
149194149541
else if( ALWAYS(IsVirtual(pTab))
149195149542
&& pFrom->fg.fromDDL
149196149543
&& ALWAYS(pTab->u.vtab.p!=0)
@@ -149202,11 +149549,13 @@
149202149549
assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 );
149203149550
#endif
149204149551
nCol = pTab->nCol;
149205149552
pTab->nCol = -1;
149206149553
pWalker->eCode = 1; /* Turn on Select.selId renumbering */
149207
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
149554
+ if( pFrom->fg.isSubquery ){
149555
+ sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect);
149556
+ }
149208149557
pWalker->eCode = eCodeOrig;
149209149558
pTab->nCol = nCol;
149210149559
}
149211149560
#endif
149212149561
}
@@ -149289,11 +149638,11 @@
149289149638
assert( ExprUseWOfst(pE) );
149290149639
iErrOfst = pE->w.iOfst;
149291149640
}
149292149641
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149293149642
int nAdd; /* Number of cols including rowid */
149294
- Table *pTab = pFrom->pTab; /* Table for this data source */
149643
+ Table *pTab = pFrom->pSTab; /* Table for this data source */
149295149644
ExprList *pNestedFrom; /* Result-set of a nested FROM clause */
149296149645
char *zTabName; /* AS name for this data source */
149297149646
const char *zSchemaName = 0; /* Schema name for this data source */
149298149647
int iDb; /* Schema index for this data src */
149299149648
IdList *pUsing; /* USING clause for pFrom[1] */
@@ -149300,14 +149649,15 @@
149300149649
149301149650
if( (zTabName = pFrom->zAlias)==0 ){
149302149651
zTabName = pTab->zName;
149303149652
}
149304149653
if( db->mallocFailed ) break;
149305
- assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
149654
+ assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) );
149306149655
if( pFrom->fg.isNestedFrom ){
149307
- assert( pFrom->pSelect!=0 );
149308
- pNestedFrom = pFrom->pSelect->pEList;
149656
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
149657
+ assert( pFrom->u4.pSubq->pSelect!=0 );
149658
+ pNestedFrom = pFrom->u4.pSubq->pSelect->pEList;
149309149659
assert( pNestedFrom!=0 );
149310149660
assert( pNestedFrom->nExpr==pTab->nCol );
149311149661
assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
149312149662
}else{
149313149663
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
@@ -149542,18 +149892,16 @@
149542149892
p->selFlags |= SF_HasTypeInfo;
149543149893
pParse = pWalker->pParse;
149544149894
assert( (p->selFlags & SF_Resolved) );
149545149895
pTabList = p->pSrc;
149546149896
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149547
- Table *pTab = pFrom->pTab;
149897
+ Table *pTab = pFrom->pSTab;
149548149898
assert( pTab!=0 );
149549
- if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
149899
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){
149550149900
/* A sub-query in the FROM clause of a SELECT */
149551
- Select *pSel = pFrom->pSelect;
149552
- if( pSel ){
149553
- sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
149554
- }
149901
+ Select *pSel = pFrom->u4.pSubq->pSelect;
149902
+ sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
149555149903
}
149556149904
}
149557149905
}
149558149906
#endif
149559149907
@@ -149863,10 +150211,11 @@
149863150211
int i;
149864150212
struct AggInfo_func *pF;
149865150213
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
149866150214
ExprList *pList;
149867150215
assert( ExprUseXList(pF->pFExpr) );
150216
+ if( pParse->nErr ) return;
149868150217
pList = pF->pFExpr->x.pList;
149869150218
if( pF->iOBTab>=0 ){
149870150219
/* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
149871150220
** were stored in emphermal table pF->iOBTab. Here, we extract those
149872150221
** inputs (in ORDER BY order) and make all calls to OP_AggStep
@@ -150072,19 +150421,21 @@
150072150421
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
150073150422
}
150074150423
if( addrNext ){
150075150424
sqlite3VdbeResolveLabel(v, addrNext);
150076150425
}
150426
+ if( pParse->nErr ) return;
150077150427
}
150078150428
if( regHit==0 && pAggInfo->nAccumulator ){
150079150429
regHit = regAcc;
150080150430
}
150081150431
if( regHit ){
150082150432
addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
150083150433
}
150084150434
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
150085150435
sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i));
150436
+ if( pParse->nErr ) return;
150086150437
}
150087150438
150088150439
pAggInfo->directMode = 0;
150089150440
if( addrHitTest ){
150090150441
sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
@@ -150196,29 +150547,32 @@
150196150547
SrcList *pTabList, /* Search for self-joins in this FROM clause */
150197150548
SrcItem *pThis, /* Search for prior reference to this subquery */
150198150549
int iFirst, int iEnd /* Range of FROM-clause entries to search. */
150199150550
){
150200150551
SrcItem *pItem;
150201
- assert( pThis->pSelect!=0 );
150202
- if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
150552
+ Select *pSel;
150553
+ assert( pThis->fg.isSubquery );
150554
+ pSel = pThis->u4.pSubq->pSelect;
150555
+ assert( pSel!=0 );
150556
+ if( pSel->selFlags & SF_PushDown ) return 0;
150203150557
while( iFirst<iEnd ){
150204150558
Select *pS1;
150205150559
pItem = &pTabList->a[iFirst++];
150206
- if( pItem->pSelect==0 ) continue;
150560
+ if( !pItem->fg.isSubquery ) continue;
150207150561
if( pItem->fg.viaCoroutine ) continue;
150208150562
if( pItem->zName==0 ) continue;
150209
- assert( pItem->pTab!=0 );
150210
- assert( pThis->pTab!=0 );
150211
- if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
150563
+ assert( pItem->pSTab!=0 );
150564
+ assert( pThis->pSTab!=0 );
150565
+ if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue;
150212150566
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
150213
- pS1 = pItem->pSelect;
150214
- if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
150567
+ pS1 = pItem->u4.pSubq->pSelect;
150568
+ if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){
150215150569
/* The query flattener left two different CTE tables with identical
150216150570
** names in the same FROM clause. */
150217150571
continue;
150218150572
}
150219
- if( pItem->pSelect->selFlags & SF_PushDown ){
150573
+ if( pS1->selFlags & SF_PushDown ){
150220150574
/* The view was modified by some other optimization such as
150221150575
** pushDownWhereTerms() */
150222150576
continue;
150223150577
}
150224150578
return pItem;
@@ -150258,10 +150612,11 @@
150258150612
static int countOfViewOptimization(Parse *pParse, Select *p){
150259150613
Select *pSub, *pPrior;
150260150614
Expr *pExpr;
150261150615
Expr *pCount;
150262150616
sqlite3 *db;
150617
+ SrcItem *pFrom;
150263150618
if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
150264150619
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
150265150620
if( p->pWhere ) return 0;
150266150621
if( p->pHaving ) return 0;
150267150622
if( p->pGroupBy ) return 0;
@@ -150272,30 +150627,30 @@
150272150627
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
150273150628
assert( ExprUseXList(pExpr) );
150274150629
if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
150275150630
if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
150276150631
if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
150277
- pSub = p->pSrc->a[0].pSelect;
150278
- if( pSub==0 ) return 0; /* The FROM is a subquery */
150632
+ pFrom = p->pSrc->a;
150633
+ if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */
150634
+ pSub = pFrom->u4.pSubq->pSelect;
150279150635
if( pSub->pPrior==0 ) return 0; /* Must be a compound */
150280150636
if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */
150281150637
do{
150282150638
if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
150283150639
if( pSub->pWhere ) return 0; /* No WHERE clause */
150284150640
if( pSub->pLimit ) return 0; /* No LIMIT clause */
150285150641
if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
150286150642
assert( pSub->pHaving==0 ); /* Due to the previous */
150287
- pSub = pSub->pPrior; /* Repeat over compound */
150643
+ pSub = pSub->pPrior; /* Repeat over compound */
150288150644
}while( pSub );
150289150645
150290150646
/* If we reach this point then it is OK to perform the transformation */
150291150647
150292150648
db = pParse->db;
150293150649
pCount = pExpr;
150294150650
pExpr = 0;
150295
- pSub = p->pSrc->a[0].pSelect;
150296
- p->pSrc->a[0].pSelect = 0;
150651
+ pSub = sqlite3SubqueryDetach(db, pFrom);
150297150652
sqlite3SrcListDelete(db, p->pSrc);
150298150653
p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
150299150654
while( pSub ){
150300150655
Expr *pTerm;
150301150656
pPrior = pSub->pPrior;
@@ -150336,16 +150691,16 @@
150336150691
static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
150337150692
int i;
150338150693
for(i=0; i<pSrc->nSrc; i++){
150339150694
SrcItem *p1 = &pSrc->a[i];
150340150695
if( p1==p0 ) continue;
150341
- if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
150696
+ if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
150342150697
return 1;
150343150698
}
150344
- if( p1->pSelect
150345
- && (p1->pSelect->selFlags & SF_NestedFrom)!=0
150346
- && sameSrcAlias(p0, p1->pSelect->pSrc)
150699
+ if( p1->fg.isSubquery
150700
+ && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0
150701
+ && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc)
150347150702
){
150348150703
return 1;
150349150704
}
150350150705
}
150351150706
return 0;
@@ -150406,17 +150761,17 @@
150406150761
while( 1 /*exit-by-break*/ ){
150407150762
if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */
150408150763
if( i==0 ) break;
150409150764
i--;
150410150765
pItem--;
150411
- if( pItem->pSelect!=0 ) return 0; /* (1c-i) */
150766
+ if( pItem->fg.isSubquery ) return 0; /* (1c-i) */
150412150767
}
150413150768
return 1;
150414150769
}
150415150770
150416150771
/*
150417
-** Generate code for the SELECT statement given in the p argument.
150772
+** Generate byte-code for the SELECT statement given in the p argument.
150418150773
**
150419150774
** The results are returned according to the SelectDest structure.
150420150775
** See comments in sqliteInt.h for further information.
150421150776
**
150422150777
** This routine returns the number of errors. If any errors are
@@ -150423,10 +150778,44 @@
150423150778
** encountered, then an appropriate error message is left in
150424150779
** pParse->zErrMsg.
150425150780
**
150426150781
** This routine does NOT free the Select structure passed in. The
150427150782
** calling function needs to do that.
150783
+**
150784
+** This is a long function. The following is an outline of the processing
150785
+** steps, with tags referencing various milestones:
150786
+**
150787
+** * Resolve names and similar preparation tag-select-0100
150788
+** * Scan of the FROM clause tag-select-0200
150789
+** + OUTER JOIN strength reduction tag-select-0220
150790
+** + Sub-query ORDER BY removal tag-select-0230
150791
+** + Query flattening tag-select-0240
150792
+** * Separate subroutine for compound-SELECT tag-select-0300
150793
+** * WHERE-clause constant propagation tag-select-0330
150794
+** * Count()-of-VIEW optimization tag-select-0350
150795
+** * Scan of the FROM clause again tag-select-0400
150796
+** + Authorize unreferenced tables tag-select-0410
150797
+** + Predicate push-down optimization tag-select-0420
150798
+** + Omit unused subquery columns optimization tag-select-0440
150799
+** + Generate code to implement subqueries tag-select-0480
150800
+** - Co-routines tag-select-0482
150801
+** - Reuse previously computed CTE tag-select-0484
150802
+** - REuse previously computed VIEW tag-select-0486
150803
+** - Materialize a VIEW or CTE tag-select-0488
150804
+** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500
150805
+** * Set up for ORDER BY tag-select-0600
150806
+** * Create output table tag-select-0630
150807
+** * Prepare registers for LIMIT tag-select-0650
150808
+** * Setup for DISTINCT tag-select-0680
150809
+** * Generate code for non-aggregate and non-GROUP BY tag-select-0700
150810
+** * Generate code for aggregate and/or GROUP BY tag-select-0800
150811
+** + GROUP BY queries tag-select-0810
150812
+** + non-GROUP BY queries tag-select-0820
150813
+** - Special case of count() w/o GROUP BY tag-select-0821
150814
+** - General case of non-GROUP BY aggregates tag-select-0822
150815
+** * Sort results, as needed tag-select-0900
150816
+** * Internal self-checks tag-select-1000
150428150817
*/
150429150818
SQLITE_PRIVATE int sqlite3Select(
150430150819
Parse *pParse, /* The parser context */
150431150820
Select *p, /* The SELECT statement being coded. */
150432150821
SelectDest *pDest /* What to do with the query results */
@@ -150466,10 +150855,11 @@
150466150855
}
150467150856
sqlite3ShowSelect(p);
150468150857
}
150469150858
#endif
150470150859
150860
+ /* tag-select-0100 */
150471150861
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
150472150862
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
150473150863
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
150474150864
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
150475150865
if( IgnorableDistinct(pDest) ){
@@ -150517,11 +150907,11 @@
150517150907
if( p->selFlags & SF_UFSrcCheck ){
150518150908
SrcItem *p0 = &p->pSrc->a[0];
150519150909
if( sameSrcAlias(p0, p->pSrc) ){
150520150910
sqlite3ErrorMsg(pParse,
150521150911
"target object/alias may not appear in FROM clause: %s",
150522
- p0->zAlias ? p0->zAlias : p0->pTab->zName
150912
+ p0->zAlias ? p0->zAlias : p0->pSTab->zName
150523150913
);
150524150914
goto select_end;
150525150915
}
150526150916
150527150917
/* Clear the SF_UFSrcCheck flag. The check has already been performed,
@@ -150552,16 +150942,17 @@
150552150942
memset(&sSort, 0, sizeof(sSort));
150553150943
sSort.pOrderBy = p->pOrderBy;
150554150944
150555150945
/* Try to do various optimizations (flattening subqueries, and strength
150556150946
** reduction of join operators) in the FROM clause up into the main query
150947
+ ** tag-select-0200
150557150948
*/
150558150949
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150559150950
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
150560150951
SrcItem *pItem = &pTabList->a[i];
150561
- Select *pSub = pItem->pSelect;
150562
- Table *pTab = pItem->pTab;
150952
+ Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0;
150953
+ Table *pTab = pItem->pSTab;
150563150954
150564150955
/* The expander should have already created transient Table objects
150565150956
** even for FROM clause elements such as subqueries that do not correspond
150566150957
** to a real table */
150567150958
assert( pTab!=0 );
@@ -150574,10 +150965,11 @@
150574150965
**
150575150966
** If terms of the i-th table are used in the WHERE clause in such a
150576150967
** way that the i-th table cannot be the NULL row of a join, then
150577150968
** perform the appropriate simplification. This is called
150578150969
** "OUTER JOIN strength reduction" in the SQLite documentation.
150970
+ ** tag-select-0220
150579150971
*/
150580150972
if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
150581150973
&& sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor,
150582150974
pItem->fg.jointype & JT_LTORJ)
150583150975
&& OptimizationEnabled(db, SQLITE_SimplifyJoin)
@@ -150644,11 +151036,12 @@
150644151036
** flattening in that case.
150645151037
*/
150646151038
if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
150647151039
assert( pSub->pGroupBy==0 );
150648151040
150649
- /* If a FROM-clause subquery has an ORDER BY clause that is not
151041
+ /* tag-select-0230:
151042
+ ** If a FROM-clause subquery has an ORDER BY clause that is not
150650151043
** really doing anything, then delete it now so that it does not
150651151044
** interfere with query flattening. See the discussion at
150652151045
** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a
150653151046
**
150654151047
** Beware of these cases where the ORDER BY clause may not be safely
@@ -150710,10 +151103,11 @@
150710151103
|| (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
150711151104
){
150712151105
continue;
150713151106
}
150714151107
151108
+ /* tag-select-0240 */
150715151109
if( flattenSubquery(pParse, p, i, isAgg) ){
150716151110
if( pParse->nErr ) goto select_end;
150717151111
/* This subquery can be absorbed into its parent. */
150718151112
i = -1;
150719151113
}
@@ -150725,11 +151119,11 @@
150725151119
}
150726151120
#endif
150727151121
150728151122
#ifndef SQLITE_OMIT_COMPOUND_SELECT
150729151123
/* Handle compound SELECT statements using the separate multiSelect()
150730
- ** procedure.
151124
+ ** procedure. tag-select-0300
150731151125
*/
150732151126
if( p->pPrior ){
150733151127
rc = multiSelect(pParse, p, pDest);
150734151128
#if TREETRACE_ENABLED
150735151129
TREETRACE(0x400,pParse,p,("end compound-select processing\n"));
@@ -150741,13 +151135,13 @@
150741151135
return rc;
150742151136
}
150743151137
#endif
150744151138
150745151139
/* Do the WHERE-clause constant propagation optimization if this is
150746
- ** a join. No need to speed time on this operation for non-join queries
151140
+ ** a join. No need to spend time on this operation for non-join queries
150747151141
** as the equivalent optimization will be handled by query planner in
150748
- ** sqlite3WhereBegin().
151142
+ ** sqlite3WhereBegin(). tag-select-0330
150749151143
*/
150750151144
if( p->pWhere!=0
150751151145
&& p->pWhere->op==TK_AND
150752151146
&& OptimizationEnabled(db, SQLITE_PropagateConst)
150753151147
&& propagateConstants(pParse, p)
@@ -150760,31 +151154,38 @@
150760151154
#endif
150761151155
}else{
150762151156
TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n"));
150763151157
}
150764151158
151159
+ /* tag-select-0350 */
150765151160
if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
150766151161
&& countOfViewOptimization(pParse, p)
150767151162
){
150768151163
if( db->mallocFailed ) goto select_end;
150769151164
pTabList = p->pSrc;
150770151165
}
150771151166
150772
- /* For each term in the FROM clause, do two things:
150773
- ** (1) Authorized unreferenced tables
150774
- ** (2) Generate code for all sub-queries
151167
+ /* Loop over all terms in the FROM clause and do two things for each term:
151168
+ **
151169
+ ** (1) Authorize unreferenced tables
151170
+ ** (2) Generate code for all sub-queries
151171
+ **
151172
+ ** tag-select-0400
150775151173
*/
150776151174
for(i=0; i<pTabList->nSrc; i++){
150777151175
SrcItem *pItem = &pTabList->a[i];
150778151176
SrcItem *pPrior;
150779151177
SelectDest dest;
151178
+ Subquery *pSubq;
150780151179
Select *pSub;
150781151180
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150782151181
const char *zSavedAuthContext;
150783151182
#endif
150784151183
150785
- /* Issue SQLITE_READ authorizations with a fake column name for any
151184
+ /* Authorized unreferenced tables. tag-select-0410
151185
+ **
151186
+ ** Issue SQLITE_READ authorizations with a fake column name for any
150786151187
** tables that are referenced but from which no values are extracted.
150787151188
** Examples of where these kinds of null SQLITE_READ authorizations
150788151189
** would occur:
150789151190
**
150790151191
** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
@@ -150797,21 +151198,32 @@
150797151198
** which would be unambiguous. But legacy authorization callbacks might
150798151199
** assume the column name is non-NULL and segfault. The use of an empty
150799151200
** string for the fake column name seems safer.
150800151201
*/
150801151202
if( pItem->colUsed==0 && pItem->zName!=0 ){
150802
- sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
151203
+ const char *zDb;
151204
+ if( pItem->fg.fixedSchema ){
151205
+ int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema);
151206
+ zDb = db->aDb[iDb].zDbSName;
151207
+ }else if( pItem->fg.isSubquery ){
151208
+ zDb = 0;
151209
+ }else{
151210
+ zDb = pItem->u4.zDatabase;
151211
+ }
151212
+ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb);
150803151213
}
150804151214
150805151215
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150806151216
/* Generate code for all sub-queries in the FROM clause
150807151217
*/
150808
- pSub = pItem->pSelect;
150809
- if( pSub==0 || pItem->addrFillSub!=0 ) continue;
151218
+ if( pItem->fg.isSubquery==0 ) continue;
151219
+ pSubq = pItem->u4.pSubq;
151220
+ assert( pSubq!=0 );
151221
+ pSub = pSubq->pSelect;
150810151222
150811151223
/* The code for a subquery should only be generated once. */
150812
- assert( pItem->addrFillSub==0 );
151224
+ if( pSubq->addrFillSub!=0 ) continue;
150813151225
150814151226
/* Increment Parse.nHeight by the height of the largest expression
150815151227
** tree referred to by this, the parent select. The child select
150816151228
** may contain expression trees of at most
150817151229
** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
@@ -150820,10 +151232,11 @@
150820151232
*/
150821151233
pParse->nHeight += sqlite3SelectExprHeight(p);
150822151234
150823151235
/* Make copies of constant WHERE-clause terms in the outer query down
150824151236
** inside the subquery. This can help the subquery to run more efficiently.
151237
+ ** This is the "predicate push-down optimization". tag-select-0420
150825151238
*/
150826151239
if( OptimizationEnabled(db, SQLITE_PushDown)
150827151240
&& (pItem->fg.isCte==0
150828151241
|| (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
150829151242
&& pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i)
@@ -150833,17 +151246,18 @@
150833151246
TREETRACE(0x4000,pParse,p,
150834151247
("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
150835151248
sqlite3TreeViewSelect(0, p, 0);
150836151249
}
150837151250
#endif
150838
- assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
151251
+ assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
150839151252
}else{
150840151253
TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
150841151254
}
150842151255
150843151256
/* Convert unused result columns of the subquery into simple NULL
150844151257
** expressions, to avoid unneeded searching and computation.
151258
+ ** tag-select-0440
150845151259
*/
150846151260
if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
150847151261
&& disableUnusedSubqueryResultColumns(pItem)
150848151262
){
150849151263
#if TREETRACE_ENABLED
@@ -150857,64 +151271,70 @@
150857151271
}
150858151272
150859151273
zSavedAuthContext = pParse->zAuthContext;
150860151274
pParse->zAuthContext = pItem->zName;
150861151275
150862
- /* Generate code to implement the subquery
151276
+ /* Generate byte-code to implement the subquery tag-select-0480
150863151277
*/
150864151278
if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
150865151279
/* Implement a co-routine that will return a single row of the result
150866
- ** set on each invocation.
151280
+ ** set on each invocation. tag-select-0482
150867151281
*/
150868151282
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
150869151283
150870
- pItem->regReturn = ++pParse->nMem;
150871
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
151284
+ pSubq->regReturn = ++pParse->nMem;
151285
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop);
150872151286
VdbeComment((v, "%!S", pItem));
150873
- pItem->addrFillSub = addrTop;
150874
- sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
151287
+ pSubq->addrFillSub = addrTop;
151288
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
150875151289
ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
150876151290
sqlite3Select(pParse, pSub, &dest);
150877
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
151291
+ pItem->pSTab->nRowLogEst = pSub->nSelectRow;
150878151292
pItem->fg.viaCoroutine = 1;
150879
- pItem->regResult = dest.iSdst;
150880
- sqlite3VdbeEndCoroutine(v, pItem->regReturn);
151293
+ pSubq->regResult = dest.iSdst;
151294
+ sqlite3VdbeEndCoroutine(v, pSubq->regReturn);
151295
+ VdbeComment((v, "end %!S", pItem));
150881151296
sqlite3VdbeJumpHere(v, addrTop-1);
150882151297
sqlite3ClearTempRegCache(pParse);
150883151298
}else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
150884151299
/* This is a CTE for which materialization code has already been
150885151300
** generated. Invoke the subroutine to compute the materialization,
150886
- ** the make the pItem->iCursor be a copy of the ephemeral table that
150887
- ** holds the result of the materialization. */
151301
+ ** then make the pItem->iCursor be a copy of the ephemeral table that
151302
+ ** holds the result of the materialization. tag-select-0484 */
150888151303
CteUse *pCteUse = pItem->u2.pCteUse;
150889151304
sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
150890151305
if( pItem->iCursor!=pCteUse->iCur ){
150891151306
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);
150892151307
VdbeComment((v, "%!S", pItem));
150893151308
}
150894151309
pSub->nSelectRow = pCteUse->nRowEst;
150895151310
}else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
150896151311
/* This view has already been materialized by a prior entry in
150897
- ** this same FROM clause. Reuse it. */
150898
- if( pPrior->addrFillSub ){
150899
- sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);
151312
+ ** this same FROM clause. Reuse it. tag-select-0486 */
151313
+ Subquery *pPriorSubq;
151314
+ assert( pPrior->fg.isSubquery );
151315
+ pPriorSubq = pPrior->u4.pSubq;
151316
+ assert( pPriorSubq!=0 );
151317
+ if( pPriorSubq->addrFillSub ){
151318
+ sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn,
151319
+ pPriorSubq->addrFillSub);
150900151320
}
150901151321
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
150902
- pSub->nSelectRow = pPrior->pSelect->nSelectRow;
151322
+ pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow;
150903151323
}else{
150904151324
/* Materialize the view. If the view is not correlated, generate a
150905151325
** subroutine to do the materialization so that subsequent uses of
150906
- ** the same view can reuse the materialization. */
151326
+ ** the same view can reuse the materialization. tag-select-0488 */
150907151327
int topAddr;
150908151328
int onceAddr = 0;
150909151329
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
150910151330
int addrExplain;
150911151331
#endif
150912151332
150913
- pItem->regReturn = ++pParse->nMem;
151333
+ pSubq->regReturn = ++pParse->nMem;
150914151334
topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
150915
- pItem->addrFillSub = topAddr+1;
151335
+ pSubq->addrFillSub = topAddr+1;
150916151336
pItem->fg.isMaterialized = 1;
150917151337
if( pItem->fg.isCorrelated==0 ){
150918151338
/* If the subquery is not correlated and if we are not inside of
150919151339
** a trigger, then we only need to compute the value of the subquery
150920151340
** once. */
@@ -150925,21 +151345,21 @@
150925151345
}
150926151346
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
150927151347
150928151348
ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
150929151349
sqlite3Select(pParse, pSub, &dest);
150930
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
151350
+ pItem->pSTab->nRowLogEst = pSub->nSelectRow;
150931151351
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
150932
- sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
151352
+ sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1);
150933151353
VdbeComment((v, "end %!S", pItem));
150934151354
sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
150935151355
sqlite3VdbeJumpHere(v, topAddr);
150936151356
sqlite3ClearTempRegCache(pParse);
150937151357
if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
150938151358
CteUse *pCteUse = pItem->u2.pCteUse;
150939
- pCteUse->addrM9e = pItem->addrFillSub;
150940
- pCteUse->regRtn = pItem->regReturn;
151359
+ pCteUse->addrM9e = pSubq->addrFillSub;
151360
+ pCteUse->regRtn = pSubq->regReturn;
150941151361
pCteUse->iCur = pItem->iCursor;
150942151362
pCteUse->nRowEst = pSub->nSelectRow;
150943151363
}
150944151364
}
150945151365
if( db->mallocFailed ) goto select_end;
@@ -150961,11 +151381,13 @@
150961151381
TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n"));
150962151382
sqlite3TreeViewSelect(0, p, 0);
150963151383
}
150964151384
#endif
150965151385
150966
- /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
151386
+ /* tag-select-0500
151387
+ **
151388
+ ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and
150967151389
** if the select-list is the same as the ORDER BY list, then this query
150968151390
** can be rewritten as a GROUP BY. In other words, this:
150969151391
**
150970151392
** SELECT DISTINCT xyz FROM ... ORDER BY xyz
150971151393
**
@@ -151011,11 +151433,11 @@
151011151433
** do the sorting. But this sorting ephemeral index might end up
151012151434
** being unused if the data can be extracted in pre-sorted order.
151013151435
** If that is the case, then the OP_OpenEphemeral instruction will be
151014151436
** changed to an OP_Noop once we figure out that the sorting index is
151015151437
** not needed. The sSort.addrSortIndex variable is used to facilitate
151016
- ** that change.
151438
+ ** that change. tag-select-0600
151017151439
*/
151018151440
if( sSort.pOrderBy ){
151019151441
KeyInfo *pKeyInfo;
151020151442
pKeyInfo = sqlite3KeyInfoFromExprList(
151021151443
pParse, sSort.pOrderBy, 0, pEList->nExpr);
@@ -151028,10 +151450,11 @@
151028151450
}else{
151029151451
sSort.addrSortIndex = -1;
151030151452
}
151031151453
151032151454
/* If the output is destined for a temporary table, open that table.
151455
+ ** tag-select-0630
151033151456
*/
151034151457
if( pDest->eDest==SRT_EphemTab ){
151035151458
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
151036151459
if( p->selFlags & SF_NestedFrom ){
151037151460
/* Delete or NULL-out result columns that will never be used */
@@ -151045,11 +151468,11 @@
151045151468
if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
151046151469
}
151047151470
}
151048151471
}
151049151472
151050
- /* Set the limiter.
151473
+ /* Set the limiter. tag-select-0650
151051151474
*/
151052151475
iEnd = sqlite3VdbeMakeLabel(pParse);
151053151476
if( (p->selFlags & SF_FixedLimit)==0 ){
151054151477
p->nSelectRow = 320; /* 4 billion rows */
151055151478
}
@@ -151057,11 +151480,11 @@
151057151480
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
151058151481
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
151059151482
sSort.sortFlags |= SORTFLAG_UseSorter;
151060151483
}
151061151484
151062
- /* Open an ephemeral index to use for the distinct set.
151485
+ /* Open an ephemeral index to use for the distinct set. tag-select-0680
151063151486
*/
151064151487
if( p->selFlags & SF_Distinct ){
151065151488
sDistinct.tabTnct = pParse->nTab++;
151066151489
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
151067151490
sDistinct.tabTnct, 0, 0,
@@ -151072,11 +151495,11 @@
151072151495
}else{
151073151496
sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
151074151497
}
151075151498
151076151499
if( !isAgg && pGroupBy==0 ){
151077
- /* No aggregate functions and no GROUP BY clause */
151500
+ /* No aggregate functions and no GROUP BY clause. tag-select-0700 */
151078151501
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
151079151502
| (p->selFlags & SF_FixedLimit);
151080151503
#ifndef SQLITE_OMIT_WINDOWFUNC
151081151504
Window *pWin = p->pWin; /* Main window object (or NULL) */
151082151505
if( pWin ){
@@ -151145,12 +151568,12 @@
151145151568
*/
151146151569
TREETRACE(0x2,pParse,p,("WhereEnd\n"));
151147151570
sqlite3WhereEnd(pWInfo);
151148151571
}
151149151572
}else{
151150
- /* This case when there exist aggregate functions or a GROUP BY clause
151151
- ** or both */
151573
+ /* This case is for when there exist aggregate functions or a GROUP BY
151574
+ ** clause or both. tag-select-0800 */
151152151575
NameContext sNC; /* Name context for processing aggregate information */
151153151576
int iAMem; /* First Mem address for storing current GROUP BY */
151154151577
int iBMem; /* First Mem address for previous GROUP BY */
151155151578
int iUseFlag; /* Mem address holding flag indicating that at least
151156151579
** one row of the input to the aggregator has been
@@ -151265,11 +151688,11 @@
151265151688
}
151266151689
#endif
151267151690
151268151691
151269151692
/* Processing for aggregates with GROUP BY is very different and
151270
- ** much more complex than aggregates without a GROUP BY.
151693
+ ** much more complex than aggregates without a GROUP BY. tag-select-0810
151271151694
*/
151272151695
if( pGroupBy ){
151273151696
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
151274151697
int addr1; /* A-vs-B comparison jump */
151275151698
int addrOutputRow; /* Start of subroutine that outputs a result row */
@@ -151562,13 +151985,16 @@
151562151985
struct AggInfo_func *pF = &pAggInfo->aFunc[0];
151563151986
fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
151564151987
}
151565151988
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
151566151989
else {
151990
+ /* Aggregate functions without GROUP BY. tag-select-0820 */
151567151991
Table *pTab;
151568151992
if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
151569
- /* If isSimpleCount() returns a pointer to a Table structure, then
151993
+ /* tag-select-0821
151994
+ **
151995
+ ** If isSimpleCount() returns a pointer to a Table structure, then
151570151996
** the SQL statement is of the form:
151571151997
**
151572151998
** SELECT count(*) FROM <tbl>
151573151999
**
151574152000
** where the Table structure returned represents table <tbl>.
@@ -151623,10 +152049,12 @@
151623152049
assignAggregateRegisters(pParse, pAggInfo);
151624152050
sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0));
151625152051
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
151626152052
explainSimpleCount(pParse, pTab, pBest);
151627152053
}else{
152054
+ /* The general case of an aggregate query without GROUP BY
152055
+ ** tag-select-0822 */
151628152056
int regAcc = 0; /* "populate accumulators" flag */
151629152057
ExprList *pDistinct = 0;
151630152058
u16 distFlag = 0;
151631152059
int eDist;
151632152060
@@ -151711,11 +152139,11 @@
151711152139
if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
151712152140
explainTempTable(pParse, "DISTINCT");
151713152141
}
151714152142
151715152143
/* If there is an ORDER BY clause, then we need to sort the results
151716
- ** and send them to the callback one by one.
152144
+ ** and send them to the callback one by one. tag-select-0900
151717152145
*/
151718152146
if( sSort.pOrderBy ){
151719152147
assert( p->pEList==pEList );
151720152148
generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
151721152149
}
@@ -151734,10 +152162,11 @@
151734152162
select_end:
151735152163
assert( db->mallocFailed==0 || db->mallocFailed==1 );
151736152164
assert( db->mallocFailed==0 || pParse->nErr!=0 );
151737152165
sqlite3ExprListDelete(db, pMinMaxOrderBy);
151738152166
#ifdef SQLITE_DEBUG
152167
+ /* Internal self-checks. tag-select-1000 */
151739152168
if( pAggInfo && !db->mallocFailed ){
151740152169
#if TREETRACE_ENABLED
151741152170
if( sqlite3TreeTrace & 0x20 ){
151742152171
TREETRACE(0x20,pParse,p,("Finished with AggInfo\n"));
151743152172
printAggInfo(pAggInfo);
@@ -152123,12 +152552,14 @@
152123152552
**
152124152553
** To maintain backwards compatibility, ignore the database
152125152554
** name on pTableName if we are reparsing out of the schema table
152126152555
*/
152127152556
if( db->init.busy && iDb!=1 ){
152128
- sqlite3DbFree(db, pTableName->a[0].zDatabase);
152129
- pTableName->a[0].zDatabase = 0;
152557
+ assert( pTableName->a[0].fg.fixedSchema==0 );
152558
+ assert( pTableName->a[0].fg.isSubquery==0 );
152559
+ sqlite3DbFree(db, pTableName->a[0].u4.zDatabase);
152560
+ pTableName->a[0].u4.zDatabase = 0;
152130152561
}
152131152562
152132152563
/* If the trigger name was unqualified, and the table is a temp table,
152133152564
** then set iDb to 1 to create the trigger in the temporary database.
152134152565
** If sqlite3SrcListLookup() returns 0, indicating the table does not
@@ -152602,11 +153033,12 @@
152602153033
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
152603153034
goto drop_trigger_cleanup;
152604153035
}
152605153036
152606153037
assert( pName->nSrc==1 );
152607
- zDb = pName->a[0].zDatabase;
153038
+ assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 );
153039
+ zDb = pName->a[0].u4.zDatabase;
152608153040
zName = pName->a[0].zName;
152609153041
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
152610153042
for(i=OMIT_TEMPDB; i<db->nDb; i++){
152611153043
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
152612153044
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
@@ -152839,11 +153271,13 @@
152839153271
assert( zName || pSrc==0 );
152840153272
if( pSrc ){
152841153273
Schema *pSchema = pStep->pTrig->pSchema;
152842153274
pSrc->a[0].zName = zName;
152843153275
if( pSchema!=db->aDb[1].pSchema ){
152844
- pSrc->a[0].pSchema = pSchema;
153276
+ assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 );
153277
+ pSrc->a[0].u4.pSchema = pSchema;
153278
+ pSrc->a[0].fg.fixedSchema = 1;
152845153279
}
152846153280
if( pStep->pFrom ){
152847153281
SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
152848153282
if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
152849153283
Select *pSubquery;
@@ -152952,11 +153386,11 @@
152952153386
SrcList *pSrc;
152953153387
assert( pSelect!=0 );
152954153388
pSrc = pSelect->pSrc;
152955153389
assert( pSrc!=0 );
152956153390
for(i=0; i<pSrc->nSrc; i++){
152957
- if( pSrc->a[i].pTab==pWalker->u.pTab ){
153391
+ if( pSrc->a[i].pSTab==pWalker->u.pTab ){
152958153392
testcase( pSelect->selFlags & SF_Correlated );
152959153393
pSelect->selFlags |= SF_Correlated;
152960153394
pWalker->eCode = 1;
152961153395
break;
152962153396
}
@@ -153023,11 +153457,11 @@
153023153457
memset(&sSelect, 0, sizeof(sSelect));
153024153458
memset(&sFrom, 0, sizeof(sFrom));
153025153459
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
153026153460
sSelect.pSrc = &sFrom;
153027153461
sFrom.nSrc = 1;
153028
- sFrom.a[0].pTab = pTab;
153462
+ sFrom.a[0].pSTab = pTab;
153029153463
sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */
153030153464
sFrom.a[0].iCursor = -1;
153031153465
sqlite3SelectPrep(pParse, &sSelect, 0);
153032153466
if( pParse->nErr==0 ){
153033153467
assert( db->mallocFailed==0 );
@@ -153734,11 +154168,11 @@
153734154168
ExprList *pList = 0;
153735154169
ExprList *pGrp = 0;
153736154170
Expr *pLimit2 = 0;
153737154171
ExprList *pOrderBy2 = 0;
153738154172
sqlite3 *db = pParse->db;
153739
- Table *pTab = pTabList->a[0].pTab;
154173
+ Table *pTab = pTabList->a[0].pSTab;
153740154174
SrcList *pSrc;
153741154175
Expr *pWhere2;
153742154176
int eDest;
153743154177
153744154178
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -153758,12 +154192,12 @@
153758154192
153759154193
assert( pTabList->nSrc>1 );
153760154194
if( pSrc ){
153761154195
assert( pSrc->a[0].fg.notCte );
153762154196
pSrc->a[0].iCursor = -1;
153763
- pSrc->a[0].pTab->nTabRef--;
153764
- pSrc->a[0].pTab = 0;
154197
+ pSrc->a[0].pSTab->nTabRef--;
154198
+ pSrc->a[0].pSTab = 0;
153765154199
}
153766154200
if( pPk ){
153767154201
for(i=0; i<pPk->nKeyCol; i++){
153768154202
Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]);
153769154203
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -155007,11 +155441,11 @@
155007155441
NameContext sNC; /* Context for resolving symbolic names */
155008155442
Expr sCol[2]; /* Index column converted into an Expr */
155009155443
int nClause = 0; /* Counter of ON CONFLICT clauses */
155010155444
155011155445
assert( pTabList->nSrc==1 );
155012
- assert( pTabList->a[0].pTab!=0 );
155446
+ assert( pTabList->a[0].pSTab!=0 );
155013155447
assert( pUpsert!=0 );
155014155448
assert( pUpsert->pUpsertTarget!=0 );
155015155449
155016155450
/* Resolve all symbolic names in the conflict-target clause, which
155017155451
** includes both the list of columns and the optional partial-index
@@ -155026,11 +155460,11 @@
155026155460
if( rc ) return rc;
155027155461
rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
155028155462
if( rc ) return rc;
155029155463
155030155464
/* Check to see if the conflict target matches the rowid. */
155031
- pTab = pTabList->a[0].pTab;
155465
+ pTab = pTabList->a[0].pSTab;
155032155466
pTarget = pUpsert->pUpsertTarget;
155033155467
iCursor = pTabList->a[0].iCursor;
155034155468
if( HasRowid(pTab)
155035155469
&& pTarget->nExpr==1
155036155470
&& (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
@@ -157198,10 +157632,11 @@
157198157632
} btree;
157199157633
struct { /* Information for virtual tables */
157200157634
int idxNum; /* Index number */
157201157635
u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
157202157636
u32 bOmitOffset : 1; /* True to let virtual table handle offset */
157637
+ u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */
157203157638
i8 isOrdered; /* True if satisfies ORDER BY */
157204157639
u16 omitMask; /* Terms that may be omitted */
157205157640
char *idxStr; /* Index identifier string */
157206157641
u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
157207157642
} vtab;
@@ -157832,11 +158267,11 @@
157832158267
Index *pIdx;
157833158268
157834158269
assert( pLoop->u.btree.pIndex!=0 );
157835158270
pIdx = pLoop->u.btree.pIndex;
157836158271
assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
157837
- if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
158272
+ if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){
157838158273
if( isSearch ){
157839158274
zFmt = "PRIMARY KEY";
157840158275
}
157841158276
}else if( flags & WHERE_PARTIALIDX ){
157842158277
zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
@@ -157875,11 +158310,13 @@
157875158310
}
157876158311
sqlite3_str_appendf(&str, "%c?)", cRangeOp);
157877158312
}
157878158313
#ifndef SQLITE_OMIT_VIRTUALTABLE
157879158314
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
157880
- sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
158315
+ sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX ");
158316
+ sqlite3_str_appendf(&str,
158317
+ pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s",
157881158318
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
157882158319
}
157883158320
#endif
157884158321
if( pItem->fg.jointype & JT_LEFT ){
157885158322
sqlite3_str_appendf(&str, " LEFT-JOIN");
@@ -157929,11 +158366,11 @@
157929158366
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
157930158367
str.printfFlags = SQLITE_PRINTF_INTERNAL;
157931158368
sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
157932158369
pLoop = pLevel->pWLoop;
157933158370
if( pLoop->wsFlags & WHERE_IPK ){
157934
- const Table *pTab = pItem->pTab;
158371
+ const Table *pTab = pItem->pSTab;
157935158372
if( pTab->iPKey>=0 ){
157936158373
sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
157937158374
}else{
157938158375
sqlite3_str_appendf(&str, "rowid=?");
157939158376
}
@@ -157992,11 +158429,13 @@
157992158429
}
157993158430
if( wsFlags & WHERE_INDEXED ){
157994158431
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
157995158432
}
157996158433
}else{
157997
- int addr = pSrclist->a[pLvl->iFrom].addrFillSub;
158434
+ int addr;
158435
+ assert( pSrclist->a[pLvl->iFrom].fg.isSubquery );
158436
+ addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub;
157998158437
VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1);
157999158438
assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine );
158000158439
assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr );
158001158440
sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1);
158002158441
}
@@ -159129,11 +159568,12 @@
159129159568
pLoop = pLevel->pWLoop;
159130159569
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
159131159570
iCur = pTabItem->iCursor;
159132159571
pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
159133159572
bRev = (pWInfo->revMask>>iLevel)&1;
159134
- VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
159573
+ VdbeModuleComment((v, "Begin WHERE-loop%d: %s",
159574
+ iLevel, pTabItem->pSTab->zName));
159135159575
#if WHERETRACE_ENABLED /* 0x4001 */
159136159576
if( sqlite3WhereTrace & 0x1 ){
159137159577
sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n",
159138159578
iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom);
159139159579
if( sqlite3WhereTrace & 0x1000 ){
@@ -159184,15 +159624,19 @@
159184159624
}
159185159625
addrHalt = pWInfo->a[j].addrBrk;
159186159626
159187159627
/* Special case of a FROM clause subquery implemented as a co-routine */
159188159628
if( pTabItem->fg.viaCoroutine ){
159189
- int regYield = pTabItem->regReturn;
159190
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
159629
+ int regYield;
159630
+ Subquery *pSubq;
159631
+ assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 );
159632
+ pSubq = pTabItem->u4.pSubq;
159633
+ regYield = pSubq->regReturn;
159634
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
159191159635
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
159192159636
VdbeCoverage(v);
159193
- VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
159637
+ VdbeComment((v, "next row of %s", pTabItem->pSTab->zName));
159194159638
pLevel->op = OP_Goto;
159195159639
}else
159196159640
159197159641
#ifndef SQLITE_OMIT_VIRTUALTABLE
159198159642
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
@@ -159917,11 +160361,11 @@
159917160361
int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
159918160362
int iRetInit; /* Address of regReturn init */
159919160363
int untestedTerms = 0; /* Some terms not completely tested */
159920160364
int ii; /* Loop counter */
159921160365
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
159922
- Table *pTab = pTabItem->pTab;
160366
+ Table *pTab = pTabItem->pSTab;
159923160367
159924160368
pTerm = pLoop->aLTerm[0];
159925160369
assert( pTerm!=0 );
159926160370
assert( pTerm->eOperator & WO_OR );
159927160371
assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -160376,11 +160820,11 @@
160376160820
/* pTab is the right-hand table of the RIGHT JOIN. Generate code that
160377160821
** will record that the current row of that table has been matched at
160378160822
** least once. This is accomplished by storing the PK for the row in
160379160823
** both the iMatch index and the regBloom Bloom filter.
160380160824
*/
160381
- pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
160825
+ pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab;
160382160826
if( HasRowid(pTab) ){
160383160827
r = sqlite3GetTempRange(pParse, 2);
160384160828
sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
160385160829
nPk = 1;
160386160830
}else{
@@ -160483,23 +160927,27 @@
160483160927
SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
160484160928
SrcList sFrom;
160485160929
Bitmask mAll = 0;
160486160930
int k;
160487160931
160488
- ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
160932
+ ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
160489160933
sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
160490160934
pRJ->regReturn);
160491160935
for(k=0; k<iLevel; k++){
160492160936
int iIdxCur;
160493160937
SrcItem *pRight;
160494160938
assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom );
160495160939
pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom];
160496160940
mAll |= pWInfo->a[k].pWLoop->maskSelf;
160497160941
if( pRight->fg.viaCoroutine ){
160942
+ Subquery *pSubq;
160943
+ assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 );
160944
+ pSubq = pRight->u4.pSubq;
160945
+ assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 );
160498160946
sqlite3VdbeAddOp3(
160499
- v, OP_Null, 0, pRight->regResult,
160500
- pRight->regResult + pRight->pSelect->pEList->nExpr-1
160947
+ v, OP_Null, 0, pSubq->regResult,
160948
+ pSubq->regResult + pSubq->pSelect->pEList->nExpr-1
160501160949
);
160502160950
}
160503160951
sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
160504160952
iIdxCur = pWInfo->a[k].iIdxCur;
160505160953
if( iIdxCur ){
@@ -160533,11 +160981,11 @@
160533160981
int iCur = pLevel->iTabCur;
160534160982
int r = ++pParse->nMem;
160535160983
int nPk;
160536160984
int jmp;
160537160985
int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
160538
- Table *pTab = pTabItem->pTab;
160986
+ Table *pTab = pTabItem->pSTab;
160539160987
if( HasRowid(pTab) ){
160540160988
sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
160541160989
nPk = 1;
160542160990
}else{
160543160991
int iPk;
@@ -160785,15 +161233,24 @@
160785161233
assert( !ExprHasProperty(pRight, EP_IntValue) );
160786161234
z = (u8*)pRight->u.zToken;
160787161235
}
160788161236
if( z ){
160789161237
160790
- /* Count the number of prefix characters prior to the first wildcard */
161238
+ /* Count the number of prefix characters prior to the first wildcard.
161239
+ ** If the underlying database has a UTF16LE encoding, then only consider
161240
+ ** ASCII characters. Note that the encoding of z[] is UTF8 - we are
161241
+ ** dealing with only UTF8 here in this code, but the database engine
161242
+ ** itself might be processing content using a different encoding. */
160791161243
cnt = 0;
160792161244
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
160793161245
cnt++;
160794
- if( c==wc[3] && z[cnt]!=0 ) cnt++;
161246
+ if( c==wc[3] && z[cnt]!=0 ){
161247
+ cnt++;
161248
+ }else if( c>=0x80 && ENC(db)==SQLITE_UTF16LE ){
161249
+ cnt--;
161250
+ break;
161251
+ }
160795161252
}
160796161253
160797161254
/* The optimization is possible only if (1) the pattern does not begin
160798161255
** with a wildcard and if (2) the non-wildcard prefix does not end with
160799161256
** an (illegal 0xff) character, or (3) the pattern does not consist of
@@ -160804,11 +161261,11 @@
160804161261
** removed. */
160805161262
if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){
160806161263
Expr *pPrefix;
160807161264
160808161265
/* A "complete" match if the pattern ends with "*" or "%" */
160809
- *pisComplete = c==wc[0] && z[cnt+1]==0;
161266
+ *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE;
160810161267
160811161268
/* Get the pattern prefix. Remove all escapes from the prefix. */
160812161269
pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
160813161270
if( pPrefix ){
160814161271
int iFrom, iTo;
@@ -161523,11 +161980,13 @@
161523161980
mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere);
161524161981
mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
161525161982
if( ALWAYS(pSrc!=0) ){
161526161983
int i;
161527161984
for(i=0; i<pSrc->nSrc; i++){
161528
- mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
161985
+ if( pSrc->a[i].fg.isSubquery ){
161986
+ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect);
161987
+ }
161529161988
if( pSrc->a[i].fg.isUsing==0 ){
161530161989
mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
161531161990
}
161532161991
if( pSrc->a[i].fg.isTabFunc ){
161533161992
mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
@@ -161561,11 +162020,11 @@
161561162020
Index *pIdx;
161562162021
int i;
161563162022
int iCur;
161564162023
do{
161565162024
iCur = pFrom->a[j].iCursor;
161566
- for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
162025
+ for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
161567162026
if( pIdx->aColExpr==0 ) continue;
161568162027
for(i=0; i<pIdx->nKeyCol; i++){
161569162028
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
161570162029
assert( pIdx->bHasExpr );
161571162030
if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
@@ -161605,11 +162064,11 @@
161605162064
return 1;
161606162065
}
161607162066
161608162067
for(i=0; i<pFrom->nSrc; i++){
161609162068
Index *pIdx;
161610
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
162069
+ for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
161611162070
if( pIdx->aColExpr ){
161612162071
return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i);
161613162072
}
161614162073
}
161615162074
}
@@ -162193,11 +162652,11 @@
162193162652
*/
162194162653
SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
162195162654
assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */
162196162655
if( p->pGroupBy==0
162197162656
&& (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
162198
- && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
162657
+ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */
162199162658
){
162200162659
ExprList *pOrderBy = p->pOrderBy;
162201162660
int iCsr = p->pSrc->a[0].iCursor;
162202162661
int ii;
162203162662
@@ -162414,11 +162873,11 @@
162414162873
int j, k;
162415162874
ExprList *pArgs;
162416162875
Expr *pColRef;
162417162876
Expr *pTerm;
162418162877
if( pItem->fg.isTabFunc==0 ) return;
162419
- pTab = pItem->pTab;
162878
+ pTab = pItem->pSTab;
162420162879
assert( pTab!=0 );
162421162880
pArgs = pItem->u1.pFuncArg;
162422162881
if( pArgs==0 ) return;
162423162882
for(j=k=0; j<pArgs->nExpr; j++){
162424162883
Expr *pRhs;
@@ -163098,11 +163557,11 @@
163098163557
/* If there is more than one table or sub-select in the FROM clause of
163099163558
** this query, then it will not be possible to show that the DISTINCT
163100163559
** clause is redundant. */
163101163560
if( pTabList->nSrc!=1 ) return 0;
163102163561
iBase = pTabList->a[0].iCursor;
163103
- pTab = pTabList->a[0].pTab;
163562
+ pTab = pTabList->a[0].pSTab;
163104163563
163105163564
/* If any of the expressions is an IPK column on table iBase, then return
163106163565
** true. Note: The (p->iTable==iBase) part of this test may be false if the
163107163566
** current SELECT is a correlated sub-query.
163108163567
*/
@@ -163362,14 +163821,14 @@
163362163821
}
163363163822
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
163364163823
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
163365163824
leftCol = pTerm->u.x.leftColumn;
163366163825
if( leftCol<0 ) return 0;
163367
- aff = pSrc->pTab->aCol[leftCol].affinity;
163826
+ aff = pSrc->pSTab->aCol[leftCol].affinity;
163368163827
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
163369163828
testcase( pTerm->pExpr->op==TK_IS );
163370
- return columnIsGoodIndexCandidate(pSrc->pTab, leftCol);
163829
+ return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol);
163371163830
}
163372163831
#endif
163373163832
163374163833
163375163834
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -163473,11 +163932,11 @@
163473163932
/* Count the number of columns that will be added to the index
163474163933
** and used to match WHERE clause constraints */
163475163934
nKeyCol = 0;
163476163935
pTabList = pWC->pWInfo->pTabList;
163477163936
pSrc = &pTabList->a[pLevel->iFrom];
163478
- pTable = pSrc->pTab;
163937
+ pTable = pSrc->pSTab;
163479163938
pWCEnd = &pWC->a[pWC->nTerm];
163480163939
pLoop = pLevel->pWLoop;
163481163940
idxCols = 0;
163482163941
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
163483163942
Expr *pExpr = pTerm->pExpr;
@@ -163615,16 +164074,21 @@
163615164074
}
163616164075
163617164076
/* Fill the automatic index with content */
163618164077
assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] );
163619164078
if( pSrc->fg.viaCoroutine ){
163620
- int regYield = pSrc->regReturn;
164079
+ int regYield;
164080
+ Subquery *pSubq;
164081
+ assert( pSrc->fg.isSubquery );
164082
+ pSubq = pSrc->u4.pSubq;
164083
+ assert( pSubq!=0 );
164084
+ regYield = pSubq->regReturn;
163621164085
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
163622
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub);
164086
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
163623164087
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
163624164088
VdbeCoverage(v);
163625
- VdbeComment((v, "next row of %s", pSrc->pTab->zName));
164089
+ VdbeComment((v, "next row of %s", pSrc->pSTab->zName));
163626164090
}else{
163627164091
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
163628164092
}
163629164093
if( pPartial ){
163630164094
iContinue = sqlite3VdbeMakeLabel(pParse);
@@ -163642,15 +164106,16 @@
163642164106
sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v));
163643164107
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
163644164108
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
163645164109
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
163646164110
if( pSrc->fg.viaCoroutine ){
164111
+ assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 );
163647164112
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
163648164113
testcase( pParse->db->mallocFailed );
163649164114
assert( pLevel->iIdxCur>0 );
163650164115
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
163651
- pSrc->regResult, pLevel->iIdxCur);
164116
+ pSrc->u4.pSubq->regResult, pLevel->iIdxCur);
163652164117
sqlite3VdbeGoto(v, addrTop);
163653164118
pSrc->fg.viaCoroutine = 0;
163654164119
}else{
163655164120
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
163656164121
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
@@ -163737,11 +164202,11 @@
163737164202
*/
163738164203
pTabList = pWInfo->pTabList;
163739164204
iSrc = pLevel->iFrom;
163740164205
pItem = &pTabList->a[iSrc];
163741164206
assert( pItem!=0 );
163742
- pTab = pItem->pTab;
164207
+ pTab = pItem->pSTab;
163743164208
assert( pTab!=0 );
163744164209
sz = sqlite3LogEstToInt(pTab->nRowLogEst);
163745164210
if( sz<10000 ){
163746164211
sz = 10000;
163747164212
}else if( sz>10000000 ){
@@ -163768,11 +164233,11 @@
163768164233
Index *pIdx = pLoop->u.btree.pIndex;
163769164234
int n = pLoop->u.btree.nEq;
163770164235
int r1 = sqlite3GetTempRange(pParse, n);
163771164236
int jj;
163772164237
for(jj=0; jj<n; jj++){
163773
- assert( pIdx->pTable==pItem->pTab );
164238
+ assert( pIdx->pTable==pItem->pSTab );
163774164239
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
163775164240
}
163776164241
sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
163777164242
sqlite3ReleaseTempRange(pParse, r1, n);
163778164243
}
@@ -163849,11 +164314,11 @@
163849164314
int eDistinct = 0;
163850164315
ExprList *pOrderBy = pWInfo->pOrderBy;
163851164316
WhereClause *p;
163852164317
163853164318
assert( pSrc!=0 );
163854
- pTab = pSrc->pTab;
164319
+ pTab = pSrc->pSTab;
163855164320
assert( pTab!=0 );
163856164321
assert( IsVirtual(pTab) );
163857164322
163858164323
/* Find all WHERE clause constraints referring to this virtual table.
163859164324
** Mark each term with the TERM_OK flag. Set nTerm to the number of
@@ -164857,11 +165322,11 @@
164857165322
SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
164858165323
if( pWC ){
164859165324
WhereInfo *pWInfo = pWC->pWInfo;
164860165325
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
164861165326
SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
164862
- Table *pTab = pItem->pTab;
165327
+ Table *pTab = pItem->pSTab;
164863165328
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
164864165329
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
164865165330
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
164866165331
sqlite3DebugPrintf(" %12s",
164867165332
pItem->zAlias ? pItem->zAlias : pTab->zName);
@@ -165845,19 +166310,19 @@
165845166310
** 1. The cost of doing one search-by-key to find the first matching
165846166311
** entry
165847166312
** 2. Stepping forward in the index pNew->nOut times to find all
165848166313
** additional matching entries.
165849166314
*/
165850
- assert( pSrc->pTab->szTabRow>0 );
166315
+ assert( pSrc->pSTab->szTabRow>0 );
165851166316
if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
165852166317
/* The pProbe->szIdxRow is low for an IPK table since the interior
165853166318
** pages are small. Thus szIdxRow gives a good estimate of seek cost.
165854166319
** But the leaf pages are full-size, so pProbe->szIdxRow would badly
165855166320
** under-estimate the scanning cost. */
165856166321
rCostIdx = pNew->nOut + 16;
165857166322
}else{
165858
- rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
166323
+ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow;
165859166324
}
165860166325
rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
165861166326
165862166327
/* Estimate the cost of running the loop. If all data is coming
165863166328
** from the index, then this is just the cost of doing the index
@@ -166318,13 +166783,13 @@
166318166783
166319166784
pNew = pBuilder->pNew;
166320166785
pWInfo = pBuilder->pWInfo;
166321166786
pTabList = pWInfo->pTabList;
166322166787
pSrc = pTabList->a + pNew->iTab;
166323
- pTab = pSrc->pTab;
166788
+ pTab = pSrc->pSTab;
166324166789
pWC = pBuilder->pWC;
166325
- assert( !IsVirtual(pSrc->pTab) );
166790
+ assert( !IsVirtual(pSrc->pSTab) );
166326166791
166327166792
if( pSrc->fg.isIndexedBy ){
166328166793
assert( pSrc->fg.isCte==0 );
166329166794
/* An INDEXED BY clause specifies a particular index to use */
166330166795
pProbe = pSrc->u2.pIBIndex;
@@ -166345,11 +166810,11 @@
166345166810
sPk.pTable = pTab;
166346166811
sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */
166347166812
sPk.idxType = SQLITE_IDXTYPE_IPK;
166348166813
aiRowEstPk[0] = pTab->nRowLogEst;
166349166814
aiRowEstPk[1] = 0;
166350
- pFirst = pSrc->pTab->pIndex;
166815
+ pFirst = pSrc->pSTab->pIndex;
166351166816
if( pSrc->fg.notIndexed==0 ){
166352166817
/* The real indices of the table are only considered if the
166353166818
** NOT INDEXED qualifier is omitted from the FROM clause */
166354166819
sPk.pNext = pFirst;
166355166820
}
@@ -166464,13 +166929,13 @@
166464166929
#else
166465166930
pNew->rRun = rSize + 16;
166466166931
#endif
166467166932
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
166468166933
whereLoopOutputAdjust(pWC, pNew, rSize);
166469
- if( pSrc->pSelect ){
166934
+ if( pSrc->fg.isSubquery ){
166470166935
if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE;
166471
- pNew->u.btree.pOrderBy = pSrc->pSelect->pOrderBy;
166936
+ pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy;
166472166937
}
166473166938
rc = whereLoopInsert(pBuilder, pNew);
166474166939
pNew->nOut = rSize;
166475166940
if( rc ) break;
166476166941
}else{
@@ -166692,11 +167157,11 @@
166692167157
pIdxInfo->estimatedRows = 25;
166693167158
pIdxInfo->idxFlags = 0;
166694167159
pHidden->mHandleIn = 0;
166695167160
166696167161
/* Invoke the virtual table xBestIndex() method */
166697
- rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
167162
+ rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo);
166698167163
if( rc ){
166699167164
if( rc==SQLITE_CONSTRAINT ){
166700167165
/* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
166701167166
** that the particular combination of parameters provided is unusable.
166702167167
** Make no entries in the loop table.
@@ -166722,11 +167187,11 @@
166722167187
|| j<0
166723167188
|| (pTerm = termFromWhereClause(pWC, j))==0
166724167189
|| pNew->aLTerm[iTerm]!=0
166725167190
|| pIdxCons->usable==0
166726167191
){
166727
- sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
167192
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
166728167193
freeIdxStr(pIdxInfo);
166729167194
return SQLITE_ERROR;
166730167195
}
166731167196
testcase( iTerm==nConstraint-1 );
166732167197
testcase( j==0 );
@@ -166785,11 +167250,11 @@
166785167250
pNew->nLTerm = mxTerm+1;
166786167251
for(i=0; i<=mxTerm; i++){
166787167252
if( pNew->aLTerm[i]==0 ){
166788167253
/* The non-zero argvIdx values must be contiguous. Raise an
166789167254
** error if they are not */
166790
- sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
167255
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
166791167256
freeIdxStr(pIdxInfo);
166792167257
return SQLITE_ERROR;
166793167258
}
166794167259
}
166795167260
assert( pNew->nLTerm<=pNew->nLSlot );
@@ -166797,10 +167262,11 @@
166797167262
pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
166798167263
pIdxInfo->needToFreeIdxStr = 0;
166799167264
pNew->u.vtab.idxStr = pIdxInfo->idxStr;
166800167265
pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
166801167266
pIdxInfo->nOrderBy : 0);
167267
+ pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0;
166802167268
pNew->rSetup = 0;
166803167269
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
166804167270
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
166805167271
166806167272
/* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
@@ -166987,11 +167453,11 @@
166987167453
pWInfo = pBuilder->pWInfo;
166988167454
pParse = pWInfo->pParse;
166989167455
pWC = pBuilder->pWC;
166990167456
pNew = pBuilder->pNew;
166991167457
pSrc = &pWInfo->pTabList->a[pNew->iTab];
166992
- assert( IsVirtual(pSrc->pTab) );
167458
+ assert( IsVirtual(pSrc->pSTab) );
166993167459
p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
166994167460
if( p==0 ) return SQLITE_NOMEM_BKPT;
166995167461
pNew->rSetup = 0;
166996167462
pNew->wsFlags = WHERE_VIRTUALTABLE;
166997167463
pNew->nLTerm = 0;
@@ -167001,11 +167467,11 @@
167001167467
freeIndexInfo(pParse->db, p);
167002167468
return SQLITE_NOMEM_BKPT;
167003167469
}
167004167470
167005167471
/* First call xBestIndex() with all constraints usable. */
167006
- WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
167472
+ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName));
167007167473
WHERETRACE(0x800, (" VirtualOne: all usable\n"));
167008167474
rc = whereLoopAddVirtualOne(
167009167475
pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
167010167476
);
167011167477
if( bRetry ){
@@ -167083,11 +167549,11 @@
167083167549
pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
167084167550
}
167085167551
}
167086167552
167087167553
freeIndexInfo(pParse->db, p);
167088
- WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
167554
+ WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc));
167089167555
return rc;
167090167556
}
167091167557
#endif /* SQLITE_OMIT_VIRTUALTABLE */
167092167558
167093167559
/*
@@ -167155,11 +167621,11 @@
167155167621
if( sqlite3WhereTrace & 0x20000 ){
167156167622
sqlite3WhereClausePrint(sSubBuild.pWC);
167157167623
}
167158167624
#endif
167159167625
#ifndef SQLITE_OMIT_VIRTUALTABLE
167160
- if( IsVirtual(pItem->pTab) ){
167626
+ if( IsVirtual(pItem->pSTab) ){
167161167627
rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
167162167628
}else
167163167629
#endif
167164167630
{
167165167631
rc = whereLoopAddBtree(&sSubBuild, mPrereq);
@@ -167269,11 +167735,11 @@
167269167735
bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
167270167736
}else if( !hasRightJoin ){
167271167737
mPrereq = 0;
167272167738
}
167273167739
#ifndef SQLITE_OMIT_VIRTUALTABLE
167274
- if( IsVirtual(pItem->pTab) ){
167740
+ if( IsVirtual(pItem->pSTab) ){
167275167741
SrcItem *p;
167276167742
for(p=&pItem[1]; p<pEnd; p++){
167277167743
if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
167278167744
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
167279167745
}
@@ -167905,11 +168371,11 @@
167905168371
rDelta = 15*(nDep-3);
167906168372
#ifdef WHERETRACE_ENABLED /* 0x4 */
167907168373
if( sqlite3WhereTrace&0x4 ){
167908168374
SrcItem *pItem = pWInfo->pTabList->a + iLoop;
167909168375
sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n",
167910
- pItem->zAlias ? pItem->zAlias : pItem->pTab->zName,
168376
+ pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName,
167911168377
nDep, rDelta);
167912168378
}
167913168379
#endif
167914168380
if( pWInfo->nOutStarDelta==0 ){
167915168381
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
@@ -168455,11 +168921,11 @@
168455168921
168456168922
pWInfo = pBuilder->pWInfo;
168457168923
if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
168458168924
assert( pWInfo->pTabList->nSrc>=1 );
168459168925
pItem = pWInfo->pTabList->a;
168460
- pTab = pItem->pTab;
168926
+ pTab = pItem->pSTab;
168461168927
if( IsVirtual(pTab) ) return 0;
168462168928
if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){
168463168929
testcase( pItem->fg.isIndexedBy );
168464168930
testcase( pItem->fg.notIndexed );
168465168931
return 0;
@@ -168718,11 +169184,11 @@
168718169184
assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
168719169185
for(i=0; i<pWInfo->nLevel; i++){
168720169186
WhereLoop *pLoop = pWInfo->a[i].pWLoop;
168721169187
const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
168722169188
SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
168723
- Table *pTab = pItem->pTab;
169189
+ Table *pTab = pItem->pSTab;
168724169190
if( (pTab->tabFlags & TF_HasStat1)==0 ) break;
168725169191
pTab->tabFlags |= TF_MaybeReanalyze;
168726169192
if( i>=1
168727169193
&& (pLoop->wsFlags & reqFlags)==reqFlags
168728169194
/* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
@@ -168875,12 +169341,12 @@
168875169341
int ii;
168876169342
for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){
168877169343
SrcItem *pItem = &pWInfo->pTabList->a[ii];
168878169344
if( !pItem->fg.isCte
168879169345
|| pItem->u2.pCteUse->eM10d!=M10d_Yes
168880
- || NEVER(pItem->pSelect==0)
168881
- || pItem->pSelect->pOrderBy==0
169346
+ || NEVER(pItem->fg.isSubquery==0)
169347
+ || pItem->u4.pSubq->pSelect->pOrderBy==0
168882169348
){
168883169349
pWInfo->revMask |= MASKBIT(ii);
168884169350
}
168885169351
}
168886169352
}
@@ -169366,19 +169832,19 @@
169366169832
*/
169367169833
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
169368169834
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
169369169835
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
169370169836
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
169371
- assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
169837
+ assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) );
169372169838
if( bOnerow || (
169373169839
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
169374
- && !IsVirtual(pTabList->a[0].pTab)
169840
+ && !IsVirtual(pTabList->a[0].pSTab)
169375169841
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
169376169842
&& OptimizationEnabled(db, SQLITE_OnePass)
169377169843
)){
169378169844
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
169379
- if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
169845
+ if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){
169380169846
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
169381169847
bFordelete = OPFLAG_FORDELETE;
169382169848
}
169383169849
pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
169384169850
}
@@ -169392,11 +169858,11 @@
169392169858
Table *pTab; /* Table to open */
169393169859
int iDb; /* Index of database containing table/index */
169394169860
SrcItem *pTabItem;
169395169861
169396169862
pTabItem = &pTabList->a[pLevel->iFrom];
169397
- pTab = pTabItem->pTab;
169863
+ pTab = pTabItem->pSTab;
169398169864
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
169399169865
pLoop = pLevel->pWLoop;
169400169866
if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
169401169867
/* Do nothing */
169402169868
}else
@@ -169463,11 +169929,11 @@
169463169929
/* This is one term of an OR-optimization using the PRIMARY KEY of a
169464169930
** WITHOUT ROWID table. No need for a separate index */
169465169931
iIndexCur = pLevel->iTabCur;
169466169932
op = 0;
169467169933
}else if( pWInfo->eOnePass!=ONEPASS_OFF ){
169468
- Index *pJ = pTabItem->pTab->pIndex;
169934
+ Index *pJ = pTabItem->pSTab->pIndex;
169469169935
iIndexCur = iAuxArg;
169470169936
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
169471169937
while( ALWAYS(pJ) && pJ!=pIx ){
169472169938
iIndexCur++;
169473169939
pJ = pJ->pNext;
@@ -169530,11 +169996,11 @@
169530169996
pRJ->iMatch = pParse->nTab++;
169531169997
pRJ->regBloom = ++pParse->nMem;
169532169998
sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
169533169999
pRJ->regReturn = ++pParse->nMem;
169534170000
sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
169535
- assert( pTab==pTabItem->pTab );
170001
+ assert( pTab==pTabItem->pSTab );
169536170002
if( HasRowid(pTab) ){
169537170003
KeyInfo *pInfo;
169538170004
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
169539170005
pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
169540170006
if( pInfo ){
@@ -169569,17 +170035,22 @@
169569170035
if( pParse->nErr ) goto whereBeginError;
169570170036
pLevel = &pWInfo->a[ii];
169571170037
wsFlags = pLevel->pWLoop->wsFlags;
169572170038
pSrc = &pTabList->a[pLevel->iFrom];
169573170039
if( pSrc->fg.isMaterialized ){
169574
- if( pSrc->fg.isCorrelated ){
169575
- sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
170040
+ Subquery *pSubq;
170041
+ int iOnce = 0;
170042
+ assert( pSrc->fg.isSubquery );
170043
+ pSubq = pSrc->u4.pSubq;
170044
+ if( pSrc->fg.isCorrelated==0 ){
170045
+ iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
169576170046
}else{
169577
- int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
169578
- sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
169579
- sqlite3VdbeJumpHere(v, iOnce);
170047
+ iOnce = 0;
169580170048
}
170049
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub);
170050
+ VdbeComment((v, "materialize %!S", pSrc));
170051
+ if( iOnce ) sqlite3VdbeJumpHere(v, iOnce);
169581170052
}
169582170053
assert( pTabList == pWInfo->pTabList );
169583170054
if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
169584170055
if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
169585170056
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -169788,13 +170259,14 @@
169788170259
if( (ws & WHERE_IDX_ONLY)==0 ){
169789170260
SrcItem *pSrc = &pTabList->a[pLevel->iFrom];
169790170261
assert( pLevel->iTabCur==pSrc->iCursor );
169791170262
if( pSrc->fg.viaCoroutine ){
169792170263
int m, n;
169793
- n = pSrc->regResult;
169794
- assert( pSrc->pTab!=0 );
169795
- m = pSrc->pTab->nCol;
170264
+ assert( pSrc->fg.isSubquery );
170265
+ n = pSrc->u4.pSubq->regResult;
170266
+ assert( pSrc->pSTab!=0 );
170267
+ m = pSrc->pSTab->nCol;
169796170268
sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1);
169797170269
}
169798170270
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
169799170271
}
169800170272
if( (ws & WHERE_INDEXED)
@@ -169814,20 +170286,20 @@
169814170286
sqlite3VdbeGoto(v, pLevel->addrFirst);
169815170287
}
169816170288
sqlite3VdbeJumpHere(v, addr);
169817170289
}
169818170290
VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
169819
- pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
170291
+ pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName));
169820170292
}
169821170293
169822170294
assert( pWInfo->nLevel<=pTabList->nSrc );
169823170295
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
169824170296
int k, last;
169825170297
VdbeOp *pOp, *pLastOp;
169826170298
Index *pIdx = 0;
169827170299
SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
169828
- Table *pTab = pTabItem->pTab;
170300
+ Table *pTab = pTabItem->pSTab;
169829170301
assert( pTab!=0 );
169830170302
pLoop = pLevel->pWLoop;
169831170303
169832170304
/* Do RIGHT JOIN processing. Generate code that will output the
169833170305
** unmatched rows of the right operand of the RIGHT JOIN with
@@ -169842,13 +170314,14 @@
169842170314
** the co-routine into OP_Copy of result contained in a register.
169843170315
** OP_Rowid becomes OP_Null.
169844170316
*/
169845170317
if( pTabItem->fg.viaCoroutine ){
169846170318
testcase( pParse->db->mallocFailed );
169847
- assert( pTabItem->regResult>=0 );
170319
+ assert( pTabItem->fg.isSubquery );
170320
+ assert( pTabItem->u4.pSubq->regResult>=0 );
169848170321
translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
169849
- pTabItem->regResult, 0);
170322
+ pTabItem->u4.pSubq->regResult, 0);
169850170323
continue;
169851170324
}
169852170325
169853170326
/* If this scan uses an index, make VDBE code substitutions to read data
169854170327
** from the index instead of from the table where possible. In some cases
@@ -171054,13 +171527,14 @@
171054171527
p->selId, p));
171055171528
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
171056171529
assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
171057171530
** of sqlite3DbMallocRawNN() called from
171058171531
** sqlite3SrcListAppend() */
171059
- if( p->pSrc ){
171532
+ if( p->pSrc==0 ){
171533
+ sqlite3SelectDelete(db, pSub);
171534
+ }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){
171060171535
Table *pTab2;
171061
- p->pSrc->a[0].pSelect = pSub;
171062171536
p->pSrc->a[0].fg.isCorrelated = 1;
171063171537
sqlite3SrcListAssignCursors(pParse, p->pSrc);
171064171538
pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
171065171539
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
171066171540
pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -171070,20 +171544,18 @@
171070171544
** the correct error message regardless. */
171071171545
rc = SQLITE_NOMEM;
171072171546
}else{
171073171547
memcpy(pTab, pTab2, sizeof(Table));
171074171548
pTab->tabFlags |= TF_Ephemeral;
171075
- p->pSrc->a[0].pTab = pTab;
171549
+ p->pSrc->a[0].pSTab = pTab;
171076171550
pTab = pTab2;
171077171551
memset(&w, 0, sizeof(w));
171078171552
w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
171079171553
w.xSelectCallback = sqlite3WalkerDepthIncrease;
171080171554
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
171081171555
sqlite3WalkSelect(&w, pSub);
171082171556
}
171083
- }else{
171084
- sqlite3SelectDelete(db, pSub);
171085171557
}
171086171558
if( db->mallocFailed ) rc = SQLITE_NOMEM;
171087171559
171088171560
/* Defer deleting the temporary table pTab because if an error occurred,
171089171561
** there could still be references to that table embedded in the
@@ -171366,14 +171838,19 @@
171366171838
** This is called by code in select.c before it calls sqlite3WhereBegin()
171367171839
** to begin iterating through the sub-query results. It is used to allocate
171368171840
** and initialize registers and cursors used by sqlite3WindowCodeStep().
171369171841
*/
171370171842
SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
171371
- int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
171372
- Window *pMWin = pSelect->pWin;
171373171843
Window *pWin;
171374
- Vdbe *v = sqlite3GetVdbe(pParse);
171844
+ int nEphExpr;
171845
+ Window *pMWin;
171846
+ Vdbe *v;
171847
+
171848
+ assert( pSelect->pSrc->a[0].fg.isSubquery );
171849
+ nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr;
171850
+ pMWin = pSelect->pWin;
171851
+ v = sqlite3GetVdbe(pParse);
171375171852
171376171853
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
171377171854
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
171378171855
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
171379171856
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
@@ -172766,11 +173243,11 @@
172766173243
Window *pMWin = p->pWin;
172767173244
ExprList *pOrderBy = pMWin->pOrderBy;
172768173245
Vdbe *v = sqlite3GetVdbe(pParse);
172769173246
int csrWrite; /* Cursor used to write to eph. table */
172770173247
int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
172771
- int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */
173248
+ int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */
172772173249
int iInput; /* To iterate through sub cols */
172773173250
int addrNe; /* Address of OP_Ne */
172774173251
int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
172775173252
int addrInteger = 0; /* Address of OP_Integer */
172776173253
int addrEmpty; /* Address of OP_Rewind in flush: */
@@ -177217,24 +177694,33 @@
177217177694
}else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
177218177695
yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
177219177696
if( yymsp[-5].minor.yy203 ){
177220177697
SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1];
177221177698
SrcItem *pOld = yymsp[-3].minor.yy203->a;
177699
+ assert( pOld->fg.fixedSchema==0 );
177222177700
pNew->zName = pOld->zName;
177223
- pNew->zDatabase = pOld->zDatabase;
177224
- pNew->pSelect = pOld->pSelect;
177225
- if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
177226
- pNew->fg.isNestedFrom = 1;
177701
+ assert( pOld->fg.fixedSchema==0 );
177702
+ if( pOld->fg.isSubquery ){
177703
+ pNew->fg.isSubquery = 1;
177704
+ pNew->u4.pSubq = pOld->u4.pSubq;
177705
+ pOld->u4.pSubq = 0;
177706
+ pOld->fg.isSubquery = 0;
177707
+ assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 );
177708
+ if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){
177709
+ pNew->fg.isNestedFrom = 1;
177710
+ }
177711
+ }else{
177712
+ pNew->u4.zDatabase = pOld->u4.zDatabase;
177713
+ pOld->u4.zDatabase = 0;
177227177714
}
177228177715
if( pOld->fg.isTabFunc ){
177229177716
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
177230177717
pOld->u1.pFuncArg = 0;
177231177718
pOld->fg.isTabFunc = 0;
177232177719
pNew->fg.isTabFunc = 1;
177233177720
}
177234
- pOld->zName = pOld->zDatabase = 0;
177235
- pOld->pSelect = 0;
177721
+ pOld->zName = 0;
177236177722
}
177237177723
sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203);
177238177724
}else{
177239177725
Select *pSubquery;
177240177726
sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
@@ -184790,10 +185276,22 @@
184790185276
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
184791185277
sqlite3 *db = va_arg(ap, sqlite3*);
184792185278
db->dbOptFlags = va_arg(ap, u32);
184793185279
break;
184794185280
}
185281
+
185282
+ /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N)
185283
+ **
185284
+ ** Write the current optimization settings into *N. A zero bit means that
185285
+ ** the optimization is on, and a 1 bit means that the optimization is off.
185286
+ */
185287
+ case SQLITE_TESTCTRL_GETOPT: {
185288
+ sqlite3 *db = va_arg(ap, sqlite3*);
185289
+ int *pN = va_arg(ap, int*);
185290
+ *pN = db->dbOptFlags;
185291
+ break;
185292
+ }
184795185293
184796185294
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
184797185295
**
184798185296
** If parameter onoff is 1, subsequent calls to localtime() fail.
184799185297
** If 2, then invoke xAlt() instead of localtime(). If 0, normal
@@ -224464,10 +224962,11 @@
224464224962
)
224465224963
){
224466224964
pIdxInfo->orderByConsumed = 1;
224467224965
pIdxInfo->idxNum |= 0x08;
224468224966
}
224967
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX;
224469224968
224470224969
return SQLITE_OK;
224471224970
}
224472224971
224473224972
/*
@@ -232374,13 +232873,36 @@
232374232873
** It is the output of the tokenizer module. For tokendata=1 tables, this
232375232874
** includes any embedded 0x00 and trailing data.
232376232875
**
232377232876
** This API can be quite slow if used with an FTS5 table created with the
232378232877
** "detail=none" or "detail=column" option.
232878
+**
232879
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
232880
+** If parameter iCol is less than zero, or greater than or equal to the
232881
+** number of columns in the table, SQLITE_RANGE is returned.
232882
+**
232883
+** Otherwise, this function attempts to retrieve the locale associated
232884
+** with column iCol of the current row. Usually, there is no associated
232885
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
232886
+** to NULL and 0, respectively. However, if the fts5_locale() function
232887
+** was used to associate a locale with the value when it was inserted
232888
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
232889
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
232890
+** is set to the size in bytes of the buffer, not including the
232891
+** nul-terminator.
232892
+**
232893
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
232894
+** SQLite error code is returned. The final value of the output parameters
232895
+** is undefined in this case.
232896
+**
232897
+** xTokenize_v2:
232898
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
232899
+** API is the same as the xTokenize() API, except that it allows a tokenizer
232900
+** locale to be specified.
232379232901
*/
232380232902
struct Fts5ExtensionApi {
232381
- int iVersion; /* Currently always set to 3 */
232903
+ int iVersion; /* Currently always set to 4 */
232382232904
232383232905
void *(*xUserData)(Fts5Context*);
232384232906
232385232907
int (*xColumnCount)(Fts5Context*);
232386232908
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -232418,10 +232940,19 @@
232418232940
int (*xQueryToken)(Fts5Context*,
232419232941
int iPhrase, int iToken,
232420232942
const char **ppToken, int *pnToken
232421232943
);
232422232944
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
232945
+
232946
+ /* Below this point are iVersion>=4 only */
232947
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
232948
+ int (*xTokenize_v2)(Fts5Context*,
232949
+ const char *pText, int nText, /* Text to tokenize */
232950
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
232951
+ void *pCtx, /* Context passed to xToken() */
232952
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
232953
+ );
232423232954
};
232424232955
232425232956
/*
232426232957
** CUSTOM AUXILIARY FUNCTIONS
232427232958
*************************************************************************/
@@ -232430,19 +232961,20 @@
232430232961
** CUSTOM TOKENIZERS
232431232962
**
232432232963
** Applications may also register custom tokenizer types. A tokenizer
232433232964
** is registered by providing fts5 with a populated instance of the
232434232965
** following structure. All structure methods must be defined, setting
232966
+**
232435232967
** any member of the fts5_tokenizer struct to NULL leads to undefined
232436232968
** behaviour. The structure methods are expected to function as follows:
232437232969
**
232438232970
** xCreate:
232439232971
** This function is used to allocate and initialize a tokenizer instance.
232440232972
** A tokenizer instance is required to actually tokenize text.
232441232973
**
232442232974
** The first argument passed to this function is a copy of the (void*)
232443
-** pointer provided by the application when the fts5_tokenizer object
232975
+** pointer provided by the application when the fts5_tokenizer_v2 object
232444232976
** was registered with FTS5 (the third argument to xCreateTokenizer()).
232445232977
** The second and third arguments are an array of nul-terminated strings
232446232978
** containing the tokenizer arguments, if any, specified following the
232447232979
** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
232448232980
** to create the FTS5 table.
@@ -232462,11 +232994,11 @@
232462232994
** This function is expected to tokenize the nText byte string indicated
232463232995
** by argument pText. pText may or may not be nul-terminated. The first
232464232996
** argument passed to this function is a pointer to an Fts5Tokenizer object
232465232997
** returned by an earlier call to xCreate().
232466232998
**
232467
-** The second argument indicates the reason that FTS5 is requesting
232999
+** The third argument indicates the reason that FTS5 is requesting
232468233000
** tokenization of the supplied text. This is always one of the following
232469233001
** four values:
232470233002
**
232471233003
** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
232472233004
** or removed from the FTS table. The tokenizer is being invoked to
@@ -232485,10 +233017,17 @@
232485233017
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
232486233018
** satisfy an fts5_api.xTokenize() request made by an auxiliary
232487233019
** function. Or an fts5_api.xColumnSize() request made by the same
232488233020
** on a columnsize=0 database.
232489233021
** </ul>
233022
+**
233023
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
233024
+** nLocale - are a pointer to a buffer containing the locale to use for
233025
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
233026
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
233027
+** which case nLocale is always 0) to indicate that the tokenizer should
233028
+** use its default locale.
232490233029
**
232491233030
** For each token in the input string, the supplied callback xToken() must
232492233031
** be invoked. The first argument to it should be a copy of the pointer
232493233032
** passed as the second argument to xTokenize(). The third and fourth
232494233033
** arguments are a pointer to a buffer containing the token text, and the
@@ -232508,10 +233047,33 @@
232508233047
** immediately return a copy of the xToken() return value. Or, if the
232509233048
** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
232510233049
** if an error occurs with the xTokenize() implementation itself, it
232511233050
** may abandon the tokenization and return any error code other than
232512233051
** SQLITE_OK or SQLITE_DONE.
233052
+**
233053
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
233054
+** then the xTokenize() method has two additional arguments - pLocale
233055
+** and nLocale. These specify the locale that the tokenizer should use
233056
+** for the current request. If pLocale and nLocale are both 0, then the
233057
+** tokenizer should use its default locale. Otherwise, pLocale points to
233058
+** an nLocale byte buffer containing the name of the locale to use as utf-8
233059
+** text. pLocale is not nul-terminated.
233060
+**
233061
+** FTS5_TOKENIZER
233062
+**
233063
+** There is also an fts5_tokenizer object. This is an older version of
233064
+** fts5_tokenizer_v2. It is similar except that:
233065
+**
233066
+** <ul>
233067
+** <li> There is no "iVersion" field, and
233068
+** <li> The xTokenize() method does not take a locale argument.
233069
+** </ul>
233070
+**
233071
+** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
233072
+** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
233073
+** registered using either API may be retrieved using both xFindTokenizer()
233074
+** and xFindTokenizer_v2().
232513233075
**
232514233076
** SYNONYM SUPPORT
232515233077
**
232516233078
** Custom tokenizers may also support synonyms. Consider a case in which a
232517233079
** user wishes to query for a phrase such as "first place". Using the
@@ -232617,10 +233179,37 @@
232617233179
** provide synonyms when tokenizing document text (method (3)) or query
232618233180
** text (method (2)), not both. Doing so will not cause any errors, but is
232619233181
** inefficient.
232620233182
*/
232621233183
typedef struct Fts5Tokenizer Fts5Tokenizer;
233184
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
233185
+struct fts5_tokenizer_v2 {
233186
+ int iVersion; /* Currently always 2 */
233187
+
233188
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
233189
+ void (*xDelete)(Fts5Tokenizer*);
233190
+ int (*xTokenize)(Fts5Tokenizer*,
233191
+ void *pCtx,
233192
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
233193
+ const char *pText, int nText,
233194
+ const char *pLocale, int nLocale,
233195
+ int (*xToken)(
233196
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
233197
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
233198
+ const char *pToken, /* Pointer to buffer containing token */
233199
+ int nToken, /* Size of token in bytes */
233200
+ int iStart, /* Byte offset of token within input text */
233201
+ int iEnd /* Byte offset of end of token within input text */
233202
+ )
233203
+ );
233204
+};
233205
+
233206
+/*
233207
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
233208
+** implementations. The following type is included for legacy applications
233209
+** that still use it.
233210
+*/
232622233211
typedef struct fts5_tokenizer fts5_tokenizer;
232623233212
struct fts5_tokenizer {
232624233213
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
232625233214
void (*xDelete)(Fts5Tokenizer*);
232626233215
int (*xTokenize)(Fts5Tokenizer*,
@@ -232635,10 +233224,11 @@
232635233224
int iStart, /* Byte offset of token within input text */
232636233225
int iEnd /* Byte offset of end of token within input text */
232637233226
)
232638233227
);
232639233228
};
233229
+
232640233230
232641233231
/* Flags that may be passed as the third argument to xTokenize() */
232642233232
#define FTS5_TOKENIZE_QUERY 0x0001
232643233233
#define FTS5_TOKENIZE_PREFIX 0x0002
232644233234
#define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -232655,11 +233245,11 @@
232655233245
/*************************************************************************
232656233246
** FTS5 EXTENSION REGISTRATION API
232657233247
*/
232658233248
typedef struct fts5_api fts5_api;
232659233249
struct fts5_api {
232660
- int iVersion; /* Currently always set to 2 */
233250
+ int iVersion; /* Currently always set to 3 */
232661233251
232662233252
/* Create a new tokenizer */
232663233253
int (*xCreateTokenizer)(
232664233254
fts5_api *pApi,
232665233255
const char *zName,
@@ -232682,10 +233272,29 @@
232682233272
const char *zName,
232683233273
void *pUserData,
232684233274
fts5_extension_function xFunction,
232685233275
void (*xDestroy)(void*)
232686233276
);
233277
+
233278
+ /* APIs below this point are only available if iVersion>=3 */
233279
+
233280
+ /* Create a new tokenizer */
233281
+ int (*xCreateTokenizer_v2)(
233282
+ fts5_api *pApi,
233283
+ const char *zName,
233284
+ void *pUserData,
233285
+ fts5_tokenizer_v2 *pTokenizer,
233286
+ void (*xDestroy)(void*)
233287
+ );
233288
+
233289
+ /* Find an existing tokenizer */
233290
+ int (*xFindTokenizer_v2)(
233291
+ fts5_api *pApi,
233292
+ const char *zName,
233293
+ void **ppUserData,
233294
+ fts5_tokenizer_v2 **ppTokenizer
233295
+ );
232687233296
};
232688233297
232689233298
/*
232690233299
** END OF REGISTRATION API
232691233300
*************************************************************************/
@@ -232858,14 +233467,17 @@
232858233467
typedef struct Fts5Config Fts5Config;
232859233468
typedef struct Fts5TokenizerConfig Fts5TokenizerConfig;
232860233469
232861233470
struct Fts5TokenizerConfig {
232862233471
Fts5Tokenizer *pTok;
232863
- fts5_tokenizer *pTokApi;
233472
+ fts5_tokenizer_v2 *pApi2;
233473
+ fts5_tokenizer *pApi1;
232864233474
const char **azArg;
232865233475
int nArg;
232866233476
int ePattern; /* FTS_PATTERN_XXX constant */
233477
+ const char *pLocale; /* Current locale to use */
233478
+ int nLocale; /* Size of pLocale in bytes */
232867233479
};
232868233480
232869233481
/*
232870233482
** An instance of the following structure encodes all information that can
232871233483
** be gleaned from the CREATE VIRTUAL TABLE statement.
@@ -232902,10 +233514,12 @@
232902233514
** This is only used for debugging. If set to false, any prefix indexes
232903233515
** are ignored. This value is configured using:
232904233516
**
232905233517
** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
232906233518
**
233519
+** bLocale:
233520
+** Set to true if locale=1 was specified when the table was created.
232907233521
*/
232908233522
struct Fts5Config {
232909233523
sqlite3 *db; /* Database handle */
232910233524
Fts5Global *pGlobal; /* Global fts5 object for handle db */
232911233525
char *zDb; /* Database holding FTS index (e.g. "main") */
@@ -232919,14 +233533,16 @@
232919233533
int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
232920233534
char *zContent; /* content table */
232921233535
char *zContentRowid; /* "content_rowid=" option value */
232922233536
int bColumnsize; /* "columnsize=" option value (dflt==1) */
232923233537
int bTokendata; /* "tokendata=" option value (dflt==0) */
233538
+ int bLocale; /* "locale=" option value (dflt==0) */
232924233539
int eDetail; /* FTS5_DETAIL_XXX value */
232925233540
char *zContentExprlist;
232926233541
Fts5TokenizerConfig t;
232927233542
int bLock; /* True when table is preparing statement */
233543
+
232928233544
232929233545
/* Values loaded from the %_config table */
232930233546
int iVersion; /* fts5 file format 'version' */
232931233547
int iCookie; /* Incremented when %_config is modified */
232932233548
int pgsz; /* Approximate page size used in %_data */
@@ -232988,10 +233604,12 @@
232988233604
/* Set the value of a single config attribute */
232989233605
static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
232990233606
232991233607
static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
232992233608
233609
+static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...);
233610
+
232993233611
/*
232994233612
** End of interface to code in fts5_config.c.
232995233613
**************************************************************************/
232996233614
232997233615
/**************************************************************************
@@ -233032,11 +233650,11 @@
233032233650
233033233651
/* Write and decode big-endian 32-bit integer values */
233034233652
static void sqlite3Fts5Put32(u8*, int);
233035233653
static int sqlite3Fts5Get32(const u8*);
233036233654
233037
-#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
233655
+#define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF)
233038233656
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
233039233657
233040233658
typedef struct Fts5PoslistReader Fts5PoslistReader;
233041233659
struct Fts5PoslistReader {
233042233660
/* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
@@ -233323,10 +233941,21 @@
233323233941
233324233942
static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
233325233943
233326233944
static int sqlite3Fts5FlushToDisk(Fts5Table*);
233327233945
233946
+static int sqlite3Fts5ExtractText(
233947
+ Fts5Config *pConfig,
233948
+ sqlite3_value *pVal, /* Value to extract text from */
233949
+ int bContent, /* Loaded from content table */
233950
+ int *pbResetTokenizer, /* OUT: True if ClearLocale() required */
233951
+ const char **ppText, /* OUT: Pointer to text buffer */
233952
+ int *pnText /* OUT: Size of (*ppText) in bytes */
233953
+);
233954
+
233955
+static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
233956
+
233328233957
/*
233329233958
** End of interface to code in fts5.c.
233330233959
**************************************************************************/
233331233960
233332233961
/**************************************************************************
@@ -233402,11 +234031,11 @@
233402234031
static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
233403234032
233404234033
static int sqlite3Fts5DropAll(Fts5Config*);
233405234034
static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
233406234035
233407
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
234036
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int);
233408234037
static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
233409234038
static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
233410234039
233411234040
static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
233412234041
@@ -233428,10 +234057,13 @@
233428234057
static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
233429234058
static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
233430234059
static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
233431234060
static int sqlite3Fts5StorageReset(Fts5Storage *p);
233432234061
234062
+static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*);
234063
+static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel);
234064
+
233433234065
/*
233434234066
** End of interface to code in fts5_storage.c.
233435234067
**************************************************************************/
233436234068
233437234069
@@ -235357,10 +235989,11 @@
235357235989
p->iOff = iEndOff;
235358235990
}
235359235991
235360235992
return rc;
235361235993
}
235994
+
235362235995
235363235996
/*
235364235997
** Implementation of highlight() function.
235365235998
*/
235366235999
static void fts5HighlightFunction(
@@ -235388,16 +236021,23 @@
235388236021
rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
235389236022
if( rc==SQLITE_RANGE ){
235390236023
sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
235391236024
rc = SQLITE_OK;
235392236025
}else if( ctx.zIn ){
236026
+ const char *pLoc = 0; /* Locale of column iCol */
236027
+ int nLoc = 0; /* Size of pLoc in bytes */
235393236028
if( rc==SQLITE_OK ){
235394236029
rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
235395236030
}
235396236031
235397236032
if( rc==SQLITE_OK ){
235398
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
236033
+ rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc);
236034
+ }
236035
+ if( rc==SQLITE_OK ){
236036
+ rc = pApi->xTokenize_v2(
236037
+ pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb
236038
+ );
235399236039
}
235400236040
if( ctx.bOpen ){
235401236041
fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
235402236042
}
235403236043
fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
@@ -235590,19 +236230,23 @@
235590236230
}
235591236231
235592236232
memset(&sFinder, 0, sizeof(Fts5SFinder));
235593236233
for(i=0; i<nCol; i++){
235594236234
if( iCol<0 || iCol==i ){
236235
+ const char *pLoc = 0; /* Locale of column iCol */
236236
+ int nLoc = 0; /* Size of pLoc in bytes */
235595236237
int nDoc;
235596236238
int nDocsize;
235597236239
int ii;
235598236240
sFinder.iPos = 0;
235599236241
sFinder.nFirst = 0;
235600236242
rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
235601236243
if( rc!=SQLITE_OK ) break;
235602
- rc = pApi->xTokenize(pFts,
235603
- sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
236244
+ rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc);
236245
+ if( rc!=SQLITE_OK ) break;
236246
+ rc = pApi->xTokenize_v2(pFts,
236247
+ sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb
235604236248
);
235605236249
if( rc!=SQLITE_OK ) break;
235606236250
rc = pApi->xColumnSize(pFts, i, &nDocsize);
235607236251
if( rc!=SQLITE_OK ) break;
235608236252
@@ -235656,10 +236300,13 @@
235656236300
}
235657236301
if( rc==SQLITE_OK && nColSize==0 ){
235658236302
rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
235659236303
}
235660236304
if( ctx.zIn ){
236305
+ const char *pLoc = 0; /* Locale of column iBestCol */
236306
+ int nLoc = 0; /* Bytes in pLoc */
236307
+
235661236308
if( rc==SQLITE_OK ){
235662236309
rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
235663236310
}
235664236311
235665236312
ctx.iRangeStart = iBestStart;
@@ -235674,11 +236321,16 @@
235674236321
while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
235675236322
rc = fts5CInstIterNext(&ctx.iter);
235676236323
}
235677236324
235678236325
if( rc==SQLITE_OK ){
235679
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
236326
+ rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc);
236327
+ }
236328
+ if( rc==SQLITE_OK ){
236329
+ rc = pApi->xTokenize_v2(
236330
+ pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb
236331
+ );
235680236332
}
235681236333
if( ctx.bOpen ){
235682236334
fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
235683236335
}
235684236336
if( ctx.iRangeEnd>=(nColSize-1) ){
@@ -235857,21 +236509,69 @@
235857236509
sqlite3_result_double(pCtx, -1.0 * score);
235858236510
}else{
235859236511
sqlite3_result_error_code(pCtx, rc);
235860236512
}
235861236513
}
236514
+
236515
+/*
236516
+** Implementation of fts5_get_locale() function.
236517
+*/
236518
+static void fts5GetLocaleFunction(
236519
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
236520
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
236521
+ sqlite3_context *pCtx, /* Context for returning result/error */
236522
+ int nVal, /* Number of values in apVal[] array */
236523
+ sqlite3_value **apVal /* Array of trailing arguments */
236524
+){
236525
+ int iCol = 0;
236526
+ int eType = 0;
236527
+ int rc = SQLITE_OK;
236528
+ const char *zLocale = 0;
236529
+ int nLocale = 0;
236530
+
236531
+ /* xColumnLocale() must be available */
236532
+ assert( pApi->iVersion>=4 );
236533
+
236534
+ if( nVal!=1 ){
236535
+ const char *z = "wrong number of arguments to function fts5_get_locale()";
236536
+ sqlite3_result_error(pCtx, z, -1);
236537
+ return;
236538
+ }
236539
+
236540
+ eType = sqlite3_value_numeric_type(apVal[0]);
236541
+ if( eType!=SQLITE_INTEGER ){
236542
+ const char *z = "non-integer argument passed to function fts5_get_locale()";
236543
+ sqlite3_result_error(pCtx, z, -1);
236544
+ return;
236545
+ }
236546
+
236547
+ iCol = sqlite3_value_int(apVal[0]);
236548
+ if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){
236549
+ sqlite3_result_error_code(pCtx, SQLITE_RANGE);
236550
+ return;
236551
+ }
236552
+
236553
+ rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale);
236554
+ if( rc!=SQLITE_OK ){
236555
+ sqlite3_result_error_code(pCtx, rc);
236556
+ return;
236557
+ }
236558
+
236559
+ sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT);
236560
+}
235862236561
235863236562
static int sqlite3Fts5AuxInit(fts5_api *pApi){
235864236563
struct Builtin {
235865236564
const char *zFunc; /* Function name (nul-terminated) */
235866236565
void *pUserData; /* User-data pointer */
235867236566
fts5_extension_function xFunc;/* Callback function */
235868236567
void (*xDestroy)(void*); /* Destructor function */
235869236568
} aBuiltin [] = {
235870
- { "snippet", 0, fts5SnippetFunction, 0 },
235871
- { "highlight", 0, fts5HighlightFunction, 0 },
235872
- { "bm25", 0, fts5Bm25Function, 0 },
236569
+ { "snippet", 0, fts5SnippetFunction, 0 },
236570
+ { "highlight", 0, fts5HighlightFunction, 0 },
236571
+ { "bm25", 0, fts5Bm25Function, 0 },
236572
+ { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 },
235873236573
};
235874236574
int rc = SQLITE_OK; /* Return code */
235875236575
int i; /* To iterate through builtin functions */
235876236576
235877236577
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
@@ -236677,10 +237377,20 @@
236677237377
}else{
236678237378
pConfig->bColumnsize = (zArg[0]=='1');
236679237379
}
236680237380
return rc;
236681237381
}
237382
+
237383
+ if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){
237384
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
237385
+ *pzErr = sqlite3_mprintf("malformed locale=... directive");
237386
+ rc = SQLITE_ERROR;
237387
+ }else{
237388
+ pConfig->bLocale = (zArg[0]=='1');
237389
+ }
237390
+ return rc;
237391
+ }
236682237392
236683237393
if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
236684237394
const Fts5Enum aDetail[] = {
236685237395
{ "none", FTS5_DETAIL_NONE },
236686237396
{ "full", FTS5_DETAIL_FULL },
@@ -236967,11 +237677,15 @@
236967237677
*/
236968237678
static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
236969237679
if( pConfig ){
236970237680
int i;
236971237681
if( pConfig->t.pTok ){
236972
- pConfig->t.pTokApi->xDelete(pConfig->t.pTok);
237682
+ if( pConfig->t.pApi1 ){
237683
+ pConfig->t.pApi1->xDelete(pConfig->t.pTok);
237684
+ }else{
237685
+ pConfig->t.pApi2->xDelete(pConfig->t.pTok);
237686
+ }
236973237687
}
236974237688
sqlite3_free((char*)pConfig->t.azArg);
236975237689
sqlite3_free(pConfig->zDb);
236976237690
sqlite3_free(pConfig->zName);
236977237691
for(i=0; i<pConfig->nCol; i++){
@@ -237050,13 +237764,19 @@
237050237764
if( pText ){
237051237765
if( pConfig->t.pTok==0 ){
237052237766
rc = sqlite3Fts5LoadTokenizer(pConfig);
237053237767
}
237054237768
if( rc==SQLITE_OK ){
237055
- rc = pConfig->t.pTokApi->xTokenize(
237056
- pConfig->t.pTok, pCtx, flags, pText, nText, xToken
237057
- );
237769
+ if( pConfig->t.pApi1 ){
237770
+ rc = pConfig->t.pApi1->xTokenize(
237771
+ pConfig->t.pTok, pCtx, flags, pText, nText, xToken
237772
+ );
237773
+ }else{
237774
+ rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags,
237775
+ pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken
237776
+ );
237777
+ }
237058237778
}
237059237779
}
237060237780
return rc;
237061237781
}
237062237782
@@ -237309,26 +238029,46 @@
237309238029
if( rc==SQLITE_OK
237310238030
&& iVersion!=FTS5_CURRENT_VERSION
237311238031
&& iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE
237312238032
){
237313238033
rc = SQLITE_ERROR;
237314
- if( pConfig->pzErrmsg ){
237315
- assert( 0==*pConfig->pzErrmsg );
237316
- *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format "
237317
- "(found %d, expected %d or %d) - run 'rebuild'",
237318
- iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
237319
- );
237320
- }
238034
+ sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format "
238035
+ "(found %d, expected %d or %d) - run 'rebuild'",
238036
+ iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
238037
+ );
237321238038
}else{
237322238039
pConfig->iVersion = iVersion;
237323238040
}
237324238041
237325238042
if( rc==SQLITE_OK ){
237326238043
pConfig->iCookie = iCookie;
237327238044
}
237328238045
return rc;
237329238046
}
238047
+
238048
+/*
238049
+** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer
238050
+** containing the error message created using printf() style formatting
238051
+** string zFmt and its trailing arguments.
238052
+*/
238053
+static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){
238054
+ va_list ap; /* ... printf arguments */
238055
+ char *zMsg = 0;
238056
+
238057
+ va_start(ap, zFmt);
238058
+ zMsg = sqlite3_vmprintf(zFmt, ap);
238059
+ if( pConfig->pzErrmsg ){
238060
+ assert( *pConfig->pzErrmsg==0 );
238061
+ *pConfig->pzErrmsg = zMsg;
238062
+ }else{
238063
+ sqlite3_free(zMsg);
238064
+ }
238065
+
238066
+ va_end(ap);
238067
+}
238068
+
238069
+
237330238070
237331238071
/*
237332238072
** 2014 May 31
237333238073
**
237334238074
** The author disclaims copyright to this source code. In place of
@@ -237614,15 +238354,16 @@
237614238354
t = fts5ExprGetToken(&sParse, &z, &token);
237615238355
sqlite3Fts5Parser(pEngine, t, token, &sParse);
237616238356
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
237617238357
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
237618238358
238359
+ assert( sParse.pExpr || sParse.rc!=SQLITE_OK );
237619238360
assert_expr_depth_ok(sParse.rc, sParse.pExpr);
237620238361
237621238362
/* If the LHS of the MATCH expression was a user column, apply the
237622238363
** implicit column-filter. */
237623
- if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
238364
+ if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){
237624238365
int n = sizeof(Fts5Colset);
237625238366
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
237626238367
if( pColset ){
237627238368
pColset->nCol = 1;
237628238369
pColset->aiCol[0] = iCol;
@@ -237635,19 +238376,11 @@
237635238376
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
237636238377
if( pNew==0 ){
237637238378
sParse.rc = SQLITE_NOMEM;
237638238379
sqlite3Fts5ParseNodeFree(sParse.pExpr);
237639238380
}else{
237640
- if( !sParse.pExpr ){
237641
- const int nByte = sizeof(Fts5ExprNode);
237642
- pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
237643
- if( pNew->pRoot ){
237644
- pNew->pRoot->bEof = 1;
237645
- }
237646
- }else{
237647
- pNew->pRoot = sParse.pExpr;
237648
- }
238381
+ pNew->pRoot = sParse.pExpr;
237649238382
pNew->pIndex = 0;
237650238383
pNew->pConfig = pConfig;
237651238384
pNew->apExprPhrase = sParse.apPhrase;
237652238385
pNew->nPhrase = sParse.nPhrase;
237653238386
pNew->bDesc = 0;
@@ -238461,11 +239194,11 @@
238461239194
pNode->bEof = 1;
238462239195
return rc;
238463239196
}
238464239197
}else{
238465239198
Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
238466
- if( pIter->iRowid==iLast || pIter->bEof ) continue;
239199
+ if( pIter->iRowid==iLast ) continue;
238467239200
bMatch = 0;
238468239201
if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
238469239202
return rc;
238470239203
}
238471239204
}
@@ -238983,13 +239716,10 @@
238983239716
){
238984239717
const int SZALLOC = 8;
238985239718
Fts5ExprNearset *pRet = 0;
238986239719
238987239720
if( pParse->rc==SQLITE_OK ){
238988
- if( pPhrase==0 ){
238989
- return pNear;
238990
- }
238991239721
if( pNear==0 ){
238992239722
sqlite3_int64 nByte;
238993239723
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
238994239724
pRet = sqlite3_malloc64(nByte);
238995239725
if( pRet==0 ){
@@ -250372,15 +251102,32 @@
250372251102
250373251103
/*
250374251104
** Each tokenizer module registered with the FTS5 module is represented
250375251105
** by an object of the following type. All such objects are stored as part
250376251106
** of the Fts5Global.pTok list.
251107
+**
251108
+** bV2Native:
251109
+** True if the tokenizer was registered using xCreateTokenizer_v2(), false
251110
+** for xCreateTokenizer(). If this variable is true, then x2 is populated
251111
+** with the routines as supplied by the caller and x1 contains synthesized
251112
+** wrapper routines. In this case the user-data pointer passed to
251113
+** x1.xCreate should be a pointer to the Fts5TokenizerModule structure,
251114
+** not a copy of pUserData.
251115
+**
251116
+** Of course, if bV2Native is false, then x1 contains the real routines and
251117
+** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule
251118
+** object should be passed to x2.xCreate.
251119
+**
251120
+** The synthesized wrapper routines are necessary for xFindTokenizer(_v2)
251121
+** calls.
250377251122
*/
250378251123
struct Fts5TokenizerModule {
250379251124
char *zName; /* Name of tokenizer */
250380251125
void *pUserData; /* User pointer passed to xCreate() */
250381
- fts5_tokenizer x; /* Tokenizer functions */
251126
+ int bV2Native; /* True if v2 native tokenizer */
251127
+ fts5_tokenizer x1; /* Tokenizer functions */
251128
+ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
250382251129
void (*xDestroy)(void*); /* Destructor function */
250383251130
Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
250384251131
};
250385251132
250386251133
struct Fts5FullTable {
@@ -250464,11 +251211,11 @@
250464251211
250465251212
/* Auxiliary data storage */
250466251213
Fts5Auxiliary *pAux; /* Currently executing extension function */
250467251214
Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
250468251215
250469
- /* Cache used by auxiliary functions xInst() and xInstCount() */
251216
+ /* Cache used by auxiliary API functions xInst() and xInstCount() */
250470251217
Fts5PoslistReader *aInstIter; /* One for each phrase */
250471251218
int nInstAlloc; /* Size of aInst[] array (entries / 3) */
250472251219
int nInstCount; /* Number of phrase instances */
250473251220
int *aInst; /* 3 integers per phrase instance */
250474251221
};
@@ -250499,10 +251246,16 @@
250499251246
#define FTS5CSR_REQUIRE_POSLIST 0x40
250500251247
250501251248
#define BitFlagAllTest(x,y) (((x) & (y))==(y))
250502251249
#define BitFlagTest(x,y) (((x) & (y))!=0)
250503251250
251251
+/*
251252
+** The subtype value and header bytes used by fts5_locale().
251253
+*/
251254
+#define FTS5_LOCALE_SUBTYPE ((unsigned int)'L')
251255
+#define FTS5_LOCALE_HEADER "\x00\xE0\xB2\xEB"
251256
+
250504251257
250505251258
/*
250506251259
** Macros to Set(), Clear() and Test() cursor flags.
250507251260
*/
250508251261
#define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -250876,11 +251629,11 @@
250876251629
}else{
250877251630
if( iCol==nCol+1 ){
250878251631
if( bSeenRank ) continue;
250879251632
idxStr[iIdxStr++] = 'r';
250880251633
bSeenRank = 1;
250881
- }else if( iCol>=0 ){
251634
+ }else{
250882251635
nSeenMatch++;
250883251636
idxStr[iIdxStr++] = 'M';
250884251637
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
250885251638
idxStr += strlen(&idxStr[iIdxStr]);
250886251639
assert( idxStr[iIdxStr]=='\0' );
@@ -251262,11 +252015,11 @@
251262252015
rc = SQLITE_NOMEM;
251263252016
}else{
251264252017
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
251265252018
SQLITE_PREPARE_PERSISTENT, &pRet, 0);
251266252019
if( rc!=SQLITE_OK ){
251267
- *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
252020
+ sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db));
251268252021
}
251269252022
sqlite3_free(zSql);
251270252023
}
251271252024
251272252025
va_end(ap);
@@ -251497,10 +252250,192 @@
251497252250
sqlite3_free(p->p.base.zErrMsg);
251498252251
p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
251499252252
va_end(ap);
251500252253
}
251501252254
252255
+/*
252256
+** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
252257
+** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
252258
+** valid until after the final call to sqlite3Fts5Tokenize() that will use
252259
+** the locale.
252260
+*/
252261
+static void fts5SetLocale(
252262
+ Fts5Config *pConfig,
252263
+ const char *zLocale,
252264
+ int nLocale
252265
+){
252266
+ Fts5TokenizerConfig *pT = &pConfig->t;
252267
+ pT->pLocale = zLocale;
252268
+ pT->nLocale = nLocale;
252269
+}
252270
+
252271
+/*
252272
+** Clear any locale configured by an earlier call to fts5SetLocale() or
252273
+** sqlite3Fts5ExtractText().
252274
+*/
252275
+static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
252276
+ fts5SetLocale(pConfig, 0, 0);
252277
+}
252278
+
252279
+/*
252280
+** This function is used to extract utf-8 text from an sqlite3_value. This
252281
+** is usually done in order to tokenize it. For example, when:
252282
+**
252283
+** * a value is written to an fts5 table,
252284
+** * a value is deleted from an FTS5_CONTENT_NORMAL table,
252285
+** * a value containing a query expression is passed to xFilter()
252286
+**
252287
+** and so on.
252288
+**
252289
+** This function handles 2 cases:
252290
+**
252291
+** 1) Ordinary values. The text can be extracted from these using
252292
+** sqlite3_value_text().
252293
+**
252294
+** 2) Combination text/locale blobs created by fts5_locale(). There
252295
+** are several cases for these:
252296
+**
252297
+** * Blobs tagged with FTS5_LOCALE_SUBTYPE.
252298
+** * Blobs read from the content table of a locale=1 external-content
252299
+** table, and
252300
+** * Blobs read from the content table of a locale=1 regular
252301
+** content table.
252302
+**
252303
+** The first two cases above should have the 4 byte FTS5_LOCALE_HEADER
252304
+** header. It is an error if a blob with the subtype or a blob read
252305
+** from the content table of an external content table does not have
252306
+** the required header. A blob read from the content table of a regular
252307
+** locale=1 table does not have the header. This is to save space.
252308
+**
252309
+** If successful, SQLITE_OK is returned and output parameters (*ppText)
252310
+** and (*pnText) are set to point to a buffer containing the extracted utf-8
252311
+** text and its length in bytes, respectively. The buffer is not
252312
+** nul-terminated. It has the same lifetime as the sqlite3_value object
252313
+** from which it is extracted.
252314
+**
252315
+** Parameter bContent must be true if the value was read from an indexed
252316
+** column (i.e. not UNINDEXED) of the on disk content.
252317
+**
252318
+** If pbResetTokenizer is not NULL and if case (2) is used, then
252319
+** fts5SetLocale() is called to ensure subsequent sqlite3Fts5Tokenize() calls
252320
+** use the locale. In this case (*pbResetTokenizer) is set to true before
252321
+** returning, to indicate that the caller must call sqlite3Fts5ClearLocale()
252322
+** to clear the locale after tokenizing the text.
252323
+*/
252324
+static int sqlite3Fts5ExtractText(
252325
+ Fts5Config *pConfig,
252326
+ sqlite3_value *pVal, /* Value to extract text from */
252327
+ int bContent, /* True if indexed table content */
252328
+ int *pbResetTokenizer, /* OUT: True if xSetLocale(NULL) required */
252329
+ const char **ppText, /* OUT: Pointer to text buffer */
252330
+ int *pnText /* OUT: Size of (*ppText) in bytes */
252331
+){
252332
+ const char *pText = 0;
252333
+ int nText = 0;
252334
+ int rc = SQLITE_OK;
252335
+ int bDecodeBlob = 0;
252336
+
252337
+ assert( pbResetTokenizer==0 || *pbResetTokenizer==0 );
252338
+ assert( bContent==0 || pConfig->eContent!=FTS5_CONTENT_NONE );
252339
+ assert( bContent==0 || sqlite3_value_subtype(pVal)==0 );
252340
+
252341
+ if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
252342
+ if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE
252343
+ || (bContent && pConfig->bLocale)
252344
+ ){
252345
+ bDecodeBlob = 1;
252346
+ }
252347
+ }
252348
+
252349
+ if( bDecodeBlob ){
252350
+ const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
252351
+ const u8 *pBlob = sqlite3_value_blob(pVal);
252352
+ int nBlob = sqlite3_value_bytes(pVal);
252353
+
252354
+ /* Unless this blob was read from the %_content table of an
252355
+ ** FTS5_CONTENT_NORMAL table, it should have the 4 byte fts5_locale()
252356
+ ** header. Check for this. If it is not found, return an error. */
252357
+ if( (!bContent || pConfig->eContent!=FTS5_CONTENT_NORMAL) ){
252358
+ if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
252359
+ rc = SQLITE_ERROR;
252360
+ }else{
252361
+ pBlob += 4;
252362
+ nBlob -= 4;
252363
+ }
252364
+ }
252365
+
252366
+ if( rc==SQLITE_OK ){
252367
+ int nLocale = 0;
252368
+
252369
+ for(nLocale=0; nLocale<nBlob; nLocale++){
252370
+ if( pBlob[nLocale]==0x00 ) break;
252371
+ }
252372
+ if( nLocale==nBlob || nLocale==0 ){
252373
+ rc = SQLITE_ERROR;
252374
+ }else{
252375
+ pText = (const char*)&pBlob[nLocale+1];
252376
+ nText = nBlob-nLocale-1;
252377
+
252378
+ if( pbResetTokenizer ){
252379
+ fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
252380
+ *pbResetTokenizer = 1;
252381
+ }
252382
+ }
252383
+ }
252384
+
252385
+ }else{
252386
+ pText = (const char*)sqlite3_value_text(pVal);
252387
+ nText = sqlite3_value_bytes(pVal);
252388
+ }
252389
+
252390
+ *ppText = pText;
252391
+ *pnText = nText;
252392
+ return rc;
252393
+}
252394
+
252395
+/*
252396
+** Argument pVal is the text of a full-text search expression. It may or
252397
+** may not have been wrapped by fts5_locale(). This function extracts
252398
+** the text of the expression, and sets output variable (*pzText) to
252399
+** point to a nul-terminated buffer containing the expression.
252400
+**
252401
+** If pVal was an fts5_locale() value, then fts5SetLocale() is called to
252402
+** set the tokenizer to use the specified locale.
252403
+**
252404
+** If output variable (*pbFreeAndReset) is set to true, then the caller
252405
+** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
252406
+** locale, and (b) call sqlite3_free() to free (*pzText).
252407
+*/
252408
+static int fts5ExtractExprText(
252409
+ Fts5Config *pConfig, /* Fts5 configuration */
252410
+ sqlite3_value *pVal, /* Value to extract expression text from */
252411
+ char **pzText, /* OUT: nul-terminated buffer of text */
252412
+ int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
252413
+){
252414
+ const char *zText = 0;
252415
+ int nText = 0;
252416
+ int rc = SQLITE_OK;
252417
+ int bReset = 0;
252418
+
252419
+ *pbFreeAndReset = 0;
252420
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, &bReset, &zText, &nText);
252421
+ if( rc==SQLITE_OK ){
252422
+ if( bReset ){
252423
+ *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, zText);
252424
+ if( rc!=SQLITE_OK ){
252425
+ sqlite3Fts5ClearLocale(pConfig);
252426
+ }else{
252427
+ *pbFreeAndReset = 1;
252428
+ }
252429
+ }else{
252430
+ *pzText = (char*)zText;
252431
+ }
252432
+ }
252433
+
252434
+ return rc;
252435
+}
252436
+
251502252437
251503252438
/*
251504252439
** This is the xFilter interface for the virtual table. See
251505252440
** the virtual table xFilter method documentation for additional
251506252441
** information.
@@ -251532,17 +252467,11 @@
251532252467
char **pzErrmsg = pConfig->pzErrmsg;
251533252468
int i;
251534252469
int iIdxStr = 0;
251535252470
Fts5Expr *pExpr = 0;
251536252471
251537
- if( pConfig->bLock ){
251538
- pTab->p.base.zErrMsg = sqlite3_mprintf(
251539
- "recursively defined fts5 content table"
251540
- );
251541
- return SQLITE_ERROR;
251542
- }
251543
-
252472
+ assert( pConfig->bLock==0 );
251544252473
if( pCsr->ePlan ){
251545252474
fts5FreeCursorComponents(pCsr);
251546252475
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
251547252476
}
251548252477
@@ -251562,12 +252491,18 @@
251562252491
switch( idxStr[iIdxStr++] ){
251563252492
case 'r':
251564252493
pRank = apVal[i];
251565252494
break;
251566252495
case 'M': {
251567
- const char *zText = (const char*)sqlite3_value_text(apVal[i]);
252496
+ char *zText = 0;
252497
+ int bFreeAndReset = 0;
252498
+ int bInternal = 0;
252499
+
252500
+ rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
252501
+ if( rc!=SQLITE_OK ) goto filter_out;
251568252502
if( zText==0 ) zText = "";
252503
+
251569252504
iCol = 0;
251570252505
do{
251571252506
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
251572252507
iIdxStr++;
251573252508
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
@@ -251575,21 +252510,27 @@
251575252510
if( zText[0]=='*' ){
251576252511
/* The user has issued a query of the form "MATCH '*...'". This
251577252512
** indicates that the MATCH expression is not a full text query,
251578252513
** but a request for an internal parameter. */
251579252514
rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
251580
- goto filter_out;
252515
+ bInternal = 1;
251581252516
}else{
251582252517
char **pzErr = &pTab->p.base.zErrMsg;
251583252518
rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
251584252519
if( rc==SQLITE_OK ){
251585252520
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
251586252521
pExpr = 0;
251587252522
}
251588
- if( rc!=SQLITE_OK ) goto filter_out;
251589252523
}
251590252524
252525
+ if( bFreeAndReset ){
252526
+ sqlite3_free(zText);
252527
+ sqlite3Fts5ClearLocale(pConfig);
252528
+ }
252529
+
252530
+ if( bInternal || rc!=SQLITE_OK ) goto filter_out;
252531
+
251591252532
break;
251592252533
}
251593252534
case 'L':
251594252535
case 'G': {
251595252536
int bGlob = (idxStr[iIdxStr-1]=='G');
@@ -251893,11 +252834,11 @@
251893252834
){
251894252835
int rc = SQLITE_OK;
251895252836
int eType1 = sqlite3_value_type(apVal[1]);
251896252837
if( eType1==SQLITE_INTEGER ){
251897252838
sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
251898
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
252839
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0);
251899252840
}
251900252841
return rc;
251901252842
}
251902252843
251903252844
static void fts5StorageInsert(
@@ -252017,59 +252958,81 @@
252017252958
}
252018252959
252019252960
/* DELETE */
252020252961
else if( nArg==1 ){
252021252962
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
252022
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
252963
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
252023252964
bUpdateOrDelete = 1;
252024252965
}
252025252966
252026252967
/* INSERT or UPDATE */
252027252968
else{
252028252969
int eType1 = sqlite3_value_numeric_type(apVal[1]);
252029252970
252030
- if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
252031
- rc = SQLITE_MISMATCH;
252971
+ /* Ensure that no fts5_locale() values are written to locale=0 tables.
252972
+ ** And that no blobs except fts5_locale() blobs are written to indexed
252973
+ ** (i.e. not UNINDEXED) columns of locale=1 tables. */
252974
+ int ii;
252975
+ for(ii=0; ii<pConfig->nCol; ii++){
252976
+ if( sqlite3_value_type(apVal[ii+2])==SQLITE_BLOB ){
252977
+ int bSub = (sqlite3_value_subtype(apVal[ii+2])==FTS5_LOCALE_SUBTYPE);
252978
+ if( (pConfig->bLocale && !bSub && pConfig->abUnindexed[ii]==0)
252979
+ || (pConfig->bLocale==0 && bSub)
252980
+ ){
252981
+ if( pConfig->bLocale==0 ){
252982
+ fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
252983
+ }
252984
+ rc = SQLITE_MISMATCH;
252985
+ goto update_out;
252986
+ }
252987
+ }
252032252988
}
252033252989
252034
- else if( eType0!=SQLITE_INTEGER ){
252990
+ if( eType0!=SQLITE_INTEGER ){
252035252991
/* An INSERT statement. If the conflict-mode is REPLACE, first remove
252036252992
** the current entry (if any). */
252037252993
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
252038252994
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
252039
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
252995
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
252040252996
bUpdateOrDelete = 1;
252041252997
}
252042252998
fts5StorageInsert(&rc, pTab, apVal, pRowid);
252043252999
}
252044253000
252045253001
/* UPDATE */
252046253002
else{
252047253003
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
252048253004
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
252049
- if( eType1==SQLITE_INTEGER && iOld!=iNew ){
253005
+ if( eType1!=SQLITE_INTEGER ){
253006
+ rc = SQLITE_MISMATCH;
253007
+ }else if( iOld!=iNew ){
252050253008
if( eConflict==SQLITE_REPLACE ){
252051
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
253009
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
252052253010
if( rc==SQLITE_OK ){
252053
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
253011
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
252054253012
}
252055253013
fts5StorageInsert(&rc, pTab, apVal, pRowid);
252056253014
}else{
252057
- rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
253015
+ rc = sqlite3Fts5StorageFindDeleteRow(pTab->pStorage, iOld);
253016
+ if( rc==SQLITE_OK ){
253017
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage,apVal,pRowid);
253018
+ }
252058253019
if( rc==SQLITE_OK ){
252059
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
253020
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
252060253021
}
252061253022
if( rc==SQLITE_OK ){
252062253023
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
252063253024
}
252064253025
}
252065253026
}else{
252066
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
253027
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
252067253028
fts5StorageInsert(&rc, pTab, apVal, pRowid);
252068253029
}
252069253030
bUpdateOrDelete = 1;
253031
+ sqlite3Fts5StorageReleaseDeleteRow(pTab->pStorage);
252070253032
}
253033
+
252071253034
}
252072253035
}
252073253036
252074253037
if( rc==SQLITE_OK
252075253038
&& bUpdateOrDelete
@@ -252082,10 +253045,11 @@
252082253045
if( rc==SQLITE_OK ){
252083253046
pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
252084253047
}
252085253048
}
252086253049
253050
+ update_out:
252087253051
pTab->p.pConfig->pzErrmsg = 0;
252088253052
return rc;
252089253053
}
252090253054
252091253055
/*
@@ -252159,21 +253123,44 @@
252159253123
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252160253124
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
252161253125
return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
252162253126
}
252163253127
253128
+/*
253129
+** Implementation of xTokenize_v2() API.
253130
+*/
253131
+static int fts5ApiTokenize_v2(
253132
+ Fts5Context *pCtx,
253133
+ const char *pText, int nText,
253134
+ const char *pLoc, int nLoc,
253135
+ void *pUserData,
253136
+ int (*xToken)(void*, int, const char*, int, int, int)
253137
+){
253138
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253139
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253140
+ int rc = SQLITE_OK;
253141
+
253142
+ fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253143
+ rc = sqlite3Fts5Tokenize(pTab->pConfig,
253144
+ FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
253145
+ );
253146
+ fts5SetLocale(pTab->pConfig, 0, 0);
253147
+
253148
+ return rc;
253149
+}
253150
+
253151
+/*
253152
+** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0
253153
+** passed as the locale.
253154
+*/
252164253155
static int fts5ApiTokenize(
252165253156
Fts5Context *pCtx,
252166253157
const char *pText, int nText,
252167253158
void *pUserData,
252168253159
int (*xToken)(void*, int, const char*, int, int, int)
252169253160
){
252170
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252171
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
252172
- return sqlite3Fts5Tokenize(
252173
- pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
252174
- );
253161
+ return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken);
252175253162
}
252176253163
252177253164
static int fts5ApiPhraseCount(Fts5Context *pCtx){
252178253165
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252179253166
return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
@@ -252191,53 +253178,76 @@
252191253178
int *pn
252192253179
){
252193253180
int rc = SQLITE_OK;
252194253181
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252195253182
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253183
+
253184
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
252196253185
if( iCol<0 || iCol>=pTab->pConfig->nCol ){
252197253186
rc = SQLITE_RANGE;
252198
- }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
252199
- || pCsr->ePlan==FTS5_PLAN_SPECIAL
252200
- ){
253187
+ }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) ){
252201253188
*pz = 0;
252202253189
*pn = 0;
252203253190
}else{
252204253191
rc = fts5SeekCursor(pCsr, 0);
252205253192
if( rc==SQLITE_OK ){
252206
- *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
252207
- *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
253193
+ Fts5Config *pConfig = pTab->pConfig;
253194
+ int bContent = (pConfig->abUnindexed[iCol]==0);
253195
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253196
+ sqlite3Fts5ExtractText(pConfig, pVal, bContent, 0, pz, pn);
252208253197
}
252209253198
}
252210253199
return rc;
252211253200
}
252212253201
253202
+/*
253203
+** This is called by various API functions - xInst, xPhraseFirst,
253204
+** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
253205
+** of the current row. This function works for both detail=full tables (in
253206
+** which case the position-list was read from the fts index) or for other
253207
+** detail= modes if the row content is available.
253208
+*/
252213253209
static int fts5CsrPoslist(
252214
- Fts5Cursor *pCsr,
252215
- int iPhrase,
252216
- const u8 **pa,
252217
- int *pn
253210
+ Fts5Cursor *pCsr, /* Fts5 cursor object */
253211
+ int iPhrase, /* Phrase to find position list for */
253212
+ const u8 **pa, /* OUT: Pointer to position list buffer */
253213
+ int *pn /* OUT: Size of (*pa) in bytes */
252218253214
){
252219253215
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
252220253216
int rc = SQLITE_OK;
252221253217
int bLive = (pCsr->pSorter==0);
252222253218
252223253219
if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
252224253220
rc = SQLITE_RANGE;
253221
+ }else if( pConfig->eDetail!=FTS5_DETAIL_FULL
253222
+ && pConfig->eContent==FTS5_CONTENT_NONE
253223
+ ){
253224
+ *pa = 0;
253225
+ *pn = 0;
253226
+ return SQLITE_OK;
252225253227
}else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
252226253228
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
252227253229
Fts5PoslistPopulator *aPopulator;
252228253230
int i;
253231
+
252229253232
aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
252230253233
if( aPopulator==0 ) rc = SQLITE_NOMEM;
253234
+ if( rc==SQLITE_OK ){
253235
+ rc = fts5SeekCursor(pCsr, 0);
253236
+ }
252231253237
for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
252232
- int n; const char *z;
252233
- rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
253238
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253239
+ const char *z = 0;
253240
+ int n = 0;
253241
+ int bReset = 0;
253242
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
252234253243
if( rc==SQLITE_OK ){
252235253244
rc = sqlite3Fts5ExprPopulatePoslists(
252236253245
pConfig, pCsr->pExpr, aPopulator, i, z, n
252237253246
);
252238253247
}
253248
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
252239253249
}
252240253250
sqlite3_free(aPopulator);
252241253251
252242253252
if( pCsr->pSorter ){
252243253253
sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -252257,11 +253267,10 @@
252257253267
}
252258253268
}else{
252259253269
*pa = 0;
252260253270
*pn = 0;
252261253271
}
252262
-
252263253272
252264253273
return rc;
252265253274
}
252266253275
252267253276
/*
@@ -252327,11 +253336,12 @@
252327253336
252328253337
aInst = &pCsr->aInst[3 * (nInst-1)];
252329253338
aInst[0] = iBest;
252330253339
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
252331253340
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
252332
- if( aInst[1]<0 || aInst[1]>=nCol ){
253341
+ assert( aInst[1]>=0 );
253342
+ if( aInst[1]>=nCol ){
252333253343
rc = FTS5_CORRUPT;
252334253344
break;
252335253345
}
252336253346
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
252337253347
}
@@ -252414,20 +253424,25 @@
252414253424
pCsr->aColumnSize[i] = -1;
252415253425
}
252416253426
}
252417253427
}else{
252418253428
int i;
253429
+ rc = fts5SeekCursor(pCsr, 0);
252419253430
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
252420253431
if( pConfig->abUnindexed[i]==0 ){
252421
- const char *z; int n;
252422
- void *p = (void*)(&pCsr->aColumnSize[i]);
253432
+ const char *z = 0;
253433
+ int n = 0;
253434
+ int bReset = 0;
253435
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253436
+
252423253437
pCsr->aColumnSize[i] = 0;
252424
- rc = fts5ApiColumnText(pCtx, i, &z, &n);
253438
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
252425253439
if( rc==SQLITE_OK ){
252426
- rc = sqlite3Fts5Tokenize(
252427
- pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
253440
+ rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
253441
+ z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
252428253442
);
253443
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
252429253444
}
252430253445
}
252431253446
}
252432253447
}
252433253448
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
@@ -252669,13 +253684,76 @@
252669253684
252670253685
252671253686
static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
252672253687
int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
252673253688
);
253689
+
253690
+/*
253691
+** The xColumnLocale() API.
253692
+*/
253693
+static int fts5ApiColumnLocale(
253694
+ Fts5Context *pCtx,
253695
+ int iCol,
253696
+ const char **pzLocale,
253697
+ int *pnLocale
253698
+){
253699
+ int rc = SQLITE_OK;
253700
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253701
+ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
253702
+
253703
+ *pzLocale = 0;
253704
+ *pnLocale = 0;
253705
+
253706
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
253707
+ if( iCol<0 || iCol>=pConfig->nCol ){
253708
+ rc = SQLITE_RANGE;
253709
+ }else if(
253710
+ pConfig->abUnindexed[iCol]==0
253711
+ && pConfig->eContent!=FTS5_CONTENT_NONE
253712
+ && pConfig->bLocale
253713
+ ){
253714
+ rc = fts5SeekCursor(pCsr, 0);
253715
+ if( rc==SQLITE_OK ){
253716
+ /* Load the value into pVal. pVal is a locale/text pair iff:
253717
+ **
253718
+ ** 1) It is an SQLITE_BLOB, and
253719
+ ** 2) Either the subtype is FTS5_LOCALE_SUBTYPE, or else the
253720
+ ** value was loaded from an FTS5_CONTENT_NORMAL table, and
253721
+ ** 3) It does not begin with an 0x00 byte.
253722
+ */
253723
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253724
+ if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
253725
+ const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
253726
+ int nBlob = sqlite3_value_bytes(pVal);
253727
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253728
+ const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253729
+ if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
253730
+ rc = SQLITE_ERROR;
253731
+ }
253732
+ pBlob += 4;
253733
+ nBlob -= 4;
253734
+ }
253735
+ if( rc==SQLITE_OK ){
253736
+ int nLocale = 0;
253737
+ for(nLocale=0; nLocale<nBlob && pBlob[nLocale]!=0x00; nLocale++);
253738
+ if( nLocale==nBlob || nLocale==0 ){
253739
+ rc = SQLITE_ERROR;
253740
+ }else{
253741
+ /* A locale/text pair */
253742
+ *pzLocale = (const char*)pBlob;
253743
+ *pnLocale = nLocale;
253744
+ }
253745
+ }
253746
+ }
253747
+ }
253748
+ }
253749
+
253750
+ return rc;
253751
+}
252674253752
252675253753
static const Fts5ExtensionApi sFts5Api = {
252676
- 3, /* iVersion */
253754
+ 4, /* iVersion */
252677253755
fts5ApiUserData,
252678253756
fts5ApiColumnCount,
252679253757
fts5ApiRowCount,
252680253758
fts5ApiColumnTotalSize,
252681253759
fts5ApiTokenize,
@@ -252692,11 +253770,13 @@
252692253770
fts5ApiPhraseFirst,
252693253771
fts5ApiPhraseNext,
252694253772
fts5ApiPhraseFirstColumn,
252695253773
fts5ApiPhraseNextColumn,
252696253774
fts5ApiQueryToken,
252697
- fts5ApiInstToken
253775
+ fts5ApiInstToken,
253776
+ fts5ApiColumnLocale,
253777
+ fts5ApiTokenize_v2
252698253778
};
252699253779
252700253780
/*
252701253781
** Implementation of API function xQueryPhrase().
252702253782
*/
@@ -252743,10 +253823,11 @@
252743253823
sqlite3_context *context,
252744253824
int argc,
252745253825
sqlite3_value **argv
252746253826
){
252747253827
assert( pCsr->pAux==0 );
253828
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
252748253829
pCsr->pAux = pAux;
252749253830
pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
252750253831
pCsr->pAux = 0;
252751253832
}
252752253833
@@ -252755,10 +253836,25 @@
252755253836
for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
252756253837
if( pCsr->iCsrId==iCsrId ) break;
252757253838
}
252758253839
return pCsr;
252759253840
}
253841
+
253842
+/*
253843
+** Parameter zFmt is a printf() style formatting string. This function
253844
+** formats it using the trailing arguments and returns the result as
253845
+** an error message to the context passed as the first argument.
253846
+*/
253847
+static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){
253848
+ char *zErr = 0;
253849
+ va_list ap;
253850
+ va_start(ap, zFmt);
253851
+ zErr = sqlite3_vmprintf(zFmt, ap);
253852
+ sqlite3_result_error(pCtx, zErr, -1);
253853
+ sqlite3_free(zErr);
253854
+ va_end(ap);
253855
+}
252760253856
252761253857
static void fts5ApiCallback(
252762253858
sqlite3_context *context,
252763253859
int argc,
252764253860
sqlite3_value **argv
@@ -252771,14 +253867,12 @@
252771253867
assert( argc>=1 );
252772253868
pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
252773253869
iCsrId = sqlite3_value_int64(argv[0]);
252774253870
252775253871
pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
252776
- if( pCsr==0 || pCsr->ePlan==0 ){
252777
- char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
252778
- sqlite3_result_error(context, zErr, -1);
252779
- sqlite3_free(zErr);
253872
+ if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){
253873
+ fts5ResultError(context, "no such cursor: %lld", iCsrId);
252780253874
}else{
252781253875
sqlite3_vtab *pTab = pCsr->base.pVtab;
252782253876
fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
252783253877
sqlite3_free(pTab->zErrMsg);
252784253878
pTab->zErrMsg = 0;
@@ -252867,10 +253961,61 @@
252867253961
}
252868253962
252869253963
sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
252870253964
return rc;
252871253965
}
253966
+
253967
+/*
253968
+** Value pVal was read from column iCol of the FTS5 table. This function
253969
+** returns it to the owner of pCtx via a call to an sqlite3_result_xxx()
253970
+** function. This function deals with the same cases as
253971
+** sqlite3Fts5ExtractText():
253972
+**
253973
+** 1) Ordinary values. These can be returned using sqlite3_result_value().
253974
+**
253975
+** 2) Blobs from fts5_locale(). The text is extracted from these and
253976
+** returned via sqlite3_result_text(). The locale is discarded.
253977
+*/
253978
+static void fts5ExtractValueFromColumn(
253979
+ sqlite3_context *pCtx,
253980
+ Fts5Config *pConfig,
253981
+ int iCol,
253982
+ sqlite3_value *pVal
253983
+){
253984
+ assert( pConfig->eContent!=FTS5_CONTENT_NONE );
253985
+
253986
+ if( pConfig->bLocale
253987
+ && sqlite3_value_type(pVal)==SQLITE_BLOB
253988
+ && pConfig->abUnindexed[iCol]==0
253989
+ ){
253990
+ const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253991
+ const u8 *pBlob = sqlite3_value_blob(pVal);
253992
+ int nBlob = sqlite3_value_bytes(pVal);
253993
+ int ii;
253994
+
253995
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253996
+ if( nBlob<SZHDR || memcmp(pBlob, FTS5_LOCALE_HEADER, SZHDR) ){
253997
+ sqlite3_result_error_code(pCtx, SQLITE_ERROR);
253998
+ return;
253999
+ }else{
254000
+ pBlob += 4;
254001
+ nBlob -= 4;
254002
+ }
254003
+ }
254004
+
254005
+ for(ii=0; ii<nBlob && pBlob[ii]; ii++);
254006
+ if( ii==0 || ii==nBlob ){
254007
+ sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254008
+ }else{
254009
+ const char *pText = (const char*)&pBlob[ii+1];
254010
+ sqlite3_result_text(pCtx, pText, nBlob-ii-1, SQLITE_TRANSIENT);
254011
+ }
254012
+ return;
254013
+ }
254014
+
254015
+ sqlite3_result_value(pCtx, pVal);
254016
+}
252872254017
252873254018
/*
252874254019
** This is the xColumn method, called by SQLite to request a value from
252875254020
** the row that the supplied cursor currently points to.
252876254021
*/
@@ -252897,12 +254042,12 @@
252897254042
** as the table. Return the cursor integer id number. This value is only
252898254043
** useful in that it may be passed as the first argument to an FTS5
252899254044
** auxiliary function. */
252900254045
sqlite3_result_int64(pCtx, pCsr->iCsrId);
252901254046
}else if( iCol==pConfig->nCol+1 ){
252902
-
252903254047
/* The value of the "rank" column. */
254048
+
252904254049
if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
252905254050
fts5PoslistBlob(pCtx, pCsr);
252906254051
}else if(
252907254052
pCsr->ePlan==FTS5_PLAN_MATCH
252908254053
|| pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
@@ -252909,24 +254054,31 @@
252909254054
){
252910254055
if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
252911254056
fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
252912254057
}
252913254058
}
252914
- }else if( !fts5IsContentless(pTab) ){
252915
- pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
252916
- rc = fts5SeekCursor(pCsr, 1);
252917
- if( rc==SQLITE_OK ){
252918
- sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
252919
- }
252920
- pConfig->pzErrmsg = 0;
252921
- }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){
252922
- char *zErr = sqlite3_mprintf("cannot UPDATE a subset of "
252923
- "columns on fts5 contentless-delete table: %s", pConfig->zName
252924
- );
252925
- sqlite3_result_error(pCtx, zErr, -1);
252926
- sqlite3_free(zErr);
252927
- }
254059
+ }else{
254060
+ /* A column created by the user containing values. */
254061
+ int bNochange = sqlite3_vtab_nochange(pCtx);
254062
+
254063
+ if( fts5IsContentless(pTab) ){
254064
+ if( bNochange && pConfig->bContentlessDelete ){
254065
+ fts5ResultError(pCtx, "cannot UPDATE a subset of "
254066
+ "columns on fts5 contentless-delete table: %s", pConfig->zName
254067
+ );
254068
+ }
254069
+ }else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){
254070
+ pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
254071
+ rc = fts5SeekCursor(pCsr, 1);
254072
+ if( rc==SQLITE_OK ){
254073
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
254074
+ fts5ExtractValueFromColumn(pCtx, pConfig, iCol, pVal);
254075
+ }
254076
+ pConfig->pzErrmsg = 0;
254077
+ }
254078
+ }
254079
+
252928254080
return rc;
252929254081
}
252930254082
252931254083
252932254084
/*
@@ -253060,53 +254212,214 @@
253060254212
}
253061254213
}
253062254214
253063254215
return rc;
253064254216
}
254217
+
254218
+/*
254219
+** This function is used by xCreateTokenizer_v2() and xCreateTokenizer().
254220
+** It allocates and partially populates a new Fts5TokenizerModule object.
254221
+** The new object is already linked into the Fts5Global context before
254222
+** returning.
254223
+**
254224
+** If successful, SQLITE_OK is returned and a pointer to the new
254225
+** Fts5TokenizerModule object returned via output parameter (*ppNew). All
254226
+** that is required is for the caller to fill in the methods in
254227
+** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native
254228
+** as appropriate.
254229
+**
254230
+** If an error occurs, an SQLite error code is returned and the final value
254231
+** of (*ppNew) undefined.
254232
+*/
254233
+static int fts5NewTokenizerModule(
254234
+ Fts5Global *pGlobal, /* Global context (one per db handle) */
254235
+ const char *zName, /* Name of new function */
254236
+ void *pUserData, /* User data for aux. function */
254237
+ void(*xDestroy)(void*), /* Destructor for pUserData */
254238
+ Fts5TokenizerModule **ppNew
254239
+){
254240
+ int rc = SQLITE_OK;
254241
+ Fts5TokenizerModule *pNew;
254242
+ sqlite3_int64 nName; /* Size of zName and its \0 terminator */
254243
+ sqlite3_int64 nByte; /* Bytes of space to allocate */
254244
+
254245
+ nName = strlen(zName) + 1;
254246
+ nByte = sizeof(Fts5TokenizerModule) + nName;
254247
+ *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte);
254248
+ if( pNew ){
254249
+ pNew->zName = (char*)&pNew[1];
254250
+ memcpy(pNew->zName, zName, nName);
254251
+ pNew->pUserData = pUserData;
254252
+ pNew->xDestroy = xDestroy;
254253
+ pNew->pNext = pGlobal->pTok;
254254
+ pGlobal->pTok = pNew;
254255
+ if( pNew->pNext==0 ){
254256
+ pGlobal->pDfltTok = pNew;
254257
+ }
254258
+ }
254259
+
254260
+ return rc;
254261
+}
254262
+
254263
+/*
254264
+** An instance of this type is used as the Fts5Tokenizer object for
254265
+** wrapper tokenizers - those that provide access to a v1 tokenizer via
254266
+** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
254267
+** via the fts5_tokenizer API.
254268
+*/
254269
+typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
254270
+struct Fts5VtoVTokenizer {
254271
+ Fts5TokenizerModule *pMod;
254272
+ Fts5Tokenizer *pReal;
254273
+};
254274
+
254275
+/*
254276
+** Create a wrapper tokenizer. The context argument pCtx points to the
254277
+** Fts5TokenizerModule object.
254278
+*/
254279
+static int fts5VtoVCreate(
254280
+ void *pCtx,
254281
+ const char **azArg,
254282
+ int nArg,
254283
+ Fts5Tokenizer **ppOut
254284
+){
254285
+ Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx;
254286
+ Fts5VtoVTokenizer *pNew = 0;
254287
+ int rc = SQLITE_OK;
254288
+
254289
+ pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
254290
+ if( rc==SQLITE_OK ){
254291
+ pNew->pMod = pMod;
254292
+ if( pMod->bV2Native ){
254293
+ rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254294
+ }else{
254295
+ rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254296
+ }
254297
+ if( rc!=SQLITE_OK ){
254298
+ sqlite3_free(pNew);
254299
+ pNew = 0;
254300
+ }
254301
+ }
254302
+
254303
+ *ppOut = (Fts5Tokenizer*)pNew;
254304
+ return rc;
254305
+}
254306
+
254307
+/*
254308
+** Delete an Fts5VtoVTokenizer wrapper tokenizer.
254309
+*/
254310
+static void fts5VtoVDelete(Fts5Tokenizer *pTok){
254311
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254312
+ if( p ){
254313
+ Fts5TokenizerModule *pMod = p->pMod;
254314
+ if( pMod->bV2Native ){
254315
+ pMod->x2.xDelete(p->pReal);
254316
+ }else{
254317
+ pMod->x1.xDelete(p->pReal);
254318
+ }
254319
+ sqlite3_free(p);
254320
+ }
254321
+}
254322
+
254323
+
254324
+/*
254325
+** xTokenizer method for a wrapper tokenizer that offers the v1 interface
254326
+** (no support for locales).
254327
+*/
254328
+static int fts5V1toV2Tokenize(
254329
+ Fts5Tokenizer *pTok,
254330
+ void *pCtx, int flags,
254331
+ const char *pText, int nText,
254332
+ int (*xToken)(void*, int, const char*, int, int, int)
254333
+){
254334
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254335
+ Fts5TokenizerModule *pMod = p->pMod;
254336
+ assert( pMod->bV2Native );
254337
+ return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
254338
+}
254339
+
254340
+/*
254341
+** xTokenizer method for a wrapper tokenizer that offers the v2 interface
254342
+** (with locale support).
254343
+*/
254344
+static int fts5V2toV1Tokenize(
254345
+ Fts5Tokenizer *pTok,
254346
+ void *pCtx, int flags,
254347
+ const char *pText, int nText,
254348
+ const char *pLocale, int nLocale,
254349
+ int (*xToken)(void*, int, const char*, int, int, int)
254350
+){
254351
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254352
+ Fts5TokenizerModule *pMod = p->pMod;
254353
+ assert( pMod->bV2Native==0 );
254354
+ return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254355
+}
253065254356
253066254357
/*
253067254358
** Register a new tokenizer. This is the implementation of the
253068
-** fts5_api.xCreateTokenizer() method.
254359
+** fts5_api.xCreateTokenizer_v2() method.
254360
+*/
254361
+static int fts5CreateTokenizer_v2(
254362
+ fts5_api *pApi, /* Global context (one per db handle) */
254363
+ const char *zName, /* Name of new function */
254364
+ void *pUserData, /* User data for aux. function */
254365
+ fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */
254366
+ void(*xDestroy)(void*) /* Destructor for pUserData */
254367
+){
254368
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
254369
+ int rc = SQLITE_OK;
254370
+
254371
+ if( pTokenizer->iVersion>2 ){
254372
+ rc = SQLITE_ERROR;
254373
+ }else{
254374
+ Fts5TokenizerModule *pNew = 0;
254375
+ rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew);
254376
+ if( pNew ){
254377
+ pNew->x2 = *pTokenizer;
254378
+ pNew->bV2Native = 1;
254379
+ pNew->x1.xCreate = fts5VtoVCreate;
254380
+ pNew->x1.xTokenize = fts5V1toV2Tokenize;
254381
+ pNew->x1.xDelete = fts5VtoVDelete;
254382
+ }
254383
+ }
254384
+
254385
+ return rc;
254386
+}
254387
+
254388
+/*
254389
+** The fts5_api.xCreateTokenizer() method.
253069254390
*/
253070254391
static int fts5CreateTokenizer(
253071254392
fts5_api *pApi, /* Global context (one per db handle) */
253072254393
const char *zName, /* Name of new function */
253073254394
void *pUserData, /* User data for aux. function */
253074254395
fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
253075254396
void(*xDestroy)(void*) /* Destructor for pUserData */
253076254397
){
253077
- Fts5Global *pGlobal = (Fts5Global*)pApi;
253078
- Fts5TokenizerModule *pNew;
253079
- sqlite3_int64 nName; /* Size of zName and its \0 terminator */
253080
- sqlite3_int64 nByte; /* Bytes of space to allocate */
254398
+ Fts5TokenizerModule *pNew = 0;
253081254399
int rc = SQLITE_OK;
253082254400
253083
- nName = strlen(zName) + 1;
253084
- nByte = sizeof(Fts5TokenizerModule) + nName;
253085
- pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
254401
+ rc = fts5NewTokenizerModule(
254402
+ (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew
254403
+ );
253086254404
if( pNew ){
253087
- memset(pNew, 0, (size_t)nByte);
253088
- pNew->zName = (char*)&pNew[1];
253089
- memcpy(pNew->zName, zName, nName);
253090
- pNew->pUserData = pUserData;
253091
- pNew->x = *pTokenizer;
253092
- pNew->xDestroy = xDestroy;
253093
- pNew->pNext = pGlobal->pTok;
253094
- pGlobal->pTok = pNew;
253095
- if( pNew->pNext==0 ){
253096
- pGlobal->pDfltTok = pNew;
253097
- }
253098
- }else{
253099
- rc = SQLITE_NOMEM;
253100
- }
253101
-
254405
+ pNew->x1 = *pTokenizer;
254406
+ pNew->x2.xCreate = fts5VtoVCreate;
254407
+ pNew->x2.xTokenize = fts5V2toV1Tokenize;
254408
+ pNew->x2.xDelete = fts5VtoVDelete;
254409
+ }
253102254410
return rc;
253103254411
}
253104254412
254413
+/*
254414
+** Search the global context passed as the first argument for a tokenizer
254415
+** module named zName. If found, return a pointer to the Fts5TokenizerModule
254416
+** object. Otherwise, return NULL.
254417
+*/
253105254418
static Fts5TokenizerModule *fts5LocateTokenizer(
253106
- Fts5Global *pGlobal,
253107
- const char *zName
254419
+ Fts5Global *pGlobal, /* Global (one per db handle) object */
254420
+ const char *zName /* Name of tokenizer module to find */
253108254421
){
253109254422
Fts5TokenizerModule *pMod = 0;
253110254423
253111254424
if( zName==0 ){
253112254425
pMod = pGlobal->pDfltTok;
@@ -253116,10 +254429,40 @@
253116254429
}
253117254430
}
253118254431
253119254432
return pMod;
253120254433
}
254434
+
254435
+/*
254436
+** Find a tokenizer. This is the implementation of the
254437
+** fts5_api.xFindTokenizer_v2() method.
254438
+*/
254439
+static int fts5FindTokenizer_v2(
254440
+ fts5_api *pApi, /* Global context (one per db handle) */
254441
+ const char *zName, /* Name of tokenizer */
254442
+ void **ppUserData,
254443
+ fts5_tokenizer_v2 **ppTokenizer /* Populate this object */
254444
+){
254445
+ int rc = SQLITE_OK;
254446
+ Fts5TokenizerModule *pMod;
254447
+
254448
+ pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
254449
+ if( pMod ){
254450
+ if( pMod->bV2Native ){
254451
+ *ppUserData = pMod->pUserData;
254452
+ }else{
254453
+ *ppUserData = (void*)pMod;
254454
+ }
254455
+ *ppTokenizer = &pMod->x2;
254456
+ }else{
254457
+ *ppTokenizer = 0;
254458
+ *ppUserData = 0;
254459
+ rc = SQLITE_ERROR;
254460
+ }
254461
+
254462
+ return rc;
254463
+}
253121254464
253122254465
/*
253123254466
** Find a tokenizer. This is the implementation of the
253124254467
** fts5_api.xFindTokenizer() method.
253125254468
*/
@@ -253132,70 +254475,79 @@
253132254475
int rc = SQLITE_OK;
253133254476
Fts5TokenizerModule *pMod;
253134254477
253135254478
pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
253136254479
if( pMod ){
253137
- *pTokenizer = pMod->x;
253138
- *ppUserData = pMod->pUserData;
253139
- }else{
253140
- memset(pTokenizer, 0, sizeof(fts5_tokenizer));
253141
- rc = SQLITE_ERROR;
253142
- }
253143
-
253144
- return rc;
253145
-}
253146
-
253147
-int fts5GetTokenizer(
253148
- Fts5Global *pGlobal,
253149
- const char **azArg,
253150
- int nArg,
253151
- Fts5Config *pConfig,
253152
- char **pzErr
253153
-){
253154
- Fts5TokenizerModule *pMod;
253155
- int rc = SQLITE_OK;
253156
-
253157
- pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
253158
- if( pMod==0 ){
253159
- assert( nArg>0 );
253160
- rc = SQLITE_ERROR;
253161
- if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
253162
- }else{
253163
- rc = pMod->x.xCreate(
253164
- pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
253165
- );
253166
- pConfig->t.pTokApi = &pMod->x;
253167
- if( rc!=SQLITE_OK ){
253168
- if( pzErr && rc!=SQLITE_NOMEM ){
253169
- *pzErr = sqlite3_mprintf("error in tokenizer constructor");
253170
- }
253171
- }else{
253172
- pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
253173
- pMod->x.xCreate, pConfig->t.pTok
253174
- );
253175
- }
253176
- }
253177
-
253178
- if( rc!=SQLITE_OK ){
253179
- pConfig->t.pTokApi = 0;
253180
- pConfig->t.pTok = 0;
254480
+ if( pMod->bV2Native==0 ){
254481
+ *ppUserData = pMod->pUserData;
254482
+ }else{
254483
+ *ppUserData = (void*)pMod;
254484
+ }
254485
+ *pTokenizer = pMod->x1;
254486
+ }else{
254487
+ memset(pTokenizer, 0, sizeof(*pTokenizer));
254488
+ *ppUserData = 0;
254489
+ rc = SQLITE_ERROR;
253181254490
}
253182254491
253183254492
return rc;
253184254493
}
253185254494
253186254495
/*
253187254496
** Attempt to instantiate the tokenizer.
253188254497
*/
253189254498
static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
253190
- return fts5GetTokenizer(
253191
- pConfig->pGlobal, pConfig->t.azArg, pConfig->t.nArg,
253192
- pConfig, pConfig->pzErrmsg
253193
- );
254499
+ const char **azArg = pConfig->t.azArg;
254500
+ const int nArg = pConfig->t.nArg;
254501
+ Fts5TokenizerModule *pMod = 0;
254502
+ int rc = SQLITE_OK;
254503
+
254504
+ pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]);
254505
+ if( pMod==0 ){
254506
+ assert( nArg>0 );
254507
+ rc = SQLITE_ERROR;
254508
+ sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]);
254509
+ }else{
254510
+ int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0;
254511
+ if( pMod->bV2Native ){
254512
+ xCreate = pMod->x2.xCreate;
254513
+ pConfig->t.pApi2 = &pMod->x2;
254514
+ }else{
254515
+ pConfig->t.pApi1 = &pMod->x1;
254516
+ xCreate = pMod->x1.xCreate;
254517
+ }
254518
+
254519
+ rc = xCreate(pMod->pUserData,
254520
+ (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
254521
+ );
254522
+
254523
+ if( rc!=SQLITE_OK ){
254524
+ if( rc!=SQLITE_NOMEM ){
254525
+ sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor");
254526
+ }
254527
+ }else if( pMod->bV2Native==0 ){
254528
+ pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
254529
+ pMod->x1.xCreate, pConfig->t.pTok
254530
+ );
254531
+ }
254532
+ }
254533
+
254534
+ if( rc!=SQLITE_OK ){
254535
+ pConfig->t.pApi1 = 0;
254536
+ pConfig->t.pApi2 = 0;
254537
+ pConfig->t.pTok = 0;
254538
+ }
254539
+
254540
+ return rc;
253194254541
}
253195254542
253196254543
254544
+/*
254545
+** xDestroy callback passed to sqlite3_create_module(). This is invoked
254546
+** when the db handle is being closed. Free memory associated with
254547
+** tokenizers and aux functions registered with this db handle.
254548
+*/
253197254549
static void fts5ModuleDestroy(void *pCtx){
253198254550
Fts5TokenizerModule *pTok, *pNextTok;
253199254551
Fts5Auxiliary *pAux, *pNextAux;
253200254552
Fts5Global *pGlobal = (Fts5Global*)pCtx;
253201254553
@@ -253212,10 +254564,14 @@
253212254564
}
253213254565
253214254566
sqlite3_free(pGlobal);
253215254567
}
253216254568
254569
+/*
254570
+** Implementation of the fts5() function used by clients to obtain the
254571
+** API pointer.
254572
+*/
253217254573
static void fts5Fts5Func(
253218254574
sqlite3_context *pCtx, /* Function call context */
253219254575
int nArg, /* Number of args */
253220254576
sqlite3_value **apArg /* Function arguments */
253221254577
){
@@ -253235,11 +254591,74 @@
253235254591
int nArg, /* Number of args */
253236254592
sqlite3_value **apUnused /* Function arguments */
253237254593
){
253238254594
assert( nArg==0 );
253239254595
UNUSED_PARAM2(nArg, apUnused);
253240
- sqlite3_result_text(pCtx, "fts5: 2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9", -1, SQLITE_TRANSIENT);
254596
+ sqlite3_result_text(pCtx, "fts5: 2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b31f96", -1, SQLITE_TRANSIENT);
254597
+}
254598
+
254599
+/*
254600
+** Implementation of fts5_locale(LOCALE, TEXT) function.
254601
+**
254602
+** If parameter LOCALE is NULL, or a zero-length string, then a copy of
254603
+** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
254604
+** text, and the value returned is a blob consisting of:
254605
+**
254606
+** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER).
254607
+** * The LOCALE, as utf-8 text, followed by
254608
+** * 0x00, followed by
254609
+** * The TEXT, as utf-8 text.
254610
+**
254611
+** There is no final nul-terminator following the TEXT value.
254612
+*/
254613
+static void fts5LocaleFunc(
254614
+ sqlite3_context *pCtx, /* Function call context */
254615
+ int nArg, /* Number of args */
254616
+ sqlite3_value **apArg /* Function arguments */
254617
+){
254618
+ const char *zLocale = 0;
254619
+ int nLocale = 0;
254620
+ const char *zText = 0;
254621
+ int nText = 0;
254622
+
254623
+ assert( nArg==2 );
254624
+ UNUSED_PARAM(nArg);
254625
+
254626
+ zLocale = (const char*)sqlite3_value_text(apArg[0]);
254627
+ nLocale = sqlite3_value_bytes(apArg[0]);
254628
+
254629
+ zText = (const char*)sqlite3_value_text(apArg[1]);
254630
+ nText = sqlite3_value_bytes(apArg[1]);
254631
+
254632
+ if( zLocale==0 || zLocale[0]=='\0' ){
254633
+ sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
254634
+ }else{
254635
+ u8 *pBlob = 0;
254636
+ u8 *pCsr = 0;
254637
+ int nBlob = 0;
254638
+ const int nHdr = 4;
254639
+ assert( sizeof(FTS5_LOCALE_HEADER)==nHdr+1 );
254640
+
254641
+ nBlob = nHdr + nLocale + 1 + nText;
254642
+ pBlob = (u8*)sqlite3_malloc(nBlob);
254643
+ if( pBlob==0 ){
254644
+ sqlite3_result_error_nomem(pCtx);
254645
+ return;
254646
+ }
254647
+
254648
+ pCsr = pBlob;
254649
+ memcpy(pCsr, FTS5_LOCALE_HEADER, nHdr);
254650
+ pCsr += nHdr;
254651
+ memcpy(pCsr, zLocale, nLocale);
254652
+ pCsr += nLocale;
254653
+ (*pCsr++) = 0x00;
254654
+ if( zText ) memcpy(pCsr, zText, nText);
254655
+ assert( &pCsr[nText]==&pBlob[nBlob] );
254656
+
254657
+ sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
254658
+ sqlite3_result_subtype(pCtx, FTS5_LOCALE_SUBTYPE);
254659
+ }
253241254660
}
253242254661
253243254662
/*
253244254663
** Return true if zName is the extension on one of the shadow tables used
253245254664
** by this module.
@@ -253330,14 +254749,16 @@
253330254749
rc = SQLITE_NOMEM;
253331254750
}else{
253332254751
void *p = (void*)pGlobal;
253333254752
memset(pGlobal, 0, sizeof(Fts5Global));
253334254753
pGlobal->db = db;
253335
- pGlobal->api.iVersion = 2;
254754
+ pGlobal->api.iVersion = 3;
253336254755
pGlobal->api.xCreateFunction = fts5CreateAux;
253337254756
pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
253338254757
pGlobal->api.xFindTokenizer = fts5FindTokenizer;
254758
+ pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
254759
+ pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
253339254760
rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
253340254761
if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
253341254762
if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
253342254763
if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
253343254764
if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -253351,10 +254772,17 @@
253351254772
rc = sqlite3_create_function(
253352254773
db, "fts5_source_id", 0,
253353254774
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
253354254775
p, fts5SourceIdFunc, 0, 0
253355254776
);
254777
+ }
254778
+ if( rc==SQLITE_OK ){
254779
+ rc = sqlite3_create_function(
254780
+ db, "fts5_locale", 2,
254781
+ SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
254782
+ p, fts5LocaleFunc, 0, 0
254783
+ );
253356254784
}
253357254785
}
253358254786
253359254787
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
253360254788
** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -253426,17 +254854,44 @@
253426254854
253427254855
253428254856
253429254857
/* #include "fts5Int.h" */
253430254858
254859
+/*
254860
+** pSavedRow:
254861
+** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it
254862
+** does a by-rowid lookup to retrieve a single row from the %_content
254863
+** table or equivalent external-content table/view.
254864
+**
254865
+** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original
254866
+** values for a row being UPDATEd. In that case, the SQL statement is
254867
+** not reset and pSavedRow is set to point at it. This is so that the
254868
+** insert operation that follows the delete may access the original
254869
+** row values for any new values for which sqlite3_value_nochange() returns
254870
+** true. i.e. if the user executes:
254871
+**
254872
+** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1);
254873
+** ...
254874
+** UPDATE fts SET a=?, b=? WHERE rowid=?;
254875
+**
254876
+** then the value passed to the xUpdate() method of this table as the
254877
+** new.c value is an sqlite3_value_nochange() value. So in this case it
254878
+** must be read from the saved row stored in Fts5Storage.pSavedRow.
254879
+**
254880
+** This is necessary - using sqlite3_value_nochange() instead of just having
254881
+** SQLite pass the original value back via xUpdate() - so as not to discard
254882
+** any locale information associated with such values.
254883
+**
254884
+*/
253431254885
struct Fts5Storage {
253432254886
Fts5Config *pConfig;
253433254887
Fts5Index *pIndex;
253434254888
int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
253435254889
i64 nTotalRow; /* Total number of rows in FTS table */
253436254890
i64 *aTotalSize; /* Total sizes of each column */
253437
- sqlite3_stmt *aStmt[11];
254891
+ sqlite3_stmt *pSavedRow;
254892
+ sqlite3_stmt *aStmt[12];
253438254893
};
253439254894
253440254895
253441254896
#if FTS5_STMT_SCAN_ASC!=0
253442254897
# error "FTS5_STMT_SCAN_ASC mismatch"
@@ -253446,18 +254901,19 @@
253446254901
#endif
253447254902
#if FTS5_STMT_LOOKUP!=2
253448254903
# error "FTS5_STMT_LOOKUP mismatch"
253449254904
#endif
253450254905
253451
-#define FTS5_STMT_INSERT_CONTENT 3
253452
-#define FTS5_STMT_REPLACE_CONTENT 4
253453
-#define FTS5_STMT_DELETE_CONTENT 5
253454
-#define FTS5_STMT_REPLACE_DOCSIZE 6
253455
-#define FTS5_STMT_DELETE_DOCSIZE 7
253456
-#define FTS5_STMT_LOOKUP_DOCSIZE 8
253457
-#define FTS5_STMT_REPLACE_CONFIG 9
253458
-#define FTS5_STMT_SCAN 10
254906
+#define FTS5_STMT_LOOKUP2 3
254907
+#define FTS5_STMT_INSERT_CONTENT 4
254908
+#define FTS5_STMT_REPLACE_CONTENT 5
254909
+#define FTS5_STMT_DELETE_CONTENT 6
254910
+#define FTS5_STMT_REPLACE_DOCSIZE 7
254911
+#define FTS5_STMT_DELETE_DOCSIZE 8
254912
+#define FTS5_STMT_LOOKUP_DOCSIZE 9
254913
+#define FTS5_STMT_REPLACE_CONFIG 10
254914
+#define FTS5_STMT_SCAN 11
253459254915
253460254916
/*
253461254917
** Prepare the two insert statements - Fts5Storage.pInsertContent and
253462254918
** Fts5Storage.pInsertDocsize - if they have not already been prepared.
253463254919
** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -253483,10 +254939,11 @@
253483254939
if( p->aStmt[eStmt]==0 ){
253484254940
const char *azStmt[] = {
253485254941
"SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
253486254942
"SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
253487254943
"SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
254944
+ "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */
253488254945
253489254946
"INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
253490254947
"REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
253491254948
"DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
253492254949
"REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */
@@ -253497,10 +254954,12 @@
253497254954
"REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
253498254955
"SELECT %s FROM %s AS T", /* SCAN */
253499254956
};
253500254957
Fts5Config *pC = p->pConfig;
253501254958
char *zSql = 0;
254959
+
254960
+ assert( ArraySize(azStmt)==ArraySize(p->aStmt) );
253502254961
253503254962
switch( eStmt ){
253504254963
case FTS5_STMT_SCAN:
253505254964
zSql = sqlite3_mprintf(azStmt[eStmt],
253506254965
pC->zContentExprlist, pC->zContent
@@ -253514,10 +254973,11 @@
253514254973
pC->zContentRowid
253515254974
);
253516254975
break;
253517254976
253518254977
case FTS5_STMT_LOOKUP:
254978
+ case FTS5_STMT_LOOKUP2:
253519254979
zSql = sqlite3_mprintf(azStmt[eStmt],
253520254980
pC->zContentExprlist, pC->zContent, pC->zContentRowid
253521254981
);
253522254982
break;
253523254983
@@ -253560,11 +255020,11 @@
253560255020
253561255021
if( zSql==0 ){
253562255022
rc = SQLITE_NOMEM;
253563255023
}else{
253564255024
int f = SQLITE_PREPARE_PERSISTENT;
253565
- if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
255025
+ if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB;
253566255026
p->pConfig->bLock++;
253567255027
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
253568255028
p->pConfig->bLock--;
253569255029
sqlite3_free(zSql);
253570255030
if( rc!=SQLITE_OK && pzErrMsg ){
@@ -253808,74 +255268,141 @@
253808255268
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
253809255269
pCtx->szCol++;
253810255270
}
253811255271
return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
253812255272
}
255273
+
255274
+/*
255275
+** This function is used as part of an UPDATE statement that modifies the
255276
+** rowid of a row. In that case, this function is called first to set
255277
+** Fts5Storage.pSavedRow to point to a statement that may be used to
255278
+** access the original values of the row being deleted - iDel.
255279
+**
255280
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
255281
+** It is not considered an error if row iDel does not exist. In this case
255282
+** pSavedRow is not set and SQLITE_OK returned.
255283
+*/
255284
+static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){
255285
+ int rc = SQLITE_OK;
255286
+ sqlite3_stmt *pSeek = 0;
255287
+
255288
+ assert( p->pSavedRow==0 );
255289
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0);
255290
+ if( rc==SQLITE_OK ){
255291
+ sqlite3_bind_int64(pSeek, 1, iDel);
255292
+ if( sqlite3_step(pSeek)!=SQLITE_ROW ){
255293
+ rc = sqlite3_reset(pSeek);
255294
+ }else{
255295
+ p->pSavedRow = pSeek;
255296
+ }
255297
+ }
255298
+
255299
+ return rc;
255300
+}
253813255301
253814255302
/*
253815255303
** If a row with rowid iDel is present in the %_content table, add the
253816255304
** delete-markers to the FTS index necessary to delete it. Do not actually
253817255305
** remove the %_content row at this time though.
255306
+**
255307
+** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left
255308
+** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access
255309
+** the original values of the row being deleted. This is used by UPDATE
255310
+** statements.
253818255311
*/
253819255312
static int fts5StorageDeleteFromIndex(
253820255313
Fts5Storage *p,
253821255314
i64 iDel,
253822
- sqlite3_value **apVal
255315
+ sqlite3_value **apVal,
255316
+ int bSaveRow /* True to set pSavedRow */
253823255317
){
253824255318
Fts5Config *pConfig = p->pConfig;
253825255319
sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
253826255320
int rc = SQLITE_OK; /* Return code */
253827255321
int rc2; /* sqlite3_reset() return code */
253828255322
int iCol;
253829255323
Fts5InsertCtx ctx;
253830255324
255325
+ assert( bSaveRow==0 || apVal==0 );
255326
+ assert( bSaveRow==0 || bSaveRow==1 );
255327
+ assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 );
255328
+
253831255329
if( apVal==0 ){
253832
- rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
253833
- if( rc!=SQLITE_OK ) return rc;
253834
- sqlite3_bind_int64(pSeek, 1, iDel);
253835
- if( sqlite3_step(pSeek)!=SQLITE_ROW ){
253836
- return sqlite3_reset(pSeek);
255330
+ if( p->pSavedRow && bSaveRow ){
255331
+ pSeek = p->pSavedRow;
255332
+ p->pSavedRow = 0;
255333
+ }else{
255334
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0);
255335
+ if( rc!=SQLITE_OK ) return rc;
255336
+ sqlite3_bind_int64(pSeek, 1, iDel);
255337
+ if( sqlite3_step(pSeek)!=SQLITE_ROW ){
255338
+ return sqlite3_reset(pSeek);
255339
+ }
253837255340
}
253838255341
}
253839255342
253840255343
ctx.pStorage = p;
253841255344
ctx.iCol = -1;
253842255345
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
253843255346
if( pConfig->abUnindexed[iCol-1]==0 ){
253844
- const char *zText;
253845
- int nText;
255347
+ sqlite3_value *pVal = 0;
255348
+ const char *pText = 0;
255349
+ int nText = 0;
255350
+ int bReset = 0;
255351
+
253846255352
assert( pSeek==0 || apVal==0 );
253847255353
assert( pSeek!=0 || apVal!=0 );
253848255354
if( pSeek ){
253849
- zText = (const char*)sqlite3_column_text(pSeek, iCol);
253850
- nText = sqlite3_column_bytes(pSeek, iCol);
253851
- }else if( ALWAYS(apVal) ){
253852
- zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
253853
- nText = sqlite3_value_bytes(apVal[iCol-1]);
255355
+ pVal = sqlite3_column_value(pSeek, iCol);
253854255356
}else{
253855
- continue;
255357
+ pVal = apVal[iCol-1];
253856255358
}
253857
- ctx.szCol = 0;
253858
- rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
253859
- zText, nText, (void*)&ctx, fts5StorageInsertCallback
255359
+
255360
+ rc = sqlite3Fts5ExtractText(
255361
+ pConfig, pVal, pSeek!=0, &bReset, &pText, &nText
253860255362
);
253861
- p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
253862
- if( p->aTotalSize[iCol-1]<0 && rc==SQLITE_OK ){
253863
- rc = FTS5_CORRUPT;
255363
+ if( rc==SQLITE_OK ){
255364
+ ctx.szCol = 0;
255365
+ rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
255366
+ pText, nText, (void*)&ctx, fts5StorageInsertCallback
255367
+ );
255368
+ p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
255369
+ if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
255370
+ rc = FTS5_CORRUPT;
255371
+ }
255372
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253864255373
}
253865255374
}
253866255375
}
253867255376
if( rc==SQLITE_OK && p->nTotalRow<1 ){
253868255377
rc = FTS5_CORRUPT;
253869255378
}else{
253870255379
p->nTotalRow--;
253871255380
}
253872255381
253873
- rc2 = sqlite3_reset(pSeek);
253874
- if( rc==SQLITE_OK ) rc = rc2;
255382
+ if( rc==SQLITE_OK && bSaveRow ){
255383
+ assert( p->pSavedRow==0 );
255384
+ p->pSavedRow = pSeek;
255385
+ }else{
255386
+ rc2 = sqlite3_reset(pSeek);
255387
+ if( rc==SQLITE_OK ) rc = rc2;
255388
+ }
253875255389
return rc;
253876255390
}
255391
+
255392
+/*
255393
+** Reset any saved statement pSavedRow. Zero pSavedRow as well. This
255394
+** should be called by the xUpdate() method of the fts5 table before
255395
+** returning from any operation that may have set Fts5Storage.pSavedRow.
255396
+*/
255397
+static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){
255398
+ assert( pStorage->pSavedRow==0
255399
+ || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2]
255400
+ );
255401
+ sqlite3_reset(pStorage->pSavedRow);
255402
+ pStorage->pSavedRow = 0;
255403
+}
253877255404
253878255405
/*
253879255406
** This function is called to process a DELETE on a contentless_delete=1
253880255407
** table. It adds the tombstone required to delete the entry with rowid
253881255408
** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs,
@@ -253929,16 +255456,16 @@
253929255456
if( p->pConfig->bContentlessDelete ){
253930255457
i64 iOrigin = 0;
253931255458
rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
253932255459
sqlite3_bind_int64(pReplace, 3, iOrigin);
253933255460
}
253934
- if( rc==SQLITE_OK ){
253935
- sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
253936
- sqlite3_step(pReplace);
253937
- rc = sqlite3_reset(pReplace);
253938
- sqlite3_bind_null(pReplace, 2);
253939
- }
255461
+ }
255462
+ if( rc==SQLITE_OK ){
255463
+ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
255464
+ sqlite3_step(pReplace);
255465
+ rc = sqlite3_reset(pReplace);
255466
+ sqlite3_bind_null(pReplace, 2);
253940255467
}
253941255468
}
253942255469
return rc;
253943255470
}
253944255471
@@ -253988,11 +255515,16 @@
253988255515
}
253989255516
253990255517
/*
253991255518
** Remove a row from the FTS table.
253992255519
*/
253993
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
255520
+static int sqlite3Fts5StorageDelete(
255521
+ Fts5Storage *p, /* Storage object */
255522
+ i64 iDel, /* Rowid to delete from table */
255523
+ sqlite3_value **apVal, /* Optional - values to remove from index */
255524
+ int bSaveRow /* If true, set pSavedRow for deleted row */
255525
+){
253994255526
Fts5Config *pConfig = p->pConfig;
253995255527
int rc;
253996255528
sqlite3_stmt *pDel = 0;
253997255529
253998255530
assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
@@ -254005,11 +255537,11 @@
254005255537
254006255538
if( rc==SQLITE_OK ){
254007255539
if( p->pConfig->bContentlessDelete ){
254008255540
rc = fts5StorageContentlessDelete(p, iDel);
254009255541
}else{
254010
- rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
255542
+ rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow);
254011255543
}
254012255544
}
254013255545
254014255546
/* Delete the %_docsize record */
254015255547
if( rc==SQLITE_OK && pConfig->bColumnsize ){
@@ -254094,18 +255626,25 @@
254094255626
sqlite3Fts5BufferZero(&buf);
254095255627
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
254096255628
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
254097255629
ctx.szCol = 0;
254098255630
if( pConfig->abUnindexed[ctx.iCol]==0 ){
254099
- const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
254100
- int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
254101
- rc = sqlite3Fts5Tokenize(pConfig,
254102
- FTS5_TOKENIZE_DOCUMENT,
254103
- zText, nText,
254104
- (void*)&ctx,
254105
- fts5StorageInsertCallback
254106
- );
255631
+ int bReset = 0; /* True if tokenizer locale must be reset */
255632
+ int nText = 0; /* Size of pText in bytes */
255633
+ const char *pText = 0; /* Pointer to buffer containing text value */
255634
+ sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
255635
+
255636
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &pText, &nText);
255637
+ if( rc==SQLITE_OK ){
255638
+ rc = sqlite3Fts5Tokenize(pConfig,
255639
+ FTS5_TOKENIZE_DOCUMENT,
255640
+ pText, nText,
255641
+ (void*)&ctx,
255642
+ fts5StorageInsertCallback
255643
+ );
255644
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255645
+ }
254107255646
}
254108255647
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
254109255648
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
254110255649
}
254111255650
p->nTotalRow++;
@@ -254185,11 +255724,35 @@
254185255724
}else{
254186255725
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
254187255726
int i; /* Counter variable */
254188255727
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
254189255728
for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
254190
- rc = sqlite3_bind_value(pInsert, i, apVal[i]);
255729
+ sqlite3_value *pVal = apVal[i];
255730
+ if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
255731
+ /* This is an UPDATE statement, and column (i-2) was not modified.
255732
+ ** Retrieve the value from Fts5Storage.pSavedRow instead. */
255733
+ pVal = sqlite3_column_value(p->pSavedRow, i-1);
255734
+ }else if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE ){
255735
+ assert( pConfig->bLocale );
255736
+ assert( i>1 );
255737
+ if( pConfig->abUnindexed[i-2] ){
255738
+ /* At attempt to insert an fts5_locale() value into an UNINDEXED
255739
+ ** column. Strip the locale away and just bind the text. */
255740
+ const char *pText = 0;
255741
+ int nText = 0;
255742
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
255743
+ sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
255744
+ }else{
255745
+ const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
255746
+ int nBlob = sqlite3_value_bytes(pVal);
255747
+ assert( nBlob>4 );
255748
+ sqlite3_bind_blob(pInsert, i, pBlob+4, nBlob-4, SQLITE_TRANSIENT);
255749
+ }
255750
+ continue;
255751
+ }
255752
+
255753
+ rc = sqlite3_bind_value(pInsert, i, pVal);
254191255754
}
254192255755
if( rc==SQLITE_OK ){
254193255756
sqlite3_step(pInsert);
254194255757
rc = sqlite3_reset(pInsert);
254195255758
}
@@ -254220,18 +255783,28 @@
254220255783
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
254221255784
}
254222255785
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
254223255786
ctx.szCol = 0;
254224255787
if( pConfig->abUnindexed[ctx.iCol]==0 ){
254225
- const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
254226
- int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
254227
- rc = sqlite3Fts5Tokenize(pConfig,
254228
- FTS5_TOKENIZE_DOCUMENT,
254229
- zText, nText,
254230
- (void*)&ctx,
254231
- fts5StorageInsertCallback
254232
- );
255788
+ int bReset = 0; /* True if tokenizer locale must be reset */
255789
+ int nText = 0; /* Size of pText in bytes */
255790
+ const char *pText = 0; /* Pointer to buffer containing text value */
255791
+ sqlite3_value *pVal = apVal[ctx.iCol+2];
255792
+ int bDisk = 0;
255793
+ if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
255794
+ pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
255795
+ bDisk = 1;
255796
+ }
255797
+ rc = sqlite3Fts5ExtractText(pConfig, pVal, bDisk, &bReset, &pText,&nText);
255798
+ if( rc==SQLITE_OK ){
255799
+ assert( bReset==0 || pConfig->bLocale );
255800
+ rc = sqlite3Fts5Tokenize(pConfig,
255801
+ FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
255802
+ fts5StorageInsertCallback
255803
+ );
255804
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255805
+ }
254233255806
}
254234255807
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
254235255808
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
254236255809
}
254237255810
p->nTotalRow++;
@@ -254398,18 +255971,26 @@
254398255971
ctx.szCol = 0;
254399255972
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
254400255973
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
254401255974
}
254402255975
if( rc==SQLITE_OK ){
254403
- const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
254404
- int nText = sqlite3_column_bytes(pScan, i+1);
254405
- rc = sqlite3Fts5Tokenize(pConfig,
254406
- FTS5_TOKENIZE_DOCUMENT,
254407
- zText, nText,
254408
- (void*)&ctx,
254409
- fts5StorageIntegrityCallback
255976
+ int bReset = 0; /* True if tokenizer locale must be reset */
255977
+ int nText = 0; /* Size of pText in bytes */
255978
+ const char *pText = 0; /* Pointer to buffer containing text value */
255979
+
255980
+ rc = sqlite3Fts5ExtractText(pConfig,
255981
+ sqlite3_column_value(pScan, i+1), 1, &bReset, &pText, &nText
254410255982
);
255983
+ if( rc==SQLITE_OK ){
255984
+ rc = sqlite3Fts5Tokenize(pConfig,
255985
+ FTS5_TOKENIZE_DOCUMENT,
255986
+ pText, nText,
255987
+ (void*)&ctx,
255988
+ fts5StorageIntegrityCallback
255989
+ );
255990
+ if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255991
+ }
254411255992
}
254412255993
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
254413255994
rc = FTS5_CORRUPT;
254414255995
}
254415255996
aTotalSize[i] += ctx.szCol;
@@ -254720,11 +256301,11 @@
254720256301
rc = SQLITE_NOMEM;
254721256302
}else{
254722256303
int i;
254723256304
memset(p, 0, sizeof(AsciiTokenizer));
254724256305
memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
254725
- for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
256306
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
254726256307
const char *zArg = azArg[i+1];
254727256308
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
254728256309
fts5AsciiAddExceptions(p, zArg, 1);
254729256310
}else
254730256311
if( 0==sqlite3_stricmp(azArg[i], "separators") ){
@@ -254731,11 +256312,10 @@
254731256312
fts5AsciiAddExceptions(p, zArg, 0);
254732256313
}else{
254733256314
rc = SQLITE_ERROR;
254734256315
}
254735256316
}
254736
- if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR;
254737256317
if( rc!=SQLITE_OK ){
254738256318
fts5AsciiDelete((Fts5Tokenizer*)p);
254739256319
p = 0;
254740256320
}
254741256321
}
@@ -255023,20 +256603,20 @@
255023256603
if( p->aFold==0 ){
255024256604
rc = SQLITE_NOMEM;
255025256605
}
255026256606
255027256607
/* Search for a "categories" argument */
255028
- for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
256608
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
255029256609
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
255030256610
zCat = azArg[i+1];
255031256611
}
255032256612
}
255033256613
if( rc==SQLITE_OK ){
255034256614
rc = unicodeSetCategories(p, zCat);
255035256615
}
255036256616
255037
- for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
256617
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
255038256618
const char *zArg = azArg[i+1];
255039256619
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
255040256620
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
255041256621
rc = SQLITE_ERROR;
255042256622
}else{
@@ -255057,12 +256637,10 @@
255057256637
/* no-op */
255058256638
}else{
255059256639
rc = SQLITE_ERROR;
255060256640
}
255061256641
}
255062
- if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
255063
-
255064256642
}else{
255065256643
rc = SQLITE_NOMEM;
255066256644
}
255067256645
if( rc!=SQLITE_OK ){
255068256646
fts5UnicodeDelete((Fts5Tokenizer*)p);
@@ -255197,11 +256775,11 @@
255197256775
** stemming. */
255198256776
#define FTS5_PORTER_MAX_TOKEN 64
255199256777
255200256778
typedef struct PorterTokenizer PorterTokenizer;
255201256779
struct PorterTokenizer {
255202
- fts5_tokenizer tokenizer; /* Parent tokenizer module */
256780
+ fts5_tokenizer_v2 tokenizer_v2; /* Parent tokenizer module */
255203256781
Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
255204256782
char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
255205256783
};
255206256784
255207256785
/*
@@ -255209,11 +256787,11 @@
255209256787
*/
255210256788
static void fts5PorterDelete(Fts5Tokenizer *pTok){
255211256789
if( pTok ){
255212256790
PorterTokenizer *p = (PorterTokenizer*)pTok;
255213256791
if( p->pTokenizer ){
255214
- p->tokenizer.xDelete(p->pTokenizer);
256792
+ p->tokenizer_v2.xDelete(p->pTokenizer);
255215256793
}
255216256794
sqlite3_free(p);
255217256795
}
255218256796
}
255219256797
@@ -255228,26 +256806,28 @@
255228256806
fts5_api *pApi = (fts5_api*)pCtx;
255229256807
int rc = SQLITE_OK;
255230256808
PorterTokenizer *pRet;
255231256809
void *pUserdata = 0;
255232256810
const char *zBase = "unicode61";
256811
+ fts5_tokenizer_v2 *pV2 = 0;
255233256812
255234256813
if( nArg>0 ){
255235256814
zBase = azArg[0];
255236256815
}
255237256816
255238256817
pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
255239256818
if( pRet ){
255240256819
memset(pRet, 0, sizeof(PorterTokenizer));
255241
- rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
256820
+ rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2);
255242256821
}else{
255243256822
rc = SQLITE_NOMEM;
255244256823
}
255245256824
if( rc==SQLITE_OK ){
255246256825
int nArg2 = (nArg>0 ? nArg-1 : 0);
255247
- const char **azArg2 = (nArg2 ? &azArg[1] : 0);
255248
- rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
256826
+ const char **az2 = (nArg2 ? &azArg[1] : 0);
256827
+ memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2));
256828
+ rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer);
255249256829
}
255250256830
255251256831
if( rc!=SQLITE_OK ){
255252256832
fts5PorterDelete((Fts5Tokenizer*)pRet);
255253256833
pRet = 0;
@@ -255894,19 +257474,20 @@
255894257474
static int fts5PorterTokenize(
255895257475
Fts5Tokenizer *pTokenizer,
255896257476
void *pCtx,
255897257477
int flags,
255898257478
const char *pText, int nText,
257479
+ const char *pLoc, int nLoc,
255899257480
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
255900257481
){
255901257482
PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
255902257483
PorterContext sCtx;
255903257484
sCtx.xToken = xToken;
255904257485
sCtx.pCtx = pCtx;
255905257486
sCtx.aBuf = p->aBuf;
255906
- return p->tokenizer.xTokenize(
255907
- p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
257487
+ return p->tokenizer_v2.xTokenize(
257488
+ p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb
255908257489
);
255909257490
}
255910257491
255911257492
/**************************************************************************
255912257493
** Start of trigram implementation.
@@ -255932,45 +257513,50 @@
255932257513
const char **azArg,
255933257514
int nArg,
255934257515
Fts5Tokenizer **ppOut
255935257516
){
255936257517
int rc = SQLITE_OK;
255937
- TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
257518
+ TrigramTokenizer *pNew = 0;
255938257519
UNUSED_PARAM(pUnused);
255939
- if( pNew==0 ){
255940
- rc = SQLITE_NOMEM;
257520
+ if( nArg%2 ){
257521
+ rc = SQLITE_ERROR;
255941257522
}else{
255942257523
int i;
255943
- pNew->bFold = 1;
255944
- pNew->iFoldParam = 0;
255945
- for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
255946
- const char *zArg = azArg[i+1];
255947
- if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
255948
- if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
255949
- rc = SQLITE_ERROR;
255950
- }else{
255951
- pNew->bFold = (zArg[0]=='0');
255952
- }
255953
- }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
255954
- if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
255955
- rc = SQLITE_ERROR;
255956
- }else{
255957
- pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
255958
- }
255959
- }else{
255960
- rc = SQLITE_ERROR;
255961
- }
255962
- }
255963
- if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
255964
-
255965
- if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
255966
- rc = SQLITE_ERROR;
255967
- }
255968
-
255969
- if( rc!=SQLITE_OK ){
255970
- fts5TriDelete((Fts5Tokenizer*)pNew);
255971
- pNew = 0;
257524
+ pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
257525
+ if( pNew==0 ){
257526
+ rc = SQLITE_NOMEM;
257527
+ }else{
257528
+ pNew->bFold = 1;
257529
+ pNew->iFoldParam = 0;
257530
+
257531
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
257532
+ const char *zArg = azArg[i+1];
257533
+ if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
257534
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
257535
+ rc = SQLITE_ERROR;
257536
+ }else{
257537
+ pNew->bFold = (zArg[0]=='0');
257538
+ }
257539
+ }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
257540
+ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
257541
+ rc = SQLITE_ERROR;
257542
+ }else{
257543
+ pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
257544
+ }
257545
+ }else{
257546
+ rc = SQLITE_ERROR;
257547
+ }
257548
+ }
257549
+
257550
+ if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
257551
+ rc = SQLITE_ERROR;
257552
+ }
257553
+
257554
+ if( rc!=SQLITE_OK ){
257555
+ fts5TriDelete((Fts5Tokenizer*)pNew);
257556
+ pNew = 0;
257557
+ }
255972257558
}
255973257559
}
255974257560
*ppOut = (Fts5Tokenizer*)pNew;
255975257561
return rc;
255976257562
}
@@ -256091,11 +257677,10 @@
256091257677
const char *zName;
256092257678
fts5_tokenizer x;
256093257679
} aBuiltin[] = {
256094257680
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
256095257681
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
256096
- { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
256097257682
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
256098257683
};
256099257684
256100257685
int rc = SQLITE_OK; /* Return code */
256101257686
int i; /* To iterate through builtin functions */
@@ -256106,11 +257691,24 @@
256106257691
(void*)pApi,
256107257692
&aBuiltin[i].x,
256108257693
0
256109257694
);
256110257695
}
256111
-
257696
+ if( rc==SQLITE_OK ){
257697
+ fts5_tokenizer_v2 sPorter = {
257698
+ 2,
257699
+ fts5PorterCreate,
257700
+ fts5PorterDelete,
257701
+ fts5PorterTokenize
257702
+ };
257703
+ rc = pApi->xCreateTokenizer_v2(pApi,
257704
+ "porter",
257705
+ (void*)pApi,
257706
+ &sPorter,
257707
+ 0
257708
+ );
257709
+ }
256112257710
return rc;
256113257711
}
256114257712
256115257713
/*
256116257714
** 2012-05-25
@@ -256476,10 +258074,13 @@
256476258074
aArray[29] = 1;
256477258075
break;
256478258076
default: return 1; }
256479258077
break;
256480258078
258079
+
258080
+ default:
258081
+ return 1;
256481258082
}
256482258083
return 0;
256483258084
}
256484258085
256485258086
static u16 aFts5UnicodeBlock[] = {
256486258087
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,13 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 7a0cdc7edb704a88a77b748cd28f6e00c498.
 
 
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -462,11 +464,11 @@
462 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463 ** [sqlite_version()] and [sqlite_source_id()].
464 */
465 #define SQLITE_VERSION "3.47.0"
466 #define SQLITE_VERSION_NUMBER 3047000
467 #define SQLITE_SOURCE_ID "2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9"
468
469 /*
470 ** CAPI3REF: Run-Time Library Version Numbers
471 ** KEYWORDS: sqlite3_version sqlite3_sourceid
472 **
@@ -7741,13 +7743,15 @@
7741 **
7742 ** ^The estimatedRows value is an estimate of the number of rows that
7743 ** will be returned by the strategy.
7744 **
7745 ** The xBestIndex method may optionally populate the idxFlags field with a
7746 ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
7747 ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
7748 ** assumes that the strategy may visit at most one row.
 
 
7749 **
7750 ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
7751 ** SQLite also assumes that if a call to the xUpdate() method is made as
7752 ** part of the same statement to delete or update a virtual table row and the
7753 ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7807,11 +7811,13 @@
7807 **
7808 ** Virtual table implementations are allowed to set the
7809 ** [sqlite3_index_info].idxFlags field to some combination of
7810 ** these bits.
7811 */
7812 #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
 
 
7813
7814 /*
7815 ** CAPI3REF: Virtual Table Constraint Operator Codes
7816 **
7817 ** These macros define the allowed values for the
@@ -8644,10 +8650,11 @@
8644 #define SQLITE_TESTCTRL_ALWAYS 13
8645 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8646 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8647 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8648 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
 
8649 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8650 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8651 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8652 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8653 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13418,13 +13425,36 @@
13418 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13419 ** includes any embedded 0x00 and trailing data.
13420 **
13421 ** This API can be quite slow if used with an FTS5 table created with the
13422 ** "detail=none" or "detail=column" option.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13423 */
13424 struct Fts5ExtensionApi {
13425 int iVersion; /* Currently always set to 3 */
13426
13427 void *(*xUserData)(Fts5Context*);
13428
13429 int (*xColumnCount)(Fts5Context*);
13430 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13462,10 +13492,19 @@
13462 int (*xQueryToken)(Fts5Context*,
13463 int iPhrase, int iToken,
13464 const char **ppToken, int *pnToken
13465 );
13466 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
 
 
 
 
 
 
 
 
 
13467 };
13468
13469 /*
13470 ** CUSTOM AUXILIARY FUNCTIONS
13471 *************************************************************************/
@@ -13474,19 +13513,20 @@
13474 ** CUSTOM TOKENIZERS
13475 **
13476 ** Applications may also register custom tokenizer types. A tokenizer
13477 ** is registered by providing fts5 with a populated instance of the
13478 ** following structure. All structure methods must be defined, setting
 
13479 ** any member of the fts5_tokenizer struct to NULL leads to undefined
13480 ** behaviour. The structure methods are expected to function as follows:
13481 **
13482 ** xCreate:
13483 ** This function is used to allocate and initialize a tokenizer instance.
13484 ** A tokenizer instance is required to actually tokenize text.
13485 **
13486 ** The first argument passed to this function is a copy of the (void*)
13487 ** pointer provided by the application when the fts5_tokenizer object
13488 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
13489 ** The second and third arguments are an array of nul-terminated strings
13490 ** containing the tokenizer arguments, if any, specified following the
13491 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
13492 ** to create the FTS5 table.
@@ -13506,11 +13546,11 @@
13506 ** This function is expected to tokenize the nText byte string indicated
13507 ** by argument pText. pText may or may not be nul-terminated. The first
13508 ** argument passed to this function is a pointer to an Fts5Tokenizer object
13509 ** returned by an earlier call to xCreate().
13510 **
13511 ** The second argument indicates the reason that FTS5 is requesting
13512 ** tokenization of the supplied text. This is always one of the following
13513 ** four values:
13514 **
13515 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
13516 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -13529,10 +13569,17 @@
13529 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
13530 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
13531 ** function. Or an fts5_api.xColumnSize() request made by the same
13532 ** on a columnsize=0 database.
13533 ** </ul>
 
 
 
 
 
 
 
13534 **
13535 ** For each token in the input string, the supplied callback xToken() must
13536 ** be invoked. The first argument to it should be a copy of the pointer
13537 ** passed as the second argument to xTokenize(). The third and fourth
13538 ** arguments are a pointer to a buffer containing the token text, and the
@@ -13552,10 +13599,33 @@
13552 ** immediately return a copy of the xToken() return value. Or, if the
13553 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
13554 ** if an error occurs with the xTokenize() implementation itself, it
13555 ** may abandon the tokenization and return any error code other than
13556 ** SQLITE_OK or SQLITE_DONE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13557 **
13558 ** SYNONYM SUPPORT
13559 **
13560 ** Custom tokenizers may also support synonyms. Consider a case in which a
13561 ** user wishes to query for a phrase such as "first place". Using the
@@ -13661,10 +13731,37 @@
13661 ** provide synonyms when tokenizing document text (method (3)) or query
13662 ** text (method (2)), not both. Doing so will not cause any errors, but is
13663 ** inefficient.
13664 */
13665 typedef struct Fts5Tokenizer Fts5Tokenizer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13666 typedef struct fts5_tokenizer fts5_tokenizer;
13667 struct fts5_tokenizer {
13668 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13669 void (*xDelete)(Fts5Tokenizer*);
13670 int (*xTokenize)(Fts5Tokenizer*,
@@ -13679,10 +13776,11 @@
13679 int iStart, /* Byte offset of token within input text */
13680 int iEnd /* Byte offset of end of token within input text */
13681 )
13682 );
13683 };
 
13684
13685 /* Flags that may be passed as the third argument to xTokenize() */
13686 #define FTS5_TOKENIZE_QUERY 0x0001
13687 #define FTS5_TOKENIZE_PREFIX 0x0002
13688 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13699,11 +13797,11 @@
13699 /*************************************************************************
13700 ** FTS5 EXTENSION REGISTRATION API
13701 */
13702 typedef struct fts5_api fts5_api;
13703 struct fts5_api {
13704 int iVersion; /* Currently always set to 2 */
13705
13706 /* Create a new tokenizer */
13707 int (*xCreateTokenizer)(
13708 fts5_api *pApi,
13709 const char *zName,
@@ -13726,10 +13824,29 @@
13726 const char *zName,
13727 void *pUserData,
13728 fts5_extension_function xFunction,
13729 void (*xDestroy)(void*)
13730 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13731 };
13732
13733 /*
13734 ** END OF REGISTRATION API
13735 *************************************************************************/
@@ -15380,10 +15497,11 @@
15380 typedef struct RowSet RowSet;
15381 typedef struct Savepoint Savepoint;
15382 typedef struct Select Select;
15383 typedef struct SQLiteThread SQLiteThread;
15384 typedef struct SelectDest SelectDest;
 
15385 typedef struct SrcItem SrcItem;
15386 typedef struct SrcList SrcList;
15387 typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
15388 typedef struct Table Table;
15389 typedef struct TableLock TableLock;
@@ -19263,10 +19381,20 @@
19263 */
19264 #define EU4_NONE 0 /* Does not use IdList.a.u4 */
19265 #define EU4_IDX 1 /* Uses IdList.a.u4.idx */
19266 #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
19267
 
 
 
 
 
 
 
 
 
 
19268 /*
19269 ** The SrcItem object represents a single term in the FROM clause of a query.
19270 ** The SrcList object is mostly an array of SrcItems.
19271 **
19272 ** The jointype starts out showing the join type between the current table
@@ -19275,33 +19403,44 @@
19275 ** jointype expresses the join between the table and the previous table.
19276 **
19277 ** In the colUsed field, the high-order bit (bit 63) is set if the table
19278 ** contains more than 63 columns and the 64-th or later column is used.
19279 **
19280 ** Union member validity:
 
 
 
19281 **
19282 ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
19283 ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
 
 
19284 ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
19285 **
19286 ** u2.pIBIndex fg.isIndexedBy && !fg.isCte
19287 ** u2.pCteUse fg.isCte && !fg.isIndexedBy
 
 
 
 
 
 
 
 
 
 
 
19288 */
19289 struct SrcItem {
19290 Schema *pSchema; /* Schema to which this item is fixed */
19291 char *zDatabase; /* Name of database holding this table */
19292 char *zName; /* Name of the table */
19293 char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
19294 Table *pTab; /* An SQL table corresponding to zName */
19295 Select *pSelect; /* A SELECT statement used in place of a table name */
19296 int addrFillSub; /* Address of subroutine to manifest a subquery */
19297 int regReturn; /* Register holding return address of addrFillSub */
19298 int regResult; /* Registers holding results of a co-routine */
19299 struct {
19300 u8 jointype; /* Type of join between this table and the previous */
19301 unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
19302 unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
 
19303 unsigned isTabFunc :1; /* True if table-valued-function syntax */
19304 unsigned isCorrelated :1; /* True if sub-query is correlated */
19305 unsigned isMaterialized:1; /* This is a materialized view */
19306 unsigned viaCoroutine :1; /* Implemented as a co-routine */
19307 unsigned isRecursive :1; /* True for recursive reference in WITH */
@@ -19311,16 +19450,14 @@
19311 unsigned isUsing :1; /* u3.pUsing is valid */
19312 unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
19313 unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
19314 unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
19315 unsigned rowidUsed :1; /* The ROWID of this table is referenced */
 
 
19316 } fg;
19317 int iCursor; /* The VDBE cursor number used to access this table */
19318 union {
19319 Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
19320 IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
19321 } u3;
19322 Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
19323 union {
19324 char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
19325 ExprList *pFuncArg; /* Arguments to table-valued-function */
19326 u32 nRow; /* Number of rows in a VALUES clause */
@@ -19327,10 +19464,19 @@
19327 } u1;
19328 union {
19329 Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
19330 CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
19331 } u2;
 
 
 
 
 
 
 
 
 
19332 };
19333
19334 /*
19335 ** The OnOrUsing object represents either an ON clause or a USING clause.
19336 ** It can never be both at the same time, but it can be neither.
@@ -19586,12 +19732,14 @@
19586 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
19587 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
19588 #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
19589 #define SF_Correlated 0x20000000 /* True if references the outer context */
19590
19591 /* True if S exists and has SF_NestedFrom */
19592 #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
 
 
19593
19594 /*
19595 ** The results of a SELECT can be distributed in several ways, as defined
19596 ** by one of the following macros. The "SRT" prefix means "SELECT Result
19597 ** Type".
@@ -20979,10 +21127,13 @@
20979 SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
20980 SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
20981 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
20982 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
20983 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
 
 
 
20984 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
20985 Token*, Select*, OnOrUsing*);
20986 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
20987 SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
20988 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
@@ -24521,12 +24672,12 @@
24521 }
24522 if( M<=2 ){
24523 Y--;
24524 M += 12;
24525 }
24526 A = Y/100;
24527 B = 2 - A + (A/4);
24528 X1 = 36525*(Y+4716)/100;
24529 X2 = 306001*(M+1)/10000;
24530 p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
24531 p->validJD = 1;
24532 if( p->validHMS ){
@@ -24706,11 +24857,11 @@
24706
24707 /*
24708 ** Compute the Year, Month, and Day from the julian day number.
24709 */
24710 static void computeYMD(DateTime *p){
24711 int Z, A, B, C, D, E, X1;
24712 if( p->validYMD ) return;
24713 if( !p->validJD ){
24714 p->Y = 2000;
24715 p->M = 1;
24716 p->D = 1;
@@ -24717,12 +24868,12 @@
24717 }else if( !validJulianDay(p->iJD) ){
24718 datetimeError(p);
24719 return;
24720 }else{
24721 Z = (int)((p->iJD + 43200000)/86400000);
24722 A = (int)((Z - 1867216.25)/36524.25);
24723 A = Z + 1 + A - (A/4);
24724 B = A + 1524;
24725 C = (int)((B - 122.1)/365.25);
24726 D = (36525*(C&32767))/100;
24727 E = (int)((B-D)/30.6001);
24728 X1 = (int)(30.6001*E);
@@ -32017,20 +32168,23 @@
32017 pItem = va_arg(ap, SrcItem*);
32018 assert( bArgList==0 );
32019 if( pItem->zAlias && !flag_altform2 ){
32020 sqlite3_str_appendall(pAccum, pItem->zAlias);
32021 }else if( pItem->zName ){
32022 if( pItem->zDatabase ){
32023 sqlite3_str_appendall(pAccum, pItem->zDatabase);
 
 
 
32024 sqlite3_str_append(pAccum, ".", 1);
32025 }
32026 sqlite3_str_appendall(pAccum, pItem->zName);
32027 }else if( pItem->zAlias ){
32028 sqlite3_str_appendall(pAccum, pItem->zAlias);
32029 }else{
32030 Select *pSel = pItem->pSelect;
32031 assert( pSel!=0 ); /* Because of tag-20240424-1 */
32032 if( pSel->selFlags & SF_NestedFrom ){
32033 sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
32034 }else if( pSel->selFlags & SF_MultiValue ){
32035 assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
32036 sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
@@ -32808,13 +32962,13 @@
32808 int n = 0;
32809 char zLine[1000];
32810 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
32811 x.printfFlags |= SQLITE_PRINTF_INTERNAL;
32812 sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
32813 if( pItem->pTab ){
32814 sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
32815 pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab,
32816 pItem->colUsed,
32817 pItem->fg.rowidUsed ? "+rowid" : "");
32818 }
32819 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
32820 sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
@@ -32841,27 +32995,34 @@
32841 if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
32842 if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
32843 if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
32844 if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte");
32845 if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom");
 
 
 
32846
32847 sqlite3StrAccumFinish(&x);
32848 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
32849 n = 0;
32850 if( pItem->pSelect ) n++;
32851 if( pItem->fg.isTabFunc ) n++;
32852 if( pItem->fg.isUsing ) n++;
32853 if( pItem->fg.isUsing ){
32854 sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
32855 }
32856 if( pItem->pSelect ){
32857 if( pItem->pTab ){
32858 Table *pTab = pItem->pTab;
 
32859 sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
32860 }
32861 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
32862 sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
 
 
 
32863 }
32864 if( pItem->fg.isTabFunc ){
32865 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
32866 }
32867 sqlite3TreeViewPop(&pView);
@@ -38721,11 +38882,11 @@
38721 ** Allowed values for the unixFile.ctrlFlags bitmask:
38722 */
38723 #define UNIXFILE_EXCL 0x01 /* Connections from one process only */
38724 #define UNIXFILE_RDONLY 0x02 /* Connection is read only */
38725 #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
38726 #ifndef SQLITE_DISABLE_DIRSYNC
38727 # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
38728 #else
38729 # define UNIXFILE_DIRSYNC 0x00
38730 #endif
38731 #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
@@ -95267,11 +95428,11 @@
95267 }
95268 break;
95269 }
95270 #endif
95271
95272 #if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE)
95273 /* Opcode: Cast P1 P2 * * *
95274 ** Synopsis: affinity(r[P1])
95275 **
95276 ** Force the value in register P1 to be the type defined by P2.
95277 **
@@ -106731,11 +106892,13 @@
106731 SrcItem *pItem;
106732
106733 pSrc = p->pSrc;
106734 if( ALWAYS(pSrc) ){
106735 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
106736 if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
 
 
106737 return WRC_Abort;
106738 }
106739 if( pItem->fg.isTabFunc
106740 && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
106741 ){
@@ -107037,11 +107200,11 @@
107037 ){
107038 Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
107039 if( pNew ){
107040 pNew->iTable = pMatch->iCursor;
107041 pNew->iColumn = iColumn;
107042 pNew->y.pTab = pMatch->pTab;
107043 assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
107044 ExprSetProperty(pNew, EP_CanBeNull);
107045 *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
107046 }
107047 }
@@ -107168,24 +107331,28 @@
107168 SrcList *pSrcList = pNC->pSrcList;
107169
107170 if( pSrcList ){
107171 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
107172 u8 hCol;
107173 pTab = pItem->pTab;
107174 assert( pTab!=0 && pTab->zName!=0 );
107175 assert( pTab->nCol>0 || pParse->nErr );
107176 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
107177 if( pItem->fg.isNestedFrom ){
107178 /* In this case, pItem is a subquery that has been formed from a
107179 ** parenthesized subset of the FROM clause terms. Example:
107180 ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
107181 ** \_________________________/
107182 ** This pItem -------------^
107183 */
107184 int hit = 0;
107185 assert( pItem->pSelect!=0 );
107186 pEList = pItem->pSelect->pEList;
 
 
 
 
107187 assert( pEList!=0 );
107188 assert( pEList->nExpr==pTab->nCol );
107189 for(j=0; j<pEList->nExpr; j++){
107190 int bRowid = 0; /* True if possible rowid match */
107191 if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
@@ -107305,12 +107472,12 @@
107305 ** words non-VIEW candidate terms take precedence over VIEWs.
107306 */
107307 if( cntTab==0
107308 || (cntTab==1
107309 && ALWAYS(pMatch!=0)
107310 && ALWAYS(pMatch->pTab!=0)
107311 && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0
107312 && (pTab->tabFlags & TF_Ephemeral)==0)
107313 ){
107314 cntTab = 1;
107315 pMatch = pItem;
107316 }else{
@@ -107327,11 +107494,11 @@
107327 }
107328 }
107329 if( pMatch ){
107330 pExpr->iTable = pMatch->iCursor;
107331 assert( ExprUseYTab(pExpr) );
107332 pExpr->y.pTab = pMatch->pTab;
107333 if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
107334 ExprSetProperty(pExpr, EP_CanBeNull);
107335 }
107336 pSchema = pExpr->y.pTab->pSchema;
107337 }
@@ -107369,11 +107536,11 @@
107369 #endif /* SQLITE_OMIT_TRIGGER */
107370 #ifndef SQLITE_OMIT_UPSERT
107371 if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){
107372 Upsert *pUpsert = pNC->uNC.pUpsert;
107373 if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
107374 pTab = pUpsert->pUpsertSrc->a[0].pTab;
107375 pExpr->iTable = EXCLUDED_TABLE_NUMBER;
107376 }
107377 }
107378 #endif /* SQLITE_OMIT_UPSERT */
107379
@@ -107452,15 +107619,15 @@
107452 if( cnt==0
107453 && cntTab>=1
107454 && pMatch
107455 && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
107456 && sqlite3IsRowid(zCol)
107457 && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
107458 ){
107459 cnt = cntTab;
107460 #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
107461 if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){
107462 eNewExprOp = TK_NULL;
107463 }
107464 #endif
107465 if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
107466 pExpr->affExpr = SQLITE_AFF_INTEGER;
@@ -107693,11 +107860,11 @@
107693 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
107694 if( p ){
107695 SrcItem *pItem = &pSrc->a[iSrc];
107696 Table *pTab;
107697 assert( ExprUseYTab(p) );
107698 pTab = p->y.pTab = pItem->pTab;
107699 p->iTable = pItem->iCursor;
107700 if( p->y.pTab->iPKey==iCol ){
107701 p->iColumn = -1;
107702 }else{
107703 p->iColumn = (ynVar)iCol;
@@ -107812,11 +107979,11 @@
107812 SrcItem *pItem;
107813 assert( pSrcList && pSrcList->nSrc>=1 );
107814 pItem = pSrcList->a;
107815 pExpr->op = TK_COLUMN;
107816 assert( ExprUseYTab(pExpr) );
107817 pExpr->y.pTab = pItem->pTab;
107818 pExpr->iTable = pItem->iCursor;
107819 pExpr->iColumn--;
107820 pExpr->affExpr = SQLITE_AFF_INTEGER;
107821 break;
107822 }
@@ -108702,11 +108869,15 @@
108702 ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
108703 ** as if it were part of the sub-query, not the parent. This block
108704 ** moves the pOrderBy down to the sub-query. It will be moved back
108705 ** after the names have been resolved. */
108706 if( p->selFlags & SF_Converted ){
108707 Select *pSub = p->pSrc->a[0].pSelect;
 
 
 
 
108708 assert( p->pSrc->nSrc==1 && p->pOrderBy );
108709 assert( pSub->pPrior && pSub->pOrderBy==0 );
108710 pSub->pOrderBy = p->pOrderBy;
108711 p->pOrderBy = 0;
108712 }
@@ -108714,17 +108885,20 @@
108714 /* Recursively resolve names in all subqueries in the FROM clause
108715 */
108716 if( pOuterNC ) pOuterNC->nNestedSelect++;
108717 for(i=0; i<p->pSrc->nSrc; i++){
108718 SrcItem *pItem = &p->pSrc->a[i];
108719 assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/
108720 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
 
 
 
108721 int nRef = pOuterNC ? pOuterNC->nRef : 0;
108722 const char *zSavedContext = pParse->zAuthContext;
108723
108724 if( pItem->zName ) pParse->zAuthContext = pItem->zName;
108725 sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
108726 pParse->zAuthContext = zSavedContext;
108727 if( pParse->nErr ) return WRC_Abort;
108728 assert( db->mallocFailed==0 );
108729
108730 /* If the number of references to the outer context changed when
@@ -108822,11 +108996,14 @@
108822 ** the sub-query back to the parent query. At this point each term
108823 ** within the ORDER BY clause has been transformed to an integer value.
108824 ** These integers will be replaced by copies of the corresponding result
108825 ** set expressions by the call to resolveOrderGroupBy() below. */
108826 if( p->selFlags & SF_Converted ){
108827 Select *pSub = p->pSrc->a[0].pSelect;
 
 
 
108828 p->pOrderBy = pSub->pOrderBy;
108829 pSub->pOrderBy = 0;
108830 }
108831
108832 /* Process the ORDER BY clause for singleton SELECT statements.
@@ -109089,11 +109266,11 @@
109089 memset(&sNC, 0, sizeof(sNC));
109090 memset(&sSrc, 0, sizeof(sSrc));
109091 if( pTab ){
109092 sSrc.nSrc = 1;
109093 sSrc.a[0].zName = pTab->zName;
109094 sSrc.a[0].pTab = pTab;
109095 sSrc.a[0].iCursor = -1;
109096 if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
109097 /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
109098 ** schema elements */
109099 type |= NC_FromDDL;
@@ -110986,19 +111163,34 @@
110986 pNew->nSrc = pNew->nAlloc = p->nSrc;
110987 for(i=0; i<p->nSrc; i++){
110988 SrcItem *pNewItem = &pNew->a[i];
110989 const SrcItem *pOldItem = &p->a[i];
110990 Table *pTab;
110991 pNewItem->pSchema = pOldItem->pSchema;
110992 pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110993 pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
110994 pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
110995 pNewItem->fg = pOldItem->fg;
110996 pNewItem->iCursor = pOldItem->iCursor;
110997 pNewItem->addrFillSub = pOldItem->addrFillSub;
110998 pNewItem->regReturn = pOldItem->regReturn;
110999 pNewItem->regResult = pOldItem->regResult;
111000 if( pNewItem->fg.isIndexedBy ){
111001 pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
111002 }else if( pNewItem->fg.isTabFunc ){
111003 pNewItem->u1.pFuncArg =
111004 sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
@@ -111007,15 +111199,14 @@
111007 }
111008 pNewItem->u2 = pOldItem->u2;
111009 if( pNewItem->fg.isCte ){
111010 pNewItem->u2.pCteUse->nUse++;
111011 }
111012 pTab = pNewItem->pTab = pOldItem->pTab;
111013 if( pTab ){
111014 pTab->nTabRef++;
111015 }
111016 pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
111017 if( pOldItem->fg.isUsing ){
111018 assert( pNewItem->fg.isUsing );
111019 pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
111020 }else{
111021 pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
@@ -111085,11 +111276,10 @@
111085 }
111086 *pp = pNew;
111087 pp = &pNew->pPrior;
111088 pNext = pNew;
111089 }
111090
111091 return pRet;
111092 }
111093 #else
111094 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
111095 assert( p==0 );
@@ -112105,12 +112295,12 @@
112105 if( p->pLimit ) return 0; /* Has no LIMIT clause */
112106 if( p->pWhere ) return 0; /* Has no WHERE clause */
112107 pSrc = p->pSrc;
112108 assert( pSrc!=0 );
112109 if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
112110 if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
112111 pTab = pSrc->a[0].pTab;
112112 assert( pTab!=0 );
112113 assert( !IsView(pTab) ); /* FROM clause is not a view */
112114 if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
112115 pEList = p->pEList;
112116 assert( pEList!=0 );
@@ -112289,11 +112479,11 @@
112289 int nExpr = pEList->nExpr;
112290
112291 assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
112292 assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
112293 assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
112294 pTab = p->pSrc->a[0].pTab;
112295
112296 /* Code an OP_Transaction and OP_TableLock for <table>. */
112297 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
112298 assert( iDb>=0 && iDb<SQLITE_MAX_DB );
112299 sqlite3CodeVerifySchema(pParse, iDb);
@@ -117727,12 +117917,13 @@
117727 }
117728 if( pStep->pFrom ){
117729 int i;
117730 for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
117731 SrcItem *p = &pStep->pFrom->a[i];
117732 if( p->pSelect ){
117733 sqlite3SelectPrep(pParse, p->pSelect, 0);
 
117734 }
117735 }
117736 }
117737
117738 if( db->mallocFailed ){
@@ -117796,12 +117987,16 @@
117796 sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
117797 sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
117798 }
117799 if( pStep->pFrom ){
117800 int i;
117801 for(i=0; i<pStep->pFrom->nSrc; i++){
117802 sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect);
 
 
 
 
117803 }
117804 }
117805 }
117806 }
117807
@@ -118044,11 +118239,11 @@
118044 assert( pWalker->pParse->db->mallocFailed );
118045 return WRC_Abort;
118046 }
118047 for(i=0; i<pSrc->nSrc; i++){
118048 SrcItem *pItem = &pSrc->a[i];
118049 if( pItem->pTab==p->pTab ){
118050 renameTokenFind(pWalker->pParse, p, pItem->zName);
118051 }
118052 }
118053 renameWalkWith(pWalker, pSelect);
118054
@@ -121178,24 +121373,25 @@
121178 int iDb = sqlite3FindDbName(db, pFix->zDb);
121179 SrcList *pList = pSelect->pSrc;
121180
121181 if( NEVER(pList==0) ) return WRC_Continue;
121182 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
121183 if( pFix->bTemp==0 ){
121184 if( pItem->zDatabase ){
121185 if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
121186 sqlite3ErrorMsg(pFix->pParse,
121187 "%s %T cannot reference objects in database %s",
121188 pFix->zType, pFix->pName, pItem->zDatabase);
121189 return WRC_Abort;
121190 }
121191 sqlite3DbFree(db, pItem->zDatabase);
121192 pItem->zDatabase = 0;
121193 pItem->fg.notCte = 1;
 
121194 }
121195 pItem->pSchema = pFix->pSchema;
121196 pItem->fg.fromDDL = 1;
 
121197 }
121198 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
121199 if( pList->a[i].fg.isUsing==0
121200 && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
121201 ){
@@ -121484,11 +121680,11 @@
121484 pTab = pParse->pTriggerTab;
121485 }else{
121486 assert( pTabList );
121487 for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
121488 if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
121489 pTab = pTabList->a[iSrc].pTab;
121490 break;
121491 }
121492 }
121493 }
121494 iCol = pExpr->iColumn;
@@ -122087,16 +122283,16 @@
122087 Parse *pParse,
122088 u32 flags,
122089 SrcItem *p
122090 ){
122091 const char *zDb;
122092 assert( p->pSchema==0 || p->zDatabase==0 );
122093 if( p->pSchema ){
122094 int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
122095 zDb = pParse->db->aDb[iDb].zDbSName;
122096 }else{
122097 zDb = p->zDatabase;
 
122098 }
122099 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
122100 }
122101
122102 /*
@@ -125077,19 +125273,21 @@
125077 if( db->mallocFailed ){
125078 goto exit_drop_table;
125079 }
125080 assert( pParse->nErr==0 );
125081 assert( pName->nSrc==1 );
 
 
125082 if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
125083 if( noErr ) db->suppressErr++;
125084 assert( isView==0 || isView==LOCATE_VIEW );
125085 pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
125086 if( noErr ) db->suppressErr--;
125087
125088 if( pTab==0 ){
125089 if( noErr ){
125090 sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
125091 sqlite3ForceNotReadOnly(pParse);
125092 }
125093 goto exit_drop_table;
125094 }
125095 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -126176,19 +126374,21 @@
126176 if( db->mallocFailed ){
126177 goto exit_drop_index;
126178 }
126179 assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
126180 assert( pName->nSrc==1 );
 
 
126181 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
126182 goto exit_drop_index;
126183 }
126184 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
126185 if( pIndex==0 ){
126186 if( !ifExists ){
126187 sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
126188 }else{
126189 sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
126190 sqlite3ForceNotReadOnly(pParse);
126191 }
126192 pParse->checkSchema = 1;
126193 goto exit_drop_index;
126194 }
@@ -126481,16 +126681,18 @@
126481 }
126482 pItem = &pList->a[pList->nSrc-1];
126483 if( pDatabase && pDatabase->z==0 ){
126484 pDatabase = 0;
126485 }
 
 
126486 if( pDatabase ){
126487 pItem->zName = sqlite3NameFromToken(db, pDatabase);
126488 pItem->zDatabase = sqlite3NameFromToken(db, pTable);
126489 }else{
126490 pItem->zName = sqlite3NameFromToken(db, pTable);
126491 pItem->zDatabase = 0;
126492 }
126493 return pList;
126494 }
126495
126496 /*
@@ -126502,16 +126704,43 @@
126502 assert( pList || pParse->db->mallocFailed );
126503 if( ALWAYS(pList) ){
126504 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
126505 if( pItem->iCursor>=0 ) continue;
126506 pItem->iCursor = pParse->nTab++;
126507 if( pItem->pSelect ){
126508 sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
 
 
 
126509 }
126510 }
126511 }
126512 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126513
126514 /*
126515 ** Delete an entire SrcList including all its substructure.
126516 */
126517 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
@@ -126518,25 +126747,84 @@
126518 int i;
126519 SrcItem *pItem;
126520 assert( db!=0 );
126521 if( pList==0 ) return;
126522 for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
126523 if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase);
 
 
 
 
 
 
 
126524 if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName);
126525 if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias);
 
 
 
 
 
126526 if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
126527 if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
126528 sqlite3DeleteTable(db, pItem->pTab);
126529 if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
126530 if( pItem->fg.isUsing ){
126531 sqlite3IdListDelete(db, pItem->u3.pUsing);
126532 }else if( pItem->u3.pOn ){
126533 sqlite3ExprDelete(db, pItem->u3.pOn);
126534 }
126535 }
126536 sqlite3DbNNFreeNN(db, pList);
126537 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126538
126539 /*
126540 ** This routine is called by the parser to add a new term to the
126541 ** end of a growing FROM clause. The "p" parameter is the part of
126542 ** the FROM clause that has already been constructed. "p" is NULL
@@ -126583,14 +126871,16 @@
126583 }
126584 assert( pAlias!=0 );
126585 if( pAlias->n ){
126586 pItem->zAlias = sqlite3NameFromToken(db, pAlias);
126587 }
 
126588 if( pSubquery ){
126589 pItem->pSelect = pSubquery;
126590 if( pSubquery->selFlags & SF_NestedFrom ){
126591 pItem->fg.isNestedFrom = 1;
 
126592 }
126593 }
126594 assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
126595 assert( pItem->fg.isUsing==0 );
126596 if( pOnUsing==0 ){
@@ -127864,21 +128154,21 @@
127864 ** return a pointer. Set an error message and return NULL if the table
127865 ** name is not found or if any other error occurs.
127866 **
127867 ** The following fields are initialized appropriate in pSrc:
127868 **
127869 ** pSrc->a[0].pTab Pointer to the Table object
127870 ** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
127871 **
127872 */
127873 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
127874 SrcItem *pItem = pSrc->a;
127875 Table *pTab;
127876 assert( pItem && pSrc->nSrc>=1 );
127877 pTab = sqlite3LocateTableItem(pParse, 0, pItem);
127878 if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab);
127879 pItem->pTab = pTab;
127880 pItem->fg.notCte = 1;
127881 if( pTab ){
127882 pTab->nTabRef++;
127883 if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){
127884 pTab = 0;
@@ -127996,11 +128286,12 @@
127996 pWhere = sqlite3ExprDup(db, pWhere, 0);
127997 pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
127998 if( pFrom ){
127999 assert( pFrom->nSrc==1 );
128000 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
128001 pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
 
128002 assert( pFrom->a[0].fg.isUsing==0 );
128003 assert( pFrom->a[0].u3.pOn==0 );
128004 }
128005 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
128006 SF_IncludeHidden, pLimit);
@@ -128058,11 +128349,11 @@
128058 ** DELETE FROM table_a WHERE rowid IN (
128059 ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
128060 ** );
128061 */
128062
128063 pTab = pSrc->a[0].pTab;
128064 if( HasRowid(pTab) ){
128065 pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
128066 pEList = sqlite3ExprListAppend(
128067 pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
128068 );
@@ -128091,13 +128382,13 @@
128091 }
128092 }
128093
128094 /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
128095 ** and the SELECT subtree. */
128096 pSrc->a[0].pTab = 0;
128097 pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
128098 pSrc->a[0].pTab = pTab;
128099 if( pSrc->a[0].fg.isIndexedBy ){
128100 assert( pSrc->a[0].fg.isCte==0 );
128101 pSrc->a[0].u2.pIBIndex = 0;
128102 pSrc->a[0].fg.isIndexedBy = 0;
128103 sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
@@ -132675,13 +132966,13 @@
132675 /* Create a SrcList structure containing the child table. We need the
132676 ** child table as a SrcList for sqlite3WhereBegin() */
132677 pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
132678 if( pSrc ){
132679 SrcItem *pItem = pSrc->a;
132680 pItem->pTab = pFKey->pFrom;
132681 pItem->zName = pFKey->pFrom->zName;
132682 pItem->pTab->nTabRef++;
132683 pItem->iCursor = pParse->nTab++;
132684
132685 if( regNew!=0 ){
132686 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
132687 }
@@ -132969,11 +133260,12 @@
132969 }
132970 pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
132971 if( pSrc ){
132972 assert( pSrc->nSrc==1 );
132973 pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom);
132974 pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
 
132975 }
132976 pSelect = sqlite3SelectNew(pParse,
132977 sqlite3ExprListAppend(pParse, 0, pRaise),
132978 pSrc,
132979 pWhere,
@@ -133703,12 +133995,15 @@
133703 ** co-routine.
133704 */
133705 SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){
133706 if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){
133707 SrcItem *pItem = &pVal->pSrc->a[0];
133708 sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn);
133709 sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1);
 
 
 
133710 }
133711 }
133712
133713 /*
133714 ** Return true if all expressions in the expression-list passed as the
@@ -133832,56 +134127,67 @@
133832 sqlite3ReadSchema(pParse);
133833 }
133834
133835 if( pRet ){
133836 SelectDest dest;
 
133837 pRet->pSrc->nSrc = 1;
133838 pRet->pPrior = pLeft->pPrior;
133839 pRet->op = pLeft->op;
133840 if( pRet->pPrior ) pRet->selFlags |= SF_Values;
133841 pLeft->pPrior = 0;
133842 pLeft->op = TK_SELECT;
133843 assert( pLeft->pNext==0 );
133844 assert( pRet->pNext==0 );
133845 p = &pRet->pSrc->a[0];
133846 p->pSelect = pLeft;
133847 p->fg.viaCoroutine = 1;
133848 p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
133849 p->regReturn = ++pParse->nMem;
133850 p->iCursor = -1;
 
133851 p->u1.nRow = 2;
133852 sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub);
133853 sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn);
133854
133855 /* Allocate registers for the output of the co-routine. Do so so
133856 ** that there are two unused registers immediately before those
133857 ** used by the co-routine. This allows the code in sqlite3Insert()
133858 ** to use these registers directly, instead of copying the output
133859 ** of the co-routine to a separate array for processing. */
133860 dest.iSdst = pParse->nMem + 3;
133861 dest.nSdst = pLeft->pEList->nExpr;
133862 pParse->nMem += 2 + dest.nSdst;
133863
133864 pLeft->selFlags |= SF_MultiValue;
133865 sqlite3Select(pParse, pLeft, &dest);
133866 p->regResult = dest.iSdst;
133867 assert( pParse->nErr || dest.iSdst>0 );
 
 
 
 
 
 
133868 pLeft = pRet;
133869 }
133870 }else{
133871 p = &pLeft->pSrc->a[0];
133872 assert( !p->fg.isTabFunc && !p->fg.isIndexedBy );
133873 p->u1.nRow++;
133874 }
133875
133876 if( pParse->nErr==0 ){
 
133877 assert( p!=0 );
133878 if( p->pSelect->pEList->nExpr!=pRow->nExpr ){
133879 sqlite3SelectWrongNumTermsError(pParse, p->pSelect);
 
 
 
 
 
133880 }else{
133881 sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0);
133882 sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn);
133883 }
133884 }
133885 sqlite3ExprListDelete(pParse->db, pRow);
133886 }
133887
@@ -134228,13 +134534,18 @@
134228 if( pSelect->pSrc->nSrc==1
134229 && pSelect->pSrc->a[0].fg.viaCoroutine
134230 && pSelect->pPrior==0
134231 ){
134232 SrcItem *pItem = &pSelect->pSrc->a[0];
134233 dest.iSDParm = pItem->regReturn;
134234 regFromSelect = pItem->regResult;
134235 nColumn = pItem->pSelect->pEList->nExpr;
 
 
 
 
 
134236 ExplainQueryPlan((pParse, 0, "SCAN %S", pItem));
134237 if( bIdListInOrder && nColumn==pTab->nCol ){
134238 regData = regFromSelect;
134239 regRowid = regData - 1;
134240 regIns = regRowid - (IsVirtual(pTab) ? 1 : 0);
@@ -136150,11 +136461,11 @@
136150 }
136151 assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
136152 if( pSelect->pSrc->nSrc!=1 ){
136153 return 0; /* FROM clause must have exactly one term */
136154 }
136155 if( pSelect->pSrc->a[0].pSelect ){
136156 return 0; /* FROM clause cannot contain a subquery */
136157 }
136158 if( pSelect->pWhere ){
136159 return 0; /* SELECT may not have a WHERE clause */
136160 }
@@ -143448,15 +143759,17 @@
143448 /*
143449 ** Mark a subquery result column as having been used.
143450 */
143451 SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
143452 assert( pItem!=0 );
143453 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
143454 if( pItem->fg.isNestedFrom ){
143455 ExprList *pResults;
143456 assert( pItem->pSelect!=0 );
143457 pResults = pItem->pSelect->pEList;
 
 
143458 assert( pResults!=0 );
143459 assert( iCol>=0 && iCol<pResults->nExpr );
143460 pResults->a[iCol].fg.bUsed = 1;
143461 }
143462 }
@@ -143486,13 +143799,13 @@
143486 assert( iEnd<pSrc->nSrc );
143487 assert( iStart>=0 );
143488 assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
143489
143490 for(i=iStart; i<=iEnd; i++){
143491 iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
143492 if( iCol>=0
143493 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
143494 ){
143495 if( piTab ){
143496 sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
143497 *piTab = i;
143498 *piCol = iCol;
@@ -143617,14 +143930,14 @@
143617
143618 pSrc = p->pSrc;
143619 pLeft = &pSrc->a[0];
143620 pRight = &pLeft[1];
143621 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
143622 Table *pRightTab = pRight->pTab;
143623 u32 joinType;
143624
143625 if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
143626 joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
143627
143628 /* If this is a NATURAL join, synthesize an appropriate USING clause
143629 ** to specify which columns should be joined.
143630 */
@@ -145046,12 +145359,16 @@
145046 int iCol = pExpr->iColumn; /* Index of column in pTab */
145047 while( pNC && !pTab ){
145048 SrcList *pTabList = pNC->pSrcList;
145049 for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
145050 if( j<pTabList->nSrc ){
145051 pTab = pTabList->a[j].pTab;
145052 pS = pTabList->a[j].pSelect;
 
 
 
 
145053 }else{
145054 pNC = pNC->pNext;
145055 }
145056 }
145057
@@ -147099,11 +147416,13 @@
147099 p->pHaving = substExpr(pSubst, p->pHaving);
147100 p->pWhere = substExpr(pSubst, p->pWhere);
147101 pSrc = p->pSrc;
147102 assert( pSrc!=0 );
147103 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
147104 substSelect(pSubst, pItem->pSelect, 1);
 
 
147105 if( pItem->fg.isTabFunc ){
147106 substExprList(pSubst, pItem->u1.pFuncArg);
147107 }
147108 }
147109 }while( doPrior && (p = p->pPrior)!=0 );
@@ -147130,11 +147449,11 @@
147130 static void recomputeColumnsUsed(
147131 Select *pSelect, /* The complete SELECT statement */
147132 SrcItem *pSrcItem /* Which FROM clause item to recompute */
147133 ){
147134 Walker w;
147135 if( NEVER(pSrcItem->pTab==0) ) return;
147136 memset(&w, 0, sizeof(w));
147137 w.xExprCallback = recomputeColumnsUsedExpr;
147138 w.xSelectCallback = sqlite3SelectWalkNoop;
147139 w.u.pSrcItem = pSrcItem;
147140 pSrcItem->colUsed = 0;
@@ -147170,12 +147489,14 @@
147170 assert( pItem->iCursor < aCsrMap[0] );
147171 if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){
147172 aCsrMap[pItem->iCursor+1] = pParse->nTab++;
147173 }
147174 pItem->iCursor = aCsrMap[pItem->iCursor+1];
147175 for(p=pItem->pSelect; p; p=p->pPrior){
147176 srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
 
 
147177 }
147178 }
147179 }
147180 }
147181
@@ -147482,11 +147803,12 @@
147482 if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
147483 pSrc = p->pSrc;
147484 assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
147485 pSubitem = &pSrc->a[iFrom];
147486 iParent = pSubitem->iCursor;
147487 pSub = pSubitem->pSelect;
 
147488 assert( pSub!=0 );
147489
147490 #ifndef SQLITE_OMIT_WINDOWFUNC
147491 if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */
147492 #endif
@@ -147535,11 +147857,11 @@
147535 **
147536 ** See also tickets #306, #350, and #3300.
147537 */
147538 if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
147539 if( pSubSrc->nSrc>1 /* (3a) */
147540 || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */
147541 || (p->selFlags & SF_Distinct)!=0 /* (3d) */
147542 || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
147543 ){
147544 return 0;
147545 }
@@ -147621,18 +147943,22 @@
147621 TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
147622 testcase( i==SQLITE_DENY );
147623 pParse->zAuthContext = zSavedAuthContext;
147624
147625 /* Delete the transient structures associated with the subquery */
147626 pSub1 = pSubitem->pSelect;
147627 sqlite3DbFree(db, pSubitem->zDatabase);
 
 
 
 
 
 
147628 sqlite3DbFree(db, pSubitem->zName);
147629 sqlite3DbFree(db, pSubitem->zAlias);
147630 pSubitem->zDatabase = 0;
147631 pSubitem->zName = 0;
147632 pSubitem->zAlias = 0;
147633 pSubitem->pSelect = 0;
147634 assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
147635
147636 /* If the sub-query is a compound SELECT statement, then (by restrictions
147637 ** 17 and 18 above) it must be a UNION ALL and the parent query must
147638 ** be of the form:
@@ -147669,20 +147995,20 @@
147669 for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
147670 Select *pNew;
147671 ExprList *pOrderBy = p->pOrderBy;
147672 Expr *pLimit = p->pLimit;
147673 Select *pPrior = p->pPrior;
147674 Table *pItemTab = pSubitem->pTab;
147675 pSubitem->pTab = 0;
147676 p->pOrderBy = 0;
147677 p->pPrior = 0;
147678 p->pLimit = 0;
147679 pNew = sqlite3SelectDup(db, p, 0);
147680 p->pLimit = pLimit;
147681 p->pOrderBy = pOrderBy;
147682 p->op = TK_ALL;
147683 pSubitem->pTab = pItemTab;
147684 if( pNew==0 ){
147685 p->pPrior = pPrior;
147686 }else{
147687 pNew->selId = ++pParse->nSelect;
147688 if( aCsrMap && ALWAYS(db->mallocFailed==0) ){
@@ -147693,15 +148019,18 @@
147693 pNew->pNext = p;
147694 p->pPrior = pNew;
147695 TREETRACE(0x4,pParse,p,("compound-subquery flattener"
147696 " creates %u as peer\n",pNew->selId));
147697 }
147698 assert( pSubitem->pSelect==0 );
147699 }
147700 sqlite3DbFree(db, aCsrMap);
147701 if( db->mallocFailed ){
147702 pSubitem->pSelect = pSub1;
 
 
 
147703 return 1;
147704 }
147705
147706 /* Defer deleting the Table object associated with the
147707 ** subquery until code generation is
@@ -147708,20 +148037,20 @@
147708 ** complete, since there may still exist Expr.pTab entries that
147709 ** refer to the subquery even after flattening. Ticket #3346.
147710 **
147711 ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
147712 */
147713 if( ALWAYS(pSubitem->pTab!=0) ){
147714 Table *pTabToDel = pSubitem->pTab;
147715 if( pTabToDel->nTabRef==1 ){
147716 Parse *pToplevel = sqlite3ParseToplevel(pParse);
147717 sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
147718 testcase( pToplevel->earlyCleanup );
147719 }else{
147720 pTabToDel->nTabRef--;
147721 }
147722 pSubitem->pTab = 0;
147723 }
147724
147725 /* The following loop runs once for each term in a compound-subquery
147726 ** flattening (as described above). If we are doing a different kind
147727 ** of flattening - a flattening other than a compound-subquery flattening -
@@ -147773,12 +148102,15 @@
147773 /* Transfer the FROM clause terms from the subquery into the
147774 ** outer query.
147775 */
147776 for(i=0; i<nSubSrc; i++){
147777 SrcItem *pItem = &pSrc->a[i+iFrom];
147778 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
147779 assert( pItem->fg.isTabFunc==0 );
 
 
 
 
147780 *pItem = pSubSrc->a[i];
147781 pItem->fg.jointype |= ltorj;
147782 iNewParent = pSubSrc->a[i].iCursor;
147783 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
147784 }
@@ -148458,14 +148790,14 @@
148458
148459 assert( pItem!=0 );
148460 if( pItem->fg.isCorrelated || pItem->fg.isCte ){
148461 return 0;
148462 }
148463 assert( pItem->pTab!=0 );
148464 pTab = pItem->pTab;
148465 assert( pItem->pSelect!=0 );
148466 pSub = pItem->pSelect;
148467 assert( pSub->pEList->nExpr==pTab->nCol );
148468 for(pX=pSub; pX; pX=pX->pPrior){
148469 if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
148470 testcase( pX->selFlags & SF_Distinct );
148471 testcase( pX->selFlags & SF_Aggregate );
@@ -148590,17 +148922,17 @@
148590 assert( !p->pGroupBy );
148591
148592 if( p->pWhere
148593 || p->pEList->nExpr!=1
148594 || p->pSrc->nSrc!=1
148595 || p->pSrc->a[0].pSelect
148596 || pAggInfo->nFunc!=1
148597 || p->pHaving
148598 ){
148599 return 0;
148600 }
148601 pTab = p->pSrc->a[0].pTab;
148602 assert( pTab!=0 );
148603 assert( !IsView(pTab) );
148604 if( !IsOrdinaryTable(pTab) ) return 0;
148605 pExpr = p->pEList->a[0].pExpr;
148606 assert( pExpr!=0 );
@@ -148621,11 +148953,11 @@
148621 ** was such a clause and the named index cannot be found, return
148622 ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
148623 ** pFrom->pIndex and return SQLITE_OK.
148624 */
148625 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){
148626 Table *pTab = pFrom->pTab;
148627 char *zIndexedBy = pFrom->u1.zIndexedBy;
148628 Index *pIdx;
148629 assert( pTab!=0 );
148630 assert( pFrom->fg.isIndexedBy!=0 );
148631
@@ -148698,11 +149030,15 @@
148698 db = pParse->db;
148699 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
148700 if( pNew==0 ) return WRC_Abort;
148701 memset(&dummy, 0, sizeof(dummy));
148702 pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
148703 if( pNewSrc==0 ) return WRC_Abort;
 
 
 
 
148704 *pNew = *p;
148705 p->pSrc = pNewSrc;
148706 p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
148707 p->op = TK_SELECT;
148708 p->pWhere = 0;
@@ -148753,11 +149089,11 @@
148753 SrcItem *pItem, /* FROM clause element to resolve */
148754 With **ppContext /* OUT: WITH clause return value belongs to */
148755 ){
148756 const char *zName = pItem->zName;
148757 With *p;
148758 assert( pItem->zDatabase==0 );
148759 assert( zName!=0 );
148760 for(p=pWith; p; p=p->pOuter){
148761 int i;
148762 for(i=0; i<p->nCte; i++){
148763 if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
@@ -148823,21 +149159,22 @@
148823 SrcItem *pFrom /* The FROM clause term to check */
148824 ){
148825 Cte *pCte; /* Matched CTE (or NULL if no match) */
148826 With *pWith; /* The matching WITH */
148827
148828 assert( pFrom->pTab==0 );
148829 if( pParse->pWith==0 ){
148830 /* There are no WITH clauses in the stack. No match is possible */
148831 return 0;
148832 }
148833 if( pParse->nErr ){
148834 /* Prior errors might have left pParse->pWith in a goofy state, so
148835 ** go no further. */
148836 return 0;
148837 }
148838 if( pFrom->zDatabase!=0 ){
 
148839 /* The FROM term contains a schema qualifier (ex: main.t1) and so
148840 ** it cannot possibly be a CTE reference. */
148841 return 0;
148842 }
148843 if( pFrom->fg.notCte ){
@@ -148869,11 +149206,11 @@
148869 sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
148870 return 2;
148871 }
148872 if( cannotBeFunction(pParse, pFrom) ) return 2;
148873
148874 assert( pFrom->pTab==0 );
148875 pTab = sqlite3DbMallocZero(db, sizeof(Table));
148876 if( pTab==0 ) return 2;
148877 pCteUse = pCte->pUse;
148878 if( pCteUse==0 ){
148879 pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0]));
@@ -148883,42 +149220,47 @@
148883 sqlite3DbFree(db, pTab);
148884 return 2;
148885 }
148886 pCteUse->eM10d = pCte->eM10d;
148887 }
148888 pFrom->pTab = pTab;
148889 pTab->nTabRef = 1;
148890 pTab->zName = sqlite3DbStrDup(db, pCte->zName);
148891 pTab->iPKey = -1;
148892 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
148893 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
148894 pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
148895 if( db->mallocFailed ) return 2;
148896 pFrom->pSelect->selFlags |= SF_CopyCte;
148897 assert( pFrom->pSelect );
 
 
148898 if( pFrom->fg.isIndexedBy ){
148899 sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
148900 return 2;
148901 }
 
148902 pFrom->fg.isCte = 1;
148903 pFrom->u2.pCteUse = pCteUse;
148904 pCteUse->nUse++;
148905
148906 /* Check if this is a recursive CTE. */
148907 pRecTerm = pSel = pFrom->pSelect;
148908 bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
148909 while( bMayRecursive && pRecTerm->op==pSel->op ){
148910 int i;
148911 SrcList *pSrc = pRecTerm->pSrc;
148912 assert( pRecTerm->pPrior!=0 );
148913 for(i=0; i<pSrc->nSrc; i++){
148914 SrcItem *pItem = &pSrc->a[i];
148915 if( pItem->zDatabase==0
148916 && pItem->zName!=0
 
 
148917 && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
148918 ){
148919 pItem->pTab = pTab;
148920 pTab->nTabRef++;
148921 pItem->fg.isRecursive = 1;
148922 if( pRecTerm->selFlags & SF_Recursive ){
148923 sqlite3ErrorMsg(pParse,
148924 "multiple references to recursive table: %s", pCte->zName
@@ -149016,15 +149358,18 @@
149016 ** allocates and populates the SrcItem.pTab object. If successful,
149017 ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
149018 ** SQLITE_NOMEM.
149019 */
149020 SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
149021 Select *pSel = pFrom->pSelect;
149022 Table *pTab;
149023
 
 
 
149024 assert( pSel );
149025 pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
149026 if( pTab==0 ) return SQLITE_NOMEM;
149027 pTab->nTabRef = 1;
149028 if( pFrom->zAlias ){
149029 pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
149030 }else{
@@ -149140,37 +149485,39 @@
149140 ** an entry of the FROM clause is a subquery instead of a table or view,
149141 ** then create a transient table structure to describe the subquery.
149142 */
149143 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149144 Table *pTab;
149145 assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
149146 if( pFrom->pTab ) continue;
149147 assert( pFrom->fg.isRecursive==0 );
149148 if( pFrom->zName==0 ){
149149 #ifndef SQLITE_OMIT_SUBQUERY
149150 Select *pSel = pFrom->pSelect;
 
 
149151 /* A sub-query in the FROM clause of a SELECT */
149152 assert( pSel!=0 );
149153 assert( pFrom->pTab==0 );
149154 if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
149155 if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
149156 #endif
149157 #ifndef SQLITE_OMIT_CTE
149158 }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){
149159 if( rc>1 ) return WRC_Abort;
149160 pTab = pFrom->pTab;
149161 assert( pTab!=0 );
149162 #endif
149163 }else{
149164 /* An ordinary table or view name in the FROM clause */
149165 assert( pFrom->pTab==0 );
149166 pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
149167 if( pTab==0 ) return WRC_Abort;
149168 if( pTab->nTabRef>=0xffff ){
149169 sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
149170 pTab->zName);
149171 pFrom->pTab = 0;
149172 return WRC_Abort;
149173 }
149174 pTab->nTabRef++;
149175 if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
149176 return WRC_Abort;
@@ -149178,19 +149525,19 @@
149178 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
149179 if( !IsOrdinaryTable(pTab) ){
149180 i16 nCol;
149181 u8 eCodeOrig = pWalker->eCode;
149182 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
149183 assert( pFrom->pSelect==0 );
149184 if( IsView(pTab) ){
149185 if( (db->flags & SQLITE_EnableView)==0
149186 && pTab->pSchema!=db->aDb[1].pSchema
149187 ){
149188 sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
149189 pTab->zName);
149190 }
149191 pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);
149192 }
149193 #ifndef SQLITE_OMIT_VIRTUALTABLE
149194 else if( ALWAYS(IsVirtual(pTab))
149195 && pFrom->fg.fromDDL
149196 && ALWAYS(pTab->u.vtab.p!=0)
@@ -149202,11 +149549,13 @@
149202 assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 );
149203 #endif
149204 nCol = pTab->nCol;
149205 pTab->nCol = -1;
149206 pWalker->eCode = 1; /* Turn on Select.selId renumbering */
149207 sqlite3WalkSelect(pWalker, pFrom->pSelect);
 
 
149208 pWalker->eCode = eCodeOrig;
149209 pTab->nCol = nCol;
149210 }
149211 #endif
149212 }
@@ -149289,11 +149638,11 @@
149289 assert( ExprUseWOfst(pE) );
149290 iErrOfst = pE->w.iOfst;
149291 }
149292 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149293 int nAdd; /* Number of cols including rowid */
149294 Table *pTab = pFrom->pTab; /* Table for this data source */
149295 ExprList *pNestedFrom; /* Result-set of a nested FROM clause */
149296 char *zTabName; /* AS name for this data source */
149297 const char *zSchemaName = 0; /* Schema name for this data source */
149298 int iDb; /* Schema index for this data src */
149299 IdList *pUsing; /* USING clause for pFrom[1] */
@@ -149300,14 +149649,15 @@
149300
149301 if( (zTabName = pFrom->zAlias)==0 ){
149302 zTabName = pTab->zName;
149303 }
149304 if( db->mallocFailed ) break;
149305 assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
149306 if( pFrom->fg.isNestedFrom ){
149307 assert( pFrom->pSelect!=0 );
149308 pNestedFrom = pFrom->pSelect->pEList;
 
149309 assert( pNestedFrom!=0 );
149310 assert( pNestedFrom->nExpr==pTab->nCol );
149311 assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
149312 }else{
149313 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
@@ -149542,18 +149892,16 @@
149542 p->selFlags |= SF_HasTypeInfo;
149543 pParse = pWalker->pParse;
149544 assert( (p->selFlags & SF_Resolved) );
149545 pTabList = p->pSrc;
149546 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149547 Table *pTab = pFrom->pTab;
149548 assert( pTab!=0 );
149549 if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
149550 /* A sub-query in the FROM clause of a SELECT */
149551 Select *pSel = pFrom->pSelect;
149552 if( pSel ){
149553 sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
149554 }
149555 }
149556 }
149557 }
149558 #endif
149559
@@ -149863,10 +150211,11 @@
149863 int i;
149864 struct AggInfo_func *pF;
149865 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
149866 ExprList *pList;
149867 assert( ExprUseXList(pF->pFExpr) );
 
149868 pList = pF->pFExpr->x.pList;
149869 if( pF->iOBTab>=0 ){
149870 /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
149871 ** were stored in emphermal table pF->iOBTab. Here, we extract those
149872 ** inputs (in ORDER BY order) and make all calls to OP_AggStep
@@ -150072,19 +150421,21 @@
150072 sqlite3ReleaseTempRange(pParse, regAgg, nArg);
150073 }
150074 if( addrNext ){
150075 sqlite3VdbeResolveLabel(v, addrNext);
150076 }
 
150077 }
150078 if( regHit==0 && pAggInfo->nAccumulator ){
150079 regHit = regAcc;
150080 }
150081 if( regHit ){
150082 addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
150083 }
150084 for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
150085 sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i));
 
150086 }
150087
150088 pAggInfo->directMode = 0;
150089 if( addrHitTest ){
150090 sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
@@ -150196,29 +150547,32 @@
150196 SrcList *pTabList, /* Search for self-joins in this FROM clause */
150197 SrcItem *pThis, /* Search for prior reference to this subquery */
150198 int iFirst, int iEnd /* Range of FROM-clause entries to search. */
150199 ){
150200 SrcItem *pItem;
150201 assert( pThis->pSelect!=0 );
150202 if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
 
 
 
150203 while( iFirst<iEnd ){
150204 Select *pS1;
150205 pItem = &pTabList->a[iFirst++];
150206 if( pItem->pSelect==0 ) continue;
150207 if( pItem->fg.viaCoroutine ) continue;
150208 if( pItem->zName==0 ) continue;
150209 assert( pItem->pTab!=0 );
150210 assert( pThis->pTab!=0 );
150211 if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
150212 if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
150213 pS1 = pItem->pSelect;
150214 if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
150215 /* The query flattener left two different CTE tables with identical
150216 ** names in the same FROM clause. */
150217 continue;
150218 }
150219 if( pItem->pSelect->selFlags & SF_PushDown ){
150220 /* The view was modified by some other optimization such as
150221 ** pushDownWhereTerms() */
150222 continue;
150223 }
150224 return pItem;
@@ -150258,10 +150612,11 @@
150258 static int countOfViewOptimization(Parse *pParse, Select *p){
150259 Select *pSub, *pPrior;
150260 Expr *pExpr;
150261 Expr *pCount;
150262 sqlite3 *db;
 
150263 if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
150264 if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
150265 if( p->pWhere ) return 0;
150266 if( p->pHaving ) return 0;
150267 if( p->pGroupBy ) return 0;
@@ -150272,30 +150627,30 @@
150272 if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
150273 assert( ExprUseXList(pExpr) );
150274 if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
150275 if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
150276 if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
150277 pSub = p->pSrc->a[0].pSelect;
150278 if( pSub==0 ) return 0; /* The FROM is a subquery */
 
150279 if( pSub->pPrior==0 ) return 0; /* Must be a compound */
150280 if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */
150281 do{
150282 if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
150283 if( pSub->pWhere ) return 0; /* No WHERE clause */
150284 if( pSub->pLimit ) return 0; /* No LIMIT clause */
150285 if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
150286 assert( pSub->pHaving==0 ); /* Due to the previous */
150287 pSub = pSub->pPrior; /* Repeat over compound */
150288 }while( pSub );
150289
150290 /* If we reach this point then it is OK to perform the transformation */
150291
150292 db = pParse->db;
150293 pCount = pExpr;
150294 pExpr = 0;
150295 pSub = p->pSrc->a[0].pSelect;
150296 p->pSrc->a[0].pSelect = 0;
150297 sqlite3SrcListDelete(db, p->pSrc);
150298 p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
150299 while( pSub ){
150300 Expr *pTerm;
150301 pPrior = pSub->pPrior;
@@ -150336,16 +150691,16 @@
150336 static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
150337 int i;
150338 for(i=0; i<pSrc->nSrc; i++){
150339 SrcItem *p1 = &pSrc->a[i];
150340 if( p1==p0 ) continue;
150341 if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
150342 return 1;
150343 }
150344 if( p1->pSelect
150345 && (p1->pSelect->selFlags & SF_NestedFrom)!=0
150346 && sameSrcAlias(p0, p1->pSelect->pSrc)
150347 ){
150348 return 1;
150349 }
150350 }
150351 return 0;
@@ -150406,17 +150761,17 @@
150406 while( 1 /*exit-by-break*/ ){
150407 if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */
150408 if( i==0 ) break;
150409 i--;
150410 pItem--;
150411 if( pItem->pSelect!=0 ) return 0; /* (1c-i) */
150412 }
150413 return 1;
150414 }
150415
150416 /*
150417 ** Generate code for the SELECT statement given in the p argument.
150418 **
150419 ** The results are returned according to the SelectDest structure.
150420 ** See comments in sqliteInt.h for further information.
150421 **
150422 ** This routine returns the number of errors. If any errors are
@@ -150423,10 +150778,44 @@
150423 ** encountered, then an appropriate error message is left in
150424 ** pParse->zErrMsg.
150425 **
150426 ** This routine does NOT free the Select structure passed in. The
150427 ** calling function needs to do that.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150428 */
150429 SQLITE_PRIVATE int sqlite3Select(
150430 Parse *pParse, /* The parser context */
150431 Select *p, /* The SELECT statement being coded. */
150432 SelectDest *pDest /* What to do with the query results */
@@ -150466,10 +150855,11 @@
150466 }
150467 sqlite3ShowSelect(p);
150468 }
150469 #endif
150470
 
150471 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
150472 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
150473 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
150474 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
150475 if( IgnorableDistinct(pDest) ){
@@ -150517,11 +150907,11 @@
150517 if( p->selFlags & SF_UFSrcCheck ){
150518 SrcItem *p0 = &p->pSrc->a[0];
150519 if( sameSrcAlias(p0, p->pSrc) ){
150520 sqlite3ErrorMsg(pParse,
150521 "target object/alias may not appear in FROM clause: %s",
150522 p0->zAlias ? p0->zAlias : p0->pTab->zName
150523 );
150524 goto select_end;
150525 }
150526
150527 /* Clear the SF_UFSrcCheck flag. The check has already been performed,
@@ -150552,16 +150942,17 @@
150552 memset(&sSort, 0, sizeof(sSort));
150553 sSort.pOrderBy = p->pOrderBy;
150554
150555 /* Try to do various optimizations (flattening subqueries, and strength
150556 ** reduction of join operators) in the FROM clause up into the main query
 
150557 */
150558 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150559 for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
150560 SrcItem *pItem = &pTabList->a[i];
150561 Select *pSub = pItem->pSelect;
150562 Table *pTab = pItem->pTab;
150563
150564 /* The expander should have already created transient Table objects
150565 ** even for FROM clause elements such as subqueries that do not correspond
150566 ** to a real table */
150567 assert( pTab!=0 );
@@ -150574,10 +150965,11 @@
150574 **
150575 ** If terms of the i-th table are used in the WHERE clause in such a
150576 ** way that the i-th table cannot be the NULL row of a join, then
150577 ** perform the appropriate simplification. This is called
150578 ** "OUTER JOIN strength reduction" in the SQLite documentation.
 
150579 */
150580 if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
150581 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor,
150582 pItem->fg.jointype & JT_LTORJ)
150583 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
@@ -150644,11 +151036,12 @@
150644 ** flattening in that case.
150645 */
150646 if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
150647 assert( pSub->pGroupBy==0 );
150648
150649 /* If a FROM-clause subquery has an ORDER BY clause that is not
 
150650 ** really doing anything, then delete it now so that it does not
150651 ** interfere with query flattening. See the discussion at
150652 ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a
150653 **
150654 ** Beware of these cases where the ORDER BY clause may not be safely
@@ -150710,10 +151103,11 @@
150710 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
150711 ){
150712 continue;
150713 }
150714
 
150715 if( flattenSubquery(pParse, p, i, isAgg) ){
150716 if( pParse->nErr ) goto select_end;
150717 /* This subquery can be absorbed into its parent. */
150718 i = -1;
150719 }
@@ -150725,11 +151119,11 @@
150725 }
150726 #endif
150727
150728 #ifndef SQLITE_OMIT_COMPOUND_SELECT
150729 /* Handle compound SELECT statements using the separate multiSelect()
150730 ** procedure.
150731 */
150732 if( p->pPrior ){
150733 rc = multiSelect(pParse, p, pDest);
150734 #if TREETRACE_ENABLED
150735 TREETRACE(0x400,pParse,p,("end compound-select processing\n"));
@@ -150741,13 +151135,13 @@
150741 return rc;
150742 }
150743 #endif
150744
150745 /* Do the WHERE-clause constant propagation optimization if this is
150746 ** a join. No need to speed time on this operation for non-join queries
150747 ** as the equivalent optimization will be handled by query planner in
150748 ** sqlite3WhereBegin().
150749 */
150750 if( p->pWhere!=0
150751 && p->pWhere->op==TK_AND
150752 && OptimizationEnabled(db, SQLITE_PropagateConst)
150753 && propagateConstants(pParse, p)
@@ -150760,31 +151154,38 @@
150760 #endif
150761 }else{
150762 TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n"));
150763 }
150764
 
150765 if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
150766 && countOfViewOptimization(pParse, p)
150767 ){
150768 if( db->mallocFailed ) goto select_end;
150769 pTabList = p->pSrc;
150770 }
150771
150772 /* For each term in the FROM clause, do two things:
150773 ** (1) Authorized unreferenced tables
150774 ** (2) Generate code for all sub-queries
 
 
 
150775 */
150776 for(i=0; i<pTabList->nSrc; i++){
150777 SrcItem *pItem = &pTabList->a[i];
150778 SrcItem *pPrior;
150779 SelectDest dest;
 
150780 Select *pSub;
150781 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150782 const char *zSavedAuthContext;
150783 #endif
150784
150785 /* Issue SQLITE_READ authorizations with a fake column name for any
 
 
150786 ** tables that are referenced but from which no values are extracted.
150787 ** Examples of where these kinds of null SQLITE_READ authorizations
150788 ** would occur:
150789 **
150790 ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
@@ -150797,21 +151198,32 @@
150797 ** which would be unambiguous. But legacy authorization callbacks might
150798 ** assume the column name is non-NULL and segfault. The use of an empty
150799 ** string for the fake column name seems safer.
150800 */
150801 if( pItem->colUsed==0 && pItem->zName!=0 ){
150802 sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
 
 
 
 
 
 
 
 
 
150803 }
150804
150805 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150806 /* Generate code for all sub-queries in the FROM clause
150807 */
150808 pSub = pItem->pSelect;
150809 if( pSub==0 || pItem->addrFillSub!=0 ) continue;
 
 
150810
150811 /* The code for a subquery should only be generated once. */
150812 assert( pItem->addrFillSub==0 );
150813
150814 /* Increment Parse.nHeight by the height of the largest expression
150815 ** tree referred to by this, the parent select. The child select
150816 ** may contain expression trees of at most
150817 ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
@@ -150820,10 +151232,11 @@
150820 */
150821 pParse->nHeight += sqlite3SelectExprHeight(p);
150822
150823 /* Make copies of constant WHERE-clause terms in the outer query down
150824 ** inside the subquery. This can help the subquery to run more efficiently.
 
150825 */
150826 if( OptimizationEnabled(db, SQLITE_PushDown)
150827 && (pItem->fg.isCte==0
150828 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
150829 && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i)
@@ -150833,17 +151246,18 @@
150833 TREETRACE(0x4000,pParse,p,
150834 ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
150835 sqlite3TreeViewSelect(0, p, 0);
150836 }
150837 #endif
150838 assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
150839 }else{
150840 TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
150841 }
150842
150843 /* Convert unused result columns of the subquery into simple NULL
150844 ** expressions, to avoid unneeded searching and computation.
 
150845 */
150846 if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
150847 && disableUnusedSubqueryResultColumns(pItem)
150848 ){
150849 #if TREETRACE_ENABLED
@@ -150857,64 +151271,70 @@
150857 }
150858
150859 zSavedAuthContext = pParse->zAuthContext;
150860 pParse->zAuthContext = pItem->zName;
150861
150862 /* Generate code to implement the subquery
150863 */
150864 if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
150865 /* Implement a co-routine that will return a single row of the result
150866 ** set on each invocation.
150867 */
150868 int addrTop = sqlite3VdbeCurrentAddr(v)+1;
150869
150870 pItem->regReturn = ++pParse->nMem;
150871 sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
150872 VdbeComment((v, "%!S", pItem));
150873 pItem->addrFillSub = addrTop;
150874 sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
150875 ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
150876 sqlite3Select(pParse, pSub, &dest);
150877 pItem->pTab->nRowLogEst = pSub->nSelectRow;
150878 pItem->fg.viaCoroutine = 1;
150879 pItem->regResult = dest.iSdst;
150880 sqlite3VdbeEndCoroutine(v, pItem->regReturn);
 
150881 sqlite3VdbeJumpHere(v, addrTop-1);
150882 sqlite3ClearTempRegCache(pParse);
150883 }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
150884 /* This is a CTE for which materialization code has already been
150885 ** generated. Invoke the subroutine to compute the materialization,
150886 ** the make the pItem->iCursor be a copy of the ephemeral table that
150887 ** holds the result of the materialization. */
150888 CteUse *pCteUse = pItem->u2.pCteUse;
150889 sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
150890 if( pItem->iCursor!=pCteUse->iCur ){
150891 sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);
150892 VdbeComment((v, "%!S", pItem));
150893 }
150894 pSub->nSelectRow = pCteUse->nRowEst;
150895 }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
150896 /* This view has already been materialized by a prior entry in
150897 ** this same FROM clause. Reuse it. */
150898 if( pPrior->addrFillSub ){
150899 sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);
 
 
 
 
 
150900 }
150901 sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
150902 pSub->nSelectRow = pPrior->pSelect->nSelectRow;
150903 }else{
150904 /* Materialize the view. If the view is not correlated, generate a
150905 ** subroutine to do the materialization so that subsequent uses of
150906 ** the same view can reuse the materialization. */
150907 int topAddr;
150908 int onceAddr = 0;
150909 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
150910 int addrExplain;
150911 #endif
150912
150913 pItem->regReturn = ++pParse->nMem;
150914 topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
150915 pItem->addrFillSub = topAddr+1;
150916 pItem->fg.isMaterialized = 1;
150917 if( pItem->fg.isCorrelated==0 ){
150918 /* If the subquery is not correlated and if we are not inside of
150919 ** a trigger, then we only need to compute the value of the subquery
150920 ** once. */
@@ -150925,21 +151345,21 @@
150925 }
150926 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
150927
150928 ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
150929 sqlite3Select(pParse, pSub, &dest);
150930 pItem->pTab->nRowLogEst = pSub->nSelectRow;
150931 if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
150932 sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
150933 VdbeComment((v, "end %!S", pItem));
150934 sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
150935 sqlite3VdbeJumpHere(v, topAddr);
150936 sqlite3ClearTempRegCache(pParse);
150937 if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
150938 CteUse *pCteUse = pItem->u2.pCteUse;
150939 pCteUse->addrM9e = pItem->addrFillSub;
150940 pCteUse->regRtn = pItem->regReturn;
150941 pCteUse->iCur = pItem->iCursor;
150942 pCteUse->nRowEst = pSub->nSelectRow;
150943 }
150944 }
150945 if( db->mallocFailed ) goto select_end;
@@ -150961,11 +151381,13 @@
150961 TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n"));
150962 sqlite3TreeViewSelect(0, p, 0);
150963 }
150964 #endif
150965
150966 /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
 
 
150967 ** if the select-list is the same as the ORDER BY list, then this query
150968 ** can be rewritten as a GROUP BY. In other words, this:
150969 **
150970 ** SELECT DISTINCT xyz FROM ... ORDER BY xyz
150971 **
@@ -151011,11 +151433,11 @@
151011 ** do the sorting. But this sorting ephemeral index might end up
151012 ** being unused if the data can be extracted in pre-sorted order.
151013 ** If that is the case, then the OP_OpenEphemeral instruction will be
151014 ** changed to an OP_Noop once we figure out that the sorting index is
151015 ** not needed. The sSort.addrSortIndex variable is used to facilitate
151016 ** that change.
151017 */
151018 if( sSort.pOrderBy ){
151019 KeyInfo *pKeyInfo;
151020 pKeyInfo = sqlite3KeyInfoFromExprList(
151021 pParse, sSort.pOrderBy, 0, pEList->nExpr);
@@ -151028,10 +151450,11 @@
151028 }else{
151029 sSort.addrSortIndex = -1;
151030 }
151031
151032 /* If the output is destined for a temporary table, open that table.
 
151033 */
151034 if( pDest->eDest==SRT_EphemTab ){
151035 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
151036 if( p->selFlags & SF_NestedFrom ){
151037 /* Delete or NULL-out result columns that will never be used */
@@ -151045,11 +151468,11 @@
151045 if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
151046 }
151047 }
151048 }
151049
151050 /* Set the limiter.
151051 */
151052 iEnd = sqlite3VdbeMakeLabel(pParse);
151053 if( (p->selFlags & SF_FixedLimit)==0 ){
151054 p->nSelectRow = 320; /* 4 billion rows */
151055 }
@@ -151057,11 +151480,11 @@
151057 if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
151058 sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
151059 sSort.sortFlags |= SORTFLAG_UseSorter;
151060 }
151061
151062 /* Open an ephemeral index to use for the distinct set.
151063 */
151064 if( p->selFlags & SF_Distinct ){
151065 sDistinct.tabTnct = pParse->nTab++;
151066 sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
151067 sDistinct.tabTnct, 0, 0,
@@ -151072,11 +151495,11 @@
151072 }else{
151073 sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
151074 }
151075
151076 if( !isAgg && pGroupBy==0 ){
151077 /* No aggregate functions and no GROUP BY clause */
151078 u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
151079 | (p->selFlags & SF_FixedLimit);
151080 #ifndef SQLITE_OMIT_WINDOWFUNC
151081 Window *pWin = p->pWin; /* Main window object (or NULL) */
151082 if( pWin ){
@@ -151145,12 +151568,12 @@
151145 */
151146 TREETRACE(0x2,pParse,p,("WhereEnd\n"));
151147 sqlite3WhereEnd(pWInfo);
151148 }
151149 }else{
151150 /* This case when there exist aggregate functions or a GROUP BY clause
151151 ** or both */
151152 NameContext sNC; /* Name context for processing aggregate information */
151153 int iAMem; /* First Mem address for storing current GROUP BY */
151154 int iBMem; /* First Mem address for previous GROUP BY */
151155 int iUseFlag; /* Mem address holding flag indicating that at least
151156 ** one row of the input to the aggregator has been
@@ -151265,11 +151688,11 @@
151265 }
151266 #endif
151267
151268
151269 /* Processing for aggregates with GROUP BY is very different and
151270 ** much more complex than aggregates without a GROUP BY.
151271 */
151272 if( pGroupBy ){
151273 KeyInfo *pKeyInfo; /* Keying information for the group by clause */
151274 int addr1; /* A-vs-B comparison jump */
151275 int addrOutputRow; /* Start of subroutine that outputs a result row */
@@ -151562,13 +151985,16 @@
151562 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
151563 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
151564 }
151565 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
151566 else {
 
151567 Table *pTab;
151568 if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
151569 /* If isSimpleCount() returns a pointer to a Table structure, then
 
 
151570 ** the SQL statement is of the form:
151571 **
151572 ** SELECT count(*) FROM <tbl>
151573 **
151574 ** where the Table structure returned represents table <tbl>.
@@ -151623,10 +152049,12 @@
151623 assignAggregateRegisters(pParse, pAggInfo);
151624 sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0));
151625 sqlite3VdbeAddOp1(v, OP_Close, iCsr);
151626 explainSimpleCount(pParse, pTab, pBest);
151627 }else{
 
 
151628 int regAcc = 0; /* "populate accumulators" flag */
151629 ExprList *pDistinct = 0;
151630 u16 distFlag = 0;
151631 int eDist;
151632
@@ -151711,11 +152139,11 @@
151711 if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
151712 explainTempTable(pParse, "DISTINCT");
151713 }
151714
151715 /* If there is an ORDER BY clause, then we need to sort the results
151716 ** and send them to the callback one by one.
151717 */
151718 if( sSort.pOrderBy ){
151719 assert( p->pEList==pEList );
151720 generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
151721 }
@@ -151734,10 +152162,11 @@
151734 select_end:
151735 assert( db->mallocFailed==0 || db->mallocFailed==1 );
151736 assert( db->mallocFailed==0 || pParse->nErr!=0 );
151737 sqlite3ExprListDelete(db, pMinMaxOrderBy);
151738 #ifdef SQLITE_DEBUG
 
151739 if( pAggInfo && !db->mallocFailed ){
151740 #if TREETRACE_ENABLED
151741 if( sqlite3TreeTrace & 0x20 ){
151742 TREETRACE(0x20,pParse,p,("Finished with AggInfo\n"));
151743 printAggInfo(pAggInfo);
@@ -152123,12 +152552,14 @@
152123 **
152124 ** To maintain backwards compatibility, ignore the database
152125 ** name on pTableName if we are reparsing out of the schema table
152126 */
152127 if( db->init.busy && iDb!=1 ){
152128 sqlite3DbFree(db, pTableName->a[0].zDatabase);
152129 pTableName->a[0].zDatabase = 0;
 
 
152130 }
152131
152132 /* If the trigger name was unqualified, and the table is a temp table,
152133 ** then set iDb to 1 to create the trigger in the temporary database.
152134 ** If sqlite3SrcListLookup() returns 0, indicating the table does not
@@ -152602,11 +153033,12 @@
152602 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
152603 goto drop_trigger_cleanup;
152604 }
152605
152606 assert( pName->nSrc==1 );
152607 zDb = pName->a[0].zDatabase;
 
152608 zName = pName->a[0].zName;
152609 assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
152610 for(i=OMIT_TEMPDB; i<db->nDb; i++){
152611 int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
152612 if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
@@ -152839,11 +153271,13 @@
152839 assert( zName || pSrc==0 );
152840 if( pSrc ){
152841 Schema *pSchema = pStep->pTrig->pSchema;
152842 pSrc->a[0].zName = zName;
152843 if( pSchema!=db->aDb[1].pSchema ){
152844 pSrc->a[0].pSchema = pSchema;
 
 
152845 }
152846 if( pStep->pFrom ){
152847 SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
152848 if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
152849 Select *pSubquery;
@@ -152952,11 +153386,11 @@
152952 SrcList *pSrc;
152953 assert( pSelect!=0 );
152954 pSrc = pSelect->pSrc;
152955 assert( pSrc!=0 );
152956 for(i=0; i<pSrc->nSrc; i++){
152957 if( pSrc->a[i].pTab==pWalker->u.pTab ){
152958 testcase( pSelect->selFlags & SF_Correlated );
152959 pSelect->selFlags |= SF_Correlated;
152960 pWalker->eCode = 1;
152961 break;
152962 }
@@ -153023,11 +153457,11 @@
153023 memset(&sSelect, 0, sizeof(sSelect));
153024 memset(&sFrom, 0, sizeof(sFrom));
153025 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
153026 sSelect.pSrc = &sFrom;
153027 sFrom.nSrc = 1;
153028 sFrom.a[0].pTab = pTab;
153029 sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */
153030 sFrom.a[0].iCursor = -1;
153031 sqlite3SelectPrep(pParse, &sSelect, 0);
153032 if( pParse->nErr==0 ){
153033 assert( db->mallocFailed==0 );
@@ -153734,11 +154168,11 @@
153734 ExprList *pList = 0;
153735 ExprList *pGrp = 0;
153736 Expr *pLimit2 = 0;
153737 ExprList *pOrderBy2 = 0;
153738 sqlite3 *db = pParse->db;
153739 Table *pTab = pTabList->a[0].pTab;
153740 SrcList *pSrc;
153741 Expr *pWhere2;
153742 int eDest;
153743
153744 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -153758,12 +154192,12 @@
153758
153759 assert( pTabList->nSrc>1 );
153760 if( pSrc ){
153761 assert( pSrc->a[0].fg.notCte );
153762 pSrc->a[0].iCursor = -1;
153763 pSrc->a[0].pTab->nTabRef--;
153764 pSrc->a[0].pTab = 0;
153765 }
153766 if( pPk ){
153767 for(i=0; i<pPk->nKeyCol; i++){
153768 Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]);
153769 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -155007,11 +155441,11 @@
155007 NameContext sNC; /* Context for resolving symbolic names */
155008 Expr sCol[2]; /* Index column converted into an Expr */
155009 int nClause = 0; /* Counter of ON CONFLICT clauses */
155010
155011 assert( pTabList->nSrc==1 );
155012 assert( pTabList->a[0].pTab!=0 );
155013 assert( pUpsert!=0 );
155014 assert( pUpsert->pUpsertTarget!=0 );
155015
155016 /* Resolve all symbolic names in the conflict-target clause, which
155017 ** includes both the list of columns and the optional partial-index
@@ -155026,11 +155460,11 @@
155026 if( rc ) return rc;
155027 rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
155028 if( rc ) return rc;
155029
155030 /* Check to see if the conflict target matches the rowid. */
155031 pTab = pTabList->a[0].pTab;
155032 pTarget = pUpsert->pUpsertTarget;
155033 iCursor = pTabList->a[0].iCursor;
155034 if( HasRowid(pTab)
155035 && pTarget->nExpr==1
155036 && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
@@ -157198,10 +157632,11 @@
157198 } btree;
157199 struct { /* Information for virtual tables */
157200 int idxNum; /* Index number */
157201 u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
157202 u32 bOmitOffset : 1; /* True to let virtual table handle offset */
 
157203 i8 isOrdered; /* True if satisfies ORDER BY */
157204 u16 omitMask; /* Terms that may be omitted */
157205 char *idxStr; /* Index identifier string */
157206 u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
157207 } vtab;
@@ -157832,11 +158267,11 @@
157832 Index *pIdx;
157833
157834 assert( pLoop->u.btree.pIndex!=0 );
157835 pIdx = pLoop->u.btree.pIndex;
157836 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
157837 if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
157838 if( isSearch ){
157839 zFmt = "PRIMARY KEY";
157840 }
157841 }else if( flags & WHERE_PARTIALIDX ){
157842 zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
@@ -157875,11 +158310,13 @@
157875 }
157876 sqlite3_str_appendf(&str, "%c?)", cRangeOp);
157877 }
157878 #ifndef SQLITE_OMIT_VIRTUALTABLE
157879 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
157880 sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
 
 
157881 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
157882 }
157883 #endif
157884 if( pItem->fg.jointype & JT_LEFT ){
157885 sqlite3_str_appendf(&str, " LEFT-JOIN");
@@ -157929,11 +158366,11 @@
157929 sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
157930 str.printfFlags = SQLITE_PRINTF_INTERNAL;
157931 sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
157932 pLoop = pLevel->pWLoop;
157933 if( pLoop->wsFlags & WHERE_IPK ){
157934 const Table *pTab = pItem->pTab;
157935 if( pTab->iPKey>=0 ){
157936 sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
157937 }else{
157938 sqlite3_str_appendf(&str, "rowid=?");
157939 }
@@ -157992,11 +158429,13 @@
157992 }
157993 if( wsFlags & WHERE_INDEXED ){
157994 sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
157995 }
157996 }else{
157997 int addr = pSrclist->a[pLvl->iFrom].addrFillSub;
 
 
157998 VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1);
157999 assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine );
158000 assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr );
158001 sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1);
158002 }
@@ -159129,11 +159568,12 @@
159129 pLoop = pLevel->pWLoop;
159130 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
159131 iCur = pTabItem->iCursor;
159132 pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
159133 bRev = (pWInfo->revMask>>iLevel)&1;
159134 VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
 
159135 #if WHERETRACE_ENABLED /* 0x4001 */
159136 if( sqlite3WhereTrace & 0x1 ){
159137 sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n",
159138 iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom);
159139 if( sqlite3WhereTrace & 0x1000 ){
@@ -159184,15 +159624,19 @@
159184 }
159185 addrHalt = pWInfo->a[j].addrBrk;
159186
159187 /* Special case of a FROM clause subquery implemented as a co-routine */
159188 if( pTabItem->fg.viaCoroutine ){
159189 int regYield = pTabItem->regReturn;
159190 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
 
 
 
 
159191 pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
159192 VdbeCoverage(v);
159193 VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
159194 pLevel->op = OP_Goto;
159195 }else
159196
159197 #ifndef SQLITE_OMIT_VIRTUALTABLE
159198 if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
@@ -159917,11 +160361,11 @@
159917 int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
159918 int iRetInit; /* Address of regReturn init */
159919 int untestedTerms = 0; /* Some terms not completely tested */
159920 int ii; /* Loop counter */
159921 Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
159922 Table *pTab = pTabItem->pTab;
159923
159924 pTerm = pLoop->aLTerm[0];
159925 assert( pTerm!=0 );
159926 assert( pTerm->eOperator & WO_OR );
159927 assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -160376,11 +160820,11 @@
160376 /* pTab is the right-hand table of the RIGHT JOIN. Generate code that
160377 ** will record that the current row of that table has been matched at
160378 ** least once. This is accomplished by storing the PK for the row in
160379 ** both the iMatch index and the regBloom Bloom filter.
160380 */
160381 pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
160382 if( HasRowid(pTab) ){
160383 r = sqlite3GetTempRange(pParse, 2);
160384 sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
160385 nPk = 1;
160386 }else{
@@ -160483,23 +160927,27 @@
160483 SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
160484 SrcList sFrom;
160485 Bitmask mAll = 0;
160486 int k;
160487
160488 ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
160489 sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
160490 pRJ->regReturn);
160491 for(k=0; k<iLevel; k++){
160492 int iIdxCur;
160493 SrcItem *pRight;
160494 assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom );
160495 pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom];
160496 mAll |= pWInfo->a[k].pWLoop->maskSelf;
160497 if( pRight->fg.viaCoroutine ){
 
 
 
 
160498 sqlite3VdbeAddOp3(
160499 v, OP_Null, 0, pRight->regResult,
160500 pRight->regResult + pRight->pSelect->pEList->nExpr-1
160501 );
160502 }
160503 sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
160504 iIdxCur = pWInfo->a[k].iIdxCur;
160505 if( iIdxCur ){
@@ -160533,11 +160981,11 @@
160533 int iCur = pLevel->iTabCur;
160534 int r = ++pParse->nMem;
160535 int nPk;
160536 int jmp;
160537 int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
160538 Table *pTab = pTabItem->pTab;
160539 if( HasRowid(pTab) ){
160540 sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
160541 nPk = 1;
160542 }else{
160543 int iPk;
@@ -160785,15 +161233,24 @@
160785 assert( !ExprHasProperty(pRight, EP_IntValue) );
160786 z = (u8*)pRight->u.zToken;
160787 }
160788 if( z ){
160789
160790 /* Count the number of prefix characters prior to the first wildcard */
 
 
 
 
160791 cnt = 0;
160792 while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
160793 cnt++;
160794 if( c==wc[3] && z[cnt]!=0 ) cnt++;
 
 
 
 
 
160795 }
160796
160797 /* The optimization is possible only if (1) the pattern does not begin
160798 ** with a wildcard and if (2) the non-wildcard prefix does not end with
160799 ** an (illegal 0xff) character, or (3) the pattern does not consist of
@@ -160804,11 +161261,11 @@
160804 ** removed. */
160805 if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){
160806 Expr *pPrefix;
160807
160808 /* A "complete" match if the pattern ends with "*" or "%" */
160809 *pisComplete = c==wc[0] && z[cnt+1]==0;
160810
160811 /* Get the pattern prefix. Remove all escapes from the prefix. */
160812 pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
160813 if( pPrefix ){
160814 int iFrom, iTo;
@@ -161523,11 +161980,13 @@
161523 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere);
161524 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
161525 if( ALWAYS(pSrc!=0) ){
161526 int i;
161527 for(i=0; i<pSrc->nSrc; i++){
161528 mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
 
 
161529 if( pSrc->a[i].fg.isUsing==0 ){
161530 mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
161531 }
161532 if( pSrc->a[i].fg.isTabFunc ){
161533 mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
@@ -161561,11 +162020,11 @@
161561 Index *pIdx;
161562 int i;
161563 int iCur;
161564 do{
161565 iCur = pFrom->a[j].iCursor;
161566 for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
161567 if( pIdx->aColExpr==0 ) continue;
161568 for(i=0; i<pIdx->nKeyCol; i++){
161569 if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
161570 assert( pIdx->bHasExpr );
161571 if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
@@ -161605,11 +162064,11 @@
161605 return 1;
161606 }
161607
161608 for(i=0; i<pFrom->nSrc; i++){
161609 Index *pIdx;
161610 for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
161611 if( pIdx->aColExpr ){
161612 return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i);
161613 }
161614 }
161615 }
@@ -162193,11 +162652,11 @@
162193 */
162194 SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
162195 assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */
162196 if( p->pGroupBy==0
162197 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
162198 && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
162199 ){
162200 ExprList *pOrderBy = p->pOrderBy;
162201 int iCsr = p->pSrc->a[0].iCursor;
162202 int ii;
162203
@@ -162414,11 +162873,11 @@
162414 int j, k;
162415 ExprList *pArgs;
162416 Expr *pColRef;
162417 Expr *pTerm;
162418 if( pItem->fg.isTabFunc==0 ) return;
162419 pTab = pItem->pTab;
162420 assert( pTab!=0 );
162421 pArgs = pItem->u1.pFuncArg;
162422 if( pArgs==0 ) return;
162423 for(j=k=0; j<pArgs->nExpr; j++){
162424 Expr *pRhs;
@@ -163098,11 +163557,11 @@
163098 /* If there is more than one table or sub-select in the FROM clause of
163099 ** this query, then it will not be possible to show that the DISTINCT
163100 ** clause is redundant. */
163101 if( pTabList->nSrc!=1 ) return 0;
163102 iBase = pTabList->a[0].iCursor;
163103 pTab = pTabList->a[0].pTab;
163104
163105 /* If any of the expressions is an IPK column on table iBase, then return
163106 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
163107 ** current SELECT is a correlated sub-query.
163108 */
@@ -163362,14 +163821,14 @@
163362 }
163363 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
163364 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
163365 leftCol = pTerm->u.x.leftColumn;
163366 if( leftCol<0 ) return 0;
163367 aff = pSrc->pTab->aCol[leftCol].affinity;
163368 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
163369 testcase( pTerm->pExpr->op==TK_IS );
163370 return columnIsGoodIndexCandidate(pSrc->pTab, leftCol);
163371 }
163372 #endif
163373
163374
163375 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -163473,11 +163932,11 @@
163473 /* Count the number of columns that will be added to the index
163474 ** and used to match WHERE clause constraints */
163475 nKeyCol = 0;
163476 pTabList = pWC->pWInfo->pTabList;
163477 pSrc = &pTabList->a[pLevel->iFrom];
163478 pTable = pSrc->pTab;
163479 pWCEnd = &pWC->a[pWC->nTerm];
163480 pLoop = pLevel->pWLoop;
163481 idxCols = 0;
163482 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
163483 Expr *pExpr = pTerm->pExpr;
@@ -163615,16 +164074,21 @@
163615 }
163616
163617 /* Fill the automatic index with content */
163618 assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] );
163619 if( pSrc->fg.viaCoroutine ){
163620 int regYield = pSrc->regReturn;
 
 
 
 
 
163621 addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
163622 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub);
163623 addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
163624 VdbeCoverage(v);
163625 VdbeComment((v, "next row of %s", pSrc->pTab->zName));
163626 }else{
163627 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
163628 }
163629 if( pPartial ){
163630 iContinue = sqlite3VdbeMakeLabel(pParse);
@@ -163642,15 +164106,16 @@
163642 sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v));
163643 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
163644 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
163645 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
163646 if( pSrc->fg.viaCoroutine ){
 
163647 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
163648 testcase( pParse->db->mallocFailed );
163649 assert( pLevel->iIdxCur>0 );
163650 translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
163651 pSrc->regResult, pLevel->iIdxCur);
163652 sqlite3VdbeGoto(v, addrTop);
163653 pSrc->fg.viaCoroutine = 0;
163654 }else{
163655 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
163656 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
@@ -163737,11 +164202,11 @@
163737 */
163738 pTabList = pWInfo->pTabList;
163739 iSrc = pLevel->iFrom;
163740 pItem = &pTabList->a[iSrc];
163741 assert( pItem!=0 );
163742 pTab = pItem->pTab;
163743 assert( pTab!=0 );
163744 sz = sqlite3LogEstToInt(pTab->nRowLogEst);
163745 if( sz<10000 ){
163746 sz = 10000;
163747 }else if( sz>10000000 ){
@@ -163768,11 +164233,11 @@
163768 Index *pIdx = pLoop->u.btree.pIndex;
163769 int n = pLoop->u.btree.nEq;
163770 int r1 = sqlite3GetTempRange(pParse, n);
163771 int jj;
163772 for(jj=0; jj<n; jj++){
163773 assert( pIdx->pTable==pItem->pTab );
163774 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
163775 }
163776 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
163777 sqlite3ReleaseTempRange(pParse, r1, n);
163778 }
@@ -163849,11 +164314,11 @@
163849 int eDistinct = 0;
163850 ExprList *pOrderBy = pWInfo->pOrderBy;
163851 WhereClause *p;
163852
163853 assert( pSrc!=0 );
163854 pTab = pSrc->pTab;
163855 assert( pTab!=0 );
163856 assert( IsVirtual(pTab) );
163857
163858 /* Find all WHERE clause constraints referring to this virtual table.
163859 ** Mark each term with the TERM_OK flag. Set nTerm to the number of
@@ -164857,11 +165322,11 @@
164857 SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
164858 if( pWC ){
164859 WhereInfo *pWInfo = pWC->pWInfo;
164860 int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
164861 SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
164862 Table *pTab = pItem->pTab;
164863 Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
164864 sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
164865 p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
164866 sqlite3DebugPrintf(" %12s",
164867 pItem->zAlias ? pItem->zAlias : pTab->zName);
@@ -165845,19 +166310,19 @@
165845 ** 1. The cost of doing one search-by-key to find the first matching
165846 ** entry
165847 ** 2. Stepping forward in the index pNew->nOut times to find all
165848 ** additional matching entries.
165849 */
165850 assert( pSrc->pTab->szTabRow>0 );
165851 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
165852 /* The pProbe->szIdxRow is low for an IPK table since the interior
165853 ** pages are small. Thus szIdxRow gives a good estimate of seek cost.
165854 ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
165855 ** under-estimate the scanning cost. */
165856 rCostIdx = pNew->nOut + 16;
165857 }else{
165858 rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
165859 }
165860 rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
165861
165862 /* Estimate the cost of running the loop. If all data is coming
165863 ** from the index, then this is just the cost of doing the index
@@ -166318,13 +166783,13 @@
166318
166319 pNew = pBuilder->pNew;
166320 pWInfo = pBuilder->pWInfo;
166321 pTabList = pWInfo->pTabList;
166322 pSrc = pTabList->a + pNew->iTab;
166323 pTab = pSrc->pTab;
166324 pWC = pBuilder->pWC;
166325 assert( !IsVirtual(pSrc->pTab) );
166326
166327 if( pSrc->fg.isIndexedBy ){
166328 assert( pSrc->fg.isCte==0 );
166329 /* An INDEXED BY clause specifies a particular index to use */
166330 pProbe = pSrc->u2.pIBIndex;
@@ -166345,11 +166810,11 @@
166345 sPk.pTable = pTab;
166346 sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */
166347 sPk.idxType = SQLITE_IDXTYPE_IPK;
166348 aiRowEstPk[0] = pTab->nRowLogEst;
166349 aiRowEstPk[1] = 0;
166350 pFirst = pSrc->pTab->pIndex;
166351 if( pSrc->fg.notIndexed==0 ){
166352 /* The real indices of the table are only considered if the
166353 ** NOT INDEXED qualifier is omitted from the FROM clause */
166354 sPk.pNext = pFirst;
166355 }
@@ -166464,13 +166929,13 @@
166464 #else
166465 pNew->rRun = rSize + 16;
166466 #endif
166467 ApplyCostMultiplier(pNew->rRun, pTab->costMult);
166468 whereLoopOutputAdjust(pWC, pNew, rSize);
166469 if( pSrc->pSelect ){
166470 if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE;
166471 pNew->u.btree.pOrderBy = pSrc->pSelect->pOrderBy;
166472 }
166473 rc = whereLoopInsert(pBuilder, pNew);
166474 pNew->nOut = rSize;
166475 if( rc ) break;
166476 }else{
@@ -166692,11 +167157,11 @@
166692 pIdxInfo->estimatedRows = 25;
166693 pIdxInfo->idxFlags = 0;
166694 pHidden->mHandleIn = 0;
166695
166696 /* Invoke the virtual table xBestIndex() method */
166697 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
166698 if( rc ){
166699 if( rc==SQLITE_CONSTRAINT ){
166700 /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
166701 ** that the particular combination of parameters provided is unusable.
166702 ** Make no entries in the loop table.
@@ -166722,11 +167187,11 @@
166722 || j<0
166723 || (pTerm = termFromWhereClause(pWC, j))==0
166724 || pNew->aLTerm[iTerm]!=0
166725 || pIdxCons->usable==0
166726 ){
166727 sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
166728 freeIdxStr(pIdxInfo);
166729 return SQLITE_ERROR;
166730 }
166731 testcase( iTerm==nConstraint-1 );
166732 testcase( j==0 );
@@ -166785,11 +167250,11 @@
166785 pNew->nLTerm = mxTerm+1;
166786 for(i=0; i<=mxTerm; i++){
166787 if( pNew->aLTerm[i]==0 ){
166788 /* The non-zero argvIdx values must be contiguous. Raise an
166789 ** error if they are not */
166790 sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
166791 freeIdxStr(pIdxInfo);
166792 return SQLITE_ERROR;
166793 }
166794 }
166795 assert( pNew->nLTerm<=pNew->nLSlot );
@@ -166797,10 +167262,11 @@
166797 pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
166798 pIdxInfo->needToFreeIdxStr = 0;
166799 pNew->u.vtab.idxStr = pIdxInfo->idxStr;
166800 pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
166801 pIdxInfo->nOrderBy : 0);
 
166802 pNew->rSetup = 0;
166803 pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
166804 pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
166805
166806 /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
@@ -166987,11 +167453,11 @@
166987 pWInfo = pBuilder->pWInfo;
166988 pParse = pWInfo->pParse;
166989 pWC = pBuilder->pWC;
166990 pNew = pBuilder->pNew;
166991 pSrc = &pWInfo->pTabList->a[pNew->iTab];
166992 assert( IsVirtual(pSrc->pTab) );
166993 p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
166994 if( p==0 ) return SQLITE_NOMEM_BKPT;
166995 pNew->rSetup = 0;
166996 pNew->wsFlags = WHERE_VIRTUALTABLE;
166997 pNew->nLTerm = 0;
@@ -167001,11 +167467,11 @@
167001 freeIndexInfo(pParse->db, p);
167002 return SQLITE_NOMEM_BKPT;
167003 }
167004
167005 /* First call xBestIndex() with all constraints usable. */
167006 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
167007 WHERETRACE(0x800, (" VirtualOne: all usable\n"));
167008 rc = whereLoopAddVirtualOne(
167009 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
167010 );
167011 if( bRetry ){
@@ -167083,11 +167549,11 @@
167083 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
167084 }
167085 }
167086
167087 freeIndexInfo(pParse->db, p);
167088 WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
167089 return rc;
167090 }
167091 #endif /* SQLITE_OMIT_VIRTUALTABLE */
167092
167093 /*
@@ -167155,11 +167621,11 @@
167155 if( sqlite3WhereTrace & 0x20000 ){
167156 sqlite3WhereClausePrint(sSubBuild.pWC);
167157 }
167158 #endif
167159 #ifndef SQLITE_OMIT_VIRTUALTABLE
167160 if( IsVirtual(pItem->pTab) ){
167161 rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
167162 }else
167163 #endif
167164 {
167165 rc = whereLoopAddBtree(&sSubBuild, mPrereq);
@@ -167269,11 +167735,11 @@
167269 bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
167270 }else if( !hasRightJoin ){
167271 mPrereq = 0;
167272 }
167273 #ifndef SQLITE_OMIT_VIRTUALTABLE
167274 if( IsVirtual(pItem->pTab) ){
167275 SrcItem *p;
167276 for(p=&pItem[1]; p<pEnd; p++){
167277 if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
167278 mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
167279 }
@@ -167905,11 +168371,11 @@
167905 rDelta = 15*(nDep-3);
167906 #ifdef WHERETRACE_ENABLED /* 0x4 */
167907 if( sqlite3WhereTrace&0x4 ){
167908 SrcItem *pItem = pWInfo->pTabList->a + iLoop;
167909 sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n",
167910 pItem->zAlias ? pItem->zAlias : pItem->pTab->zName,
167911 nDep, rDelta);
167912 }
167913 #endif
167914 if( pWInfo->nOutStarDelta==0 ){
167915 for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
@@ -168455,11 +168921,11 @@
168455
168456 pWInfo = pBuilder->pWInfo;
168457 if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
168458 assert( pWInfo->pTabList->nSrc>=1 );
168459 pItem = pWInfo->pTabList->a;
168460 pTab = pItem->pTab;
168461 if( IsVirtual(pTab) ) return 0;
168462 if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){
168463 testcase( pItem->fg.isIndexedBy );
168464 testcase( pItem->fg.notIndexed );
168465 return 0;
@@ -168718,11 +169184,11 @@
168718 assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
168719 for(i=0; i<pWInfo->nLevel; i++){
168720 WhereLoop *pLoop = pWInfo->a[i].pWLoop;
168721 const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
168722 SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
168723 Table *pTab = pItem->pTab;
168724 if( (pTab->tabFlags & TF_HasStat1)==0 ) break;
168725 pTab->tabFlags |= TF_MaybeReanalyze;
168726 if( i>=1
168727 && (pLoop->wsFlags & reqFlags)==reqFlags
168728 /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
@@ -168875,12 +169341,12 @@
168875 int ii;
168876 for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){
168877 SrcItem *pItem = &pWInfo->pTabList->a[ii];
168878 if( !pItem->fg.isCte
168879 || pItem->u2.pCteUse->eM10d!=M10d_Yes
168880 || NEVER(pItem->pSelect==0)
168881 || pItem->pSelect->pOrderBy==0
168882 ){
168883 pWInfo->revMask |= MASKBIT(ii);
168884 }
168885 }
168886 }
@@ -169366,19 +169832,19 @@
169366 */
169367 assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
169368 if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
169369 int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
169370 int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
169371 assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
169372 if( bOnerow || (
169373 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
169374 && !IsVirtual(pTabList->a[0].pTab)
169375 && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
169376 && OptimizationEnabled(db, SQLITE_OnePass)
169377 )){
169378 pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
169379 if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
169380 if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
169381 bFordelete = OPFLAG_FORDELETE;
169382 }
169383 pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
169384 }
@@ -169392,11 +169858,11 @@
169392 Table *pTab; /* Table to open */
169393 int iDb; /* Index of database containing table/index */
169394 SrcItem *pTabItem;
169395
169396 pTabItem = &pTabList->a[pLevel->iFrom];
169397 pTab = pTabItem->pTab;
169398 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
169399 pLoop = pLevel->pWLoop;
169400 if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
169401 /* Do nothing */
169402 }else
@@ -169463,11 +169929,11 @@
169463 /* This is one term of an OR-optimization using the PRIMARY KEY of a
169464 ** WITHOUT ROWID table. No need for a separate index */
169465 iIndexCur = pLevel->iTabCur;
169466 op = 0;
169467 }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
169468 Index *pJ = pTabItem->pTab->pIndex;
169469 iIndexCur = iAuxArg;
169470 assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
169471 while( ALWAYS(pJ) && pJ!=pIx ){
169472 iIndexCur++;
169473 pJ = pJ->pNext;
@@ -169530,11 +169996,11 @@
169530 pRJ->iMatch = pParse->nTab++;
169531 pRJ->regBloom = ++pParse->nMem;
169532 sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
169533 pRJ->regReturn = ++pParse->nMem;
169534 sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
169535 assert( pTab==pTabItem->pTab );
169536 if( HasRowid(pTab) ){
169537 KeyInfo *pInfo;
169538 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
169539 pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
169540 if( pInfo ){
@@ -169569,17 +170035,22 @@
169569 if( pParse->nErr ) goto whereBeginError;
169570 pLevel = &pWInfo->a[ii];
169571 wsFlags = pLevel->pWLoop->wsFlags;
169572 pSrc = &pTabList->a[pLevel->iFrom];
169573 if( pSrc->fg.isMaterialized ){
169574 if( pSrc->fg.isCorrelated ){
169575 sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
 
 
 
 
169576 }else{
169577 int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
169578 sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
169579 sqlite3VdbeJumpHere(v, iOnce);
169580 }
 
 
 
169581 }
169582 assert( pTabList == pWInfo->pTabList );
169583 if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
169584 if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
169585 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -169788,13 +170259,14 @@
169788 if( (ws & WHERE_IDX_ONLY)==0 ){
169789 SrcItem *pSrc = &pTabList->a[pLevel->iFrom];
169790 assert( pLevel->iTabCur==pSrc->iCursor );
169791 if( pSrc->fg.viaCoroutine ){
169792 int m, n;
169793 n = pSrc->regResult;
169794 assert( pSrc->pTab!=0 );
169795 m = pSrc->pTab->nCol;
 
169796 sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1);
169797 }
169798 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
169799 }
169800 if( (ws & WHERE_INDEXED)
@@ -169814,20 +170286,20 @@
169814 sqlite3VdbeGoto(v, pLevel->addrFirst);
169815 }
169816 sqlite3VdbeJumpHere(v, addr);
169817 }
169818 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
169819 pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
169820 }
169821
169822 assert( pWInfo->nLevel<=pTabList->nSrc );
169823 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
169824 int k, last;
169825 VdbeOp *pOp, *pLastOp;
169826 Index *pIdx = 0;
169827 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
169828 Table *pTab = pTabItem->pTab;
169829 assert( pTab!=0 );
169830 pLoop = pLevel->pWLoop;
169831
169832 /* Do RIGHT JOIN processing. Generate code that will output the
169833 ** unmatched rows of the right operand of the RIGHT JOIN with
@@ -169842,13 +170314,14 @@
169842 ** the co-routine into OP_Copy of result contained in a register.
169843 ** OP_Rowid becomes OP_Null.
169844 */
169845 if( pTabItem->fg.viaCoroutine ){
169846 testcase( pParse->db->mallocFailed );
169847 assert( pTabItem->regResult>=0 );
 
169848 translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
169849 pTabItem->regResult, 0);
169850 continue;
169851 }
169852
169853 /* If this scan uses an index, make VDBE code substitutions to read data
169854 ** from the index instead of from the table where possible. In some cases
@@ -171054,13 +171527,14 @@
171054 p->selId, p));
171055 p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
171056 assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
171057 ** of sqlite3DbMallocRawNN() called from
171058 ** sqlite3SrcListAppend() */
171059 if( p->pSrc ){
 
 
171060 Table *pTab2;
171061 p->pSrc->a[0].pSelect = pSub;
171062 p->pSrc->a[0].fg.isCorrelated = 1;
171063 sqlite3SrcListAssignCursors(pParse, p->pSrc);
171064 pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
171065 pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
171066 pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -171070,20 +171544,18 @@
171070 ** the correct error message regardless. */
171071 rc = SQLITE_NOMEM;
171072 }else{
171073 memcpy(pTab, pTab2, sizeof(Table));
171074 pTab->tabFlags |= TF_Ephemeral;
171075 p->pSrc->a[0].pTab = pTab;
171076 pTab = pTab2;
171077 memset(&w, 0, sizeof(w));
171078 w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
171079 w.xSelectCallback = sqlite3WalkerDepthIncrease;
171080 w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
171081 sqlite3WalkSelect(&w, pSub);
171082 }
171083 }else{
171084 sqlite3SelectDelete(db, pSub);
171085 }
171086 if( db->mallocFailed ) rc = SQLITE_NOMEM;
171087
171088 /* Defer deleting the temporary table pTab because if an error occurred,
171089 ** there could still be references to that table embedded in the
@@ -171366,14 +171838,19 @@
171366 ** This is called by code in select.c before it calls sqlite3WhereBegin()
171367 ** to begin iterating through the sub-query results. It is used to allocate
171368 ** and initialize registers and cursors used by sqlite3WindowCodeStep().
171369 */
171370 SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
171371 int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
171372 Window *pMWin = pSelect->pWin;
171373 Window *pWin;
171374 Vdbe *v = sqlite3GetVdbe(pParse);
 
 
 
 
 
 
 
171375
171376 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
171377 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
171378 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
171379 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
@@ -172766,11 +173243,11 @@
172766 Window *pMWin = p->pWin;
172767 ExprList *pOrderBy = pMWin->pOrderBy;
172768 Vdbe *v = sqlite3GetVdbe(pParse);
172769 int csrWrite; /* Cursor used to write to eph. table */
172770 int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
172771 int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */
172772 int iInput; /* To iterate through sub cols */
172773 int addrNe; /* Address of OP_Ne */
172774 int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
172775 int addrInteger = 0; /* Address of OP_Integer */
172776 int addrEmpty; /* Address of OP_Rewind in flush: */
@@ -177217,24 +177694,33 @@
177217 }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
177218 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
177219 if( yymsp[-5].minor.yy203 ){
177220 SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1];
177221 SrcItem *pOld = yymsp[-3].minor.yy203->a;
 
177222 pNew->zName = pOld->zName;
177223 pNew->zDatabase = pOld->zDatabase;
177224 pNew->pSelect = pOld->pSelect;
177225 if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
177226 pNew->fg.isNestedFrom = 1;
 
 
 
 
 
 
 
 
 
177227 }
177228 if( pOld->fg.isTabFunc ){
177229 pNew->u1.pFuncArg = pOld->u1.pFuncArg;
177230 pOld->u1.pFuncArg = 0;
177231 pOld->fg.isTabFunc = 0;
177232 pNew->fg.isTabFunc = 1;
177233 }
177234 pOld->zName = pOld->zDatabase = 0;
177235 pOld->pSelect = 0;
177236 }
177237 sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203);
177238 }else{
177239 Select *pSubquery;
177240 sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
@@ -184790,10 +185276,22 @@
184790 case SQLITE_TESTCTRL_OPTIMIZATIONS: {
184791 sqlite3 *db = va_arg(ap, sqlite3*);
184792 db->dbOptFlags = va_arg(ap, u32);
184793 break;
184794 }
 
 
 
 
 
 
 
 
 
 
 
 
184795
184796 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
184797 **
184798 ** If parameter onoff is 1, subsequent calls to localtime() fail.
184799 ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
@@ -224464,10 +224962,11 @@
224464 )
224465 ){
224466 pIdxInfo->orderByConsumed = 1;
224467 pIdxInfo->idxNum |= 0x08;
224468 }
 
224469
224470 return SQLITE_OK;
224471 }
224472
224473 /*
@@ -232374,13 +232873,36 @@
232374 ** It is the output of the tokenizer module. For tokendata=1 tables, this
232375 ** includes any embedded 0x00 and trailing data.
232376 **
232377 ** This API can be quite slow if used with an FTS5 table created with the
232378 ** "detail=none" or "detail=column" option.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232379 */
232380 struct Fts5ExtensionApi {
232381 int iVersion; /* Currently always set to 3 */
232382
232383 void *(*xUserData)(Fts5Context*);
232384
232385 int (*xColumnCount)(Fts5Context*);
232386 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -232418,10 +232940,19 @@
232418 int (*xQueryToken)(Fts5Context*,
232419 int iPhrase, int iToken,
232420 const char **ppToken, int *pnToken
232421 );
232422 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
 
 
 
 
 
 
 
 
 
232423 };
232424
232425 /*
232426 ** CUSTOM AUXILIARY FUNCTIONS
232427 *************************************************************************/
@@ -232430,19 +232961,20 @@
232430 ** CUSTOM TOKENIZERS
232431 **
232432 ** Applications may also register custom tokenizer types. A tokenizer
232433 ** is registered by providing fts5 with a populated instance of the
232434 ** following structure. All structure methods must be defined, setting
 
232435 ** any member of the fts5_tokenizer struct to NULL leads to undefined
232436 ** behaviour. The structure methods are expected to function as follows:
232437 **
232438 ** xCreate:
232439 ** This function is used to allocate and initialize a tokenizer instance.
232440 ** A tokenizer instance is required to actually tokenize text.
232441 **
232442 ** The first argument passed to this function is a copy of the (void*)
232443 ** pointer provided by the application when the fts5_tokenizer object
232444 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
232445 ** The second and third arguments are an array of nul-terminated strings
232446 ** containing the tokenizer arguments, if any, specified following the
232447 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
232448 ** to create the FTS5 table.
@@ -232462,11 +232994,11 @@
232462 ** This function is expected to tokenize the nText byte string indicated
232463 ** by argument pText. pText may or may not be nul-terminated. The first
232464 ** argument passed to this function is a pointer to an Fts5Tokenizer object
232465 ** returned by an earlier call to xCreate().
232466 **
232467 ** The second argument indicates the reason that FTS5 is requesting
232468 ** tokenization of the supplied text. This is always one of the following
232469 ** four values:
232470 **
232471 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
232472 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -232485,10 +233017,17 @@
232485 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
232486 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
232487 ** function. Or an fts5_api.xColumnSize() request made by the same
232488 ** on a columnsize=0 database.
232489 ** </ul>
 
 
 
 
 
 
 
232490 **
232491 ** For each token in the input string, the supplied callback xToken() must
232492 ** be invoked. The first argument to it should be a copy of the pointer
232493 ** passed as the second argument to xTokenize(). The third and fourth
232494 ** arguments are a pointer to a buffer containing the token text, and the
@@ -232508,10 +233047,33 @@
232508 ** immediately return a copy of the xToken() return value. Or, if the
232509 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
232510 ** if an error occurs with the xTokenize() implementation itself, it
232511 ** may abandon the tokenization and return any error code other than
232512 ** SQLITE_OK or SQLITE_DONE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232513 **
232514 ** SYNONYM SUPPORT
232515 **
232516 ** Custom tokenizers may also support synonyms. Consider a case in which a
232517 ** user wishes to query for a phrase such as "first place". Using the
@@ -232617,10 +233179,37 @@
232617 ** provide synonyms when tokenizing document text (method (3)) or query
232618 ** text (method (2)), not both. Doing so will not cause any errors, but is
232619 ** inefficient.
232620 */
232621 typedef struct Fts5Tokenizer Fts5Tokenizer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232622 typedef struct fts5_tokenizer fts5_tokenizer;
232623 struct fts5_tokenizer {
232624 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
232625 void (*xDelete)(Fts5Tokenizer*);
232626 int (*xTokenize)(Fts5Tokenizer*,
@@ -232635,10 +233224,11 @@
232635 int iStart, /* Byte offset of token within input text */
232636 int iEnd /* Byte offset of end of token within input text */
232637 )
232638 );
232639 };
 
232640
232641 /* Flags that may be passed as the third argument to xTokenize() */
232642 #define FTS5_TOKENIZE_QUERY 0x0001
232643 #define FTS5_TOKENIZE_PREFIX 0x0002
232644 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -232655,11 +233245,11 @@
232655 /*************************************************************************
232656 ** FTS5 EXTENSION REGISTRATION API
232657 */
232658 typedef struct fts5_api fts5_api;
232659 struct fts5_api {
232660 int iVersion; /* Currently always set to 2 */
232661
232662 /* Create a new tokenizer */
232663 int (*xCreateTokenizer)(
232664 fts5_api *pApi,
232665 const char *zName,
@@ -232682,10 +233272,29 @@
232682 const char *zName,
232683 void *pUserData,
232684 fts5_extension_function xFunction,
232685 void (*xDestroy)(void*)
232686 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232687 };
232688
232689 /*
232690 ** END OF REGISTRATION API
232691 *************************************************************************/
@@ -232858,14 +233467,17 @@
232858 typedef struct Fts5Config Fts5Config;
232859 typedef struct Fts5TokenizerConfig Fts5TokenizerConfig;
232860
232861 struct Fts5TokenizerConfig {
232862 Fts5Tokenizer *pTok;
232863 fts5_tokenizer *pTokApi;
 
232864 const char **azArg;
232865 int nArg;
232866 int ePattern; /* FTS_PATTERN_XXX constant */
 
 
232867 };
232868
232869 /*
232870 ** An instance of the following structure encodes all information that can
232871 ** be gleaned from the CREATE VIRTUAL TABLE statement.
@@ -232902,10 +233514,12 @@
232902 ** This is only used for debugging. If set to false, any prefix indexes
232903 ** are ignored. This value is configured using:
232904 **
232905 ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
232906 **
 
 
232907 */
232908 struct Fts5Config {
232909 sqlite3 *db; /* Database handle */
232910 Fts5Global *pGlobal; /* Global fts5 object for handle db */
232911 char *zDb; /* Database holding FTS index (e.g. "main") */
@@ -232919,14 +233533,16 @@
232919 int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
232920 char *zContent; /* content table */
232921 char *zContentRowid; /* "content_rowid=" option value */
232922 int bColumnsize; /* "columnsize=" option value (dflt==1) */
232923 int bTokendata; /* "tokendata=" option value (dflt==0) */
 
232924 int eDetail; /* FTS5_DETAIL_XXX value */
232925 char *zContentExprlist;
232926 Fts5TokenizerConfig t;
232927 int bLock; /* True when table is preparing statement */
 
232928
232929 /* Values loaded from the %_config table */
232930 int iVersion; /* fts5 file format 'version' */
232931 int iCookie; /* Incremented when %_config is modified */
232932 int pgsz; /* Approximate page size used in %_data */
@@ -232988,10 +233604,12 @@
232988 /* Set the value of a single config attribute */
232989 static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
232990
232991 static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
232992
 
 
232993 /*
232994 ** End of interface to code in fts5_config.c.
232995 **************************************************************************/
232996
232997 /**************************************************************************
@@ -233032,11 +233650,11 @@
233032
233033 /* Write and decode big-endian 32-bit integer values */
233034 static void sqlite3Fts5Put32(u8*, int);
233035 static int sqlite3Fts5Get32(const u8*);
233036
233037 #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
233038 #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
233039
233040 typedef struct Fts5PoslistReader Fts5PoslistReader;
233041 struct Fts5PoslistReader {
233042 /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
@@ -233323,10 +233941,21 @@
233323
233324 static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
233325
233326 static int sqlite3Fts5FlushToDisk(Fts5Table*);
233327
 
 
 
 
 
 
 
 
 
 
 
233328 /*
233329 ** End of interface to code in fts5.c.
233330 **************************************************************************/
233331
233332 /**************************************************************************
@@ -233402,11 +234031,11 @@
233402 static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
233403
233404 static int sqlite3Fts5DropAll(Fts5Config*);
233405 static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
233406
233407 static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
233408 static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
233409 static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
233410
233411 static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
233412
@@ -233428,10 +234057,13 @@
233428 static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
233429 static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
233430 static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
233431 static int sqlite3Fts5StorageReset(Fts5Storage *p);
233432
 
 
 
233433 /*
233434 ** End of interface to code in fts5_storage.c.
233435 **************************************************************************/
233436
233437
@@ -235357,10 +235989,11 @@
235357 p->iOff = iEndOff;
235358 }
235359
235360 return rc;
235361 }
 
235362
235363 /*
235364 ** Implementation of highlight() function.
235365 */
235366 static void fts5HighlightFunction(
@@ -235388,16 +236021,23 @@
235388 rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
235389 if( rc==SQLITE_RANGE ){
235390 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
235391 rc = SQLITE_OK;
235392 }else if( ctx.zIn ){
 
 
235393 if( rc==SQLITE_OK ){
235394 rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
235395 }
235396
235397 if( rc==SQLITE_OK ){
235398 rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
 
 
 
 
 
235399 }
235400 if( ctx.bOpen ){
235401 fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
235402 }
235403 fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
@@ -235590,19 +236230,23 @@
235590 }
235591
235592 memset(&sFinder, 0, sizeof(Fts5SFinder));
235593 for(i=0; i<nCol; i++){
235594 if( iCol<0 || iCol==i ){
 
 
235595 int nDoc;
235596 int nDocsize;
235597 int ii;
235598 sFinder.iPos = 0;
235599 sFinder.nFirst = 0;
235600 rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
235601 if( rc!=SQLITE_OK ) break;
235602 rc = pApi->xTokenize(pFts,
235603 sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
 
 
235604 );
235605 if( rc!=SQLITE_OK ) break;
235606 rc = pApi->xColumnSize(pFts, i, &nDocsize);
235607 if( rc!=SQLITE_OK ) break;
235608
@@ -235656,10 +236300,13 @@
235656 }
235657 if( rc==SQLITE_OK && nColSize==0 ){
235658 rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
235659 }
235660 if( ctx.zIn ){
 
 
 
235661 if( rc==SQLITE_OK ){
235662 rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
235663 }
235664
235665 ctx.iRangeStart = iBestStart;
@@ -235674,11 +236321,16 @@
235674 while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
235675 rc = fts5CInstIterNext(&ctx.iter);
235676 }
235677
235678 if( rc==SQLITE_OK ){
235679 rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
 
 
 
 
 
235680 }
235681 if( ctx.bOpen ){
235682 fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
235683 }
235684 if( ctx.iRangeEnd>=(nColSize-1) ){
@@ -235857,21 +236509,69 @@
235857 sqlite3_result_double(pCtx, -1.0 * score);
235858 }else{
235859 sqlite3_result_error_code(pCtx, rc);
235860 }
235861 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235862
235863 static int sqlite3Fts5AuxInit(fts5_api *pApi){
235864 struct Builtin {
235865 const char *zFunc; /* Function name (nul-terminated) */
235866 void *pUserData; /* User-data pointer */
235867 fts5_extension_function xFunc;/* Callback function */
235868 void (*xDestroy)(void*); /* Destructor function */
235869 } aBuiltin [] = {
235870 { "snippet", 0, fts5SnippetFunction, 0 },
235871 { "highlight", 0, fts5HighlightFunction, 0 },
235872 { "bm25", 0, fts5Bm25Function, 0 },
 
235873 };
235874 int rc = SQLITE_OK; /* Return code */
235875 int i; /* To iterate through builtin functions */
235876
235877 for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
@@ -236677,10 +237377,20 @@
236677 }else{
236678 pConfig->bColumnsize = (zArg[0]=='1');
236679 }
236680 return rc;
236681 }
 
 
 
 
 
 
 
 
 
 
236682
236683 if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
236684 const Fts5Enum aDetail[] = {
236685 { "none", FTS5_DETAIL_NONE },
236686 { "full", FTS5_DETAIL_FULL },
@@ -236967,11 +237677,15 @@
236967 */
236968 static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
236969 if( pConfig ){
236970 int i;
236971 if( pConfig->t.pTok ){
236972 pConfig->t.pTokApi->xDelete(pConfig->t.pTok);
 
 
 
 
236973 }
236974 sqlite3_free((char*)pConfig->t.azArg);
236975 sqlite3_free(pConfig->zDb);
236976 sqlite3_free(pConfig->zName);
236977 for(i=0; i<pConfig->nCol; i++){
@@ -237050,13 +237764,19 @@
237050 if( pText ){
237051 if( pConfig->t.pTok==0 ){
237052 rc = sqlite3Fts5LoadTokenizer(pConfig);
237053 }
237054 if( rc==SQLITE_OK ){
237055 rc = pConfig->t.pTokApi->xTokenize(
237056 pConfig->t.pTok, pCtx, flags, pText, nText, xToken
237057 );
 
 
 
 
 
 
237058 }
237059 }
237060 return rc;
237061 }
237062
@@ -237309,26 +238029,46 @@
237309 if( rc==SQLITE_OK
237310 && iVersion!=FTS5_CURRENT_VERSION
237311 && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE
237312 ){
237313 rc = SQLITE_ERROR;
237314 if( pConfig->pzErrmsg ){
237315 assert( 0==*pConfig->pzErrmsg );
237316 *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format "
237317 "(found %d, expected %d or %d) - run 'rebuild'",
237318 iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
237319 );
237320 }
237321 }else{
237322 pConfig->iVersion = iVersion;
237323 }
237324
237325 if( rc==SQLITE_OK ){
237326 pConfig->iCookie = iCookie;
237327 }
237328 return rc;
237329 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237330
237331 /*
237332 ** 2014 May 31
237333 **
237334 ** The author disclaims copyright to this source code. In place of
@@ -237614,15 +238354,16 @@
237614 t = fts5ExprGetToken(&sParse, &z, &token);
237615 sqlite3Fts5Parser(pEngine, t, token, &sParse);
237616 }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
237617 sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
237618
 
237619 assert_expr_depth_ok(sParse.rc, sParse.pExpr);
237620
237621 /* If the LHS of the MATCH expression was a user column, apply the
237622 ** implicit column-filter. */
237623 if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
237624 int n = sizeof(Fts5Colset);
237625 Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
237626 if( pColset ){
237627 pColset->nCol = 1;
237628 pColset->aiCol[0] = iCol;
@@ -237635,19 +238376,11 @@
237635 *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
237636 if( pNew==0 ){
237637 sParse.rc = SQLITE_NOMEM;
237638 sqlite3Fts5ParseNodeFree(sParse.pExpr);
237639 }else{
237640 if( !sParse.pExpr ){
237641 const int nByte = sizeof(Fts5ExprNode);
237642 pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
237643 if( pNew->pRoot ){
237644 pNew->pRoot->bEof = 1;
237645 }
237646 }else{
237647 pNew->pRoot = sParse.pExpr;
237648 }
237649 pNew->pIndex = 0;
237650 pNew->pConfig = pConfig;
237651 pNew->apExprPhrase = sParse.apPhrase;
237652 pNew->nPhrase = sParse.nPhrase;
237653 pNew->bDesc = 0;
@@ -238461,11 +239194,11 @@
238461 pNode->bEof = 1;
238462 return rc;
238463 }
238464 }else{
238465 Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
238466 if( pIter->iRowid==iLast || pIter->bEof ) continue;
238467 bMatch = 0;
238468 if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
238469 return rc;
238470 }
238471 }
@@ -238983,13 +239716,10 @@
238983 ){
238984 const int SZALLOC = 8;
238985 Fts5ExprNearset *pRet = 0;
238986
238987 if( pParse->rc==SQLITE_OK ){
238988 if( pPhrase==0 ){
238989 return pNear;
238990 }
238991 if( pNear==0 ){
238992 sqlite3_int64 nByte;
238993 nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
238994 pRet = sqlite3_malloc64(nByte);
238995 if( pRet==0 ){
@@ -250372,15 +251102,32 @@
250372
250373 /*
250374 ** Each tokenizer module registered with the FTS5 module is represented
250375 ** by an object of the following type. All such objects are stored as part
250376 ** of the Fts5Global.pTok list.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250377 */
250378 struct Fts5TokenizerModule {
250379 char *zName; /* Name of tokenizer */
250380 void *pUserData; /* User pointer passed to xCreate() */
250381 fts5_tokenizer x; /* Tokenizer functions */
 
 
250382 void (*xDestroy)(void*); /* Destructor function */
250383 Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
250384 };
250385
250386 struct Fts5FullTable {
@@ -250464,11 +251211,11 @@
250464
250465 /* Auxiliary data storage */
250466 Fts5Auxiliary *pAux; /* Currently executing extension function */
250467 Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
250468
250469 /* Cache used by auxiliary functions xInst() and xInstCount() */
250470 Fts5PoslistReader *aInstIter; /* One for each phrase */
250471 int nInstAlloc; /* Size of aInst[] array (entries / 3) */
250472 int nInstCount; /* Number of phrase instances */
250473 int *aInst; /* 3 integers per phrase instance */
250474 };
@@ -250499,10 +251246,16 @@
250499 #define FTS5CSR_REQUIRE_POSLIST 0x40
250500
250501 #define BitFlagAllTest(x,y) (((x) & (y))==(y))
250502 #define BitFlagTest(x,y) (((x) & (y))!=0)
250503
 
 
 
 
 
 
250504
250505 /*
250506 ** Macros to Set(), Clear() and Test() cursor flags.
250507 */
250508 #define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -250876,11 +251629,11 @@
250876 }else{
250877 if( iCol==nCol+1 ){
250878 if( bSeenRank ) continue;
250879 idxStr[iIdxStr++] = 'r';
250880 bSeenRank = 1;
250881 }else if( iCol>=0 ){
250882 nSeenMatch++;
250883 idxStr[iIdxStr++] = 'M';
250884 sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
250885 idxStr += strlen(&idxStr[iIdxStr]);
250886 assert( idxStr[iIdxStr]=='\0' );
@@ -251262,11 +252015,11 @@
251262 rc = SQLITE_NOMEM;
251263 }else{
251264 rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
251265 SQLITE_PREPARE_PERSISTENT, &pRet, 0);
251266 if( rc!=SQLITE_OK ){
251267 *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
251268 }
251269 sqlite3_free(zSql);
251270 }
251271
251272 va_end(ap);
@@ -251497,10 +252250,192 @@
251497 sqlite3_free(p->p.base.zErrMsg);
251498 p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
251499 va_end(ap);
251500 }
251501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251502
251503 /*
251504 ** This is the xFilter interface for the virtual table. See
251505 ** the virtual table xFilter method documentation for additional
251506 ** information.
@@ -251532,17 +252467,11 @@
251532 char **pzErrmsg = pConfig->pzErrmsg;
251533 int i;
251534 int iIdxStr = 0;
251535 Fts5Expr *pExpr = 0;
251536
251537 if( pConfig->bLock ){
251538 pTab->p.base.zErrMsg = sqlite3_mprintf(
251539 "recursively defined fts5 content table"
251540 );
251541 return SQLITE_ERROR;
251542 }
251543
251544 if( pCsr->ePlan ){
251545 fts5FreeCursorComponents(pCsr);
251546 memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
251547 }
251548
@@ -251562,12 +252491,18 @@
251562 switch( idxStr[iIdxStr++] ){
251563 case 'r':
251564 pRank = apVal[i];
251565 break;
251566 case 'M': {
251567 const char *zText = (const char*)sqlite3_value_text(apVal[i]);
 
 
 
 
 
251568 if( zText==0 ) zText = "";
 
251569 iCol = 0;
251570 do{
251571 iCol = iCol*10 + (idxStr[iIdxStr]-'0');
251572 iIdxStr++;
251573 }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
@@ -251575,21 +252510,27 @@
251575 if( zText[0]=='*' ){
251576 /* The user has issued a query of the form "MATCH '*...'". This
251577 ** indicates that the MATCH expression is not a full text query,
251578 ** but a request for an internal parameter. */
251579 rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
251580 goto filter_out;
251581 }else{
251582 char **pzErr = &pTab->p.base.zErrMsg;
251583 rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
251584 if( rc==SQLITE_OK ){
251585 rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
251586 pExpr = 0;
251587 }
251588 if( rc!=SQLITE_OK ) goto filter_out;
251589 }
251590
 
 
 
 
 
 
 
251591 break;
251592 }
251593 case 'L':
251594 case 'G': {
251595 int bGlob = (idxStr[iIdxStr-1]=='G');
@@ -251893,11 +252834,11 @@
251893 ){
251894 int rc = SQLITE_OK;
251895 int eType1 = sqlite3_value_type(apVal[1]);
251896 if( eType1==SQLITE_INTEGER ){
251897 sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
251898 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
251899 }
251900 return rc;
251901 }
251902
251903 static void fts5StorageInsert(
@@ -252017,59 +252958,81 @@
252017 }
252018
252019 /* DELETE */
252020 else if( nArg==1 ){
252021 i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
252022 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
252023 bUpdateOrDelete = 1;
252024 }
252025
252026 /* INSERT or UPDATE */
252027 else{
252028 int eType1 = sqlite3_value_numeric_type(apVal[1]);
252029
252030 if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
252031 rc = SQLITE_MISMATCH;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252032 }
252033
252034 else if( eType0!=SQLITE_INTEGER ){
252035 /* An INSERT statement. If the conflict-mode is REPLACE, first remove
252036 ** the current entry (if any). */
252037 if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
252038 i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
252039 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
252040 bUpdateOrDelete = 1;
252041 }
252042 fts5StorageInsert(&rc, pTab, apVal, pRowid);
252043 }
252044
252045 /* UPDATE */
252046 else{
252047 i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
252048 i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
252049 if( eType1==SQLITE_INTEGER && iOld!=iNew ){
 
 
252050 if( eConflict==SQLITE_REPLACE ){
252051 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
252052 if( rc==SQLITE_OK ){
252053 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
252054 }
252055 fts5StorageInsert(&rc, pTab, apVal, pRowid);
252056 }else{
252057 rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
 
 
 
252058 if( rc==SQLITE_OK ){
252059 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
252060 }
252061 if( rc==SQLITE_OK ){
252062 rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
252063 }
252064 }
252065 }else{
252066 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
252067 fts5StorageInsert(&rc, pTab, apVal, pRowid);
252068 }
252069 bUpdateOrDelete = 1;
 
252070 }
 
252071 }
252072 }
252073
252074 if( rc==SQLITE_OK
252075 && bUpdateOrDelete
@@ -252082,10 +253045,11 @@
252082 if( rc==SQLITE_OK ){
252083 pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
252084 }
252085 }
252086
 
252087 pTab->p.pConfig->pzErrmsg = 0;
252088 return rc;
252089 }
252090
252091 /*
@@ -252159,21 +253123,44 @@
252159 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252160 Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
252161 return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
252162 }
252163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252164 static int fts5ApiTokenize(
252165 Fts5Context *pCtx,
252166 const char *pText, int nText,
252167 void *pUserData,
252168 int (*xToken)(void*, int, const char*, int, int, int)
252169 ){
252170 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252171 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
252172 return sqlite3Fts5Tokenize(
252173 pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
252174 );
252175 }
252176
252177 static int fts5ApiPhraseCount(Fts5Context *pCtx){
252178 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252179 return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
@@ -252191,53 +253178,76 @@
252191 int *pn
252192 ){
252193 int rc = SQLITE_OK;
252194 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
252195 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
 
 
252196 if( iCol<0 || iCol>=pTab->pConfig->nCol ){
252197 rc = SQLITE_RANGE;
252198 }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
252199 || pCsr->ePlan==FTS5_PLAN_SPECIAL
252200 ){
252201 *pz = 0;
252202 *pn = 0;
252203 }else{
252204 rc = fts5SeekCursor(pCsr, 0);
252205 if( rc==SQLITE_OK ){
252206 *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
252207 *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
 
 
252208 }
252209 }
252210 return rc;
252211 }
252212
 
 
 
 
 
 
 
252213 static int fts5CsrPoslist(
252214 Fts5Cursor *pCsr,
252215 int iPhrase,
252216 const u8 **pa,
252217 int *pn
252218 ){
252219 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
252220 int rc = SQLITE_OK;
252221 int bLive = (pCsr->pSorter==0);
252222
252223 if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
252224 rc = SQLITE_RANGE;
 
 
 
 
 
 
252225 }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
252226 if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
252227 Fts5PoslistPopulator *aPopulator;
252228 int i;
 
252229 aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
252230 if( aPopulator==0 ) rc = SQLITE_NOMEM;
 
 
 
252231 for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
252232 int n; const char *z;
252233 rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
 
 
 
252234 if( rc==SQLITE_OK ){
252235 rc = sqlite3Fts5ExprPopulatePoslists(
252236 pConfig, pCsr->pExpr, aPopulator, i, z, n
252237 );
252238 }
 
252239 }
252240 sqlite3_free(aPopulator);
252241
252242 if( pCsr->pSorter ){
252243 sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -252257,11 +253267,10 @@
252257 }
252258 }else{
252259 *pa = 0;
252260 *pn = 0;
252261 }
252262
252263
252264 return rc;
252265 }
252266
252267 /*
@@ -252327,11 +253336,12 @@
252327
252328 aInst = &pCsr->aInst[3 * (nInst-1)];
252329 aInst[0] = iBest;
252330 aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
252331 aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
252332 if( aInst[1]<0 || aInst[1]>=nCol ){
 
252333 rc = FTS5_CORRUPT;
252334 break;
252335 }
252336 sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
252337 }
@@ -252414,20 +253424,25 @@
252414 pCsr->aColumnSize[i] = -1;
252415 }
252416 }
252417 }else{
252418 int i;
 
252419 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
252420 if( pConfig->abUnindexed[i]==0 ){
252421 const char *z; int n;
252422 void *p = (void*)(&pCsr->aColumnSize[i]);
 
 
 
252423 pCsr->aColumnSize[i] = 0;
252424 rc = fts5ApiColumnText(pCtx, i, &z, &n);
252425 if( rc==SQLITE_OK ){
252426 rc = sqlite3Fts5Tokenize(
252427 pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
252428 );
 
252429 }
252430 }
252431 }
252432 }
252433 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
@@ -252669,13 +253684,76 @@
252669
252670
252671 static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
252672 int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
252673 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252674
252675 static const Fts5ExtensionApi sFts5Api = {
252676 3, /* iVersion */
252677 fts5ApiUserData,
252678 fts5ApiColumnCount,
252679 fts5ApiRowCount,
252680 fts5ApiColumnTotalSize,
252681 fts5ApiTokenize,
@@ -252692,11 +253770,13 @@
252692 fts5ApiPhraseFirst,
252693 fts5ApiPhraseNext,
252694 fts5ApiPhraseFirstColumn,
252695 fts5ApiPhraseNextColumn,
252696 fts5ApiQueryToken,
252697 fts5ApiInstToken
 
 
252698 };
252699
252700 /*
252701 ** Implementation of API function xQueryPhrase().
252702 */
@@ -252743,10 +253823,11 @@
252743 sqlite3_context *context,
252744 int argc,
252745 sqlite3_value **argv
252746 ){
252747 assert( pCsr->pAux==0 );
 
252748 pCsr->pAux = pAux;
252749 pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
252750 pCsr->pAux = 0;
252751 }
252752
@@ -252755,10 +253836,25 @@
252755 for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
252756 if( pCsr->iCsrId==iCsrId ) break;
252757 }
252758 return pCsr;
252759 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252760
252761 static void fts5ApiCallback(
252762 sqlite3_context *context,
252763 int argc,
252764 sqlite3_value **argv
@@ -252771,14 +253867,12 @@
252771 assert( argc>=1 );
252772 pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
252773 iCsrId = sqlite3_value_int64(argv[0]);
252774
252775 pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
252776 if( pCsr==0 || pCsr->ePlan==0 ){
252777 char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
252778 sqlite3_result_error(context, zErr, -1);
252779 sqlite3_free(zErr);
252780 }else{
252781 sqlite3_vtab *pTab = pCsr->base.pVtab;
252782 fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
252783 sqlite3_free(pTab->zErrMsg);
252784 pTab->zErrMsg = 0;
@@ -252867,10 +253961,61 @@
252867 }
252868
252869 sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
252870 return rc;
252871 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252872
252873 /*
252874 ** This is the xColumn method, called by SQLite to request a value from
252875 ** the row that the supplied cursor currently points to.
252876 */
@@ -252897,12 +254042,12 @@
252897 ** as the table. Return the cursor integer id number. This value is only
252898 ** useful in that it may be passed as the first argument to an FTS5
252899 ** auxiliary function. */
252900 sqlite3_result_int64(pCtx, pCsr->iCsrId);
252901 }else if( iCol==pConfig->nCol+1 ){
252902
252903 /* The value of the "rank" column. */
 
252904 if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
252905 fts5PoslistBlob(pCtx, pCsr);
252906 }else if(
252907 pCsr->ePlan==FTS5_PLAN_MATCH
252908 || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
@@ -252909,24 +254054,31 @@
252909 ){
252910 if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
252911 fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
252912 }
252913 }
252914 }else if( !fts5IsContentless(pTab) ){
252915 pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
252916 rc = fts5SeekCursor(pCsr, 1);
252917 if( rc==SQLITE_OK ){
252918 sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
252919 }
252920 pConfig->pzErrmsg = 0;
252921 }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){
252922 char *zErr = sqlite3_mprintf("cannot UPDATE a subset of "
252923 "columns on fts5 contentless-delete table: %s", pConfig->zName
252924 );
252925 sqlite3_result_error(pCtx, zErr, -1);
252926 sqlite3_free(zErr);
252927 }
 
 
 
 
 
 
 
252928 return rc;
252929 }
252930
252931
252932 /*
@@ -253060,53 +254212,214 @@
253060 }
253061 }
253062
253063 return rc;
253064 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253065
253066 /*
253067 ** Register a new tokenizer. This is the implementation of the
253068 ** fts5_api.xCreateTokenizer() method.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253069 */
253070 static int fts5CreateTokenizer(
253071 fts5_api *pApi, /* Global context (one per db handle) */
253072 const char *zName, /* Name of new function */
253073 void *pUserData, /* User data for aux. function */
253074 fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
253075 void(*xDestroy)(void*) /* Destructor for pUserData */
253076 ){
253077 Fts5Global *pGlobal = (Fts5Global*)pApi;
253078 Fts5TokenizerModule *pNew;
253079 sqlite3_int64 nName; /* Size of zName and its \0 terminator */
253080 sqlite3_int64 nByte; /* Bytes of space to allocate */
253081 int rc = SQLITE_OK;
253082
253083 nName = strlen(zName) + 1;
253084 nByte = sizeof(Fts5TokenizerModule) + nName;
253085 pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
253086 if( pNew ){
253087 memset(pNew, 0, (size_t)nByte);
253088 pNew->zName = (char*)&pNew[1];
253089 memcpy(pNew->zName, zName, nName);
253090 pNew->pUserData = pUserData;
253091 pNew->x = *pTokenizer;
253092 pNew->xDestroy = xDestroy;
253093 pNew->pNext = pGlobal->pTok;
253094 pGlobal->pTok = pNew;
253095 if( pNew->pNext==0 ){
253096 pGlobal->pDfltTok = pNew;
253097 }
253098 }else{
253099 rc = SQLITE_NOMEM;
253100 }
253101
253102 return rc;
253103 }
253104
 
 
 
 
 
253105 static Fts5TokenizerModule *fts5LocateTokenizer(
253106 Fts5Global *pGlobal,
253107 const char *zName
253108 ){
253109 Fts5TokenizerModule *pMod = 0;
253110
253111 if( zName==0 ){
253112 pMod = pGlobal->pDfltTok;
@@ -253116,10 +254429,40 @@
253116 }
253117 }
253118
253119 return pMod;
253120 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253121
253122 /*
253123 ** Find a tokenizer. This is the implementation of the
253124 ** fts5_api.xFindTokenizer() method.
253125 */
@@ -253132,70 +254475,79 @@
253132 int rc = SQLITE_OK;
253133 Fts5TokenizerModule *pMod;
253134
253135 pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
253136 if( pMod ){
253137 *pTokenizer = pMod->x;
253138 *ppUserData = pMod->pUserData;
253139 }else{
253140 memset(pTokenizer, 0, sizeof(fts5_tokenizer));
253141 rc = SQLITE_ERROR;
253142 }
253143
253144 return rc;
253145 }
253146
253147 int fts5GetTokenizer(
253148 Fts5Global *pGlobal,
253149 const char **azArg,
253150 int nArg,
253151 Fts5Config *pConfig,
253152 char **pzErr
253153 ){
253154 Fts5TokenizerModule *pMod;
253155 int rc = SQLITE_OK;
253156
253157 pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
253158 if( pMod==0 ){
253159 assert( nArg>0 );
253160 rc = SQLITE_ERROR;
253161 if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
253162 }else{
253163 rc = pMod->x.xCreate(
253164 pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
253165 );
253166 pConfig->t.pTokApi = &pMod->x;
253167 if( rc!=SQLITE_OK ){
253168 if( pzErr && rc!=SQLITE_NOMEM ){
253169 *pzErr = sqlite3_mprintf("error in tokenizer constructor");
253170 }
253171 }else{
253172 pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
253173 pMod->x.xCreate, pConfig->t.pTok
253174 );
253175 }
253176 }
253177
253178 if( rc!=SQLITE_OK ){
253179 pConfig->t.pTokApi = 0;
253180 pConfig->t.pTok = 0;
253181 }
253182
253183 return rc;
253184 }
253185
253186 /*
253187 ** Attempt to instantiate the tokenizer.
253188 */
253189 static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
253190 return fts5GetTokenizer(
253191 pConfig->pGlobal, pConfig->t.azArg, pConfig->t.nArg,
253192 pConfig, pConfig->pzErrmsg
253193 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253194 }
253195
253196
 
 
 
 
 
253197 static void fts5ModuleDestroy(void *pCtx){
253198 Fts5TokenizerModule *pTok, *pNextTok;
253199 Fts5Auxiliary *pAux, *pNextAux;
253200 Fts5Global *pGlobal = (Fts5Global*)pCtx;
253201
@@ -253212,10 +254564,14 @@
253212 }
253213
253214 sqlite3_free(pGlobal);
253215 }
253216
 
 
 
 
253217 static void fts5Fts5Func(
253218 sqlite3_context *pCtx, /* Function call context */
253219 int nArg, /* Number of args */
253220 sqlite3_value **apArg /* Function arguments */
253221 ){
@@ -253235,11 +254591,74 @@
253235 int nArg, /* Number of args */
253236 sqlite3_value **apUnused /* Function arguments */
253237 ){
253238 assert( nArg==0 );
253239 UNUSED_PARAM2(nArg, apUnused);
253240 sqlite3_result_text(pCtx, "fts5: 2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9", -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253241 }
253242
253243 /*
253244 ** Return true if zName is the extension on one of the shadow tables used
253245 ** by this module.
@@ -253330,14 +254749,16 @@
253330 rc = SQLITE_NOMEM;
253331 }else{
253332 void *p = (void*)pGlobal;
253333 memset(pGlobal, 0, sizeof(Fts5Global));
253334 pGlobal->db = db;
253335 pGlobal->api.iVersion = 2;
253336 pGlobal->api.xCreateFunction = fts5CreateAux;
253337 pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
253338 pGlobal->api.xFindTokenizer = fts5FindTokenizer;
 
 
253339 rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
253340 if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
253341 if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
253342 if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
253343 if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -253351,10 +254772,17 @@
253351 rc = sqlite3_create_function(
253352 db, "fts5_source_id", 0,
253353 SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
253354 p, fts5SourceIdFunc, 0, 0
253355 );
 
 
 
 
 
 
 
253356 }
253357 }
253358
253359 /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
253360 ** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -253426,17 +254854,44 @@
253426
253427
253428
253429 /* #include "fts5Int.h" */
253430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253431 struct Fts5Storage {
253432 Fts5Config *pConfig;
253433 Fts5Index *pIndex;
253434 int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
253435 i64 nTotalRow; /* Total number of rows in FTS table */
253436 i64 *aTotalSize; /* Total sizes of each column */
253437 sqlite3_stmt *aStmt[11];
 
253438 };
253439
253440
253441 #if FTS5_STMT_SCAN_ASC!=0
253442 # error "FTS5_STMT_SCAN_ASC mismatch"
@@ -253446,18 +254901,19 @@
253446 #endif
253447 #if FTS5_STMT_LOOKUP!=2
253448 # error "FTS5_STMT_LOOKUP mismatch"
253449 #endif
253450
253451 #define FTS5_STMT_INSERT_CONTENT 3
253452 #define FTS5_STMT_REPLACE_CONTENT 4
253453 #define FTS5_STMT_DELETE_CONTENT 5
253454 #define FTS5_STMT_REPLACE_DOCSIZE 6
253455 #define FTS5_STMT_DELETE_DOCSIZE 7
253456 #define FTS5_STMT_LOOKUP_DOCSIZE 8
253457 #define FTS5_STMT_REPLACE_CONFIG 9
253458 #define FTS5_STMT_SCAN 10
 
253459
253460 /*
253461 ** Prepare the two insert statements - Fts5Storage.pInsertContent and
253462 ** Fts5Storage.pInsertDocsize - if they have not already been prepared.
253463 ** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -253483,10 +254939,11 @@
253483 if( p->aStmt[eStmt]==0 ){
253484 const char *azStmt[] = {
253485 "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
253486 "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
253487 "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
 
253488
253489 "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
253490 "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
253491 "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
253492 "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */
@@ -253497,10 +254954,12 @@
253497 "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
253498 "SELECT %s FROM %s AS T", /* SCAN */
253499 };
253500 Fts5Config *pC = p->pConfig;
253501 char *zSql = 0;
 
 
253502
253503 switch( eStmt ){
253504 case FTS5_STMT_SCAN:
253505 zSql = sqlite3_mprintf(azStmt[eStmt],
253506 pC->zContentExprlist, pC->zContent
@@ -253514,10 +254973,11 @@
253514 pC->zContentRowid
253515 );
253516 break;
253517
253518 case FTS5_STMT_LOOKUP:
 
253519 zSql = sqlite3_mprintf(azStmt[eStmt],
253520 pC->zContentExprlist, pC->zContent, pC->zContentRowid
253521 );
253522 break;
253523
@@ -253560,11 +255020,11 @@
253560
253561 if( zSql==0 ){
253562 rc = SQLITE_NOMEM;
253563 }else{
253564 int f = SQLITE_PREPARE_PERSISTENT;
253565 if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
253566 p->pConfig->bLock++;
253567 rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
253568 p->pConfig->bLock--;
253569 sqlite3_free(zSql);
253570 if( rc!=SQLITE_OK && pzErrMsg ){
@@ -253808,74 +255268,141 @@
253808 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
253809 pCtx->szCol++;
253810 }
253811 return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
253812 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253813
253814 /*
253815 ** If a row with rowid iDel is present in the %_content table, add the
253816 ** delete-markers to the FTS index necessary to delete it. Do not actually
253817 ** remove the %_content row at this time though.
 
 
 
 
 
253818 */
253819 static int fts5StorageDeleteFromIndex(
253820 Fts5Storage *p,
253821 i64 iDel,
253822 sqlite3_value **apVal
 
253823 ){
253824 Fts5Config *pConfig = p->pConfig;
253825 sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
253826 int rc = SQLITE_OK; /* Return code */
253827 int rc2; /* sqlite3_reset() return code */
253828 int iCol;
253829 Fts5InsertCtx ctx;
253830
 
 
 
 
253831 if( apVal==0 ){
253832 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
253833 if( rc!=SQLITE_OK ) return rc;
253834 sqlite3_bind_int64(pSeek, 1, iDel);
253835 if( sqlite3_step(pSeek)!=SQLITE_ROW ){
253836 return sqlite3_reset(pSeek);
 
 
 
 
 
253837 }
253838 }
253839
253840 ctx.pStorage = p;
253841 ctx.iCol = -1;
253842 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
253843 if( pConfig->abUnindexed[iCol-1]==0 ){
253844 const char *zText;
253845 int nText;
 
 
 
253846 assert( pSeek==0 || apVal==0 );
253847 assert( pSeek!=0 || apVal!=0 );
253848 if( pSeek ){
253849 zText = (const char*)sqlite3_column_text(pSeek, iCol);
253850 nText = sqlite3_column_bytes(pSeek, iCol);
253851 }else if( ALWAYS(apVal) ){
253852 zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
253853 nText = sqlite3_value_bytes(apVal[iCol-1]);
253854 }else{
253855 continue;
253856 }
253857 ctx.szCol = 0;
253858 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
253859 zText, nText, (void*)&ctx, fts5StorageInsertCallback
253860 );
253861 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
253862 if( p->aTotalSize[iCol-1]<0 && rc==SQLITE_OK ){
253863 rc = FTS5_CORRUPT;
 
 
 
 
 
 
 
253864 }
253865 }
253866 }
253867 if( rc==SQLITE_OK && p->nTotalRow<1 ){
253868 rc = FTS5_CORRUPT;
253869 }else{
253870 p->nTotalRow--;
253871 }
253872
253873 rc2 = sqlite3_reset(pSeek);
253874 if( rc==SQLITE_OK ) rc = rc2;
 
 
 
 
 
253875 return rc;
253876 }
 
 
 
 
 
 
 
 
 
 
 
 
 
253877
253878 /*
253879 ** This function is called to process a DELETE on a contentless_delete=1
253880 ** table. It adds the tombstone required to delete the entry with rowid
253881 ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs,
@@ -253929,16 +255456,16 @@
253929 if( p->pConfig->bContentlessDelete ){
253930 i64 iOrigin = 0;
253931 rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
253932 sqlite3_bind_int64(pReplace, 3, iOrigin);
253933 }
253934 if( rc==SQLITE_OK ){
253935 sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
253936 sqlite3_step(pReplace);
253937 rc = sqlite3_reset(pReplace);
253938 sqlite3_bind_null(pReplace, 2);
253939 }
253940 }
253941 }
253942 return rc;
253943 }
253944
@@ -253988,11 +255515,16 @@
253988 }
253989
253990 /*
253991 ** Remove a row from the FTS table.
253992 */
253993 static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
 
 
 
 
 
253994 Fts5Config *pConfig = p->pConfig;
253995 int rc;
253996 sqlite3_stmt *pDel = 0;
253997
253998 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
@@ -254005,11 +255537,11 @@
254005
254006 if( rc==SQLITE_OK ){
254007 if( p->pConfig->bContentlessDelete ){
254008 rc = fts5StorageContentlessDelete(p, iDel);
254009 }else{
254010 rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
254011 }
254012 }
254013
254014 /* Delete the %_docsize record */
254015 if( rc==SQLITE_OK && pConfig->bColumnsize ){
@@ -254094,18 +255626,25 @@
254094 sqlite3Fts5BufferZero(&buf);
254095 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
254096 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
254097 ctx.szCol = 0;
254098 if( pConfig->abUnindexed[ctx.iCol]==0 ){
254099 const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
254100 int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
254101 rc = sqlite3Fts5Tokenize(pConfig,
254102 FTS5_TOKENIZE_DOCUMENT,
254103 zText, nText,
254104 (void*)&ctx,
254105 fts5StorageInsertCallback
254106 );
 
 
 
 
 
 
 
254107 }
254108 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
254109 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
254110 }
254111 p->nTotalRow++;
@@ -254185,11 +255724,35 @@
254185 }else{
254186 sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
254187 int i; /* Counter variable */
254188 rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
254189 for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
254190 rc = sqlite3_bind_value(pInsert, i, apVal[i]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254191 }
254192 if( rc==SQLITE_OK ){
254193 sqlite3_step(pInsert);
254194 rc = sqlite3_reset(pInsert);
254195 }
@@ -254220,18 +255783,28 @@
254220 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
254221 }
254222 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
254223 ctx.szCol = 0;
254224 if( pConfig->abUnindexed[ctx.iCol]==0 ){
254225 const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
254226 int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
254227 rc = sqlite3Fts5Tokenize(pConfig,
254228 FTS5_TOKENIZE_DOCUMENT,
254229 zText, nText,
254230 (void*)&ctx,
254231 fts5StorageInsertCallback
254232 );
 
 
 
 
 
 
 
 
 
 
254233 }
254234 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
254235 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
254236 }
254237 p->nTotalRow++;
@@ -254398,18 +255971,26 @@
254398 ctx.szCol = 0;
254399 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
254400 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
254401 }
254402 if( rc==SQLITE_OK ){
254403 const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
254404 int nText = sqlite3_column_bytes(pScan, i+1);
254405 rc = sqlite3Fts5Tokenize(pConfig,
254406 FTS5_TOKENIZE_DOCUMENT,
254407 zText, nText,
254408 (void*)&ctx,
254409 fts5StorageIntegrityCallback
254410 );
 
 
 
 
 
 
 
 
 
254411 }
254412 if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
254413 rc = FTS5_CORRUPT;
254414 }
254415 aTotalSize[i] += ctx.szCol;
@@ -254720,11 +256301,11 @@
254720 rc = SQLITE_NOMEM;
254721 }else{
254722 int i;
254723 memset(p, 0, sizeof(AsciiTokenizer));
254724 memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
254725 for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
254726 const char *zArg = azArg[i+1];
254727 if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
254728 fts5AsciiAddExceptions(p, zArg, 1);
254729 }else
254730 if( 0==sqlite3_stricmp(azArg[i], "separators") ){
@@ -254731,11 +256312,10 @@
254731 fts5AsciiAddExceptions(p, zArg, 0);
254732 }else{
254733 rc = SQLITE_ERROR;
254734 }
254735 }
254736 if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR;
254737 if( rc!=SQLITE_OK ){
254738 fts5AsciiDelete((Fts5Tokenizer*)p);
254739 p = 0;
254740 }
254741 }
@@ -255023,20 +256603,20 @@
255023 if( p->aFold==0 ){
255024 rc = SQLITE_NOMEM;
255025 }
255026
255027 /* Search for a "categories" argument */
255028 for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
255029 if( 0==sqlite3_stricmp(azArg[i], "categories") ){
255030 zCat = azArg[i+1];
255031 }
255032 }
255033 if( rc==SQLITE_OK ){
255034 rc = unicodeSetCategories(p, zCat);
255035 }
255036
255037 for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
255038 const char *zArg = azArg[i+1];
255039 if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
255040 if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
255041 rc = SQLITE_ERROR;
255042 }else{
@@ -255057,12 +256637,10 @@
255057 /* no-op */
255058 }else{
255059 rc = SQLITE_ERROR;
255060 }
255061 }
255062 if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
255063
255064 }else{
255065 rc = SQLITE_NOMEM;
255066 }
255067 if( rc!=SQLITE_OK ){
255068 fts5UnicodeDelete((Fts5Tokenizer*)p);
@@ -255197,11 +256775,11 @@
255197 ** stemming. */
255198 #define FTS5_PORTER_MAX_TOKEN 64
255199
255200 typedef struct PorterTokenizer PorterTokenizer;
255201 struct PorterTokenizer {
255202 fts5_tokenizer tokenizer; /* Parent tokenizer module */
255203 Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
255204 char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
255205 };
255206
255207 /*
@@ -255209,11 +256787,11 @@
255209 */
255210 static void fts5PorterDelete(Fts5Tokenizer *pTok){
255211 if( pTok ){
255212 PorterTokenizer *p = (PorterTokenizer*)pTok;
255213 if( p->pTokenizer ){
255214 p->tokenizer.xDelete(p->pTokenizer);
255215 }
255216 sqlite3_free(p);
255217 }
255218 }
255219
@@ -255228,26 +256806,28 @@
255228 fts5_api *pApi = (fts5_api*)pCtx;
255229 int rc = SQLITE_OK;
255230 PorterTokenizer *pRet;
255231 void *pUserdata = 0;
255232 const char *zBase = "unicode61";
 
255233
255234 if( nArg>0 ){
255235 zBase = azArg[0];
255236 }
255237
255238 pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
255239 if( pRet ){
255240 memset(pRet, 0, sizeof(PorterTokenizer));
255241 rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
255242 }else{
255243 rc = SQLITE_NOMEM;
255244 }
255245 if( rc==SQLITE_OK ){
255246 int nArg2 = (nArg>0 ? nArg-1 : 0);
255247 const char **azArg2 = (nArg2 ? &azArg[1] : 0);
255248 rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
 
255249 }
255250
255251 if( rc!=SQLITE_OK ){
255252 fts5PorterDelete((Fts5Tokenizer*)pRet);
255253 pRet = 0;
@@ -255894,19 +257474,20 @@
255894 static int fts5PorterTokenize(
255895 Fts5Tokenizer *pTokenizer,
255896 void *pCtx,
255897 int flags,
255898 const char *pText, int nText,
 
255899 int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
255900 ){
255901 PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
255902 PorterContext sCtx;
255903 sCtx.xToken = xToken;
255904 sCtx.pCtx = pCtx;
255905 sCtx.aBuf = p->aBuf;
255906 return p->tokenizer.xTokenize(
255907 p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
255908 );
255909 }
255910
255911 /**************************************************************************
255912 ** Start of trigram implementation.
@@ -255932,45 +257513,50 @@
255932 const char **azArg,
255933 int nArg,
255934 Fts5Tokenizer **ppOut
255935 ){
255936 int rc = SQLITE_OK;
255937 TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
255938 UNUSED_PARAM(pUnused);
255939 if( pNew==0 ){
255940 rc = SQLITE_NOMEM;
255941 }else{
255942 int i;
255943 pNew->bFold = 1;
255944 pNew->iFoldParam = 0;
255945 for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
255946 const char *zArg = azArg[i+1];
255947 if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
255948 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
255949 rc = SQLITE_ERROR;
255950 }else{
255951 pNew->bFold = (zArg[0]=='0');
255952 }
255953 }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
255954 if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
255955 rc = SQLITE_ERROR;
255956 }else{
255957 pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
255958 }
255959 }else{
255960 rc = SQLITE_ERROR;
255961 }
255962 }
255963 if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
255964
255965 if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
255966 rc = SQLITE_ERROR;
255967 }
255968
255969 if( rc!=SQLITE_OK ){
255970 fts5TriDelete((Fts5Tokenizer*)pNew);
255971 pNew = 0;
 
 
 
 
 
255972 }
255973 }
255974 *ppOut = (Fts5Tokenizer*)pNew;
255975 return rc;
255976 }
@@ -256091,11 +257677,10 @@
256091 const char *zName;
256092 fts5_tokenizer x;
256093 } aBuiltin[] = {
256094 { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
256095 { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
256096 { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
256097 { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
256098 };
256099
256100 int rc = SQLITE_OK; /* Return code */
256101 int i; /* To iterate through builtin functions */
@@ -256106,11 +257691,24 @@
256106 (void*)pApi,
256107 &aBuiltin[i].x,
256108 0
256109 );
256110 }
256111
 
 
 
 
 
 
 
 
 
 
 
 
 
256112 return rc;
256113 }
256114
256115 /*
256116 ** 2012-05-25
@@ -256476,10 +258074,13 @@
256476 aArray[29] = 1;
256477 break;
256478 default: return 1; }
256479 break;
256480
 
 
 
256481 }
256482 return 0;
256483 }
256484
256485 static u16 aFts5UnicodeBlock[] = {
256486
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,13 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 9a9d0f6301faefe324261f03543023ffb6a9 with changes in files:
22 **
23 ** src/shell.c.in
24 */
25 #define SQLITE_CORE 1
26 #define SQLITE_AMALGAMATION 1
27 #ifndef SQLITE_PRIVATE
28 # define SQLITE_PRIVATE static
@@ -462,11 +464,11 @@
464 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
465 ** [sqlite_version()] and [sqlite_source_id()].
466 */
467 #define SQLITE_VERSION "3.47.0"
468 #define SQLITE_VERSION_NUMBER 3047000
469 #define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
470
471 /*
472 ** CAPI3REF: Run-Time Library Version Numbers
473 ** KEYWORDS: sqlite3_version sqlite3_sourceid
474 **
@@ -7741,13 +7743,15 @@
7743 **
7744 ** ^The estimatedRows value is an estimate of the number of rows that
7745 ** will be returned by the strategy.
7746 **
7747 ** The xBestIndex method may optionally populate the idxFlags field with a
7748 ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
7749 ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
7750 ** output to show the idxNum has hex instead of as decimal. Another flag is
7751 ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
7752 ** return at most one row.
7753 **
7754 ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
7755 ** SQLite also assumes that if a call to the xUpdate() method is made as
7756 ** part of the same statement to delete or update a virtual table row and the
7757 ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7807,11 +7811,13 @@
7811 **
7812 ** Virtual table implementations are allowed to set the
7813 ** [sqlite3_index_info].idxFlags field to some combination of
7814 ** these bits.
7815 */
7816 #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
7817 #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
7818 /* in EXPLAIN QUERY PLAN */
7819
7820 /*
7821 ** CAPI3REF: Virtual Table Constraint Operator Codes
7822 **
7823 ** These macros define the allowed values for the
@@ -8644,10 +8650,11 @@
8650 #define SQLITE_TESTCTRL_ALWAYS 13
8651 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8652 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8653 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8654 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8655 #define SQLITE_TESTCTRL_GETOPT 16
8656 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8657 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8658 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8659 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8660 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13418,13 +13425,36 @@
13425 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13426 ** includes any embedded 0x00 and trailing data.
13427 **
13428 ** This API can be quite slow if used with an FTS5 table created with the
13429 ** "detail=none" or "detail=column" option.
13430 **
13431 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13432 ** If parameter iCol is less than zero, or greater than or equal to the
13433 ** number of columns in the table, SQLITE_RANGE is returned.
13434 **
13435 ** Otherwise, this function attempts to retrieve the locale associated
13436 ** with column iCol of the current row. Usually, there is no associated
13437 ** locale, and output parameters (*pzLocale) and (*pnLocale) are set
13438 ** to NULL and 0, respectively. However, if the fts5_locale() function
13439 ** was used to associate a locale with the value when it was inserted
13440 ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
13441 ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
13442 ** is set to the size in bytes of the buffer, not including the
13443 ** nul-terminator.
13444 **
13445 ** If successful, SQLITE_OK is returned. Or, if an error occurs, an
13446 ** SQLite error code is returned. The final value of the output parameters
13447 ** is undefined in this case.
13448 **
13449 ** xTokenize_v2:
13450 ** Tokenize text using the tokenizer belonging to the FTS5 table. This
13451 ** API is the same as the xTokenize() API, except that it allows a tokenizer
13452 ** locale to be specified.
13453 */
13454 struct Fts5ExtensionApi {
13455 int iVersion; /* Currently always set to 4 */
13456
13457 void *(*xUserData)(Fts5Context*);
13458
13459 int (*xColumnCount)(Fts5Context*);
13460 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13462,10 +13492,19 @@
13492 int (*xQueryToken)(Fts5Context*,
13493 int iPhrase, int iToken,
13494 const char **ppToken, int *pnToken
13495 );
13496 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13497
13498 /* Below this point are iVersion>=4 only */
13499 int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
13500 int (*xTokenize_v2)(Fts5Context*,
13501 const char *pText, int nText, /* Text to tokenize */
13502 const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
13503 void *pCtx, /* Context passed to xToken() */
13504 int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
13505 );
13506 };
13507
13508 /*
13509 ** CUSTOM AUXILIARY FUNCTIONS
13510 *************************************************************************/
@@ -13474,19 +13513,20 @@
13513 ** CUSTOM TOKENIZERS
13514 **
13515 ** Applications may also register custom tokenizer types. A tokenizer
13516 ** is registered by providing fts5 with a populated instance of the
13517 ** following structure. All structure methods must be defined, setting
13518 **
13519 ** any member of the fts5_tokenizer struct to NULL leads to undefined
13520 ** behaviour. The structure methods are expected to function as follows:
13521 **
13522 ** xCreate:
13523 ** This function is used to allocate and initialize a tokenizer instance.
13524 ** A tokenizer instance is required to actually tokenize text.
13525 **
13526 ** The first argument passed to this function is a copy of the (void*)
13527 ** pointer provided by the application when the fts5_tokenizer_v2 object
13528 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
13529 ** The second and third arguments are an array of nul-terminated strings
13530 ** containing the tokenizer arguments, if any, specified following the
13531 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
13532 ** to create the FTS5 table.
@@ -13506,11 +13546,11 @@
13546 ** This function is expected to tokenize the nText byte string indicated
13547 ** by argument pText. pText may or may not be nul-terminated. The first
13548 ** argument passed to this function is a pointer to an Fts5Tokenizer object
13549 ** returned by an earlier call to xCreate().
13550 **
13551 ** The third argument indicates the reason that FTS5 is requesting
13552 ** tokenization of the supplied text. This is always one of the following
13553 ** four values:
13554 **
13555 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
13556 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -13529,10 +13569,17 @@
13569 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
13570 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
13571 ** function. Or an fts5_api.xColumnSize() request made by the same
13572 ** on a columnsize=0 database.
13573 ** </ul>
13574 **
13575 ** The sixth and seventh arguments passed to xTokenize() - pLocale and
13576 ** nLocale - are a pointer to a buffer containing the locale to use for
13577 ** tokenization (e.g. "en_US") and its size in bytes, respectively. The
13578 ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
13579 ** which case nLocale is always 0) to indicate that the tokenizer should
13580 ** use its default locale.
13581 **
13582 ** For each token in the input string, the supplied callback xToken() must
13583 ** be invoked. The first argument to it should be a copy of the pointer
13584 ** passed as the second argument to xTokenize(). The third and fourth
13585 ** arguments are a pointer to a buffer containing the token text, and the
@@ -13552,10 +13599,33 @@
13599 ** immediately return a copy of the xToken() return value. Or, if the
13600 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
13601 ** if an error occurs with the xTokenize() implementation itself, it
13602 ** may abandon the tokenization and return any error code other than
13603 ** SQLITE_OK or SQLITE_DONE.
13604 **
13605 ** If the tokenizer is registered using an fts5_tokenizer_v2 object,
13606 ** then the xTokenize() method has two additional arguments - pLocale
13607 ** and nLocale. These specify the locale that the tokenizer should use
13608 ** for the current request. If pLocale and nLocale are both 0, then the
13609 ** tokenizer should use its default locale. Otherwise, pLocale points to
13610 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13611 ** text. pLocale is not nul-terminated.
13612 **
13613 ** FTS5_TOKENIZER
13614 **
13615 ** There is also an fts5_tokenizer object. This is an older version of
13616 ** fts5_tokenizer_v2. It is similar except that:
13617 **
13618 ** <ul>
13619 ** <li> There is no "iVersion" field, and
13620 ** <li> The xTokenize() method does not take a locale argument.
13621 ** </ul>
13622 **
13623 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13624 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13625 ** registered using either API may be retrieved using both xFindTokenizer()
13626 ** and xFindTokenizer_v2().
13627 **
13628 ** SYNONYM SUPPORT
13629 **
13630 ** Custom tokenizers may also support synonyms. Consider a case in which a
13631 ** user wishes to query for a phrase such as "first place". Using the
@@ -13661,10 +13731,37 @@
13731 ** provide synonyms when tokenizing document text (method (3)) or query
13732 ** text (method (2)), not both. Doing so will not cause any errors, but is
13733 ** inefficient.
13734 */
13735 typedef struct Fts5Tokenizer Fts5Tokenizer;
13736 typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
13737 struct fts5_tokenizer_v2 {
13738 int iVersion; /* Currently always 2 */
13739
13740 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13741 void (*xDelete)(Fts5Tokenizer*);
13742 int (*xTokenize)(Fts5Tokenizer*,
13743 void *pCtx,
13744 int flags, /* Mask of FTS5_TOKENIZE_* flags */
13745 const char *pText, int nText,
13746 const char *pLocale, int nLocale,
13747 int (*xToken)(
13748 void *pCtx, /* Copy of 2nd argument to xTokenize() */
13749 int tflags, /* Mask of FTS5_TOKEN_* flags */
13750 const char *pToken, /* Pointer to buffer containing token */
13751 int nToken, /* Size of token in bytes */
13752 int iStart, /* Byte offset of token within input text */
13753 int iEnd /* Byte offset of end of token within input text */
13754 )
13755 );
13756 };
13757
13758 /*
13759 ** New code should use the fts5_tokenizer_v2 type to define tokenizer
13760 ** implementations. The following type is included for legacy applications
13761 ** that still use it.
13762 */
13763 typedef struct fts5_tokenizer fts5_tokenizer;
13764 struct fts5_tokenizer {
13765 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13766 void (*xDelete)(Fts5Tokenizer*);
13767 int (*xTokenize)(Fts5Tokenizer*,
@@ -13679,10 +13776,11 @@
13776 int iStart, /* Byte offset of token within input text */
13777 int iEnd /* Byte offset of end of token within input text */
13778 )
13779 );
13780 };
13781
13782
13783 /* Flags that may be passed as the third argument to xTokenize() */
13784 #define FTS5_TOKENIZE_QUERY 0x0001
13785 #define FTS5_TOKENIZE_PREFIX 0x0002
13786 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13699,11 +13797,11 @@
13797 /*************************************************************************
13798 ** FTS5 EXTENSION REGISTRATION API
13799 */
13800 typedef struct fts5_api fts5_api;
13801 struct fts5_api {
13802 int iVersion; /* Currently always set to 3 */
13803
13804 /* Create a new tokenizer */
13805 int (*xCreateTokenizer)(
13806 fts5_api *pApi,
13807 const char *zName,
@@ -13726,10 +13824,29 @@
13824 const char *zName,
13825 void *pUserData,
13826 fts5_extension_function xFunction,
13827 void (*xDestroy)(void*)
13828 );
13829
13830 /* APIs below this point are only available if iVersion>=3 */
13831
13832 /* Create a new tokenizer */
13833 int (*xCreateTokenizer_v2)(
13834 fts5_api *pApi,
13835 const char *zName,
13836 void *pUserData,
13837 fts5_tokenizer_v2 *pTokenizer,
13838 void (*xDestroy)(void*)
13839 );
13840
13841 /* Find an existing tokenizer */
13842 int (*xFindTokenizer_v2)(
13843 fts5_api *pApi,
13844 const char *zName,
13845 void **ppUserData,
13846 fts5_tokenizer_v2 **ppTokenizer
13847 );
13848 };
13849
13850 /*
13851 ** END OF REGISTRATION API
13852 *************************************************************************/
@@ -15380,10 +15497,11 @@
15497 typedef struct RowSet RowSet;
15498 typedef struct Savepoint Savepoint;
15499 typedef struct Select Select;
15500 typedef struct SQLiteThread SQLiteThread;
15501 typedef struct SelectDest SelectDest;
15502 typedef struct Subquery Subquery;
15503 typedef struct SrcItem SrcItem;
15504 typedef struct SrcList SrcList;
15505 typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
15506 typedef struct Table Table;
15507 typedef struct TableLock TableLock;
@@ -19263,10 +19381,20 @@
19381 */
19382 #define EU4_NONE 0 /* Does not use IdList.a.u4 */
19383 #define EU4_IDX 1 /* Uses IdList.a.u4.idx */
19384 #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
19385
19386 /*
19387 ** Details of the implementation of a subquery.
19388 */
19389 struct Subquery {
19390 Select *pSelect; /* A SELECT statement used in place of a table name */
19391 int addrFillSub; /* Address of subroutine to initialize a subquery */
19392 int regReturn; /* Register holding return address of addrFillSub */
19393 int regResult; /* Registers holding results of a co-routine */
19394 };
19395
19396 /*
19397 ** The SrcItem object represents a single term in the FROM clause of a query.
19398 ** The SrcList object is mostly an array of SrcItems.
19399 **
19400 ** The jointype starts out showing the join type between the current table
@@ -19275,33 +19403,44 @@
19403 ** jointype expresses the join between the table and the previous table.
19404 **
19405 ** In the colUsed field, the high-order bit (bit 63) is set if the table
19406 ** contains more than 63 columns and the 64-th or later column is used.
19407 **
19408 ** Aggressive use of "union" helps keep the size of the object small. This
19409 ** has been shown to boost performance, in addition to saving memory.
19410 ** Access to union elements is gated by the following rules which should
19411 ** always be checked, either by an if-statement or by an assert().
19412 **
19413 ** Field Only access if this is true
19414 ** --------------- -----------------------------------
19415 ** u1.zIndexedBy fg.isIndexedBy
19416 ** u1.pFuncArg fg.isTabFunc
19417 ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
19418 **
19419 ** u2.pIBIndex fg.isIndexedBy
19420 ** u2.pCteUse fg.isCte
19421 **
19422 ** u3.pOn !fg.isUsing
19423 ** u3.pUsing fg.isUsing
19424 **
19425 ** u4.zDatabase !fg.fixedSchema && !fg.isSubquery
19426 ** u4.pSchema fg.fixedSchema
19427 ** u4.pSubq fg.isSubquery
19428 **
19429 ** See also the sqlite3SrcListDelete() routine for assert() statements that
19430 ** check invariants on the fields of this object, especially the flags
19431 ** inside the fg struct.
19432 */
19433 struct SrcItem {
 
 
19434 char *zName; /* Name of the table */
19435 char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
19436 Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */
 
 
 
 
19437 struct {
19438 u8 jointype; /* Type of join between this table and the previous */
19439 unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
19440 unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
19441 unsigned isSubquery :1; /* True if this term is a subquery */
19442 unsigned isTabFunc :1; /* True if table-valued-function syntax */
19443 unsigned isCorrelated :1; /* True if sub-query is correlated */
19444 unsigned isMaterialized:1; /* This is a materialized view */
19445 unsigned viaCoroutine :1; /* Implemented as a co-routine */
19446 unsigned isRecursive :1; /* True for recursive reference in WITH */
@@ -19311,16 +19450,14 @@
19450 unsigned isUsing :1; /* u3.pUsing is valid */
19451 unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
19452 unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
19453 unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
19454 unsigned rowidUsed :1; /* The ROWID of this table is referenced */
19455 unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
19456 unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
19457 } fg;
19458 int iCursor; /* The VDBE cursor number used to access this table */
 
 
 
 
19459 Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
19460 union {
19461 char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
19462 ExprList *pFuncArg; /* Arguments to table-valued-function */
19463 u32 nRow; /* Number of rows in a VALUES clause */
@@ -19327,10 +19464,19 @@
19464 } u1;
19465 union {
19466 Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
19467 CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
19468 } u2;
19469 union {
19470 Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
19471 IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
19472 } u3;
19473 union {
19474 Schema *pSchema; /* Schema to which this item is fixed */
19475 char *zDatabase; /* Name of database holding this table */
19476 Subquery *pSubq; /* Description of a subquery */
19477 } u4;
19478 };
19479
19480 /*
19481 ** The OnOrUsing object represents either an ON clause or a USING clause.
19482 ** It can never be both at the same time, but it can be neither.
@@ -19586,12 +19732,14 @@
19732 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
19733 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
19734 #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
19735 #define SF_Correlated 0x20000000 /* True if references the outer context */
19736
19737 /* True if SrcItem X is a subquery that has SF_NestedFrom */
19738 #define IsNestedFrom(X) \
19739 ((X)->fg.isSubquery && \
19740 ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
19741
19742 /*
19743 ** The results of a SELECT can be distributed in several ways, as defined
19744 ** by one of the following macros. The "SRT" prefix means "SELECT Result
19745 ** Type".
@@ -20979,10 +21127,13 @@
21127 SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
21128 SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
21129 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
21130 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
21131 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
21132 SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*);
21133 SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*);
21134 SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int);
21135 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
21136 Token*, Select*, OnOrUsing*);
21137 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
21138 SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
21139 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
@@ -24521,12 +24672,12 @@
24672 }
24673 if( M<=2 ){
24674 Y--;
24675 M += 12;
24676 }
24677 A = (Y+4800)/100;
24678 B = 38 - A + (A/4);
24679 X1 = 36525*(Y+4716)/100;
24680 X2 = 306001*(M+1)/10000;
24681 p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
24682 p->validJD = 1;
24683 if( p->validHMS ){
@@ -24706,11 +24857,11 @@
24857
24858 /*
24859 ** Compute the Year, Month, and Day from the julian day number.
24860 */
24861 static void computeYMD(DateTime *p){
24862 int Z, alpha, A, B, C, D, E, X1;
24863 if( p->validYMD ) return;
24864 if( !p->validJD ){
24865 p->Y = 2000;
24866 p->M = 1;
24867 p->D = 1;
@@ -24717,12 +24868,12 @@
24868 }else if( !validJulianDay(p->iJD) ){
24869 datetimeError(p);
24870 return;
24871 }else{
24872 Z = (int)((p->iJD + 43200000)/86400000);
24873 alpha = (int)((Z + 32044.75)/36524.25) - 52;
24874 A = Z + 1 + alpha - ((alpha+100)/4) + 25;
24875 B = A + 1524;
24876 C = (int)((B - 122.1)/365.25);
24877 D = (36525*(C&32767))/100;
24878 E = (int)((B-D)/30.6001);
24879 X1 = (int)(30.6001*E);
@@ -32017,20 +32168,23 @@
32168 pItem = va_arg(ap, SrcItem*);
32169 assert( bArgList==0 );
32170 if( pItem->zAlias && !flag_altform2 ){
32171 sqlite3_str_appendall(pAccum, pItem->zAlias);
32172 }else if( pItem->zName ){
32173 if( pItem->fg.fixedSchema==0
32174 && pItem->fg.isSubquery==0
32175 && pItem->u4.zDatabase!=0
32176 ){
32177 sqlite3_str_appendall(pAccum, pItem->u4.zDatabase);
32178 sqlite3_str_append(pAccum, ".", 1);
32179 }
32180 sqlite3_str_appendall(pAccum, pItem->zName);
32181 }else if( pItem->zAlias ){
32182 sqlite3_str_appendall(pAccum, pItem->zAlias);
32183 }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */
32184 Select *pSel = pItem->u4.pSubq->pSelect;
32185 assert( pSel!=0 );
32186 if( pSel->selFlags & SF_NestedFrom ){
32187 sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
32188 }else if( pSel->selFlags & SF_MultiValue ){
32189 assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
32190 sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
@@ -32808,13 +32962,13 @@
32962 int n = 0;
32963 char zLine[1000];
32964 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
32965 x.printfFlags |= SQLITE_PRINTF_INTERNAL;
32966 sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
32967 if( pItem->pSTab ){
32968 sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
32969 pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab,
32970 pItem->colUsed,
32971 pItem->fg.rowidUsed ? "+rowid" : "");
32972 }
32973 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
32974 sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
@@ -32841,27 +32995,34 @@
32995 if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
32996 if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
32997 if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
32998 if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte");
32999 if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom");
33000 if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema");
33001 if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema");
33002 if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery");
33003
33004 sqlite3StrAccumFinish(&x);
33005 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
33006 n = 0;
33007 if( pItem->fg.isSubquery ) n++;
33008 if( pItem->fg.isTabFunc ) n++;
33009 if( pItem->fg.isUsing ) n++;
33010 if( pItem->fg.isUsing ){
33011 sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
33012 }
33013 if( pItem->fg.isSubquery ){
33014 assert( n==1 );
33015 if( pItem->pSTab ){
33016 Table *pTab = pItem->pSTab;
33017 sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
33018 }
33019 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
33020 sqlite3TreeViewPush(&pView, 0);
33021 sqlite3TreeViewLine(pView, "SUBQUERY");
33022 sqlite3TreeViewPop(&pView);
33023 sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
33024 }
33025 if( pItem->fg.isTabFunc ){
33026 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
33027 }
33028 sqlite3TreeViewPop(&pView);
@@ -38721,11 +38882,11 @@
38882 ** Allowed values for the unixFile.ctrlFlags bitmask:
38883 */
38884 #define UNIXFILE_EXCL 0x01 /* Connections from one process only */
38885 #define UNIXFILE_RDONLY 0x02 /* Connection is read only */
38886 #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
38887 #if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX)
38888 # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
38889 #else
38890 # define UNIXFILE_DIRSYNC 0x00
38891 #endif
38892 #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
@@ -95267,11 +95428,11 @@
95428 }
95429 break;
95430 }
95431 #endif
95432
95433 #if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE)
95434 /* Opcode: Cast P1 P2 * * *
95435 ** Synopsis: affinity(r[P1])
95436 **
95437 ** Force the value in register P1 to be the type defined by P2.
95438 **
@@ -106731,11 +106892,13 @@
106892 SrcItem *pItem;
106893
106894 pSrc = p->pSrc;
106895 if( ALWAYS(pSrc) ){
106896 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
106897 if( pItem->fg.isSubquery
106898 && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect)
106899 ){
106900 return WRC_Abort;
106901 }
106902 if( pItem->fg.isTabFunc
106903 && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
106904 ){
@@ -107037,11 +107200,11 @@
107200 ){
107201 Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
107202 if( pNew ){
107203 pNew->iTable = pMatch->iCursor;
107204 pNew->iColumn = iColumn;
107205 pNew->y.pTab = pMatch->pSTab;
107206 assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
107207 ExprSetProperty(pNew, EP_CanBeNull);
107208 *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
107209 }
107210 }
@@ -107168,24 +107331,28 @@
107331 SrcList *pSrcList = pNC->pSrcList;
107332
107333 if( pSrcList ){
107334 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
107335 u8 hCol;
107336 pTab = pItem->pSTab;
107337 assert( pTab!=0 && pTab->zName!=0 );
107338 assert( pTab->nCol>0 || pParse->nErr );
107339 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem));
107340 if( pItem->fg.isNestedFrom ){
107341 /* In this case, pItem is a subquery that has been formed from a
107342 ** parenthesized subset of the FROM clause terms. Example:
107343 ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
107344 ** \_________________________/
107345 ** This pItem -------------^
107346 */
107347 int hit = 0;
107348 Select *pSel;
107349 assert( pItem->fg.isSubquery );
107350 assert( pItem->u4.pSubq!=0 );
107351 pSel = pItem->u4.pSubq->pSelect;
107352 assert( pSel!=0 );
107353 pEList = pSel->pEList;
107354 assert( pEList!=0 );
107355 assert( pEList->nExpr==pTab->nCol );
107356 for(j=0; j<pEList->nExpr; j++){
107357 int bRowid = 0; /* True if possible rowid match */
107358 if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
@@ -107305,12 +107472,12 @@
107472 ** words non-VIEW candidate terms take precedence over VIEWs.
107473 */
107474 if( cntTab==0
107475 || (cntTab==1
107476 && ALWAYS(pMatch!=0)
107477 && ALWAYS(pMatch->pSTab!=0)
107478 && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0
107479 && (pTab->tabFlags & TF_Ephemeral)==0)
107480 ){
107481 cntTab = 1;
107482 pMatch = pItem;
107483 }else{
@@ -107327,11 +107494,11 @@
107494 }
107495 }
107496 if( pMatch ){
107497 pExpr->iTable = pMatch->iCursor;
107498 assert( ExprUseYTab(pExpr) );
107499 pExpr->y.pTab = pMatch->pSTab;
107500 if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
107501 ExprSetProperty(pExpr, EP_CanBeNull);
107502 }
107503 pSchema = pExpr->y.pTab->pSchema;
107504 }
@@ -107369,11 +107536,11 @@
107536 #endif /* SQLITE_OMIT_TRIGGER */
107537 #ifndef SQLITE_OMIT_UPSERT
107538 if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){
107539 Upsert *pUpsert = pNC->uNC.pUpsert;
107540 if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
107541 pTab = pUpsert->pUpsertSrc->a[0].pSTab;
107542 pExpr->iTable = EXCLUDED_TABLE_NUMBER;
107543 }
107544 }
107545 #endif /* SQLITE_OMIT_UPSERT */
107546
@@ -107452,15 +107619,15 @@
107619 if( cnt==0
107620 && cntTab>=1
107621 && pMatch
107622 && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
107623 && sqlite3IsRowid(zCol)
107624 && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom)
107625 ){
107626 cnt = cntTab;
107627 #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
107628 if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){
107629 eNewExprOp = TK_NULL;
107630 }
107631 #endif
107632 if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
107633 pExpr->affExpr = SQLITE_AFF_INTEGER;
@@ -107693,11 +107860,11 @@
107860 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
107861 if( p ){
107862 SrcItem *pItem = &pSrc->a[iSrc];
107863 Table *pTab;
107864 assert( ExprUseYTab(p) );
107865 pTab = p->y.pTab = pItem->pSTab;
107866 p->iTable = pItem->iCursor;
107867 if( p->y.pTab->iPKey==iCol ){
107868 p->iColumn = -1;
107869 }else{
107870 p->iColumn = (ynVar)iCol;
@@ -107812,11 +107979,11 @@
107979 SrcItem *pItem;
107980 assert( pSrcList && pSrcList->nSrc>=1 );
107981 pItem = pSrcList->a;
107982 pExpr->op = TK_COLUMN;
107983 assert( ExprUseYTab(pExpr) );
107984 pExpr->y.pTab = pItem->pSTab;
107985 pExpr->iTable = pItem->iCursor;
107986 pExpr->iColumn--;
107987 pExpr->affExpr = SQLITE_AFF_INTEGER;
107988 break;
107989 }
@@ -108702,11 +108869,15 @@
108869 ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
108870 ** as if it were part of the sub-query, not the parent. This block
108871 ** moves the pOrderBy down to the sub-query. It will be moved back
108872 ** after the names have been resolved. */
108873 if( p->selFlags & SF_Converted ){
108874 Select *pSub;
108875 assert( p->pSrc->a[0].fg.isSubquery );
108876 assert( p->pSrc->a[0].u4.pSubq!=0 );
108877 pSub = p->pSrc->a[0].u4.pSubq->pSelect;
108878 assert( pSub!=0 );
108879 assert( p->pSrc->nSrc==1 && p->pOrderBy );
108880 assert( pSub->pPrior && pSub->pOrderBy==0 );
108881 pSub->pOrderBy = p->pOrderBy;
108882 p->pOrderBy = 0;
108883 }
@@ -108714,17 +108885,20 @@
108885 /* Recursively resolve names in all subqueries in the FROM clause
108886 */
108887 if( pOuterNC ) pOuterNC->nNestedSelect++;
108888 for(i=0; i<p->pSrc->nSrc; i++){
108889 SrcItem *pItem = &p->pSrc->a[i];
108890 assert( pItem->zName!=0
108891 || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/
108892 if( pItem->fg.isSubquery
108893 && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0
108894 ){
108895 int nRef = pOuterNC ? pOuterNC->nRef : 0;
108896 const char *zSavedContext = pParse->zAuthContext;
108897
108898 if( pItem->zName ) pParse->zAuthContext = pItem->zName;
108899 sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC);
108900 pParse->zAuthContext = zSavedContext;
108901 if( pParse->nErr ) return WRC_Abort;
108902 assert( db->mallocFailed==0 );
108903
108904 /* If the number of references to the outer context changed when
@@ -108822,11 +108996,14 @@
108996 ** the sub-query back to the parent query. At this point each term
108997 ** within the ORDER BY clause has been transformed to an integer value.
108998 ** These integers will be replaced by copies of the corresponding result
108999 ** set expressions by the call to resolveOrderGroupBy() below. */
109000 if( p->selFlags & SF_Converted ){
109001 Select *pSub;
109002 assert( p->pSrc->a[0].fg.isSubquery );
109003 pSub = p->pSrc->a[0].u4.pSubq->pSelect;
109004 assert( pSub!=0 );
109005 p->pOrderBy = pSub->pOrderBy;
109006 pSub->pOrderBy = 0;
109007 }
109008
109009 /* Process the ORDER BY clause for singleton SELECT statements.
@@ -109089,11 +109266,11 @@
109266 memset(&sNC, 0, sizeof(sNC));
109267 memset(&sSrc, 0, sizeof(sSrc));
109268 if( pTab ){
109269 sSrc.nSrc = 1;
109270 sSrc.a[0].zName = pTab->zName;
109271 sSrc.a[0].pSTab = pTab;
109272 sSrc.a[0].iCursor = -1;
109273 if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
109274 /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
109275 ** schema elements */
109276 type |= NC_FromDDL;
@@ -110986,19 +111163,34 @@
111163 pNew->nSrc = pNew->nAlloc = p->nSrc;
111164 for(i=0; i<p->nSrc; i++){
111165 SrcItem *pNewItem = &pNew->a[i];
111166 const SrcItem *pOldItem = &p->a[i];
111167 Table *pTab;
111168 pNewItem->fg = pOldItem->fg;
111169 if( pOldItem->fg.isSubquery ){
111170 Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery));
111171 if( pNewSubq==0 ){
111172 assert( db->mallocFailed );
111173 pNewItem->fg.isSubquery = 0;
111174 }else{
111175 memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq));
111176 pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags);
111177 if( pNewSubq->pSelect==0 ){
111178 sqlite3DbFree(db, pNewSubq);
111179 pNewSubq = 0;
111180 pNewItem->fg.isSubquery = 0;
111181 }
111182 }
111183 pNewItem->u4.pSubq = pNewSubq;
111184 }else if( pOldItem->fg.fixedSchema ){
111185 pNewItem->u4.pSchema = pOldItem->u4.pSchema;
111186 }else{
111187 pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase);
111188 }
111189 pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
111190 pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
 
111191 pNewItem->iCursor = pOldItem->iCursor;
 
 
 
111192 if( pNewItem->fg.isIndexedBy ){
111193 pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
111194 }else if( pNewItem->fg.isTabFunc ){
111195 pNewItem->u1.pFuncArg =
111196 sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
@@ -111007,15 +111199,14 @@
111199 }
111200 pNewItem->u2 = pOldItem->u2;
111201 if( pNewItem->fg.isCte ){
111202 pNewItem->u2.pCteUse->nUse++;
111203 }
111204 pTab = pNewItem->pSTab = pOldItem->pSTab;
111205 if( pTab ){
111206 pTab->nTabRef++;
111207 }
 
111208 if( pOldItem->fg.isUsing ){
111209 assert( pNewItem->fg.isUsing );
111210 pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
111211 }else{
111212 pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
@@ -111085,11 +111276,10 @@
111276 }
111277 *pp = pNew;
111278 pp = &pNew->pPrior;
111279 pNext = pNew;
111280 }
 
111281 return pRet;
111282 }
111283 #else
111284 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
111285 assert( p==0 );
@@ -112105,12 +112295,12 @@
112295 if( p->pLimit ) return 0; /* Has no LIMIT clause */
112296 if( p->pWhere ) return 0; /* Has no WHERE clause */
112297 pSrc = p->pSrc;
112298 assert( pSrc!=0 );
112299 if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
112300 if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */
112301 pTab = pSrc->a[0].pSTab;
112302 assert( pTab!=0 );
112303 assert( !IsView(pTab) ); /* FROM clause is not a view */
112304 if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
112305 pEList = p->pEList;
112306 assert( pEList!=0 );
@@ -112289,11 +112479,11 @@
112479 int nExpr = pEList->nExpr;
112480
112481 assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
112482 assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
112483 assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
112484 pTab = p->pSrc->a[0].pSTab;
112485
112486 /* Code an OP_Transaction and OP_TableLock for <table>. */
112487 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
112488 assert( iDb>=0 && iDb<SQLITE_MAX_DB );
112489 sqlite3CodeVerifySchema(pParse, iDb);
@@ -117727,12 +117917,13 @@
117917 }
117918 if( pStep->pFrom ){
117919 int i;
117920 for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
117921 SrcItem *p = &pStep->pFrom->a[i];
117922 if( p->fg.isSubquery ){
117923 assert( p->u4.pSubq!=0 );
117924 sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0);
117925 }
117926 }
117927 }
117928
117929 if( db->mallocFailed ){
@@ -117796,12 +117987,16 @@
117987 sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
117988 sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
117989 }
117990 if( pStep->pFrom ){
117991 int i;
117992 SrcList *pFrom = pStep->pFrom;
117993 for(i=0; i<pFrom->nSrc; i++){
117994 if( pFrom->a[i].fg.isSubquery ){
117995 assert( pFrom->a[i].u4.pSubq!=0 );
117996 sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect);
117997 }
117998 }
117999 }
118000 }
118001 }
118002
@@ -118044,11 +118239,11 @@
118239 assert( pWalker->pParse->db->mallocFailed );
118240 return WRC_Abort;
118241 }
118242 for(i=0; i<pSrc->nSrc; i++){
118243 SrcItem *pItem = &pSrc->a[i];
118244 if( pItem->pSTab==p->pTab ){
118245 renameTokenFind(pWalker->pParse, p, pItem->zName);
118246 }
118247 }
118248 renameWalkWith(pWalker, pSelect);
118249
@@ -121178,24 +121373,25 @@
121373 int iDb = sqlite3FindDbName(db, pFix->zDb);
121374 SrcList *pList = pSelect->pSrc;
121375
121376 if( NEVER(pList==0) ) return WRC_Continue;
121377 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
121378 if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){
121379 if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
121380 if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){
121381 sqlite3ErrorMsg(pFix->pParse,
121382 "%s %T cannot reference objects in database %s",
121383 pFix->zType, pFix->pName, pItem->u4.zDatabase);
121384 return WRC_Abort;
121385 }
121386 sqlite3DbFree(db, pItem->u4.zDatabase);
 
121387 pItem->fg.notCte = 1;
121388 pItem->fg.hadSchema = 1;
121389 }
121390 pItem->u4.pSchema = pFix->pSchema;
121391 pItem->fg.fromDDL = 1;
121392 pItem->fg.fixedSchema = 1;
121393 }
121394 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
121395 if( pList->a[i].fg.isUsing==0
121396 && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
121397 ){
@@ -121484,11 +121680,11 @@
121680 pTab = pParse->pTriggerTab;
121681 }else{
121682 assert( pTabList );
121683 for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
121684 if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
121685 pTab = pTabList->a[iSrc].pSTab;
121686 break;
121687 }
121688 }
121689 }
121690 iCol = pExpr->iColumn;
@@ -122087,16 +122283,16 @@
122283 Parse *pParse,
122284 u32 flags,
122285 SrcItem *p
122286 ){
122287 const char *zDb;
122288 if( p->fg.fixedSchema ){
122289 int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema);
 
122290 zDb = pParse->db->aDb[iDb].zDbSName;
122291 }else{
122292 assert( !p->fg.isSubquery );
122293 zDb = p->u4.zDatabase;
122294 }
122295 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
122296 }
122297
122298 /*
@@ -125077,19 +125273,21 @@
125273 if( db->mallocFailed ){
125274 goto exit_drop_table;
125275 }
125276 assert( pParse->nErr==0 );
125277 assert( pName->nSrc==1 );
125278 assert( pName->a[0].fg.fixedSchema==0 );
125279 assert( pName->a[0].fg.isSubquery==0 );
125280 if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
125281 if( noErr ) db->suppressErr++;
125282 assert( isView==0 || isView==LOCATE_VIEW );
125283 pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
125284 if( noErr ) db->suppressErr--;
125285
125286 if( pTab==0 ){
125287 if( noErr ){
125288 sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
125289 sqlite3ForceNotReadOnly(pParse);
125290 }
125291 goto exit_drop_table;
125292 }
125293 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -126176,19 +126374,21 @@
126374 if( db->mallocFailed ){
126375 goto exit_drop_index;
126376 }
126377 assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
126378 assert( pName->nSrc==1 );
126379 assert( pName->a[0].fg.fixedSchema==0 );
126380 assert( pName->a[0].fg.isSubquery==0 );
126381 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
126382 goto exit_drop_index;
126383 }
126384 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase);
126385 if( pIndex==0 ){
126386 if( !ifExists ){
126387 sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
126388 }else{
126389 sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
126390 sqlite3ForceNotReadOnly(pParse);
126391 }
126392 pParse->checkSchema = 1;
126393 goto exit_drop_index;
126394 }
@@ -126481,16 +126681,18 @@
126681 }
126682 pItem = &pList->a[pList->nSrc-1];
126683 if( pDatabase && pDatabase->z==0 ){
126684 pDatabase = 0;
126685 }
126686 assert( pItem->fg.fixedSchema==0 );
126687 assert( pItem->fg.isSubquery==0 );
126688 if( pDatabase ){
126689 pItem->zName = sqlite3NameFromToken(db, pDatabase);
126690 pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable);
126691 }else{
126692 pItem->zName = sqlite3NameFromToken(db, pTable);
126693 pItem->u4.zDatabase = 0;
126694 }
126695 return pList;
126696 }
126697
126698 /*
@@ -126502,16 +126704,43 @@
126704 assert( pList || pParse->db->mallocFailed );
126705 if( ALWAYS(pList) ){
126706 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
126707 if( pItem->iCursor>=0 ) continue;
126708 pItem->iCursor = pParse->nTab++;
126709 if( pItem->fg.isSubquery ){
126710 assert( pItem->u4.pSubq!=0 );
126711 assert( pItem->u4.pSubq->pSelect!=0 );
126712 assert( pItem->u4.pSubq->pSelect->pSrc!=0 );
126713 sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc);
126714 }
126715 }
126716 }
126717 }
126718
126719 /*
126720 ** Delete a Subquery object and its substructure.
126721 */
126722 SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){
126723 assert( pSubq!=0 && pSubq->pSelect!=0 );
126724 sqlite3SelectDelete(db, pSubq->pSelect);
126725 sqlite3DbFree(db, pSubq);
126726 }
126727
126728 /*
126729 ** Remove a Subquery from a SrcItem. Return the associated Select object.
126730 ** The returned Select becomes the responsibility of the caller.
126731 */
126732 SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){
126733 Select *pSel;
126734 assert( pItem!=0 );
126735 assert( pItem->fg.isSubquery );
126736 pSel = pItem->u4.pSubq->pSelect;
126737 sqlite3DbFree(db, pItem->u4.pSubq);
126738 pItem->u4.pSubq = 0;
126739 pItem->fg.isSubquery = 0;
126740 return pSel;
126741 }
126742
126743 /*
126744 ** Delete an entire SrcList including all its substructure.
126745 */
126746 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
@@ -126518,25 +126747,84 @@
126747 int i;
126748 SrcItem *pItem;
126749 assert( db!=0 );
126750 if( pList==0 ) return;
126751 for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
126752
126753 /* Check invariants on SrcItem */
126754 assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc );
126755 assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy );
126756 assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery );
126757 assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 &&
126758 pItem->u4.pSubq->pSelect!=0) );
126759
126760 if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName);
126761 if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias);
126762 if( pItem->fg.isSubquery ){
126763 sqlite3SubqueryDelete(db, pItem->u4.pSubq);
126764 }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
126765 sqlite3DbNNFreeNN(db, pItem->u4.zDatabase);
126766 }
126767 if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
126768 if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
126769 sqlite3DeleteTable(db, pItem->pSTab);
 
126770 if( pItem->fg.isUsing ){
126771 sqlite3IdListDelete(db, pItem->u3.pUsing);
126772 }else if( pItem->u3.pOn ){
126773 sqlite3ExprDelete(db, pItem->u3.pOn);
126774 }
126775 }
126776 sqlite3DbNNFreeNN(db, pList);
126777 }
126778
126779 /*
126780 ** Attach a Subquery object to pItem->uv.pSubq. Set the
126781 ** pSelect value but leave all the other values initialized
126782 ** to zero.
126783 **
126784 ** A copy of the Select object is made if dupSelect is true, and the
126785 ** SrcItem takes responsibility for deleting the copy. If dupSelect is
126786 ** false, ownership of the Select passes to the SrcItem. Either way,
126787 ** the SrcItem will take responsibility for deleting the Select.
126788 **
126789 ** When dupSelect is zero, that means the Select might get deleted right
126790 ** away if there is an OOM error. Beware.
126791 **
126792 ** Return non-zero on success. Return zero on an OOM error.
126793 */
126794 SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(
126795 Parse *pParse, /* Parsing context */
126796 SrcItem *pItem, /* Item to which the subquery is to be attached */
126797 Select *pSelect, /* The subquery SELECT. Must be non-NULL */
126798 int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/
126799 ){
126800 Subquery *p;
126801 assert( pSelect!=0 );
126802 assert( pItem->fg.isSubquery==0 );
126803 if( pItem->fg.fixedSchema ){
126804 pItem->u4.pSchema = 0;
126805 pItem->fg.fixedSchema = 0;
126806 }else if( pItem->u4.zDatabase!=0 ){
126807 sqlite3DbFree(pParse->db, pItem->u4.zDatabase);
126808 pItem->u4.zDatabase = 0;
126809 }
126810 if( dupSelect ){
126811 pSelect = sqlite3SelectDup(pParse->db, pSelect, 0);
126812 if( pSelect==0 ) return 0;
126813 }
126814 p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery));
126815 if( p==0 ){
126816 sqlite3SelectDelete(pParse->db, pSelect);
126817 return 0;
126818 }
126819 pItem->fg.isSubquery = 1;
126820 p->pSelect = pSelect;
126821 assert( offsetof(Subquery, pSelect)==0 );
126822 memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect));
126823 return 1;
126824 }
126825
126826
126827 /*
126828 ** This routine is called by the parser to add a new term to the
126829 ** end of a growing FROM clause. The "p" parameter is the part of
126830 ** the FROM clause that has already been constructed. "p" is NULL
@@ -126583,14 +126871,16 @@
126871 }
126872 assert( pAlias!=0 );
126873 if( pAlias->n ){
126874 pItem->zAlias = sqlite3NameFromToken(db, pAlias);
126875 }
126876 assert( pSubquery==0 || pDatabase==0 );
126877 if( pSubquery ){
126878 if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){
126879 if( pSubquery->selFlags & SF_NestedFrom ){
126880 pItem->fg.isNestedFrom = 1;
126881 }
126882 }
126883 }
126884 assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
126885 assert( pItem->fg.isUsing==0 );
126886 if( pOnUsing==0 ){
@@ -127864,21 +128154,21 @@
128154 ** return a pointer. Set an error message and return NULL if the table
128155 ** name is not found or if any other error occurs.
128156 **
128157 ** The following fields are initialized appropriate in pSrc:
128158 **
128159 ** pSrc->a[0].spTab Pointer to the Table object
128160 ** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one
128161 **
128162 */
128163 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
128164 SrcItem *pItem = pSrc->a;
128165 Table *pTab;
128166 assert( pItem && pSrc->nSrc>=1 );
128167 pTab = sqlite3LocateTableItem(pParse, 0, pItem);
128168 if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab);
128169 pItem->pSTab = pTab;
128170 pItem->fg.notCte = 1;
128171 if( pTab ){
128172 pTab->nTabRef++;
128173 if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){
128174 pTab = 0;
@@ -127996,11 +128286,12 @@
128286 pWhere = sqlite3ExprDup(db, pWhere, 0);
128287 pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
128288 if( pFrom ){
128289 assert( pFrom->nSrc==1 );
128290 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
128291 assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 );
128292 pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
128293 assert( pFrom->a[0].fg.isUsing==0 );
128294 assert( pFrom->a[0].u3.pOn==0 );
128295 }
128296 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
128297 SF_IncludeHidden, pLimit);
@@ -128058,11 +128349,11 @@
128349 ** DELETE FROM table_a WHERE rowid IN (
128350 ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
128351 ** );
128352 */
128353
128354 pTab = pSrc->a[0].pSTab;
128355 if( HasRowid(pTab) ){
128356 pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
128357 pEList = sqlite3ExprListAppend(
128358 pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
128359 );
@@ -128091,13 +128382,13 @@
128382 }
128383 }
128384
128385 /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
128386 ** and the SELECT subtree. */
128387 pSrc->a[0].pSTab = 0;
128388 pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
128389 pSrc->a[0].pSTab = pTab;
128390 if( pSrc->a[0].fg.isIndexedBy ){
128391 assert( pSrc->a[0].fg.isCte==0 );
128392 pSrc->a[0].u2.pIBIndex = 0;
128393 pSrc->a[0].fg.isIndexedBy = 0;
128394 sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
@@ -132675,13 +132966,13 @@
132966 /* Create a SrcList structure containing the child table. We need the
132967 ** child table as a SrcList for sqlite3WhereBegin() */
132968 pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
132969 if( pSrc ){
132970 SrcItem *pItem = pSrc->a;
132971 pItem->pSTab = pFKey->pFrom;
132972 pItem->zName = pFKey->pFrom->zName;
132973 pItem->pSTab->nTabRef++;
132974 pItem->iCursor = pParse->nTab++;
132975
132976 if( regNew!=0 ){
132977 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
132978 }
@@ -132969,11 +133260,12 @@
133260 }
133261 pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
133262 if( pSrc ){
133263 assert( pSrc->nSrc==1 );
133264 pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom);
133265 assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 );
133266 pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
133267 }
133268 pSelect = sqlite3SelectNew(pParse,
133269 sqlite3ExprListAppend(pParse, 0, pRaise),
133270 pSrc,
133271 pWhere,
@@ -133703,12 +133995,15 @@
133995 ** co-routine.
133996 */
133997 SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){
133998 if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){
133999 SrcItem *pItem = &pVal->pSrc->a[0];
134000 assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr );
134001 if( pItem->fg.isSubquery ){
134002 sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn);
134003 sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1);
134004 }
134005 }
134006 }
134007
134008 /*
134009 ** Return true if all expressions in the expression-list passed as the
@@ -133832,56 +134127,67 @@
134127 sqlite3ReadSchema(pParse);
134128 }
134129
134130 if( pRet ){
134131 SelectDest dest;
134132 Subquery *pSubq;
134133 pRet->pSrc->nSrc = 1;
134134 pRet->pPrior = pLeft->pPrior;
134135 pRet->op = pLeft->op;
134136 if( pRet->pPrior ) pRet->selFlags |= SF_Values;
134137 pLeft->pPrior = 0;
134138 pLeft->op = TK_SELECT;
134139 assert( pLeft->pNext==0 );
134140 assert( pRet->pNext==0 );
134141 p = &pRet->pSrc->a[0];
 
134142 p->fg.viaCoroutine = 1;
 
 
134143 p->iCursor = -1;
134144 assert( !p->fg.isIndexedBy && !p->fg.isTabFunc );
134145 p->u1.nRow = 2;
134146 if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){
134147 pSubq = p->u4.pSubq;
134148 pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
134149 pSubq->regReturn = ++pParse->nMem;
134150 sqlite3VdbeAddOp3(v, OP_InitCoroutine,
134151 pSubq->regReturn, 0, pSubq->addrFillSub);
134152 sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
134153
134154 /* Allocate registers for the output of the co-routine. Do so so
134155 ** that there are two unused registers immediately before those
134156 ** used by the co-routine. This allows the code in sqlite3Insert()
134157 ** to use these registers directly, instead of copying the output
134158 ** of the co-routine to a separate array for processing. */
134159 dest.iSdst = pParse->nMem + 3;
134160 dest.nSdst = pLeft->pEList->nExpr;
134161 pParse->nMem += 2 + dest.nSdst;
134162
134163 pLeft->selFlags |= SF_MultiValue;
134164 sqlite3Select(pParse, pLeft, &dest);
134165 pSubq->regResult = dest.iSdst;
134166 assert( pParse->nErr || dest.iSdst>0 );
134167 }
134168 pLeft = pRet;
134169 }
134170 }else{
134171 p = &pLeft->pSrc->a[0];
134172 assert( !p->fg.isTabFunc && !p->fg.isIndexedBy );
134173 p->u1.nRow++;
134174 }
134175
134176 if( pParse->nErr==0 ){
134177 Subquery *pSubq;
134178 assert( p!=0 );
134179 assert( p->fg.isSubquery );
134180 pSubq = p->u4.pSubq;
134181 assert( pSubq!=0 );
134182 assert( pSubq->pSelect!=0 );
134183 assert( pSubq->pSelect->pEList!=0 );
134184 if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){
134185 sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect);
134186 }else{
134187 sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0);
134188 sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn);
134189 }
134190 }
134191 sqlite3ExprListDelete(pParse->db, pRow);
134192 }
134193
@@ -134228,13 +134534,18 @@
134534 if( pSelect->pSrc->nSrc==1
134535 && pSelect->pSrc->a[0].fg.viaCoroutine
134536 && pSelect->pPrior==0
134537 ){
134538 SrcItem *pItem = &pSelect->pSrc->a[0];
134539 Subquery *pSubq;
134540 assert( pItem->fg.isSubquery );
134541 pSubq = pItem->u4.pSubq;
134542 dest.iSDParm = pSubq->regReturn;
134543 regFromSelect = pSubq->regResult;
134544 assert( pSubq->pSelect!=0 );
134545 assert( pSubq->pSelect->pEList!=0 );
134546 nColumn = pSubq->pSelect->pEList->nExpr;
134547 ExplainQueryPlan((pParse, 0, "SCAN %S", pItem));
134548 if( bIdListInOrder && nColumn==pTab->nCol ){
134549 regData = regFromSelect;
134550 regRowid = regData - 1;
134551 regIns = regRowid - (IsVirtual(pTab) ? 1 : 0);
@@ -136150,11 +136461,11 @@
136461 }
136462 assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
136463 if( pSelect->pSrc->nSrc!=1 ){
136464 return 0; /* FROM clause must have exactly one term */
136465 }
136466 if( pSelect->pSrc->a[0].fg.isSubquery ){
136467 return 0; /* FROM clause cannot contain a subquery */
136468 }
136469 if( pSelect->pWhere ){
136470 return 0; /* SELECT may not have a WHERE clause */
136471 }
@@ -143448,15 +143759,17 @@
143759 /*
143760 ** Mark a subquery result column as having been used.
143761 */
143762 SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
143763 assert( pItem!=0 );
143764 assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
143765 if( pItem->fg.isNestedFrom ){
143766 ExprList *pResults;
143767 assert( pItem->fg.isSubquery );
143768 assert( pItem->u4.pSubq!=0 );
143769 assert( pItem->u4.pSubq->pSelect!=0 );
143770 pResults = pItem->u4.pSubq->pSelect->pEList;
143771 assert( pResults!=0 );
143772 assert( iCol>=0 && iCol<pResults->nExpr );
143773 pResults->a[iCol].fg.bUsed = 1;
143774 }
143775 }
@@ -143486,13 +143799,13 @@
143799 assert( iEnd<pSrc->nSrc );
143800 assert( iStart>=0 );
143801 assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
143802
143803 for(i=iStart; i<=iEnd; i++){
143804 iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol);
143805 if( iCol>=0
143806 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0)
143807 ){
143808 if( piTab ){
143809 sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
143810 *piTab = i;
143811 *piCol = iCol;
@@ -143617,14 +143930,14 @@
143930
143931 pSrc = p->pSrc;
143932 pLeft = &pSrc->a[0];
143933 pRight = &pLeft[1];
143934 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
143935 Table *pRightTab = pRight->pSTab;
143936 u32 joinType;
143937
143938 if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue;
143939 joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
143940
143941 /* If this is a NATURAL join, synthesize an appropriate USING clause
143942 ** to specify which columns should be joined.
143943 */
@@ -145046,12 +145359,16 @@
145359 int iCol = pExpr->iColumn; /* Index of column in pTab */
145360 while( pNC && !pTab ){
145361 SrcList *pTabList = pNC->pSrcList;
145362 for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
145363 if( j<pTabList->nSrc ){
145364 pTab = pTabList->a[j].pSTab;
145365 if( pTabList->a[j].fg.isSubquery ){
145366 pS = pTabList->a[j].u4.pSubq->pSelect;
145367 }else{
145368 pS = 0;
145369 }
145370 }else{
145371 pNC = pNC->pNext;
145372 }
145373 }
145374
@@ -147099,11 +147416,13 @@
147416 p->pHaving = substExpr(pSubst, p->pHaving);
147417 p->pWhere = substExpr(pSubst, p->pWhere);
147418 pSrc = p->pSrc;
147419 assert( pSrc!=0 );
147420 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
147421 if( pItem->fg.isSubquery ){
147422 substSelect(pSubst, pItem->u4.pSubq->pSelect, 1);
147423 }
147424 if( pItem->fg.isTabFunc ){
147425 substExprList(pSubst, pItem->u1.pFuncArg);
147426 }
147427 }
147428 }while( doPrior && (p = p->pPrior)!=0 );
@@ -147130,11 +147449,11 @@
147449 static void recomputeColumnsUsed(
147450 Select *pSelect, /* The complete SELECT statement */
147451 SrcItem *pSrcItem /* Which FROM clause item to recompute */
147452 ){
147453 Walker w;
147454 if( NEVER(pSrcItem->pSTab==0) ) return;
147455 memset(&w, 0, sizeof(w));
147456 w.xExprCallback = recomputeColumnsUsedExpr;
147457 w.xSelectCallback = sqlite3SelectWalkNoop;
147458 w.u.pSrcItem = pSrcItem;
147459 pSrcItem->colUsed = 0;
@@ -147170,12 +147489,14 @@
147489 assert( pItem->iCursor < aCsrMap[0] );
147490 if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){
147491 aCsrMap[pItem->iCursor+1] = pParse->nTab++;
147492 }
147493 pItem->iCursor = aCsrMap[pItem->iCursor+1];
147494 if( pItem->fg.isSubquery ){
147495 for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){
147496 srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
147497 }
147498 }
147499 }
147500 }
147501 }
147502
@@ -147482,11 +147803,12 @@
147803 if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
147804 pSrc = p->pSrc;
147805 assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
147806 pSubitem = &pSrc->a[iFrom];
147807 iParent = pSubitem->iCursor;
147808 assert( pSubitem->fg.isSubquery );
147809 pSub = pSubitem->u4.pSubq->pSelect;
147810 assert( pSub!=0 );
147811
147812 #ifndef SQLITE_OMIT_WINDOWFUNC
147813 if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */
147814 #endif
@@ -147535,11 +147857,11 @@
147857 **
147858 ** See also tickets #306, #350, and #3300.
147859 */
147860 if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
147861 if( pSubSrc->nSrc>1 /* (3a) */
147862 || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */
147863 || (p->selFlags & SF_Distinct)!=0 /* (3d) */
147864 || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
147865 ){
147866 return 0;
147867 }
@@ -147621,18 +147943,22 @@
147943 TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
147944 testcase( i==SQLITE_DENY );
147945 pParse->zAuthContext = zSavedAuthContext;
147946
147947 /* Delete the transient structures associated with the subquery */
147948
147949 if( ALWAYS(pSubitem->fg.isSubquery) ){
147950 pSub1 = sqlite3SubqueryDetach(db, pSubitem);
147951 }else{
147952 pSub1 = 0;
147953 }
147954 assert( pSubitem->fg.isSubquery==0 );
147955 assert( pSubitem->fg.fixedSchema==0 );
147956 sqlite3DbFree(db, pSubitem->zName);
147957 sqlite3DbFree(db, pSubitem->zAlias);
 
147958 pSubitem->zName = 0;
147959 pSubitem->zAlias = 0;
 
147960 assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
147961
147962 /* If the sub-query is a compound SELECT statement, then (by restrictions
147963 ** 17 and 18 above) it must be a UNION ALL and the parent query must
147964 ** be of the form:
@@ -147669,20 +147995,20 @@
147995 for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
147996 Select *pNew;
147997 ExprList *pOrderBy = p->pOrderBy;
147998 Expr *pLimit = p->pLimit;
147999 Select *pPrior = p->pPrior;
148000 Table *pItemTab = pSubitem->pSTab;
148001 pSubitem->pSTab = 0;
148002 p->pOrderBy = 0;
148003 p->pPrior = 0;
148004 p->pLimit = 0;
148005 pNew = sqlite3SelectDup(db, p, 0);
148006 p->pLimit = pLimit;
148007 p->pOrderBy = pOrderBy;
148008 p->op = TK_ALL;
148009 pSubitem->pSTab = pItemTab;
148010 if( pNew==0 ){
148011 p->pPrior = pPrior;
148012 }else{
148013 pNew->selId = ++pParse->nSelect;
148014 if( aCsrMap && ALWAYS(db->mallocFailed==0) ){
@@ -147693,15 +148019,18 @@
148019 pNew->pNext = p;
148020 p->pPrior = pNew;
148021 TREETRACE(0x4,pParse,p,("compound-subquery flattener"
148022 " creates %u as peer\n",pNew->selId));
148023 }
148024 assert( pSubitem->fg.isSubquery==0 );
148025 }
148026 sqlite3DbFree(db, aCsrMap);
148027 if( db->mallocFailed ){
148028 assert( pSubitem->fg.fixedSchema==0 );
148029 assert( pSubitem->fg.isSubquery==0 );
148030 assert( pSubitem->u4.zDatabase==0 );
148031 sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0);
148032 return 1;
148033 }
148034
148035 /* Defer deleting the Table object associated with the
148036 ** subquery until code generation is
@@ -147708,20 +148037,20 @@
148037 ** complete, since there may still exist Expr.pTab entries that
148038 ** refer to the subquery even after flattening. Ticket #3346.
148039 **
148040 ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
148041 */
148042 if( ALWAYS(pSubitem->pSTab!=0) ){
148043 Table *pTabToDel = pSubitem->pSTab;
148044 if( pTabToDel->nTabRef==1 ){
148045 Parse *pToplevel = sqlite3ParseToplevel(pParse);
148046 sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
148047 testcase( pToplevel->earlyCleanup );
148048 }else{
148049 pTabToDel->nTabRef--;
148050 }
148051 pSubitem->pSTab = 0;
148052 }
148053
148054 /* The following loop runs once for each term in a compound-subquery
148055 ** flattening (as described above). If we are doing a different kind
148056 ** of flattening - a flattening other than a compound-subquery flattening -
@@ -147773,12 +148102,15 @@
148102 /* Transfer the FROM clause terms from the subquery into the
148103 ** outer query.
148104 */
148105 for(i=0; i<nSubSrc; i++){
148106 SrcItem *pItem = &pSrc->a[i+iFrom];
 
148107 assert( pItem->fg.isTabFunc==0 );
148108 assert( pItem->fg.isSubquery
148109 || pItem->fg.fixedSchema
148110 || pItem->u4.zDatabase==0 );
148111 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
148112 *pItem = pSubSrc->a[i];
148113 pItem->fg.jointype |= ltorj;
148114 iNewParent = pSubSrc->a[i].iCursor;
148115 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
148116 }
@@ -148458,14 +148790,14 @@
148790
148791 assert( pItem!=0 );
148792 if( pItem->fg.isCorrelated || pItem->fg.isCte ){
148793 return 0;
148794 }
148795 assert( pItem->pSTab!=0 );
148796 pTab = pItem->pSTab;
148797 assert( pItem->fg.isSubquery );
148798 pSub = pItem->u4.pSubq->pSelect;
148799 assert( pSub->pEList->nExpr==pTab->nCol );
148800 for(pX=pSub; pX; pX=pX->pPrior){
148801 if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
148802 testcase( pX->selFlags & SF_Distinct );
148803 testcase( pX->selFlags & SF_Aggregate );
@@ -148590,17 +148922,17 @@
148922 assert( !p->pGroupBy );
148923
148924 if( p->pWhere
148925 || p->pEList->nExpr!=1
148926 || p->pSrc->nSrc!=1
148927 || p->pSrc->a[0].fg.isSubquery
148928 || pAggInfo->nFunc!=1
148929 || p->pHaving
148930 ){
148931 return 0;
148932 }
148933 pTab = p->pSrc->a[0].pSTab;
148934 assert( pTab!=0 );
148935 assert( !IsView(pTab) );
148936 if( !IsOrdinaryTable(pTab) ) return 0;
148937 pExpr = p->pEList->a[0].pExpr;
148938 assert( pExpr!=0 );
@@ -148621,11 +148953,11 @@
148953 ** was such a clause and the named index cannot be found, return
148954 ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
148955 ** pFrom->pIndex and return SQLITE_OK.
148956 */
148957 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){
148958 Table *pTab = pFrom->pSTab;
148959 char *zIndexedBy = pFrom->u1.zIndexedBy;
148960 Index *pIdx;
148961 assert( pTab!=0 );
148962 assert( pFrom->fg.isIndexedBy!=0 );
148963
@@ -148698,11 +149030,15 @@
149030 db = pParse->db;
149031 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
149032 if( pNew==0 ) return WRC_Abort;
149033 memset(&dummy, 0, sizeof(dummy));
149034 pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
149035 assert( pNewSrc!=0 || pParse->nErr );
149036 if( pParse->nErr ){
149037 sqlite3SrcListDelete(db, pNewSrc);
149038 return WRC_Abort;
149039 }
149040 *pNew = *p;
149041 p->pSrc = pNewSrc;
149042 p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
149043 p->op = TK_SELECT;
149044 p->pWhere = 0;
@@ -148753,11 +149089,11 @@
149089 SrcItem *pItem, /* FROM clause element to resolve */
149090 With **ppContext /* OUT: WITH clause return value belongs to */
149091 ){
149092 const char *zName = pItem->zName;
149093 With *p;
149094 assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 );
149095 assert( zName!=0 );
149096 for(p=pWith; p; p=p->pOuter){
149097 int i;
149098 for(i=0; i<p->nCte; i++){
149099 if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
@@ -148823,21 +149159,22 @@
149159 SrcItem *pFrom /* The FROM clause term to check */
149160 ){
149161 Cte *pCte; /* Matched CTE (or NULL if no match) */
149162 With *pWith; /* The matching WITH */
149163
149164 assert( pFrom->pSTab==0 );
149165 if( pParse->pWith==0 ){
149166 /* There are no WITH clauses in the stack. No match is possible */
149167 return 0;
149168 }
149169 if( pParse->nErr ){
149170 /* Prior errors might have left pParse->pWith in a goofy state, so
149171 ** go no further. */
149172 return 0;
149173 }
149174 assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 );
149175 if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){
149176 /* The FROM term contains a schema qualifier (ex: main.t1) and so
149177 ** it cannot possibly be a CTE reference. */
149178 return 0;
149179 }
149180 if( pFrom->fg.notCte ){
@@ -148869,11 +149206,11 @@
149206 sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
149207 return 2;
149208 }
149209 if( cannotBeFunction(pParse, pFrom) ) return 2;
149210
149211 assert( pFrom->pSTab==0 );
149212 pTab = sqlite3DbMallocZero(db, sizeof(Table));
149213 if( pTab==0 ) return 2;
149214 pCteUse = pCte->pUse;
149215 if( pCteUse==0 ){
149216 pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0]));
@@ -148883,42 +149220,47 @@
149220 sqlite3DbFree(db, pTab);
149221 return 2;
149222 }
149223 pCteUse->eM10d = pCte->eM10d;
149224 }
149225 pFrom->pSTab = pTab;
149226 pTab->nTabRef = 1;
149227 pTab->zName = sqlite3DbStrDup(db, pCte->zName);
149228 pTab->iPKey = -1;
149229 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
149230 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
149231 sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1);
149232 if( db->mallocFailed ) return 2;
149233 assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
149234 pSel = pFrom->u4.pSubq->pSelect;
149235 assert( pSel!=0 );
149236 pSel->selFlags |= SF_CopyCte;
149237 if( pFrom->fg.isIndexedBy ){
149238 sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
149239 return 2;
149240 }
149241 assert( !pFrom->fg.isIndexedBy );
149242 pFrom->fg.isCte = 1;
149243 pFrom->u2.pCteUse = pCteUse;
149244 pCteUse->nUse++;
149245
149246 /* Check if this is a recursive CTE. */
149247 pRecTerm = pSel;
149248 bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
149249 while( bMayRecursive && pRecTerm->op==pSel->op ){
149250 int i;
149251 SrcList *pSrc = pRecTerm->pSrc;
149252 assert( pRecTerm->pPrior!=0 );
149253 for(i=0; i<pSrc->nSrc; i++){
149254 SrcItem *pItem = &pSrc->a[i];
149255 if( pItem->zName!=0
149256 && !pItem->fg.hadSchema
149257 && ALWAYS( !pItem->fg.isSubquery )
149258 && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0)
149259 && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
149260 ){
149261 pItem->pSTab = pTab;
149262 pTab->nTabRef++;
149263 pItem->fg.isRecursive = 1;
149264 if( pRecTerm->selFlags & SF_Recursive ){
149265 sqlite3ErrorMsg(pParse,
149266 "multiple references to recursive table: %s", pCte->zName
@@ -149016,15 +149358,18 @@
149358 ** allocates and populates the SrcItem.pTab object. If successful,
149359 ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
149360 ** SQLITE_NOMEM.
149361 */
149362 SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
149363 Select *pSel;
149364 Table *pTab;
149365
149366 assert( pFrom->fg.isSubquery );
149367 assert( pFrom->u4.pSubq!=0 );
149368 pSel = pFrom->u4.pSubq->pSelect;
149369 assert( pSel );
149370 pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
149371 if( pTab==0 ) return SQLITE_NOMEM;
149372 pTab->nTabRef = 1;
149373 if( pFrom->zAlias ){
149374 pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
149375 }else{
@@ -149140,37 +149485,39 @@
149485 ** an entry of the FROM clause is a subquery instead of a table or view,
149486 ** then create a transient table structure to describe the subquery.
149487 */
149488 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149489 Table *pTab;
149490 assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 );
149491 if( pFrom->pSTab ) continue;
149492 assert( pFrom->fg.isRecursive==0 );
149493 if( pFrom->zName==0 ){
149494 #ifndef SQLITE_OMIT_SUBQUERY
149495 Select *pSel;
149496 assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 );
149497 pSel = pFrom->u4.pSubq->pSelect;
149498 /* A sub-query in the FROM clause of a SELECT */
149499 assert( pSel!=0 );
149500 assert( pFrom->pSTab==0 );
149501 if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
149502 if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
149503 #endif
149504 #ifndef SQLITE_OMIT_CTE
149505 }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){
149506 if( rc>1 ) return WRC_Abort;
149507 pTab = pFrom->pSTab;
149508 assert( pTab!=0 );
149509 #endif
149510 }else{
149511 /* An ordinary table or view name in the FROM clause */
149512 assert( pFrom->pSTab==0 );
149513 pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
149514 if( pTab==0 ) return WRC_Abort;
149515 if( pTab->nTabRef>=0xffff ){
149516 sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
149517 pTab->zName);
149518 pFrom->pSTab = 0;
149519 return WRC_Abort;
149520 }
149521 pTab->nTabRef++;
149522 if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
149523 return WRC_Abort;
@@ -149178,19 +149525,19 @@
149525 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
149526 if( !IsOrdinaryTable(pTab) ){
149527 i16 nCol;
149528 u8 eCodeOrig = pWalker->eCode;
149529 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
149530 assert( pFrom->fg.isSubquery==0 );
149531 if( IsView(pTab) ){
149532 if( (db->flags & SQLITE_EnableView)==0
149533 && pTab->pSchema!=db->aDb[1].pSchema
149534 ){
149535 sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
149536 pTab->zName);
149537 }
149538 sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1);
149539 }
149540 #ifndef SQLITE_OMIT_VIRTUALTABLE
149541 else if( ALWAYS(IsVirtual(pTab))
149542 && pFrom->fg.fromDDL
149543 && ALWAYS(pTab->u.vtab.p!=0)
@@ -149202,11 +149549,13 @@
149549 assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 );
149550 #endif
149551 nCol = pTab->nCol;
149552 pTab->nCol = -1;
149553 pWalker->eCode = 1; /* Turn on Select.selId renumbering */
149554 if( pFrom->fg.isSubquery ){
149555 sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect);
149556 }
149557 pWalker->eCode = eCodeOrig;
149558 pTab->nCol = nCol;
149559 }
149560 #endif
149561 }
@@ -149289,11 +149638,11 @@
149638 assert( ExprUseWOfst(pE) );
149639 iErrOfst = pE->w.iOfst;
149640 }
149641 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149642 int nAdd; /* Number of cols including rowid */
149643 Table *pTab = pFrom->pSTab; /* Table for this data source */
149644 ExprList *pNestedFrom; /* Result-set of a nested FROM clause */
149645 char *zTabName; /* AS name for this data source */
149646 const char *zSchemaName = 0; /* Schema name for this data source */
149647 int iDb; /* Schema index for this data src */
149648 IdList *pUsing; /* USING clause for pFrom[1] */
@@ -149300,14 +149649,15 @@
149649
149650 if( (zTabName = pFrom->zAlias)==0 ){
149651 zTabName = pTab->zName;
149652 }
149653 if( db->mallocFailed ) break;
149654 assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) );
149655 if( pFrom->fg.isNestedFrom ){
149656 assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
149657 assert( pFrom->u4.pSubq->pSelect!=0 );
149658 pNestedFrom = pFrom->u4.pSubq->pSelect->pEList;
149659 assert( pNestedFrom!=0 );
149660 assert( pNestedFrom->nExpr==pTab->nCol );
149661 assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
149662 }else{
149663 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
@@ -149542,18 +149892,16 @@
149892 p->selFlags |= SF_HasTypeInfo;
149893 pParse = pWalker->pParse;
149894 assert( (p->selFlags & SF_Resolved) );
149895 pTabList = p->pSrc;
149896 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
149897 Table *pTab = pFrom->pSTab;
149898 assert( pTab!=0 );
149899 if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){
149900 /* A sub-query in the FROM clause of a SELECT */
149901 Select *pSel = pFrom->u4.pSubq->pSelect;
149902 sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
 
 
149903 }
149904 }
149905 }
149906 #endif
149907
@@ -149863,10 +150211,11 @@
150211 int i;
150212 struct AggInfo_func *pF;
150213 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
150214 ExprList *pList;
150215 assert( ExprUseXList(pF->pFExpr) );
150216 if( pParse->nErr ) return;
150217 pList = pF->pFExpr->x.pList;
150218 if( pF->iOBTab>=0 ){
150219 /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
150220 ** were stored in emphermal table pF->iOBTab. Here, we extract those
150221 ** inputs (in ORDER BY order) and make all calls to OP_AggStep
@@ -150072,19 +150421,21 @@
150421 sqlite3ReleaseTempRange(pParse, regAgg, nArg);
150422 }
150423 if( addrNext ){
150424 sqlite3VdbeResolveLabel(v, addrNext);
150425 }
150426 if( pParse->nErr ) return;
150427 }
150428 if( regHit==0 && pAggInfo->nAccumulator ){
150429 regHit = regAcc;
150430 }
150431 if( regHit ){
150432 addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
150433 }
150434 for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
150435 sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i));
150436 if( pParse->nErr ) return;
150437 }
150438
150439 pAggInfo->directMode = 0;
150440 if( addrHitTest ){
150441 sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
@@ -150196,29 +150547,32 @@
150547 SrcList *pTabList, /* Search for self-joins in this FROM clause */
150548 SrcItem *pThis, /* Search for prior reference to this subquery */
150549 int iFirst, int iEnd /* Range of FROM-clause entries to search. */
150550 ){
150551 SrcItem *pItem;
150552 Select *pSel;
150553 assert( pThis->fg.isSubquery );
150554 pSel = pThis->u4.pSubq->pSelect;
150555 assert( pSel!=0 );
150556 if( pSel->selFlags & SF_PushDown ) return 0;
150557 while( iFirst<iEnd ){
150558 Select *pS1;
150559 pItem = &pTabList->a[iFirst++];
150560 if( !pItem->fg.isSubquery ) continue;
150561 if( pItem->fg.viaCoroutine ) continue;
150562 if( pItem->zName==0 ) continue;
150563 assert( pItem->pSTab!=0 );
150564 assert( pThis->pSTab!=0 );
150565 if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue;
150566 if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
150567 pS1 = pItem->u4.pSubq->pSelect;
150568 if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){
150569 /* The query flattener left two different CTE tables with identical
150570 ** names in the same FROM clause. */
150571 continue;
150572 }
150573 if( pS1->selFlags & SF_PushDown ){
150574 /* The view was modified by some other optimization such as
150575 ** pushDownWhereTerms() */
150576 continue;
150577 }
150578 return pItem;
@@ -150258,10 +150612,11 @@
150612 static int countOfViewOptimization(Parse *pParse, Select *p){
150613 Select *pSub, *pPrior;
150614 Expr *pExpr;
150615 Expr *pCount;
150616 sqlite3 *db;
150617 SrcItem *pFrom;
150618 if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
150619 if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
150620 if( p->pWhere ) return 0;
150621 if( p->pHaving ) return 0;
150622 if( p->pGroupBy ) return 0;
@@ -150272,30 +150627,30 @@
150627 if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
150628 assert( ExprUseXList(pExpr) );
150629 if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
150630 if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
150631 if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
150632 pFrom = p->pSrc->a;
150633 if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */
150634 pSub = pFrom->u4.pSubq->pSelect;
150635 if( pSub->pPrior==0 ) return 0; /* Must be a compound */
150636 if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */
150637 do{
150638 if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
150639 if( pSub->pWhere ) return 0; /* No WHERE clause */
150640 if( pSub->pLimit ) return 0; /* No LIMIT clause */
150641 if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
150642 assert( pSub->pHaving==0 ); /* Due to the previous */
150643 pSub = pSub->pPrior; /* Repeat over compound */
150644 }while( pSub );
150645
150646 /* If we reach this point then it is OK to perform the transformation */
150647
150648 db = pParse->db;
150649 pCount = pExpr;
150650 pExpr = 0;
150651 pSub = sqlite3SubqueryDetach(db, pFrom);
 
150652 sqlite3SrcListDelete(db, p->pSrc);
150653 p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
150654 while( pSub ){
150655 Expr *pTerm;
150656 pPrior = pSub->pPrior;
@@ -150336,16 +150691,16 @@
150691 static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
150692 int i;
150693 for(i=0; i<pSrc->nSrc; i++){
150694 SrcItem *p1 = &pSrc->a[i];
150695 if( p1==p0 ) continue;
150696 if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
150697 return 1;
150698 }
150699 if( p1->fg.isSubquery
150700 && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0
150701 && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc)
150702 ){
150703 return 1;
150704 }
150705 }
150706 return 0;
@@ -150406,17 +150761,17 @@
150761 while( 1 /*exit-by-break*/ ){
150762 if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */
150763 if( i==0 ) break;
150764 i--;
150765 pItem--;
150766 if( pItem->fg.isSubquery ) return 0; /* (1c-i) */
150767 }
150768 return 1;
150769 }
150770
150771 /*
150772 ** Generate byte-code for the SELECT statement given in the p argument.
150773 **
150774 ** The results are returned according to the SelectDest structure.
150775 ** See comments in sqliteInt.h for further information.
150776 **
150777 ** This routine returns the number of errors. If any errors are
@@ -150423,10 +150778,44 @@
150778 ** encountered, then an appropriate error message is left in
150779 ** pParse->zErrMsg.
150780 **
150781 ** This routine does NOT free the Select structure passed in. The
150782 ** calling function needs to do that.
150783 **
150784 ** This is a long function. The following is an outline of the processing
150785 ** steps, with tags referencing various milestones:
150786 **
150787 ** * Resolve names and similar preparation tag-select-0100
150788 ** * Scan of the FROM clause tag-select-0200
150789 ** + OUTER JOIN strength reduction tag-select-0220
150790 ** + Sub-query ORDER BY removal tag-select-0230
150791 ** + Query flattening tag-select-0240
150792 ** * Separate subroutine for compound-SELECT tag-select-0300
150793 ** * WHERE-clause constant propagation tag-select-0330
150794 ** * Count()-of-VIEW optimization tag-select-0350
150795 ** * Scan of the FROM clause again tag-select-0400
150796 ** + Authorize unreferenced tables tag-select-0410
150797 ** + Predicate push-down optimization tag-select-0420
150798 ** + Omit unused subquery columns optimization tag-select-0440
150799 ** + Generate code to implement subqueries tag-select-0480
150800 ** - Co-routines tag-select-0482
150801 ** - Reuse previously computed CTE tag-select-0484
150802 ** - REuse previously computed VIEW tag-select-0486
150803 ** - Materialize a VIEW or CTE tag-select-0488
150804 ** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500
150805 ** * Set up for ORDER BY tag-select-0600
150806 ** * Create output table tag-select-0630
150807 ** * Prepare registers for LIMIT tag-select-0650
150808 ** * Setup for DISTINCT tag-select-0680
150809 ** * Generate code for non-aggregate and non-GROUP BY tag-select-0700
150810 ** * Generate code for aggregate and/or GROUP BY tag-select-0800
150811 ** + GROUP BY queries tag-select-0810
150812 ** + non-GROUP BY queries tag-select-0820
150813 ** - Special case of count() w/o GROUP BY tag-select-0821
150814 ** - General case of non-GROUP BY aggregates tag-select-0822
150815 ** * Sort results, as needed tag-select-0900
150816 ** * Internal self-checks tag-select-1000
150817 */
150818 SQLITE_PRIVATE int sqlite3Select(
150819 Parse *pParse, /* The parser context */
150820 Select *p, /* The SELECT statement being coded. */
150821 SelectDest *pDest /* What to do with the query results */
@@ -150466,10 +150855,11 @@
150855 }
150856 sqlite3ShowSelect(p);
150857 }
150858 #endif
150859
150860 /* tag-select-0100 */
150861 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
150862 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
150863 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
150864 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
150865 if( IgnorableDistinct(pDest) ){
@@ -150517,11 +150907,11 @@
150907 if( p->selFlags & SF_UFSrcCheck ){
150908 SrcItem *p0 = &p->pSrc->a[0];
150909 if( sameSrcAlias(p0, p->pSrc) ){
150910 sqlite3ErrorMsg(pParse,
150911 "target object/alias may not appear in FROM clause: %s",
150912 p0->zAlias ? p0->zAlias : p0->pSTab->zName
150913 );
150914 goto select_end;
150915 }
150916
150917 /* Clear the SF_UFSrcCheck flag. The check has already been performed,
@@ -150552,16 +150942,17 @@
150942 memset(&sSort, 0, sizeof(sSort));
150943 sSort.pOrderBy = p->pOrderBy;
150944
150945 /* Try to do various optimizations (flattening subqueries, and strength
150946 ** reduction of join operators) in the FROM clause up into the main query
150947 ** tag-select-0200
150948 */
150949 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
150950 for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
150951 SrcItem *pItem = &pTabList->a[i];
150952 Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0;
150953 Table *pTab = pItem->pSTab;
150954
150955 /* The expander should have already created transient Table objects
150956 ** even for FROM clause elements such as subqueries that do not correspond
150957 ** to a real table */
150958 assert( pTab!=0 );
@@ -150574,10 +150965,11 @@
150965 **
150966 ** If terms of the i-th table are used in the WHERE clause in such a
150967 ** way that the i-th table cannot be the NULL row of a join, then
150968 ** perform the appropriate simplification. This is called
150969 ** "OUTER JOIN strength reduction" in the SQLite documentation.
150970 ** tag-select-0220
150971 */
150972 if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
150973 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor,
150974 pItem->fg.jointype & JT_LTORJ)
150975 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
@@ -150644,11 +151036,12 @@
151036 ** flattening in that case.
151037 */
151038 if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
151039 assert( pSub->pGroupBy==0 );
151040
151041 /* tag-select-0230:
151042 ** If a FROM-clause subquery has an ORDER BY clause that is not
151043 ** really doing anything, then delete it now so that it does not
151044 ** interfere with query flattening. See the discussion at
151045 ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a
151046 **
151047 ** Beware of these cases where the ORDER BY clause may not be safely
@@ -150710,10 +151103,11 @@
151103 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
151104 ){
151105 continue;
151106 }
151107
151108 /* tag-select-0240 */
151109 if( flattenSubquery(pParse, p, i, isAgg) ){
151110 if( pParse->nErr ) goto select_end;
151111 /* This subquery can be absorbed into its parent. */
151112 i = -1;
151113 }
@@ -150725,11 +151119,11 @@
151119 }
151120 #endif
151121
151122 #ifndef SQLITE_OMIT_COMPOUND_SELECT
151123 /* Handle compound SELECT statements using the separate multiSelect()
151124 ** procedure. tag-select-0300
151125 */
151126 if( p->pPrior ){
151127 rc = multiSelect(pParse, p, pDest);
151128 #if TREETRACE_ENABLED
151129 TREETRACE(0x400,pParse,p,("end compound-select processing\n"));
@@ -150741,13 +151135,13 @@
151135 return rc;
151136 }
151137 #endif
151138
151139 /* Do the WHERE-clause constant propagation optimization if this is
151140 ** a join. No need to spend time on this operation for non-join queries
151141 ** as the equivalent optimization will be handled by query planner in
151142 ** sqlite3WhereBegin(). tag-select-0330
151143 */
151144 if( p->pWhere!=0
151145 && p->pWhere->op==TK_AND
151146 && OptimizationEnabled(db, SQLITE_PropagateConst)
151147 && propagateConstants(pParse, p)
@@ -150760,31 +151154,38 @@
151154 #endif
151155 }else{
151156 TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n"));
151157 }
151158
151159 /* tag-select-0350 */
151160 if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
151161 && countOfViewOptimization(pParse, p)
151162 ){
151163 if( db->mallocFailed ) goto select_end;
151164 pTabList = p->pSrc;
151165 }
151166
151167 /* Loop over all terms in the FROM clause and do two things for each term:
151168 **
151169 ** (1) Authorize unreferenced tables
151170 ** (2) Generate code for all sub-queries
151171 **
151172 ** tag-select-0400
151173 */
151174 for(i=0; i<pTabList->nSrc; i++){
151175 SrcItem *pItem = &pTabList->a[i];
151176 SrcItem *pPrior;
151177 SelectDest dest;
151178 Subquery *pSubq;
151179 Select *pSub;
151180 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
151181 const char *zSavedAuthContext;
151182 #endif
151183
151184 /* Authorized unreferenced tables. tag-select-0410
151185 **
151186 ** Issue SQLITE_READ authorizations with a fake column name for any
151187 ** tables that are referenced but from which no values are extracted.
151188 ** Examples of where these kinds of null SQLITE_READ authorizations
151189 ** would occur:
151190 **
151191 ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
@@ -150797,21 +151198,32 @@
151198 ** which would be unambiguous. But legacy authorization callbacks might
151199 ** assume the column name is non-NULL and segfault. The use of an empty
151200 ** string for the fake column name seems safer.
151201 */
151202 if( pItem->colUsed==0 && pItem->zName!=0 ){
151203 const char *zDb;
151204 if( pItem->fg.fixedSchema ){
151205 int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema);
151206 zDb = db->aDb[iDb].zDbSName;
151207 }else if( pItem->fg.isSubquery ){
151208 zDb = 0;
151209 }else{
151210 zDb = pItem->u4.zDatabase;
151211 }
151212 sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb);
151213 }
151214
151215 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
151216 /* Generate code for all sub-queries in the FROM clause
151217 */
151218 if( pItem->fg.isSubquery==0 ) continue;
151219 pSubq = pItem->u4.pSubq;
151220 assert( pSubq!=0 );
151221 pSub = pSubq->pSelect;
151222
151223 /* The code for a subquery should only be generated once. */
151224 if( pSubq->addrFillSub!=0 ) continue;
151225
151226 /* Increment Parse.nHeight by the height of the largest expression
151227 ** tree referred to by this, the parent select. The child select
151228 ** may contain expression trees of at most
151229 ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
@@ -150820,10 +151232,11 @@
151232 */
151233 pParse->nHeight += sqlite3SelectExprHeight(p);
151234
151235 /* Make copies of constant WHERE-clause terms in the outer query down
151236 ** inside the subquery. This can help the subquery to run more efficiently.
151237 ** This is the "predicate push-down optimization". tag-select-0420
151238 */
151239 if( OptimizationEnabled(db, SQLITE_PushDown)
151240 && (pItem->fg.isCte==0
151241 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
151242 && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i)
@@ -150833,17 +151246,18 @@
151246 TREETRACE(0x4000,pParse,p,
151247 ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
151248 sqlite3TreeViewSelect(0, p, 0);
151249 }
151250 #endif
151251 assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
151252 }else{
151253 TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
151254 }
151255
151256 /* Convert unused result columns of the subquery into simple NULL
151257 ** expressions, to avoid unneeded searching and computation.
151258 ** tag-select-0440
151259 */
151260 if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
151261 && disableUnusedSubqueryResultColumns(pItem)
151262 ){
151263 #if TREETRACE_ENABLED
@@ -150857,64 +151271,70 @@
151271 }
151272
151273 zSavedAuthContext = pParse->zAuthContext;
151274 pParse->zAuthContext = pItem->zName;
151275
151276 /* Generate byte-code to implement the subquery tag-select-0480
151277 */
151278 if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
151279 /* Implement a co-routine that will return a single row of the result
151280 ** set on each invocation. tag-select-0482
151281 */
151282 int addrTop = sqlite3VdbeCurrentAddr(v)+1;
151283
151284 pSubq->regReturn = ++pParse->nMem;
151285 sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop);
151286 VdbeComment((v, "%!S", pItem));
151287 pSubq->addrFillSub = addrTop;
151288 sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
151289 ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
151290 sqlite3Select(pParse, pSub, &dest);
151291 pItem->pSTab->nRowLogEst = pSub->nSelectRow;
151292 pItem->fg.viaCoroutine = 1;
151293 pSubq->regResult = dest.iSdst;
151294 sqlite3VdbeEndCoroutine(v, pSubq->regReturn);
151295 VdbeComment((v, "end %!S", pItem));
151296 sqlite3VdbeJumpHere(v, addrTop-1);
151297 sqlite3ClearTempRegCache(pParse);
151298 }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
151299 /* This is a CTE for which materialization code has already been
151300 ** generated. Invoke the subroutine to compute the materialization,
151301 ** then make the pItem->iCursor be a copy of the ephemeral table that
151302 ** holds the result of the materialization. tag-select-0484 */
151303 CteUse *pCteUse = pItem->u2.pCteUse;
151304 sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
151305 if( pItem->iCursor!=pCteUse->iCur ){
151306 sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);
151307 VdbeComment((v, "%!S", pItem));
151308 }
151309 pSub->nSelectRow = pCteUse->nRowEst;
151310 }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
151311 /* This view has already been materialized by a prior entry in
151312 ** this same FROM clause. Reuse it. tag-select-0486 */
151313 Subquery *pPriorSubq;
151314 assert( pPrior->fg.isSubquery );
151315 pPriorSubq = pPrior->u4.pSubq;
151316 assert( pPriorSubq!=0 );
151317 if( pPriorSubq->addrFillSub ){
151318 sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn,
151319 pPriorSubq->addrFillSub);
151320 }
151321 sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
151322 pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow;
151323 }else{
151324 /* Materialize the view. If the view is not correlated, generate a
151325 ** subroutine to do the materialization so that subsequent uses of
151326 ** the same view can reuse the materialization. tag-select-0488 */
151327 int topAddr;
151328 int onceAddr = 0;
151329 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
151330 int addrExplain;
151331 #endif
151332
151333 pSubq->regReturn = ++pParse->nMem;
151334 topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
151335 pSubq->addrFillSub = topAddr+1;
151336 pItem->fg.isMaterialized = 1;
151337 if( pItem->fg.isCorrelated==0 ){
151338 /* If the subquery is not correlated and if we are not inside of
151339 ** a trigger, then we only need to compute the value of the subquery
151340 ** once. */
@@ -150925,21 +151345,21 @@
151345 }
151346 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
151347
151348 ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
151349 sqlite3Select(pParse, pSub, &dest);
151350 pItem->pSTab->nRowLogEst = pSub->nSelectRow;
151351 if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
151352 sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1);
151353 VdbeComment((v, "end %!S", pItem));
151354 sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
151355 sqlite3VdbeJumpHere(v, topAddr);
151356 sqlite3ClearTempRegCache(pParse);
151357 if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
151358 CteUse *pCteUse = pItem->u2.pCteUse;
151359 pCteUse->addrM9e = pSubq->addrFillSub;
151360 pCteUse->regRtn = pSubq->regReturn;
151361 pCteUse->iCur = pItem->iCursor;
151362 pCteUse->nRowEst = pSub->nSelectRow;
151363 }
151364 }
151365 if( db->mallocFailed ) goto select_end;
@@ -150961,11 +151381,13 @@
151381 TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n"));
151382 sqlite3TreeViewSelect(0, p, 0);
151383 }
151384 #endif
151385
151386 /* tag-select-0500
151387 **
151388 ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and
151389 ** if the select-list is the same as the ORDER BY list, then this query
151390 ** can be rewritten as a GROUP BY. In other words, this:
151391 **
151392 ** SELECT DISTINCT xyz FROM ... ORDER BY xyz
151393 **
@@ -151011,11 +151433,11 @@
151433 ** do the sorting. But this sorting ephemeral index might end up
151434 ** being unused if the data can be extracted in pre-sorted order.
151435 ** If that is the case, then the OP_OpenEphemeral instruction will be
151436 ** changed to an OP_Noop once we figure out that the sorting index is
151437 ** not needed. The sSort.addrSortIndex variable is used to facilitate
151438 ** that change. tag-select-0600
151439 */
151440 if( sSort.pOrderBy ){
151441 KeyInfo *pKeyInfo;
151442 pKeyInfo = sqlite3KeyInfoFromExprList(
151443 pParse, sSort.pOrderBy, 0, pEList->nExpr);
@@ -151028,10 +151450,11 @@
151450 }else{
151451 sSort.addrSortIndex = -1;
151452 }
151453
151454 /* If the output is destined for a temporary table, open that table.
151455 ** tag-select-0630
151456 */
151457 if( pDest->eDest==SRT_EphemTab ){
151458 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
151459 if( p->selFlags & SF_NestedFrom ){
151460 /* Delete or NULL-out result columns that will never be used */
@@ -151045,11 +151468,11 @@
151468 if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
151469 }
151470 }
151471 }
151472
151473 /* Set the limiter. tag-select-0650
151474 */
151475 iEnd = sqlite3VdbeMakeLabel(pParse);
151476 if( (p->selFlags & SF_FixedLimit)==0 ){
151477 p->nSelectRow = 320; /* 4 billion rows */
151478 }
@@ -151057,11 +151480,11 @@
151480 if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
151481 sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
151482 sSort.sortFlags |= SORTFLAG_UseSorter;
151483 }
151484
151485 /* Open an ephemeral index to use for the distinct set. tag-select-0680
151486 */
151487 if( p->selFlags & SF_Distinct ){
151488 sDistinct.tabTnct = pParse->nTab++;
151489 sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
151490 sDistinct.tabTnct, 0, 0,
@@ -151072,11 +151495,11 @@
151495 }else{
151496 sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
151497 }
151498
151499 if( !isAgg && pGroupBy==0 ){
151500 /* No aggregate functions and no GROUP BY clause. tag-select-0700 */
151501 u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
151502 | (p->selFlags & SF_FixedLimit);
151503 #ifndef SQLITE_OMIT_WINDOWFUNC
151504 Window *pWin = p->pWin; /* Main window object (or NULL) */
151505 if( pWin ){
@@ -151145,12 +151568,12 @@
151568 */
151569 TREETRACE(0x2,pParse,p,("WhereEnd\n"));
151570 sqlite3WhereEnd(pWInfo);
151571 }
151572 }else{
151573 /* This case is for when there exist aggregate functions or a GROUP BY
151574 ** clause or both. tag-select-0800 */
151575 NameContext sNC; /* Name context for processing aggregate information */
151576 int iAMem; /* First Mem address for storing current GROUP BY */
151577 int iBMem; /* First Mem address for previous GROUP BY */
151578 int iUseFlag; /* Mem address holding flag indicating that at least
151579 ** one row of the input to the aggregator has been
@@ -151265,11 +151688,11 @@
151688 }
151689 #endif
151690
151691
151692 /* Processing for aggregates with GROUP BY is very different and
151693 ** much more complex than aggregates without a GROUP BY. tag-select-0810
151694 */
151695 if( pGroupBy ){
151696 KeyInfo *pKeyInfo; /* Keying information for the group by clause */
151697 int addr1; /* A-vs-B comparison jump */
151698 int addrOutputRow; /* Start of subroutine that outputs a result row */
@@ -151562,13 +151985,16 @@
151985 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
151986 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
151987 }
151988 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
151989 else {
151990 /* Aggregate functions without GROUP BY. tag-select-0820 */
151991 Table *pTab;
151992 if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
151993 /* tag-select-0821
151994 **
151995 ** If isSimpleCount() returns a pointer to a Table structure, then
151996 ** the SQL statement is of the form:
151997 **
151998 ** SELECT count(*) FROM <tbl>
151999 **
152000 ** where the Table structure returned represents table <tbl>.
@@ -151623,10 +152049,12 @@
152049 assignAggregateRegisters(pParse, pAggInfo);
152050 sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0));
152051 sqlite3VdbeAddOp1(v, OP_Close, iCsr);
152052 explainSimpleCount(pParse, pTab, pBest);
152053 }else{
152054 /* The general case of an aggregate query without GROUP BY
152055 ** tag-select-0822 */
152056 int regAcc = 0; /* "populate accumulators" flag */
152057 ExprList *pDistinct = 0;
152058 u16 distFlag = 0;
152059 int eDist;
152060
@@ -151711,11 +152139,11 @@
152139 if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
152140 explainTempTable(pParse, "DISTINCT");
152141 }
152142
152143 /* If there is an ORDER BY clause, then we need to sort the results
152144 ** and send them to the callback one by one. tag-select-0900
152145 */
152146 if( sSort.pOrderBy ){
152147 assert( p->pEList==pEList );
152148 generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
152149 }
@@ -151734,10 +152162,11 @@
152162 select_end:
152163 assert( db->mallocFailed==0 || db->mallocFailed==1 );
152164 assert( db->mallocFailed==0 || pParse->nErr!=0 );
152165 sqlite3ExprListDelete(db, pMinMaxOrderBy);
152166 #ifdef SQLITE_DEBUG
152167 /* Internal self-checks. tag-select-1000 */
152168 if( pAggInfo && !db->mallocFailed ){
152169 #if TREETRACE_ENABLED
152170 if( sqlite3TreeTrace & 0x20 ){
152171 TREETRACE(0x20,pParse,p,("Finished with AggInfo\n"));
152172 printAggInfo(pAggInfo);
@@ -152123,12 +152552,14 @@
152552 **
152553 ** To maintain backwards compatibility, ignore the database
152554 ** name on pTableName if we are reparsing out of the schema table
152555 */
152556 if( db->init.busy && iDb!=1 ){
152557 assert( pTableName->a[0].fg.fixedSchema==0 );
152558 assert( pTableName->a[0].fg.isSubquery==0 );
152559 sqlite3DbFree(db, pTableName->a[0].u4.zDatabase);
152560 pTableName->a[0].u4.zDatabase = 0;
152561 }
152562
152563 /* If the trigger name was unqualified, and the table is a temp table,
152564 ** then set iDb to 1 to create the trigger in the temporary database.
152565 ** If sqlite3SrcListLookup() returns 0, indicating the table does not
@@ -152602,11 +153033,12 @@
153033 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
153034 goto drop_trigger_cleanup;
153035 }
153036
153037 assert( pName->nSrc==1 );
153038 assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 );
153039 zDb = pName->a[0].u4.zDatabase;
153040 zName = pName->a[0].zName;
153041 assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
153042 for(i=OMIT_TEMPDB; i<db->nDb; i++){
153043 int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
153044 if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
@@ -152839,11 +153271,13 @@
153271 assert( zName || pSrc==0 );
153272 if( pSrc ){
153273 Schema *pSchema = pStep->pTrig->pSchema;
153274 pSrc->a[0].zName = zName;
153275 if( pSchema!=db->aDb[1].pSchema ){
153276 assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 );
153277 pSrc->a[0].u4.pSchema = pSchema;
153278 pSrc->a[0].fg.fixedSchema = 1;
153279 }
153280 if( pStep->pFrom ){
153281 SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
153282 if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
153283 Select *pSubquery;
@@ -152952,11 +153386,11 @@
153386 SrcList *pSrc;
153387 assert( pSelect!=0 );
153388 pSrc = pSelect->pSrc;
153389 assert( pSrc!=0 );
153390 for(i=0; i<pSrc->nSrc; i++){
153391 if( pSrc->a[i].pSTab==pWalker->u.pTab ){
153392 testcase( pSelect->selFlags & SF_Correlated );
153393 pSelect->selFlags |= SF_Correlated;
153394 pWalker->eCode = 1;
153395 break;
153396 }
@@ -153023,11 +153457,11 @@
153457 memset(&sSelect, 0, sizeof(sSelect));
153458 memset(&sFrom, 0, sizeof(sFrom));
153459 sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
153460 sSelect.pSrc = &sFrom;
153461 sFrom.nSrc = 1;
153462 sFrom.a[0].pSTab = pTab;
153463 sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */
153464 sFrom.a[0].iCursor = -1;
153465 sqlite3SelectPrep(pParse, &sSelect, 0);
153466 if( pParse->nErr==0 ){
153467 assert( db->mallocFailed==0 );
@@ -153734,11 +154168,11 @@
154168 ExprList *pList = 0;
154169 ExprList *pGrp = 0;
154170 Expr *pLimit2 = 0;
154171 ExprList *pOrderBy2 = 0;
154172 sqlite3 *db = pParse->db;
154173 Table *pTab = pTabList->a[0].pSTab;
154174 SrcList *pSrc;
154175 Expr *pWhere2;
154176 int eDest;
154177
154178 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -153758,12 +154192,12 @@
154192
154193 assert( pTabList->nSrc>1 );
154194 if( pSrc ){
154195 assert( pSrc->a[0].fg.notCte );
154196 pSrc->a[0].iCursor = -1;
154197 pSrc->a[0].pSTab->nTabRef--;
154198 pSrc->a[0].pSTab = 0;
154199 }
154200 if( pPk ){
154201 for(i=0; i<pPk->nKeyCol; i++){
154202 Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]);
154203 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -155007,11 +155441,11 @@
155441 NameContext sNC; /* Context for resolving symbolic names */
155442 Expr sCol[2]; /* Index column converted into an Expr */
155443 int nClause = 0; /* Counter of ON CONFLICT clauses */
155444
155445 assert( pTabList->nSrc==1 );
155446 assert( pTabList->a[0].pSTab!=0 );
155447 assert( pUpsert!=0 );
155448 assert( pUpsert->pUpsertTarget!=0 );
155449
155450 /* Resolve all symbolic names in the conflict-target clause, which
155451 ** includes both the list of columns and the optional partial-index
@@ -155026,11 +155460,11 @@
155460 if( rc ) return rc;
155461 rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
155462 if( rc ) return rc;
155463
155464 /* Check to see if the conflict target matches the rowid. */
155465 pTab = pTabList->a[0].pSTab;
155466 pTarget = pUpsert->pUpsertTarget;
155467 iCursor = pTabList->a[0].iCursor;
155468 if( HasRowid(pTab)
155469 && pTarget->nExpr==1
155470 && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
@@ -157198,10 +157632,11 @@
157632 } btree;
157633 struct { /* Information for virtual tables */
157634 int idxNum; /* Index number */
157635 u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
157636 u32 bOmitOffset : 1; /* True to let virtual table handle offset */
157637 u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */
157638 i8 isOrdered; /* True if satisfies ORDER BY */
157639 u16 omitMask; /* Terms that may be omitted */
157640 char *idxStr; /* Index identifier string */
157641 u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
157642 } vtab;
@@ -157832,11 +158267,11 @@
158267 Index *pIdx;
158268
158269 assert( pLoop->u.btree.pIndex!=0 );
158270 pIdx = pLoop->u.btree.pIndex;
158271 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
158272 if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){
158273 if( isSearch ){
158274 zFmt = "PRIMARY KEY";
158275 }
158276 }else if( flags & WHERE_PARTIALIDX ){
158277 zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
@@ -157875,11 +158310,13 @@
158310 }
158311 sqlite3_str_appendf(&str, "%c?)", cRangeOp);
158312 }
158313 #ifndef SQLITE_OMIT_VIRTUALTABLE
158314 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
158315 sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX ");
158316 sqlite3_str_appendf(&str,
158317 pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s",
158318 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
158319 }
158320 #endif
158321 if( pItem->fg.jointype & JT_LEFT ){
158322 sqlite3_str_appendf(&str, " LEFT-JOIN");
@@ -157929,11 +158366,11 @@
158366 sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
158367 str.printfFlags = SQLITE_PRINTF_INTERNAL;
158368 sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
158369 pLoop = pLevel->pWLoop;
158370 if( pLoop->wsFlags & WHERE_IPK ){
158371 const Table *pTab = pItem->pSTab;
158372 if( pTab->iPKey>=0 ){
158373 sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
158374 }else{
158375 sqlite3_str_appendf(&str, "rowid=?");
158376 }
@@ -157992,11 +158429,13 @@
158429 }
158430 if( wsFlags & WHERE_INDEXED ){
158431 sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
158432 }
158433 }else{
158434 int addr;
158435 assert( pSrclist->a[pLvl->iFrom].fg.isSubquery );
158436 addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub;
158437 VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1);
158438 assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine );
158439 assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr );
158440 sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1);
158441 }
@@ -159129,11 +159568,12 @@
159568 pLoop = pLevel->pWLoop;
159569 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
159570 iCur = pTabItem->iCursor;
159571 pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
159572 bRev = (pWInfo->revMask>>iLevel)&1;
159573 VdbeModuleComment((v, "Begin WHERE-loop%d: %s",
159574 iLevel, pTabItem->pSTab->zName));
159575 #if WHERETRACE_ENABLED /* 0x4001 */
159576 if( sqlite3WhereTrace & 0x1 ){
159577 sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n",
159578 iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom);
159579 if( sqlite3WhereTrace & 0x1000 ){
@@ -159184,15 +159624,19 @@
159624 }
159625 addrHalt = pWInfo->a[j].addrBrk;
159626
159627 /* Special case of a FROM clause subquery implemented as a co-routine */
159628 if( pTabItem->fg.viaCoroutine ){
159629 int regYield;
159630 Subquery *pSubq;
159631 assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 );
159632 pSubq = pTabItem->u4.pSubq;
159633 regYield = pSubq->regReturn;
159634 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
159635 pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
159636 VdbeCoverage(v);
159637 VdbeComment((v, "next row of %s", pTabItem->pSTab->zName));
159638 pLevel->op = OP_Goto;
159639 }else
159640
159641 #ifndef SQLITE_OMIT_VIRTUALTABLE
159642 if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
@@ -159917,11 +160361,11 @@
160361 int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
160362 int iRetInit; /* Address of regReturn init */
160363 int untestedTerms = 0; /* Some terms not completely tested */
160364 int ii; /* Loop counter */
160365 Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
160366 Table *pTab = pTabItem->pSTab;
160367
160368 pTerm = pLoop->aLTerm[0];
160369 assert( pTerm!=0 );
160370 assert( pTerm->eOperator & WO_OR );
160371 assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -160376,11 +160820,11 @@
160820 /* pTab is the right-hand table of the RIGHT JOIN. Generate code that
160821 ** will record that the current row of that table has been matched at
160822 ** least once. This is accomplished by storing the PK for the row in
160823 ** both the iMatch index and the regBloom Bloom filter.
160824 */
160825 pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab;
160826 if( HasRowid(pTab) ){
160827 r = sqlite3GetTempRange(pParse, 2);
160828 sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
160829 nPk = 1;
160830 }else{
@@ -160483,23 +160927,27 @@
160927 SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
160928 SrcList sFrom;
160929 Bitmask mAll = 0;
160930 int k;
160931
160932 ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
160933 sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
160934 pRJ->regReturn);
160935 for(k=0; k<iLevel; k++){
160936 int iIdxCur;
160937 SrcItem *pRight;
160938 assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom );
160939 pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom];
160940 mAll |= pWInfo->a[k].pWLoop->maskSelf;
160941 if( pRight->fg.viaCoroutine ){
160942 Subquery *pSubq;
160943 assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 );
160944 pSubq = pRight->u4.pSubq;
160945 assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 );
160946 sqlite3VdbeAddOp3(
160947 v, OP_Null, 0, pSubq->regResult,
160948 pSubq->regResult + pSubq->pSelect->pEList->nExpr-1
160949 );
160950 }
160951 sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
160952 iIdxCur = pWInfo->a[k].iIdxCur;
160953 if( iIdxCur ){
@@ -160533,11 +160981,11 @@
160981 int iCur = pLevel->iTabCur;
160982 int r = ++pParse->nMem;
160983 int nPk;
160984 int jmp;
160985 int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
160986 Table *pTab = pTabItem->pSTab;
160987 if( HasRowid(pTab) ){
160988 sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
160989 nPk = 1;
160990 }else{
160991 int iPk;
@@ -160785,15 +161233,24 @@
161233 assert( !ExprHasProperty(pRight, EP_IntValue) );
161234 z = (u8*)pRight->u.zToken;
161235 }
161236 if( z ){
161237
161238 /* Count the number of prefix characters prior to the first wildcard.
161239 ** If the underlying database has a UTF16LE encoding, then only consider
161240 ** ASCII characters. Note that the encoding of z[] is UTF8 - we are
161241 ** dealing with only UTF8 here in this code, but the database engine
161242 ** itself might be processing content using a different encoding. */
161243 cnt = 0;
161244 while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
161245 cnt++;
161246 if( c==wc[3] && z[cnt]!=0 ){
161247 cnt++;
161248 }else if( c>=0x80 && ENC(db)==SQLITE_UTF16LE ){
161249 cnt--;
161250 break;
161251 }
161252 }
161253
161254 /* The optimization is possible only if (1) the pattern does not begin
161255 ** with a wildcard and if (2) the non-wildcard prefix does not end with
161256 ** an (illegal 0xff) character, or (3) the pattern does not consist of
@@ -160804,11 +161261,11 @@
161261 ** removed. */
161262 if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){
161263 Expr *pPrefix;
161264
161265 /* A "complete" match if the pattern ends with "*" or "%" */
161266 *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE;
161267
161268 /* Get the pattern prefix. Remove all escapes from the prefix. */
161269 pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
161270 if( pPrefix ){
161271 int iFrom, iTo;
@@ -161523,11 +161980,13 @@
161980 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere);
161981 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
161982 if( ALWAYS(pSrc!=0) ){
161983 int i;
161984 for(i=0; i<pSrc->nSrc; i++){
161985 if( pSrc->a[i].fg.isSubquery ){
161986 mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect);
161987 }
161988 if( pSrc->a[i].fg.isUsing==0 ){
161989 mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
161990 }
161991 if( pSrc->a[i].fg.isTabFunc ){
161992 mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
@@ -161561,11 +162020,11 @@
162020 Index *pIdx;
162021 int i;
162022 int iCur;
162023 do{
162024 iCur = pFrom->a[j].iCursor;
162025 for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
162026 if( pIdx->aColExpr==0 ) continue;
162027 for(i=0; i<pIdx->nKeyCol; i++){
162028 if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
162029 assert( pIdx->bHasExpr );
162030 if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
@@ -161605,11 +162064,11 @@
162064 return 1;
162065 }
162066
162067 for(i=0; i<pFrom->nSrc; i++){
162068 Index *pIdx;
162069 for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
162070 if( pIdx->aColExpr ){
162071 return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i);
162072 }
162073 }
162074 }
@@ -162193,11 +162652,11 @@
162652 */
162653 SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
162654 assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */
162655 if( p->pGroupBy==0
162656 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
162657 && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */
162658 ){
162659 ExprList *pOrderBy = p->pOrderBy;
162660 int iCsr = p->pSrc->a[0].iCursor;
162661 int ii;
162662
@@ -162414,11 +162873,11 @@
162873 int j, k;
162874 ExprList *pArgs;
162875 Expr *pColRef;
162876 Expr *pTerm;
162877 if( pItem->fg.isTabFunc==0 ) return;
162878 pTab = pItem->pSTab;
162879 assert( pTab!=0 );
162880 pArgs = pItem->u1.pFuncArg;
162881 if( pArgs==0 ) return;
162882 for(j=k=0; j<pArgs->nExpr; j++){
162883 Expr *pRhs;
@@ -163098,11 +163557,11 @@
163557 /* If there is more than one table or sub-select in the FROM clause of
163558 ** this query, then it will not be possible to show that the DISTINCT
163559 ** clause is redundant. */
163560 if( pTabList->nSrc!=1 ) return 0;
163561 iBase = pTabList->a[0].iCursor;
163562 pTab = pTabList->a[0].pSTab;
163563
163564 /* If any of the expressions is an IPK column on table iBase, then return
163565 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
163566 ** current SELECT is a correlated sub-query.
163567 */
@@ -163362,14 +163821,14 @@
163821 }
163822 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
163823 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
163824 leftCol = pTerm->u.x.leftColumn;
163825 if( leftCol<0 ) return 0;
163826 aff = pSrc->pSTab->aCol[leftCol].affinity;
163827 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
163828 testcase( pTerm->pExpr->op==TK_IS );
163829 return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol);
163830 }
163831 #endif
163832
163833
163834 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -163473,11 +163932,11 @@
163932 /* Count the number of columns that will be added to the index
163933 ** and used to match WHERE clause constraints */
163934 nKeyCol = 0;
163935 pTabList = pWC->pWInfo->pTabList;
163936 pSrc = &pTabList->a[pLevel->iFrom];
163937 pTable = pSrc->pSTab;
163938 pWCEnd = &pWC->a[pWC->nTerm];
163939 pLoop = pLevel->pWLoop;
163940 idxCols = 0;
163941 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
163942 Expr *pExpr = pTerm->pExpr;
@@ -163615,16 +164074,21 @@
164074 }
164075
164076 /* Fill the automatic index with content */
164077 assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] );
164078 if( pSrc->fg.viaCoroutine ){
164079 int regYield;
164080 Subquery *pSubq;
164081 assert( pSrc->fg.isSubquery );
164082 pSubq = pSrc->u4.pSubq;
164083 assert( pSubq!=0 );
164084 regYield = pSubq->regReturn;
164085 addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
164086 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
164087 addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
164088 VdbeCoverage(v);
164089 VdbeComment((v, "next row of %s", pSrc->pSTab->zName));
164090 }else{
164091 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
164092 }
164093 if( pPartial ){
164094 iContinue = sqlite3VdbeMakeLabel(pParse);
@@ -163642,15 +164106,16 @@
164106 sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v));
164107 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
164108 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
164109 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
164110 if( pSrc->fg.viaCoroutine ){
164111 assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 );
164112 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
164113 testcase( pParse->db->mallocFailed );
164114 assert( pLevel->iIdxCur>0 );
164115 translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
164116 pSrc->u4.pSubq->regResult, pLevel->iIdxCur);
164117 sqlite3VdbeGoto(v, addrTop);
164118 pSrc->fg.viaCoroutine = 0;
164119 }else{
164120 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
164121 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
@@ -163737,11 +164202,11 @@
164202 */
164203 pTabList = pWInfo->pTabList;
164204 iSrc = pLevel->iFrom;
164205 pItem = &pTabList->a[iSrc];
164206 assert( pItem!=0 );
164207 pTab = pItem->pSTab;
164208 assert( pTab!=0 );
164209 sz = sqlite3LogEstToInt(pTab->nRowLogEst);
164210 if( sz<10000 ){
164211 sz = 10000;
164212 }else if( sz>10000000 ){
@@ -163768,11 +164233,11 @@
164233 Index *pIdx = pLoop->u.btree.pIndex;
164234 int n = pLoop->u.btree.nEq;
164235 int r1 = sqlite3GetTempRange(pParse, n);
164236 int jj;
164237 for(jj=0; jj<n; jj++){
164238 assert( pIdx->pTable==pItem->pSTab );
164239 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
164240 }
164241 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
164242 sqlite3ReleaseTempRange(pParse, r1, n);
164243 }
@@ -163849,11 +164314,11 @@
164314 int eDistinct = 0;
164315 ExprList *pOrderBy = pWInfo->pOrderBy;
164316 WhereClause *p;
164317
164318 assert( pSrc!=0 );
164319 pTab = pSrc->pSTab;
164320 assert( pTab!=0 );
164321 assert( IsVirtual(pTab) );
164322
164323 /* Find all WHERE clause constraints referring to this virtual table.
164324 ** Mark each term with the TERM_OK flag. Set nTerm to the number of
@@ -164857,11 +165322,11 @@
165322 SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
165323 if( pWC ){
165324 WhereInfo *pWInfo = pWC->pWInfo;
165325 int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
165326 SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
165327 Table *pTab = pItem->pSTab;
165328 Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
165329 sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
165330 p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
165331 sqlite3DebugPrintf(" %12s",
165332 pItem->zAlias ? pItem->zAlias : pTab->zName);
@@ -165845,19 +166310,19 @@
166310 ** 1. The cost of doing one search-by-key to find the first matching
166311 ** entry
166312 ** 2. Stepping forward in the index pNew->nOut times to find all
166313 ** additional matching entries.
166314 */
166315 assert( pSrc->pSTab->szTabRow>0 );
166316 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
166317 /* The pProbe->szIdxRow is low for an IPK table since the interior
166318 ** pages are small. Thus szIdxRow gives a good estimate of seek cost.
166319 ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
166320 ** under-estimate the scanning cost. */
166321 rCostIdx = pNew->nOut + 16;
166322 }else{
166323 rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow;
166324 }
166325 rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
166326
166327 /* Estimate the cost of running the loop. If all data is coming
166328 ** from the index, then this is just the cost of doing the index
@@ -166318,13 +166783,13 @@
166783
166784 pNew = pBuilder->pNew;
166785 pWInfo = pBuilder->pWInfo;
166786 pTabList = pWInfo->pTabList;
166787 pSrc = pTabList->a + pNew->iTab;
166788 pTab = pSrc->pSTab;
166789 pWC = pBuilder->pWC;
166790 assert( !IsVirtual(pSrc->pSTab) );
166791
166792 if( pSrc->fg.isIndexedBy ){
166793 assert( pSrc->fg.isCte==0 );
166794 /* An INDEXED BY clause specifies a particular index to use */
166795 pProbe = pSrc->u2.pIBIndex;
@@ -166345,11 +166810,11 @@
166810 sPk.pTable = pTab;
166811 sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */
166812 sPk.idxType = SQLITE_IDXTYPE_IPK;
166813 aiRowEstPk[0] = pTab->nRowLogEst;
166814 aiRowEstPk[1] = 0;
166815 pFirst = pSrc->pSTab->pIndex;
166816 if( pSrc->fg.notIndexed==0 ){
166817 /* The real indices of the table are only considered if the
166818 ** NOT INDEXED qualifier is omitted from the FROM clause */
166819 sPk.pNext = pFirst;
166820 }
@@ -166464,13 +166929,13 @@
166929 #else
166930 pNew->rRun = rSize + 16;
166931 #endif
166932 ApplyCostMultiplier(pNew->rRun, pTab->costMult);
166933 whereLoopOutputAdjust(pWC, pNew, rSize);
166934 if( pSrc->fg.isSubquery ){
166935 if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE;
166936 pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy;
166937 }
166938 rc = whereLoopInsert(pBuilder, pNew);
166939 pNew->nOut = rSize;
166940 if( rc ) break;
166941 }else{
@@ -166692,11 +167157,11 @@
167157 pIdxInfo->estimatedRows = 25;
167158 pIdxInfo->idxFlags = 0;
167159 pHidden->mHandleIn = 0;
167160
167161 /* Invoke the virtual table xBestIndex() method */
167162 rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo);
167163 if( rc ){
167164 if( rc==SQLITE_CONSTRAINT ){
167165 /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
167166 ** that the particular combination of parameters provided is unusable.
167167 ** Make no entries in the loop table.
@@ -166722,11 +167187,11 @@
167187 || j<0
167188 || (pTerm = termFromWhereClause(pWC, j))==0
167189 || pNew->aLTerm[iTerm]!=0
167190 || pIdxCons->usable==0
167191 ){
167192 sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
167193 freeIdxStr(pIdxInfo);
167194 return SQLITE_ERROR;
167195 }
167196 testcase( iTerm==nConstraint-1 );
167197 testcase( j==0 );
@@ -166785,11 +167250,11 @@
167250 pNew->nLTerm = mxTerm+1;
167251 for(i=0; i<=mxTerm; i++){
167252 if( pNew->aLTerm[i]==0 ){
167253 /* The non-zero argvIdx values must be contiguous. Raise an
167254 ** error if they are not */
167255 sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
167256 freeIdxStr(pIdxInfo);
167257 return SQLITE_ERROR;
167258 }
167259 }
167260 assert( pNew->nLTerm<=pNew->nLSlot );
@@ -166797,10 +167262,11 @@
167262 pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
167263 pIdxInfo->needToFreeIdxStr = 0;
167264 pNew->u.vtab.idxStr = pIdxInfo->idxStr;
167265 pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
167266 pIdxInfo->nOrderBy : 0);
167267 pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0;
167268 pNew->rSetup = 0;
167269 pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
167270 pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
167271
167272 /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
@@ -166987,11 +167453,11 @@
167453 pWInfo = pBuilder->pWInfo;
167454 pParse = pWInfo->pParse;
167455 pWC = pBuilder->pWC;
167456 pNew = pBuilder->pNew;
167457 pSrc = &pWInfo->pTabList->a[pNew->iTab];
167458 assert( IsVirtual(pSrc->pSTab) );
167459 p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
167460 if( p==0 ) return SQLITE_NOMEM_BKPT;
167461 pNew->rSetup = 0;
167462 pNew->wsFlags = WHERE_VIRTUALTABLE;
167463 pNew->nLTerm = 0;
@@ -167001,11 +167467,11 @@
167467 freeIndexInfo(pParse->db, p);
167468 return SQLITE_NOMEM_BKPT;
167469 }
167470
167471 /* First call xBestIndex() with all constraints usable. */
167472 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName));
167473 WHERETRACE(0x800, (" VirtualOne: all usable\n"));
167474 rc = whereLoopAddVirtualOne(
167475 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
167476 );
167477 if( bRetry ){
@@ -167083,11 +167549,11 @@
167549 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
167550 }
167551 }
167552
167553 freeIndexInfo(pParse->db, p);
167554 WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc));
167555 return rc;
167556 }
167557 #endif /* SQLITE_OMIT_VIRTUALTABLE */
167558
167559 /*
@@ -167155,11 +167621,11 @@
167621 if( sqlite3WhereTrace & 0x20000 ){
167622 sqlite3WhereClausePrint(sSubBuild.pWC);
167623 }
167624 #endif
167625 #ifndef SQLITE_OMIT_VIRTUALTABLE
167626 if( IsVirtual(pItem->pSTab) ){
167627 rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
167628 }else
167629 #endif
167630 {
167631 rc = whereLoopAddBtree(&sSubBuild, mPrereq);
@@ -167269,11 +167735,11 @@
167735 bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
167736 }else if( !hasRightJoin ){
167737 mPrereq = 0;
167738 }
167739 #ifndef SQLITE_OMIT_VIRTUALTABLE
167740 if( IsVirtual(pItem->pSTab) ){
167741 SrcItem *p;
167742 for(p=&pItem[1]; p<pEnd; p++){
167743 if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
167744 mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
167745 }
@@ -167905,11 +168371,11 @@
168371 rDelta = 15*(nDep-3);
168372 #ifdef WHERETRACE_ENABLED /* 0x4 */
168373 if( sqlite3WhereTrace&0x4 ){
168374 SrcItem *pItem = pWInfo->pTabList->a + iLoop;
168375 sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n",
168376 pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName,
168377 nDep, rDelta);
168378 }
168379 #endif
168380 if( pWInfo->nOutStarDelta==0 ){
168381 for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
@@ -168455,11 +168921,11 @@
168921
168922 pWInfo = pBuilder->pWInfo;
168923 if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
168924 assert( pWInfo->pTabList->nSrc>=1 );
168925 pItem = pWInfo->pTabList->a;
168926 pTab = pItem->pSTab;
168927 if( IsVirtual(pTab) ) return 0;
168928 if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){
168929 testcase( pItem->fg.isIndexedBy );
168930 testcase( pItem->fg.notIndexed );
168931 return 0;
@@ -168718,11 +169184,11 @@
169184 assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
169185 for(i=0; i<pWInfo->nLevel; i++){
169186 WhereLoop *pLoop = pWInfo->a[i].pWLoop;
169187 const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
169188 SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
169189 Table *pTab = pItem->pSTab;
169190 if( (pTab->tabFlags & TF_HasStat1)==0 ) break;
169191 pTab->tabFlags |= TF_MaybeReanalyze;
169192 if( i>=1
169193 && (pLoop->wsFlags & reqFlags)==reqFlags
169194 /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
@@ -168875,12 +169341,12 @@
169341 int ii;
169342 for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){
169343 SrcItem *pItem = &pWInfo->pTabList->a[ii];
169344 if( !pItem->fg.isCte
169345 || pItem->u2.pCteUse->eM10d!=M10d_Yes
169346 || NEVER(pItem->fg.isSubquery==0)
169347 || pItem->u4.pSubq->pSelect->pOrderBy==0
169348 ){
169349 pWInfo->revMask |= MASKBIT(ii);
169350 }
169351 }
169352 }
@@ -169366,19 +169832,19 @@
169832 */
169833 assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
169834 if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
169835 int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
169836 int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
169837 assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) );
169838 if( bOnerow || (
169839 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
169840 && !IsVirtual(pTabList->a[0].pSTab)
169841 && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
169842 && OptimizationEnabled(db, SQLITE_OnePass)
169843 )){
169844 pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
169845 if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){
169846 if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
169847 bFordelete = OPFLAG_FORDELETE;
169848 }
169849 pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
169850 }
@@ -169392,11 +169858,11 @@
169858 Table *pTab; /* Table to open */
169859 int iDb; /* Index of database containing table/index */
169860 SrcItem *pTabItem;
169861
169862 pTabItem = &pTabList->a[pLevel->iFrom];
169863 pTab = pTabItem->pSTab;
169864 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
169865 pLoop = pLevel->pWLoop;
169866 if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
169867 /* Do nothing */
169868 }else
@@ -169463,11 +169929,11 @@
169929 /* This is one term of an OR-optimization using the PRIMARY KEY of a
169930 ** WITHOUT ROWID table. No need for a separate index */
169931 iIndexCur = pLevel->iTabCur;
169932 op = 0;
169933 }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
169934 Index *pJ = pTabItem->pSTab->pIndex;
169935 iIndexCur = iAuxArg;
169936 assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
169937 while( ALWAYS(pJ) && pJ!=pIx ){
169938 iIndexCur++;
169939 pJ = pJ->pNext;
@@ -169530,11 +169996,11 @@
169996 pRJ->iMatch = pParse->nTab++;
169997 pRJ->regBloom = ++pParse->nMem;
169998 sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
169999 pRJ->regReturn = ++pParse->nMem;
170000 sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
170001 assert( pTab==pTabItem->pSTab );
170002 if( HasRowid(pTab) ){
170003 KeyInfo *pInfo;
170004 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
170005 pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
170006 if( pInfo ){
@@ -169569,17 +170035,22 @@
170035 if( pParse->nErr ) goto whereBeginError;
170036 pLevel = &pWInfo->a[ii];
170037 wsFlags = pLevel->pWLoop->wsFlags;
170038 pSrc = &pTabList->a[pLevel->iFrom];
170039 if( pSrc->fg.isMaterialized ){
170040 Subquery *pSubq;
170041 int iOnce = 0;
170042 assert( pSrc->fg.isSubquery );
170043 pSubq = pSrc->u4.pSubq;
170044 if( pSrc->fg.isCorrelated==0 ){
170045 iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
170046 }else{
170047 iOnce = 0;
 
 
170048 }
170049 sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub);
170050 VdbeComment((v, "materialize %!S", pSrc));
170051 if( iOnce ) sqlite3VdbeJumpHere(v, iOnce);
170052 }
170053 assert( pTabList == pWInfo->pTabList );
170054 if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
170055 if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
170056 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -169788,13 +170259,14 @@
170259 if( (ws & WHERE_IDX_ONLY)==0 ){
170260 SrcItem *pSrc = &pTabList->a[pLevel->iFrom];
170261 assert( pLevel->iTabCur==pSrc->iCursor );
170262 if( pSrc->fg.viaCoroutine ){
170263 int m, n;
170264 assert( pSrc->fg.isSubquery );
170265 n = pSrc->u4.pSubq->regResult;
170266 assert( pSrc->pSTab!=0 );
170267 m = pSrc->pSTab->nCol;
170268 sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1);
170269 }
170270 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
170271 }
170272 if( (ws & WHERE_INDEXED)
@@ -169814,20 +170286,20 @@
170286 sqlite3VdbeGoto(v, pLevel->addrFirst);
170287 }
170288 sqlite3VdbeJumpHere(v, addr);
170289 }
170290 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
170291 pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName));
170292 }
170293
170294 assert( pWInfo->nLevel<=pTabList->nSrc );
170295 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
170296 int k, last;
170297 VdbeOp *pOp, *pLastOp;
170298 Index *pIdx = 0;
170299 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
170300 Table *pTab = pTabItem->pSTab;
170301 assert( pTab!=0 );
170302 pLoop = pLevel->pWLoop;
170303
170304 /* Do RIGHT JOIN processing. Generate code that will output the
170305 ** unmatched rows of the right operand of the RIGHT JOIN with
@@ -169842,13 +170314,14 @@
170314 ** the co-routine into OP_Copy of result contained in a register.
170315 ** OP_Rowid becomes OP_Null.
170316 */
170317 if( pTabItem->fg.viaCoroutine ){
170318 testcase( pParse->db->mallocFailed );
170319 assert( pTabItem->fg.isSubquery );
170320 assert( pTabItem->u4.pSubq->regResult>=0 );
170321 translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
170322 pTabItem->u4.pSubq->regResult, 0);
170323 continue;
170324 }
170325
170326 /* If this scan uses an index, make VDBE code substitutions to read data
170327 ** from the index instead of from the table where possible. In some cases
@@ -171054,13 +171527,14 @@
171527 p->selId, p));
171528 p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
171529 assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
171530 ** of sqlite3DbMallocRawNN() called from
171531 ** sqlite3SrcListAppend() */
171532 if( p->pSrc==0 ){
171533 sqlite3SelectDelete(db, pSub);
171534 }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){
171535 Table *pTab2;
 
171536 p->pSrc->a[0].fg.isCorrelated = 1;
171537 sqlite3SrcListAssignCursors(pParse, p->pSrc);
171538 pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
171539 pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
171540 pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -171070,20 +171544,18 @@
171544 ** the correct error message regardless. */
171545 rc = SQLITE_NOMEM;
171546 }else{
171547 memcpy(pTab, pTab2, sizeof(Table));
171548 pTab->tabFlags |= TF_Ephemeral;
171549 p->pSrc->a[0].pSTab = pTab;
171550 pTab = pTab2;
171551 memset(&w, 0, sizeof(w));
171552 w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
171553 w.xSelectCallback = sqlite3WalkerDepthIncrease;
171554 w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
171555 sqlite3WalkSelect(&w, pSub);
171556 }
 
 
171557 }
171558 if( db->mallocFailed ) rc = SQLITE_NOMEM;
171559
171560 /* Defer deleting the temporary table pTab because if an error occurred,
171561 ** there could still be references to that table embedded in the
@@ -171366,14 +171838,19 @@
171838 ** This is called by code in select.c before it calls sqlite3WhereBegin()
171839 ** to begin iterating through the sub-query results. It is used to allocate
171840 ** and initialize registers and cursors used by sqlite3WindowCodeStep().
171841 */
171842 SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
 
 
171843 Window *pWin;
171844 int nEphExpr;
171845 Window *pMWin;
171846 Vdbe *v;
171847
171848 assert( pSelect->pSrc->a[0].fg.isSubquery );
171849 nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr;
171850 pMWin = pSelect->pWin;
171851 v = sqlite3GetVdbe(pParse);
171852
171853 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
171854 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
171855 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
171856 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
@@ -172766,11 +173243,11 @@
173243 Window *pMWin = p->pWin;
173244 ExprList *pOrderBy = pMWin->pOrderBy;
173245 Vdbe *v = sqlite3GetVdbe(pParse);
173246 int csrWrite; /* Cursor used to write to eph. table */
173247 int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
173248 int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */
173249 int iInput; /* To iterate through sub cols */
173250 int addrNe; /* Address of OP_Ne */
173251 int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
173252 int addrInteger = 0; /* Address of OP_Integer */
173253 int addrEmpty; /* Address of OP_Rewind in flush: */
@@ -177217,24 +177694,33 @@
177694 }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
177695 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
177696 if( yymsp[-5].minor.yy203 ){
177697 SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1];
177698 SrcItem *pOld = yymsp[-3].minor.yy203->a;
177699 assert( pOld->fg.fixedSchema==0 );
177700 pNew->zName = pOld->zName;
177701 assert( pOld->fg.fixedSchema==0 );
177702 if( pOld->fg.isSubquery ){
177703 pNew->fg.isSubquery = 1;
177704 pNew->u4.pSubq = pOld->u4.pSubq;
177705 pOld->u4.pSubq = 0;
177706 pOld->fg.isSubquery = 0;
177707 assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 );
177708 if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){
177709 pNew->fg.isNestedFrom = 1;
177710 }
177711 }else{
177712 pNew->u4.zDatabase = pOld->u4.zDatabase;
177713 pOld->u4.zDatabase = 0;
177714 }
177715 if( pOld->fg.isTabFunc ){
177716 pNew->u1.pFuncArg = pOld->u1.pFuncArg;
177717 pOld->u1.pFuncArg = 0;
177718 pOld->fg.isTabFunc = 0;
177719 pNew->fg.isTabFunc = 1;
177720 }
177721 pOld->zName = 0;
 
177722 }
177723 sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203);
177724 }else{
177725 Select *pSubquery;
177726 sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
@@ -184790,10 +185276,22 @@
185276 case SQLITE_TESTCTRL_OPTIMIZATIONS: {
185277 sqlite3 *db = va_arg(ap, sqlite3*);
185278 db->dbOptFlags = va_arg(ap, u32);
185279 break;
185280 }
185281
185282 /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N)
185283 **
185284 ** Write the current optimization settings into *N. A zero bit means that
185285 ** the optimization is on, and a 1 bit means that the optimization is off.
185286 */
185287 case SQLITE_TESTCTRL_GETOPT: {
185288 sqlite3 *db = va_arg(ap, sqlite3*);
185289 int *pN = va_arg(ap, int*);
185290 *pN = db->dbOptFlags;
185291 break;
185292 }
185293
185294 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
185295 **
185296 ** If parameter onoff is 1, subsequent calls to localtime() fail.
185297 ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
@@ -224464,10 +224962,11 @@
224962 )
224963 ){
224964 pIdxInfo->orderByConsumed = 1;
224965 pIdxInfo->idxNum |= 0x08;
224966 }
224967 pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX;
224968
224969 return SQLITE_OK;
224970 }
224971
224972 /*
@@ -232374,13 +232873,36 @@
232873 ** It is the output of the tokenizer module. For tokendata=1 tables, this
232874 ** includes any embedded 0x00 and trailing data.
232875 **
232876 ** This API can be quite slow if used with an FTS5 table created with the
232877 ** "detail=none" or "detail=column" option.
232878 **
232879 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
232880 ** If parameter iCol is less than zero, or greater than or equal to the
232881 ** number of columns in the table, SQLITE_RANGE is returned.
232882 **
232883 ** Otherwise, this function attempts to retrieve the locale associated
232884 ** with column iCol of the current row. Usually, there is no associated
232885 ** locale, and output parameters (*pzLocale) and (*pnLocale) are set
232886 ** to NULL and 0, respectively. However, if the fts5_locale() function
232887 ** was used to associate a locale with the value when it was inserted
232888 ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
232889 ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
232890 ** is set to the size in bytes of the buffer, not including the
232891 ** nul-terminator.
232892 **
232893 ** If successful, SQLITE_OK is returned. Or, if an error occurs, an
232894 ** SQLite error code is returned. The final value of the output parameters
232895 ** is undefined in this case.
232896 **
232897 ** xTokenize_v2:
232898 ** Tokenize text using the tokenizer belonging to the FTS5 table. This
232899 ** API is the same as the xTokenize() API, except that it allows a tokenizer
232900 ** locale to be specified.
232901 */
232902 struct Fts5ExtensionApi {
232903 int iVersion; /* Currently always set to 4 */
232904
232905 void *(*xUserData)(Fts5Context*);
232906
232907 int (*xColumnCount)(Fts5Context*);
232908 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -232418,10 +232940,19 @@
232940 int (*xQueryToken)(Fts5Context*,
232941 int iPhrase, int iToken,
232942 const char **ppToken, int *pnToken
232943 );
232944 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
232945
232946 /* Below this point are iVersion>=4 only */
232947 int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
232948 int (*xTokenize_v2)(Fts5Context*,
232949 const char *pText, int nText, /* Text to tokenize */
232950 const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
232951 void *pCtx, /* Context passed to xToken() */
232952 int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
232953 );
232954 };
232955
232956 /*
232957 ** CUSTOM AUXILIARY FUNCTIONS
232958 *************************************************************************/
@@ -232430,19 +232961,20 @@
232961 ** CUSTOM TOKENIZERS
232962 **
232963 ** Applications may also register custom tokenizer types. A tokenizer
232964 ** is registered by providing fts5 with a populated instance of the
232965 ** following structure. All structure methods must be defined, setting
232966 **
232967 ** any member of the fts5_tokenizer struct to NULL leads to undefined
232968 ** behaviour. The structure methods are expected to function as follows:
232969 **
232970 ** xCreate:
232971 ** This function is used to allocate and initialize a tokenizer instance.
232972 ** A tokenizer instance is required to actually tokenize text.
232973 **
232974 ** The first argument passed to this function is a copy of the (void*)
232975 ** pointer provided by the application when the fts5_tokenizer_v2 object
232976 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
232977 ** The second and third arguments are an array of nul-terminated strings
232978 ** containing the tokenizer arguments, if any, specified following the
232979 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
232980 ** to create the FTS5 table.
@@ -232462,11 +232994,11 @@
232994 ** This function is expected to tokenize the nText byte string indicated
232995 ** by argument pText. pText may or may not be nul-terminated. The first
232996 ** argument passed to this function is a pointer to an Fts5Tokenizer object
232997 ** returned by an earlier call to xCreate().
232998 **
232999 ** The third argument indicates the reason that FTS5 is requesting
233000 ** tokenization of the supplied text. This is always one of the following
233001 ** four values:
233002 **
233003 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
233004 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -232485,10 +233017,17 @@
233017 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
233018 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
233019 ** function. Or an fts5_api.xColumnSize() request made by the same
233020 ** on a columnsize=0 database.
233021 ** </ul>
233022 **
233023 ** The sixth and seventh arguments passed to xTokenize() - pLocale and
233024 ** nLocale - are a pointer to a buffer containing the locale to use for
233025 ** tokenization (e.g. "en_US") and its size in bytes, respectively. The
233026 ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
233027 ** which case nLocale is always 0) to indicate that the tokenizer should
233028 ** use its default locale.
233029 **
233030 ** For each token in the input string, the supplied callback xToken() must
233031 ** be invoked. The first argument to it should be a copy of the pointer
233032 ** passed as the second argument to xTokenize(). The third and fourth
233033 ** arguments are a pointer to a buffer containing the token text, and the
@@ -232508,10 +233047,33 @@
233047 ** immediately return a copy of the xToken() return value. Or, if the
233048 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
233049 ** if an error occurs with the xTokenize() implementation itself, it
233050 ** may abandon the tokenization and return any error code other than
233051 ** SQLITE_OK or SQLITE_DONE.
233052 **
233053 ** If the tokenizer is registered using an fts5_tokenizer_v2 object,
233054 ** then the xTokenize() method has two additional arguments - pLocale
233055 ** and nLocale. These specify the locale that the tokenizer should use
233056 ** for the current request. If pLocale and nLocale are both 0, then the
233057 ** tokenizer should use its default locale. Otherwise, pLocale points to
233058 ** an nLocale byte buffer containing the name of the locale to use as utf-8
233059 ** text. pLocale is not nul-terminated.
233060 **
233061 ** FTS5_TOKENIZER
233062 **
233063 ** There is also an fts5_tokenizer object. This is an older version of
233064 ** fts5_tokenizer_v2. It is similar except that:
233065 **
233066 ** <ul>
233067 ** <li> There is no "iVersion" field, and
233068 ** <li> The xTokenize() method does not take a locale argument.
233069 ** </ul>
233070 **
233071 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
233072 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
233073 ** registered using either API may be retrieved using both xFindTokenizer()
233074 ** and xFindTokenizer_v2().
233075 **
233076 ** SYNONYM SUPPORT
233077 **
233078 ** Custom tokenizers may also support synonyms. Consider a case in which a
233079 ** user wishes to query for a phrase such as "first place". Using the
@@ -232617,10 +233179,37 @@
233179 ** provide synonyms when tokenizing document text (method (3)) or query
233180 ** text (method (2)), not both. Doing so will not cause any errors, but is
233181 ** inefficient.
233182 */
233183 typedef struct Fts5Tokenizer Fts5Tokenizer;
233184 typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
233185 struct fts5_tokenizer_v2 {
233186 int iVersion; /* Currently always 2 */
233187
233188 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
233189 void (*xDelete)(Fts5Tokenizer*);
233190 int (*xTokenize)(Fts5Tokenizer*,
233191 void *pCtx,
233192 int flags, /* Mask of FTS5_TOKENIZE_* flags */
233193 const char *pText, int nText,
233194 const char *pLocale, int nLocale,
233195 int (*xToken)(
233196 void *pCtx, /* Copy of 2nd argument to xTokenize() */
233197 int tflags, /* Mask of FTS5_TOKEN_* flags */
233198 const char *pToken, /* Pointer to buffer containing token */
233199 int nToken, /* Size of token in bytes */
233200 int iStart, /* Byte offset of token within input text */
233201 int iEnd /* Byte offset of end of token within input text */
233202 )
233203 );
233204 };
233205
233206 /*
233207 ** New code should use the fts5_tokenizer_v2 type to define tokenizer
233208 ** implementations. The following type is included for legacy applications
233209 ** that still use it.
233210 */
233211 typedef struct fts5_tokenizer fts5_tokenizer;
233212 struct fts5_tokenizer {
233213 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
233214 void (*xDelete)(Fts5Tokenizer*);
233215 int (*xTokenize)(Fts5Tokenizer*,
@@ -232635,10 +233224,11 @@
233224 int iStart, /* Byte offset of token within input text */
233225 int iEnd /* Byte offset of end of token within input text */
233226 )
233227 );
233228 };
233229
233230
233231 /* Flags that may be passed as the third argument to xTokenize() */
233232 #define FTS5_TOKENIZE_QUERY 0x0001
233233 #define FTS5_TOKENIZE_PREFIX 0x0002
233234 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -232655,11 +233245,11 @@
233245 /*************************************************************************
233246 ** FTS5 EXTENSION REGISTRATION API
233247 */
233248 typedef struct fts5_api fts5_api;
233249 struct fts5_api {
233250 int iVersion; /* Currently always set to 3 */
233251
233252 /* Create a new tokenizer */
233253 int (*xCreateTokenizer)(
233254 fts5_api *pApi,
233255 const char *zName,
@@ -232682,10 +233272,29 @@
233272 const char *zName,
233273 void *pUserData,
233274 fts5_extension_function xFunction,
233275 void (*xDestroy)(void*)
233276 );
233277
233278 /* APIs below this point are only available if iVersion>=3 */
233279
233280 /* Create a new tokenizer */
233281 int (*xCreateTokenizer_v2)(
233282 fts5_api *pApi,
233283 const char *zName,
233284 void *pUserData,
233285 fts5_tokenizer_v2 *pTokenizer,
233286 void (*xDestroy)(void*)
233287 );
233288
233289 /* Find an existing tokenizer */
233290 int (*xFindTokenizer_v2)(
233291 fts5_api *pApi,
233292 const char *zName,
233293 void **ppUserData,
233294 fts5_tokenizer_v2 **ppTokenizer
233295 );
233296 };
233297
233298 /*
233299 ** END OF REGISTRATION API
233300 *************************************************************************/
@@ -232858,14 +233467,17 @@
233467 typedef struct Fts5Config Fts5Config;
233468 typedef struct Fts5TokenizerConfig Fts5TokenizerConfig;
233469
233470 struct Fts5TokenizerConfig {
233471 Fts5Tokenizer *pTok;
233472 fts5_tokenizer_v2 *pApi2;
233473 fts5_tokenizer *pApi1;
233474 const char **azArg;
233475 int nArg;
233476 int ePattern; /* FTS_PATTERN_XXX constant */
233477 const char *pLocale; /* Current locale to use */
233478 int nLocale; /* Size of pLocale in bytes */
233479 };
233480
233481 /*
233482 ** An instance of the following structure encodes all information that can
233483 ** be gleaned from the CREATE VIRTUAL TABLE statement.
@@ -232902,10 +233514,12 @@
233514 ** This is only used for debugging. If set to false, any prefix indexes
233515 ** are ignored. This value is configured using:
233516 **
233517 ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
233518 **
233519 ** bLocale:
233520 ** Set to true if locale=1 was specified when the table was created.
233521 */
233522 struct Fts5Config {
233523 sqlite3 *db; /* Database handle */
233524 Fts5Global *pGlobal; /* Global fts5 object for handle db */
233525 char *zDb; /* Database holding FTS index (e.g. "main") */
@@ -232919,14 +233533,16 @@
233533 int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
233534 char *zContent; /* content table */
233535 char *zContentRowid; /* "content_rowid=" option value */
233536 int bColumnsize; /* "columnsize=" option value (dflt==1) */
233537 int bTokendata; /* "tokendata=" option value (dflt==0) */
233538 int bLocale; /* "locale=" option value (dflt==0) */
233539 int eDetail; /* FTS5_DETAIL_XXX value */
233540 char *zContentExprlist;
233541 Fts5TokenizerConfig t;
233542 int bLock; /* True when table is preparing statement */
233543
233544
233545 /* Values loaded from the %_config table */
233546 int iVersion; /* fts5 file format 'version' */
233547 int iCookie; /* Incremented when %_config is modified */
233548 int pgsz; /* Approximate page size used in %_data */
@@ -232988,10 +233604,12 @@
233604 /* Set the value of a single config attribute */
233605 static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
233606
233607 static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
233608
233609 static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...);
233610
233611 /*
233612 ** End of interface to code in fts5_config.c.
233613 **************************************************************************/
233614
233615 /**************************************************************************
@@ -233032,11 +233650,11 @@
233650
233651 /* Write and decode big-endian 32-bit integer values */
233652 static void sqlite3Fts5Put32(u8*, int);
233653 static int sqlite3Fts5Get32(const u8*);
233654
233655 #define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF)
233656 #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
233657
233658 typedef struct Fts5PoslistReader Fts5PoslistReader;
233659 struct Fts5PoslistReader {
233660 /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
@@ -233323,10 +233941,21 @@
233941
233942 static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
233943
233944 static int sqlite3Fts5FlushToDisk(Fts5Table*);
233945
233946 static int sqlite3Fts5ExtractText(
233947 Fts5Config *pConfig,
233948 sqlite3_value *pVal, /* Value to extract text from */
233949 int bContent, /* Loaded from content table */
233950 int *pbResetTokenizer, /* OUT: True if ClearLocale() required */
233951 const char **ppText, /* OUT: Pointer to text buffer */
233952 int *pnText /* OUT: Size of (*ppText) in bytes */
233953 );
233954
233955 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
233956
233957 /*
233958 ** End of interface to code in fts5.c.
233959 **************************************************************************/
233960
233961 /**************************************************************************
@@ -233402,11 +234031,11 @@
234031 static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
234032
234033 static int sqlite3Fts5DropAll(Fts5Config*);
234034 static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
234035
234036 static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int);
234037 static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
234038 static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
234039
234040 static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
234041
@@ -233428,10 +234057,13 @@
234057 static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
234058 static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
234059 static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
234060 static int sqlite3Fts5StorageReset(Fts5Storage *p);
234061
234062 static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*);
234063 static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel);
234064
234065 /*
234066 ** End of interface to code in fts5_storage.c.
234067 **************************************************************************/
234068
234069
@@ -235357,10 +235989,11 @@
235989 p->iOff = iEndOff;
235990 }
235991
235992 return rc;
235993 }
235994
235995
235996 /*
235997 ** Implementation of highlight() function.
235998 */
235999 static void fts5HighlightFunction(
@@ -235388,16 +236021,23 @@
236021 rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
236022 if( rc==SQLITE_RANGE ){
236023 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
236024 rc = SQLITE_OK;
236025 }else if( ctx.zIn ){
236026 const char *pLoc = 0; /* Locale of column iCol */
236027 int nLoc = 0; /* Size of pLoc in bytes */
236028 if( rc==SQLITE_OK ){
236029 rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
236030 }
236031
236032 if( rc==SQLITE_OK ){
236033 rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc);
236034 }
236035 if( rc==SQLITE_OK ){
236036 rc = pApi->xTokenize_v2(
236037 pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb
236038 );
236039 }
236040 if( ctx.bOpen ){
236041 fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
236042 }
236043 fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
@@ -235590,19 +236230,23 @@
236230 }
236231
236232 memset(&sFinder, 0, sizeof(Fts5SFinder));
236233 for(i=0; i<nCol; i++){
236234 if( iCol<0 || iCol==i ){
236235 const char *pLoc = 0; /* Locale of column iCol */
236236 int nLoc = 0; /* Size of pLoc in bytes */
236237 int nDoc;
236238 int nDocsize;
236239 int ii;
236240 sFinder.iPos = 0;
236241 sFinder.nFirst = 0;
236242 rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
236243 if( rc!=SQLITE_OK ) break;
236244 rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc);
236245 if( rc!=SQLITE_OK ) break;
236246 rc = pApi->xTokenize_v2(pFts,
236247 sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb
236248 );
236249 if( rc!=SQLITE_OK ) break;
236250 rc = pApi->xColumnSize(pFts, i, &nDocsize);
236251 if( rc!=SQLITE_OK ) break;
236252
@@ -235656,10 +236300,13 @@
236300 }
236301 if( rc==SQLITE_OK && nColSize==0 ){
236302 rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
236303 }
236304 if( ctx.zIn ){
236305 const char *pLoc = 0; /* Locale of column iBestCol */
236306 int nLoc = 0; /* Bytes in pLoc */
236307
236308 if( rc==SQLITE_OK ){
236309 rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
236310 }
236311
236312 ctx.iRangeStart = iBestStart;
@@ -235674,11 +236321,16 @@
236321 while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
236322 rc = fts5CInstIterNext(&ctx.iter);
236323 }
236324
236325 if( rc==SQLITE_OK ){
236326 rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc);
236327 }
236328 if( rc==SQLITE_OK ){
236329 rc = pApi->xTokenize_v2(
236330 pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb
236331 );
236332 }
236333 if( ctx.bOpen ){
236334 fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
236335 }
236336 if( ctx.iRangeEnd>=(nColSize-1) ){
@@ -235857,21 +236509,69 @@
236509 sqlite3_result_double(pCtx, -1.0 * score);
236510 }else{
236511 sqlite3_result_error_code(pCtx, rc);
236512 }
236513 }
236514
236515 /*
236516 ** Implementation of fts5_get_locale() function.
236517 */
236518 static void fts5GetLocaleFunction(
236519 const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
236520 Fts5Context *pFts, /* First arg to pass to pApi functions */
236521 sqlite3_context *pCtx, /* Context for returning result/error */
236522 int nVal, /* Number of values in apVal[] array */
236523 sqlite3_value **apVal /* Array of trailing arguments */
236524 ){
236525 int iCol = 0;
236526 int eType = 0;
236527 int rc = SQLITE_OK;
236528 const char *zLocale = 0;
236529 int nLocale = 0;
236530
236531 /* xColumnLocale() must be available */
236532 assert( pApi->iVersion>=4 );
236533
236534 if( nVal!=1 ){
236535 const char *z = "wrong number of arguments to function fts5_get_locale()";
236536 sqlite3_result_error(pCtx, z, -1);
236537 return;
236538 }
236539
236540 eType = sqlite3_value_numeric_type(apVal[0]);
236541 if( eType!=SQLITE_INTEGER ){
236542 const char *z = "non-integer argument passed to function fts5_get_locale()";
236543 sqlite3_result_error(pCtx, z, -1);
236544 return;
236545 }
236546
236547 iCol = sqlite3_value_int(apVal[0]);
236548 if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){
236549 sqlite3_result_error_code(pCtx, SQLITE_RANGE);
236550 return;
236551 }
236552
236553 rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale);
236554 if( rc!=SQLITE_OK ){
236555 sqlite3_result_error_code(pCtx, rc);
236556 return;
236557 }
236558
236559 sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT);
236560 }
236561
236562 static int sqlite3Fts5AuxInit(fts5_api *pApi){
236563 struct Builtin {
236564 const char *zFunc; /* Function name (nul-terminated) */
236565 void *pUserData; /* User-data pointer */
236566 fts5_extension_function xFunc;/* Callback function */
236567 void (*xDestroy)(void*); /* Destructor function */
236568 } aBuiltin [] = {
236569 { "snippet", 0, fts5SnippetFunction, 0 },
236570 { "highlight", 0, fts5HighlightFunction, 0 },
236571 { "bm25", 0, fts5Bm25Function, 0 },
236572 { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 },
236573 };
236574 int rc = SQLITE_OK; /* Return code */
236575 int i; /* To iterate through builtin functions */
236576
236577 for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
@@ -236677,10 +237377,20 @@
237377 }else{
237378 pConfig->bColumnsize = (zArg[0]=='1');
237379 }
237380 return rc;
237381 }
237382
237383 if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){
237384 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
237385 *pzErr = sqlite3_mprintf("malformed locale=... directive");
237386 rc = SQLITE_ERROR;
237387 }else{
237388 pConfig->bLocale = (zArg[0]=='1');
237389 }
237390 return rc;
237391 }
237392
237393 if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
237394 const Fts5Enum aDetail[] = {
237395 { "none", FTS5_DETAIL_NONE },
237396 { "full", FTS5_DETAIL_FULL },
@@ -236967,11 +237677,15 @@
237677 */
237678 static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
237679 if( pConfig ){
237680 int i;
237681 if( pConfig->t.pTok ){
237682 if( pConfig->t.pApi1 ){
237683 pConfig->t.pApi1->xDelete(pConfig->t.pTok);
237684 }else{
237685 pConfig->t.pApi2->xDelete(pConfig->t.pTok);
237686 }
237687 }
237688 sqlite3_free((char*)pConfig->t.azArg);
237689 sqlite3_free(pConfig->zDb);
237690 sqlite3_free(pConfig->zName);
237691 for(i=0; i<pConfig->nCol; i++){
@@ -237050,13 +237764,19 @@
237764 if( pText ){
237765 if( pConfig->t.pTok==0 ){
237766 rc = sqlite3Fts5LoadTokenizer(pConfig);
237767 }
237768 if( rc==SQLITE_OK ){
237769 if( pConfig->t.pApi1 ){
237770 rc = pConfig->t.pApi1->xTokenize(
237771 pConfig->t.pTok, pCtx, flags, pText, nText, xToken
237772 );
237773 }else{
237774 rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags,
237775 pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken
237776 );
237777 }
237778 }
237779 }
237780 return rc;
237781 }
237782
@@ -237309,26 +238029,46 @@
238029 if( rc==SQLITE_OK
238030 && iVersion!=FTS5_CURRENT_VERSION
238031 && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE
238032 ){
238033 rc = SQLITE_ERROR;
238034 sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format "
238035 "(found %d, expected %d or %d) - run 'rebuild'",
238036 iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
238037 );
 
 
 
238038 }else{
238039 pConfig->iVersion = iVersion;
238040 }
238041
238042 if( rc==SQLITE_OK ){
238043 pConfig->iCookie = iCookie;
238044 }
238045 return rc;
238046 }
238047
238048 /*
238049 ** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer
238050 ** containing the error message created using printf() style formatting
238051 ** string zFmt and its trailing arguments.
238052 */
238053 static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){
238054 va_list ap; /* ... printf arguments */
238055 char *zMsg = 0;
238056
238057 va_start(ap, zFmt);
238058 zMsg = sqlite3_vmprintf(zFmt, ap);
238059 if( pConfig->pzErrmsg ){
238060 assert( *pConfig->pzErrmsg==0 );
238061 *pConfig->pzErrmsg = zMsg;
238062 }else{
238063 sqlite3_free(zMsg);
238064 }
238065
238066 va_end(ap);
238067 }
238068
238069
238070
238071 /*
238072 ** 2014 May 31
238073 **
238074 ** The author disclaims copyright to this source code. In place of
@@ -237614,15 +238354,16 @@
238354 t = fts5ExprGetToken(&sParse, &z, &token);
238355 sqlite3Fts5Parser(pEngine, t, token, &sParse);
238356 }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
238357 sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
238358
238359 assert( sParse.pExpr || sParse.rc!=SQLITE_OK );
238360 assert_expr_depth_ok(sParse.rc, sParse.pExpr);
238361
238362 /* If the LHS of the MATCH expression was a user column, apply the
238363 ** implicit column-filter. */
238364 if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){
238365 int n = sizeof(Fts5Colset);
238366 Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
238367 if( pColset ){
238368 pColset->nCol = 1;
238369 pColset->aiCol[0] = iCol;
@@ -237635,19 +238376,11 @@
238376 *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
238377 if( pNew==0 ){
238378 sParse.rc = SQLITE_NOMEM;
238379 sqlite3Fts5ParseNodeFree(sParse.pExpr);
238380 }else{
238381 pNew->pRoot = sParse.pExpr;
 
 
 
 
 
 
 
 
238382 pNew->pIndex = 0;
238383 pNew->pConfig = pConfig;
238384 pNew->apExprPhrase = sParse.apPhrase;
238385 pNew->nPhrase = sParse.nPhrase;
238386 pNew->bDesc = 0;
@@ -238461,11 +239194,11 @@
239194 pNode->bEof = 1;
239195 return rc;
239196 }
239197 }else{
239198 Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
239199 if( pIter->iRowid==iLast ) continue;
239200 bMatch = 0;
239201 if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
239202 return rc;
239203 }
239204 }
@@ -238983,13 +239716,10 @@
239716 ){
239717 const int SZALLOC = 8;
239718 Fts5ExprNearset *pRet = 0;
239719
239720 if( pParse->rc==SQLITE_OK ){
 
 
 
239721 if( pNear==0 ){
239722 sqlite3_int64 nByte;
239723 nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
239724 pRet = sqlite3_malloc64(nByte);
239725 if( pRet==0 ){
@@ -250372,15 +251102,32 @@
251102
251103 /*
251104 ** Each tokenizer module registered with the FTS5 module is represented
251105 ** by an object of the following type. All such objects are stored as part
251106 ** of the Fts5Global.pTok list.
251107 **
251108 ** bV2Native:
251109 ** True if the tokenizer was registered using xCreateTokenizer_v2(), false
251110 ** for xCreateTokenizer(). If this variable is true, then x2 is populated
251111 ** with the routines as supplied by the caller and x1 contains synthesized
251112 ** wrapper routines. In this case the user-data pointer passed to
251113 ** x1.xCreate should be a pointer to the Fts5TokenizerModule structure,
251114 ** not a copy of pUserData.
251115 **
251116 ** Of course, if bV2Native is false, then x1 contains the real routines and
251117 ** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule
251118 ** object should be passed to x2.xCreate.
251119 **
251120 ** The synthesized wrapper routines are necessary for xFindTokenizer(_v2)
251121 ** calls.
251122 */
251123 struct Fts5TokenizerModule {
251124 char *zName; /* Name of tokenizer */
251125 void *pUserData; /* User pointer passed to xCreate() */
251126 int bV2Native; /* True if v2 native tokenizer */
251127 fts5_tokenizer x1; /* Tokenizer functions */
251128 fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
251129 void (*xDestroy)(void*); /* Destructor function */
251130 Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
251131 };
251132
251133 struct Fts5FullTable {
@@ -250464,11 +251211,11 @@
251211
251212 /* Auxiliary data storage */
251213 Fts5Auxiliary *pAux; /* Currently executing extension function */
251214 Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
251215
251216 /* Cache used by auxiliary API functions xInst() and xInstCount() */
251217 Fts5PoslistReader *aInstIter; /* One for each phrase */
251218 int nInstAlloc; /* Size of aInst[] array (entries / 3) */
251219 int nInstCount; /* Number of phrase instances */
251220 int *aInst; /* 3 integers per phrase instance */
251221 };
@@ -250499,10 +251246,16 @@
251246 #define FTS5CSR_REQUIRE_POSLIST 0x40
251247
251248 #define BitFlagAllTest(x,y) (((x) & (y))==(y))
251249 #define BitFlagTest(x,y) (((x) & (y))!=0)
251250
251251 /*
251252 ** The subtype value and header bytes used by fts5_locale().
251253 */
251254 #define FTS5_LOCALE_SUBTYPE ((unsigned int)'L')
251255 #define FTS5_LOCALE_HEADER "\x00\xE0\xB2\xEB"
251256
251257
251258 /*
251259 ** Macros to Set(), Clear() and Test() cursor flags.
251260 */
251261 #define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -250876,11 +251629,11 @@
251629 }else{
251630 if( iCol==nCol+1 ){
251631 if( bSeenRank ) continue;
251632 idxStr[iIdxStr++] = 'r';
251633 bSeenRank = 1;
251634 }else{
251635 nSeenMatch++;
251636 idxStr[iIdxStr++] = 'M';
251637 sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
251638 idxStr += strlen(&idxStr[iIdxStr]);
251639 assert( idxStr[iIdxStr]=='\0' );
@@ -251262,11 +252015,11 @@
252015 rc = SQLITE_NOMEM;
252016 }else{
252017 rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
252018 SQLITE_PREPARE_PERSISTENT, &pRet, 0);
252019 if( rc!=SQLITE_OK ){
252020 sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db));
252021 }
252022 sqlite3_free(zSql);
252023 }
252024
252025 va_end(ap);
@@ -251497,10 +252250,192 @@
252250 sqlite3_free(p->p.base.zErrMsg);
252251 p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
252252 va_end(ap);
252253 }
252254
252255 /*
252256 ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
252257 ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
252258 ** valid until after the final call to sqlite3Fts5Tokenize() that will use
252259 ** the locale.
252260 */
252261 static void fts5SetLocale(
252262 Fts5Config *pConfig,
252263 const char *zLocale,
252264 int nLocale
252265 ){
252266 Fts5TokenizerConfig *pT = &pConfig->t;
252267 pT->pLocale = zLocale;
252268 pT->nLocale = nLocale;
252269 }
252270
252271 /*
252272 ** Clear any locale configured by an earlier call to fts5SetLocale() or
252273 ** sqlite3Fts5ExtractText().
252274 */
252275 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
252276 fts5SetLocale(pConfig, 0, 0);
252277 }
252278
252279 /*
252280 ** This function is used to extract utf-8 text from an sqlite3_value. This
252281 ** is usually done in order to tokenize it. For example, when:
252282 **
252283 ** * a value is written to an fts5 table,
252284 ** * a value is deleted from an FTS5_CONTENT_NORMAL table,
252285 ** * a value containing a query expression is passed to xFilter()
252286 **
252287 ** and so on.
252288 **
252289 ** This function handles 2 cases:
252290 **
252291 ** 1) Ordinary values. The text can be extracted from these using
252292 ** sqlite3_value_text().
252293 **
252294 ** 2) Combination text/locale blobs created by fts5_locale(). There
252295 ** are several cases for these:
252296 **
252297 ** * Blobs tagged with FTS5_LOCALE_SUBTYPE.
252298 ** * Blobs read from the content table of a locale=1 external-content
252299 ** table, and
252300 ** * Blobs read from the content table of a locale=1 regular
252301 ** content table.
252302 **
252303 ** The first two cases above should have the 4 byte FTS5_LOCALE_HEADER
252304 ** header. It is an error if a blob with the subtype or a blob read
252305 ** from the content table of an external content table does not have
252306 ** the required header. A blob read from the content table of a regular
252307 ** locale=1 table does not have the header. This is to save space.
252308 **
252309 ** If successful, SQLITE_OK is returned and output parameters (*ppText)
252310 ** and (*pnText) are set to point to a buffer containing the extracted utf-8
252311 ** text and its length in bytes, respectively. The buffer is not
252312 ** nul-terminated. It has the same lifetime as the sqlite3_value object
252313 ** from which it is extracted.
252314 **
252315 ** Parameter bContent must be true if the value was read from an indexed
252316 ** column (i.e. not UNINDEXED) of the on disk content.
252317 **
252318 ** If pbResetTokenizer is not NULL and if case (2) is used, then
252319 ** fts5SetLocale() is called to ensure subsequent sqlite3Fts5Tokenize() calls
252320 ** use the locale. In this case (*pbResetTokenizer) is set to true before
252321 ** returning, to indicate that the caller must call sqlite3Fts5ClearLocale()
252322 ** to clear the locale after tokenizing the text.
252323 */
252324 static int sqlite3Fts5ExtractText(
252325 Fts5Config *pConfig,
252326 sqlite3_value *pVal, /* Value to extract text from */
252327 int bContent, /* True if indexed table content */
252328 int *pbResetTokenizer, /* OUT: True if xSetLocale(NULL) required */
252329 const char **ppText, /* OUT: Pointer to text buffer */
252330 int *pnText /* OUT: Size of (*ppText) in bytes */
252331 ){
252332 const char *pText = 0;
252333 int nText = 0;
252334 int rc = SQLITE_OK;
252335 int bDecodeBlob = 0;
252336
252337 assert( pbResetTokenizer==0 || *pbResetTokenizer==0 );
252338 assert( bContent==0 || pConfig->eContent!=FTS5_CONTENT_NONE );
252339 assert( bContent==0 || sqlite3_value_subtype(pVal)==0 );
252340
252341 if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
252342 if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE
252343 || (bContent && pConfig->bLocale)
252344 ){
252345 bDecodeBlob = 1;
252346 }
252347 }
252348
252349 if( bDecodeBlob ){
252350 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
252351 const u8 *pBlob = sqlite3_value_blob(pVal);
252352 int nBlob = sqlite3_value_bytes(pVal);
252353
252354 /* Unless this blob was read from the %_content table of an
252355 ** FTS5_CONTENT_NORMAL table, it should have the 4 byte fts5_locale()
252356 ** header. Check for this. If it is not found, return an error. */
252357 if( (!bContent || pConfig->eContent!=FTS5_CONTENT_NORMAL) ){
252358 if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
252359 rc = SQLITE_ERROR;
252360 }else{
252361 pBlob += 4;
252362 nBlob -= 4;
252363 }
252364 }
252365
252366 if( rc==SQLITE_OK ){
252367 int nLocale = 0;
252368
252369 for(nLocale=0; nLocale<nBlob; nLocale++){
252370 if( pBlob[nLocale]==0x00 ) break;
252371 }
252372 if( nLocale==nBlob || nLocale==0 ){
252373 rc = SQLITE_ERROR;
252374 }else{
252375 pText = (const char*)&pBlob[nLocale+1];
252376 nText = nBlob-nLocale-1;
252377
252378 if( pbResetTokenizer ){
252379 fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
252380 *pbResetTokenizer = 1;
252381 }
252382 }
252383 }
252384
252385 }else{
252386 pText = (const char*)sqlite3_value_text(pVal);
252387 nText = sqlite3_value_bytes(pVal);
252388 }
252389
252390 *ppText = pText;
252391 *pnText = nText;
252392 return rc;
252393 }
252394
252395 /*
252396 ** Argument pVal is the text of a full-text search expression. It may or
252397 ** may not have been wrapped by fts5_locale(). This function extracts
252398 ** the text of the expression, and sets output variable (*pzText) to
252399 ** point to a nul-terminated buffer containing the expression.
252400 **
252401 ** If pVal was an fts5_locale() value, then fts5SetLocale() is called to
252402 ** set the tokenizer to use the specified locale.
252403 **
252404 ** If output variable (*pbFreeAndReset) is set to true, then the caller
252405 ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
252406 ** locale, and (b) call sqlite3_free() to free (*pzText).
252407 */
252408 static int fts5ExtractExprText(
252409 Fts5Config *pConfig, /* Fts5 configuration */
252410 sqlite3_value *pVal, /* Value to extract expression text from */
252411 char **pzText, /* OUT: nul-terminated buffer of text */
252412 int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
252413 ){
252414 const char *zText = 0;
252415 int nText = 0;
252416 int rc = SQLITE_OK;
252417 int bReset = 0;
252418
252419 *pbFreeAndReset = 0;
252420 rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, &bReset, &zText, &nText);
252421 if( rc==SQLITE_OK ){
252422 if( bReset ){
252423 *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, zText);
252424 if( rc!=SQLITE_OK ){
252425 sqlite3Fts5ClearLocale(pConfig);
252426 }else{
252427 *pbFreeAndReset = 1;
252428 }
252429 }else{
252430 *pzText = (char*)zText;
252431 }
252432 }
252433
252434 return rc;
252435 }
252436
252437
252438 /*
252439 ** This is the xFilter interface for the virtual table. See
252440 ** the virtual table xFilter method documentation for additional
252441 ** information.
@@ -251532,17 +252467,11 @@
252467 char **pzErrmsg = pConfig->pzErrmsg;
252468 int i;
252469 int iIdxStr = 0;
252470 Fts5Expr *pExpr = 0;
252471
252472 assert( pConfig->bLock==0 );
 
 
 
 
 
 
252473 if( pCsr->ePlan ){
252474 fts5FreeCursorComponents(pCsr);
252475 memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
252476 }
252477
@@ -251562,12 +252491,18 @@
252491 switch( idxStr[iIdxStr++] ){
252492 case 'r':
252493 pRank = apVal[i];
252494 break;
252495 case 'M': {
252496 char *zText = 0;
252497 int bFreeAndReset = 0;
252498 int bInternal = 0;
252499
252500 rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
252501 if( rc!=SQLITE_OK ) goto filter_out;
252502 if( zText==0 ) zText = "";
252503
252504 iCol = 0;
252505 do{
252506 iCol = iCol*10 + (idxStr[iIdxStr]-'0');
252507 iIdxStr++;
252508 }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
@@ -251575,21 +252510,27 @@
252510 if( zText[0]=='*' ){
252511 /* The user has issued a query of the form "MATCH '*...'". This
252512 ** indicates that the MATCH expression is not a full text query,
252513 ** but a request for an internal parameter. */
252514 rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
252515 bInternal = 1;
252516 }else{
252517 char **pzErr = &pTab->p.base.zErrMsg;
252518 rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
252519 if( rc==SQLITE_OK ){
252520 rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
252521 pExpr = 0;
252522 }
 
252523 }
252524
252525 if( bFreeAndReset ){
252526 sqlite3_free(zText);
252527 sqlite3Fts5ClearLocale(pConfig);
252528 }
252529
252530 if( bInternal || rc!=SQLITE_OK ) goto filter_out;
252531
252532 break;
252533 }
252534 case 'L':
252535 case 'G': {
252536 int bGlob = (idxStr[iIdxStr-1]=='G');
@@ -251893,11 +252834,11 @@
252834 ){
252835 int rc = SQLITE_OK;
252836 int eType1 = sqlite3_value_type(apVal[1]);
252837 if( eType1==SQLITE_INTEGER ){
252838 sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
252839 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0);
252840 }
252841 return rc;
252842 }
252843
252844 static void fts5StorageInsert(
@@ -252017,59 +252958,81 @@
252958 }
252959
252960 /* DELETE */
252961 else if( nArg==1 ){
252962 i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
252963 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
252964 bUpdateOrDelete = 1;
252965 }
252966
252967 /* INSERT or UPDATE */
252968 else{
252969 int eType1 = sqlite3_value_numeric_type(apVal[1]);
252970
252971 /* Ensure that no fts5_locale() values are written to locale=0 tables.
252972 ** And that no blobs except fts5_locale() blobs are written to indexed
252973 ** (i.e. not UNINDEXED) columns of locale=1 tables. */
252974 int ii;
252975 for(ii=0; ii<pConfig->nCol; ii++){
252976 if( sqlite3_value_type(apVal[ii+2])==SQLITE_BLOB ){
252977 int bSub = (sqlite3_value_subtype(apVal[ii+2])==FTS5_LOCALE_SUBTYPE);
252978 if( (pConfig->bLocale && !bSub && pConfig->abUnindexed[ii]==0)
252979 || (pConfig->bLocale==0 && bSub)
252980 ){
252981 if( pConfig->bLocale==0 ){
252982 fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
252983 }
252984 rc = SQLITE_MISMATCH;
252985 goto update_out;
252986 }
252987 }
252988 }
252989
252990 if( eType0!=SQLITE_INTEGER ){
252991 /* An INSERT statement. If the conflict-mode is REPLACE, first remove
252992 ** the current entry (if any). */
252993 if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
252994 i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
252995 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
252996 bUpdateOrDelete = 1;
252997 }
252998 fts5StorageInsert(&rc, pTab, apVal, pRowid);
252999 }
253000
253001 /* UPDATE */
253002 else{
253003 i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
253004 i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
253005 if( eType1!=SQLITE_INTEGER ){
253006 rc = SQLITE_MISMATCH;
253007 }else if( iOld!=iNew ){
253008 if( eConflict==SQLITE_REPLACE ){
253009 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
253010 if( rc==SQLITE_OK ){
253011 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
253012 }
253013 fts5StorageInsert(&rc, pTab, apVal, pRowid);
253014 }else{
253015 rc = sqlite3Fts5StorageFindDeleteRow(pTab->pStorage, iOld);
253016 if( rc==SQLITE_OK ){
253017 rc = sqlite3Fts5StorageContentInsert(pTab->pStorage,apVal,pRowid);
253018 }
253019 if( rc==SQLITE_OK ){
253020 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
253021 }
253022 if( rc==SQLITE_OK ){
253023 rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
253024 }
253025 }
253026 }else{
253027 rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1);
253028 fts5StorageInsert(&rc, pTab, apVal, pRowid);
253029 }
253030 bUpdateOrDelete = 1;
253031 sqlite3Fts5StorageReleaseDeleteRow(pTab->pStorage);
253032 }
253033
253034 }
253035 }
253036
253037 if( rc==SQLITE_OK
253038 && bUpdateOrDelete
@@ -252082,10 +253045,11 @@
253045 if( rc==SQLITE_OK ){
253046 pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
253047 }
253048 }
253049
253050 update_out:
253051 pTab->p.pConfig->pzErrmsg = 0;
253052 return rc;
253053 }
253054
253055 /*
@@ -252159,21 +253123,44 @@
253123 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253124 Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
253125 return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
253126 }
253127
253128 /*
253129 ** Implementation of xTokenize_v2() API.
253130 */
253131 static int fts5ApiTokenize_v2(
253132 Fts5Context *pCtx,
253133 const char *pText, int nText,
253134 const char *pLoc, int nLoc,
253135 void *pUserData,
253136 int (*xToken)(void*, int, const char*, int, int, int)
253137 ){
253138 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253139 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253140 int rc = SQLITE_OK;
253141
253142 fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253143 rc = sqlite3Fts5Tokenize(pTab->pConfig,
253144 FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
253145 );
253146 fts5SetLocale(pTab->pConfig, 0, 0);
253147
253148 return rc;
253149 }
253150
253151 /*
253152 ** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0
253153 ** passed as the locale.
253154 */
253155 static int fts5ApiTokenize(
253156 Fts5Context *pCtx,
253157 const char *pText, int nText,
253158 void *pUserData,
253159 int (*xToken)(void*, int, const char*, int, int, int)
253160 ){
253161 return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken);
 
 
 
 
253162 }
253163
253164 static int fts5ApiPhraseCount(Fts5Context *pCtx){
253165 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253166 return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
@@ -252191,53 +253178,76 @@
253178 int *pn
253179 ){
253180 int rc = SQLITE_OK;
253181 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253182 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253183
253184 assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
253185 if( iCol<0 || iCol>=pTab->pConfig->nCol ){
253186 rc = SQLITE_RANGE;
253187 }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) ){
 
 
253188 *pz = 0;
253189 *pn = 0;
253190 }else{
253191 rc = fts5SeekCursor(pCsr, 0);
253192 if( rc==SQLITE_OK ){
253193 Fts5Config *pConfig = pTab->pConfig;
253194 int bContent = (pConfig->abUnindexed[iCol]==0);
253195 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253196 sqlite3Fts5ExtractText(pConfig, pVal, bContent, 0, pz, pn);
253197 }
253198 }
253199 return rc;
253200 }
253201
253202 /*
253203 ** This is called by various API functions - xInst, xPhraseFirst,
253204 ** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
253205 ** of the current row. This function works for both detail=full tables (in
253206 ** which case the position-list was read from the fts index) or for other
253207 ** detail= modes if the row content is available.
253208 */
253209 static int fts5CsrPoslist(
253210 Fts5Cursor *pCsr, /* Fts5 cursor object */
253211 int iPhrase, /* Phrase to find position list for */
253212 const u8 **pa, /* OUT: Pointer to position list buffer */
253213 int *pn /* OUT: Size of (*pa) in bytes */
253214 ){
253215 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
253216 int rc = SQLITE_OK;
253217 int bLive = (pCsr->pSorter==0);
253218
253219 if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
253220 rc = SQLITE_RANGE;
253221 }else if( pConfig->eDetail!=FTS5_DETAIL_FULL
253222 && pConfig->eContent==FTS5_CONTENT_NONE
253223 ){
253224 *pa = 0;
253225 *pn = 0;
253226 return SQLITE_OK;
253227 }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
253228 if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
253229 Fts5PoslistPopulator *aPopulator;
253230 int i;
253231
253232 aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
253233 if( aPopulator==0 ) rc = SQLITE_NOMEM;
253234 if( rc==SQLITE_OK ){
253235 rc = fts5SeekCursor(pCsr, 0);
253236 }
253237 for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
253238 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253239 const char *z = 0;
253240 int n = 0;
253241 int bReset = 0;
253242 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253243 if( rc==SQLITE_OK ){
253244 rc = sqlite3Fts5ExprPopulatePoslists(
253245 pConfig, pCsr->pExpr, aPopulator, i, z, n
253246 );
253247 }
253248 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253249 }
253250 sqlite3_free(aPopulator);
253251
253252 if( pCsr->pSorter ){
253253 sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -252257,11 +253267,10 @@
253267 }
253268 }else{
253269 *pa = 0;
253270 *pn = 0;
253271 }
 
253272
253273 return rc;
253274 }
253275
253276 /*
@@ -252327,11 +253336,12 @@
253336
253337 aInst = &pCsr->aInst[3 * (nInst-1)];
253338 aInst[0] = iBest;
253339 aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
253340 aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
253341 assert( aInst[1]>=0 );
253342 if( aInst[1]>=nCol ){
253343 rc = FTS5_CORRUPT;
253344 break;
253345 }
253346 sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
253347 }
@@ -252414,20 +253424,25 @@
253424 pCsr->aColumnSize[i] = -1;
253425 }
253426 }
253427 }else{
253428 int i;
253429 rc = fts5SeekCursor(pCsr, 0);
253430 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
253431 if( pConfig->abUnindexed[i]==0 ){
253432 const char *z = 0;
253433 int n = 0;
253434 int bReset = 0;
253435 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253436
253437 pCsr->aColumnSize[i] = 0;
253438 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253439 if( rc==SQLITE_OK ){
253440 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
253441 z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
253442 );
253443 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253444 }
253445 }
253446 }
253447 }
253448 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
@@ -252669,13 +253684,76 @@
253684
253685
253686 static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
253687 int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
253688 );
253689
253690 /*
253691 ** The xColumnLocale() API.
253692 */
253693 static int fts5ApiColumnLocale(
253694 Fts5Context *pCtx,
253695 int iCol,
253696 const char **pzLocale,
253697 int *pnLocale
253698 ){
253699 int rc = SQLITE_OK;
253700 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253701 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
253702
253703 *pzLocale = 0;
253704 *pnLocale = 0;
253705
253706 assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
253707 if( iCol<0 || iCol>=pConfig->nCol ){
253708 rc = SQLITE_RANGE;
253709 }else if(
253710 pConfig->abUnindexed[iCol]==0
253711 && pConfig->eContent!=FTS5_CONTENT_NONE
253712 && pConfig->bLocale
253713 ){
253714 rc = fts5SeekCursor(pCsr, 0);
253715 if( rc==SQLITE_OK ){
253716 /* Load the value into pVal. pVal is a locale/text pair iff:
253717 **
253718 ** 1) It is an SQLITE_BLOB, and
253719 ** 2) Either the subtype is FTS5_LOCALE_SUBTYPE, or else the
253720 ** value was loaded from an FTS5_CONTENT_NORMAL table, and
253721 ** 3) It does not begin with an 0x00 byte.
253722 */
253723 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253724 if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
253725 const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
253726 int nBlob = sqlite3_value_bytes(pVal);
253727 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253728 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253729 if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
253730 rc = SQLITE_ERROR;
253731 }
253732 pBlob += 4;
253733 nBlob -= 4;
253734 }
253735 if( rc==SQLITE_OK ){
253736 int nLocale = 0;
253737 for(nLocale=0; nLocale<nBlob && pBlob[nLocale]!=0x00; nLocale++);
253738 if( nLocale==nBlob || nLocale==0 ){
253739 rc = SQLITE_ERROR;
253740 }else{
253741 /* A locale/text pair */
253742 *pzLocale = (const char*)pBlob;
253743 *pnLocale = nLocale;
253744 }
253745 }
253746 }
253747 }
253748 }
253749
253750 return rc;
253751 }
253752
253753 static const Fts5ExtensionApi sFts5Api = {
253754 4, /* iVersion */
253755 fts5ApiUserData,
253756 fts5ApiColumnCount,
253757 fts5ApiRowCount,
253758 fts5ApiColumnTotalSize,
253759 fts5ApiTokenize,
@@ -252692,11 +253770,13 @@
253770 fts5ApiPhraseFirst,
253771 fts5ApiPhraseNext,
253772 fts5ApiPhraseFirstColumn,
253773 fts5ApiPhraseNextColumn,
253774 fts5ApiQueryToken,
253775 fts5ApiInstToken,
253776 fts5ApiColumnLocale,
253777 fts5ApiTokenize_v2
253778 };
253779
253780 /*
253781 ** Implementation of API function xQueryPhrase().
253782 */
@@ -252743,10 +253823,11 @@
253823 sqlite3_context *context,
253824 int argc,
253825 sqlite3_value **argv
253826 ){
253827 assert( pCsr->pAux==0 );
253828 assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
253829 pCsr->pAux = pAux;
253830 pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
253831 pCsr->pAux = 0;
253832 }
253833
@@ -252755,10 +253836,25 @@
253836 for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
253837 if( pCsr->iCsrId==iCsrId ) break;
253838 }
253839 return pCsr;
253840 }
253841
253842 /*
253843 ** Parameter zFmt is a printf() style formatting string. This function
253844 ** formats it using the trailing arguments and returns the result as
253845 ** an error message to the context passed as the first argument.
253846 */
253847 static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){
253848 char *zErr = 0;
253849 va_list ap;
253850 va_start(ap, zFmt);
253851 zErr = sqlite3_vmprintf(zFmt, ap);
253852 sqlite3_result_error(pCtx, zErr, -1);
253853 sqlite3_free(zErr);
253854 va_end(ap);
253855 }
253856
253857 static void fts5ApiCallback(
253858 sqlite3_context *context,
253859 int argc,
253860 sqlite3_value **argv
@@ -252771,14 +253867,12 @@
253867 assert( argc>=1 );
253868 pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
253869 iCsrId = sqlite3_value_int64(argv[0]);
253870
253871 pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
253872 if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){
253873 fts5ResultError(context, "no such cursor: %lld", iCsrId);
 
 
253874 }else{
253875 sqlite3_vtab *pTab = pCsr->base.pVtab;
253876 fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
253877 sqlite3_free(pTab->zErrMsg);
253878 pTab->zErrMsg = 0;
@@ -252867,10 +253961,61 @@
253961 }
253962
253963 sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
253964 return rc;
253965 }
253966
253967 /*
253968 ** Value pVal was read from column iCol of the FTS5 table. This function
253969 ** returns it to the owner of pCtx via a call to an sqlite3_result_xxx()
253970 ** function. This function deals with the same cases as
253971 ** sqlite3Fts5ExtractText():
253972 **
253973 ** 1) Ordinary values. These can be returned using sqlite3_result_value().
253974 **
253975 ** 2) Blobs from fts5_locale(). The text is extracted from these and
253976 ** returned via sqlite3_result_text(). The locale is discarded.
253977 */
253978 static void fts5ExtractValueFromColumn(
253979 sqlite3_context *pCtx,
253980 Fts5Config *pConfig,
253981 int iCol,
253982 sqlite3_value *pVal
253983 ){
253984 assert( pConfig->eContent!=FTS5_CONTENT_NONE );
253985
253986 if( pConfig->bLocale
253987 && sqlite3_value_type(pVal)==SQLITE_BLOB
253988 && pConfig->abUnindexed[iCol]==0
253989 ){
253990 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253991 const u8 *pBlob = sqlite3_value_blob(pVal);
253992 int nBlob = sqlite3_value_bytes(pVal);
253993 int ii;
253994
253995 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253996 if( nBlob<SZHDR || memcmp(pBlob, FTS5_LOCALE_HEADER, SZHDR) ){
253997 sqlite3_result_error_code(pCtx, SQLITE_ERROR);
253998 return;
253999 }else{
254000 pBlob += 4;
254001 nBlob -= 4;
254002 }
254003 }
254004
254005 for(ii=0; ii<nBlob && pBlob[ii]; ii++);
254006 if( ii==0 || ii==nBlob ){
254007 sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254008 }else{
254009 const char *pText = (const char*)&pBlob[ii+1];
254010 sqlite3_result_text(pCtx, pText, nBlob-ii-1, SQLITE_TRANSIENT);
254011 }
254012 return;
254013 }
254014
254015 sqlite3_result_value(pCtx, pVal);
254016 }
254017
254018 /*
254019 ** This is the xColumn method, called by SQLite to request a value from
254020 ** the row that the supplied cursor currently points to.
254021 */
@@ -252897,12 +254042,12 @@
254042 ** as the table. Return the cursor integer id number. This value is only
254043 ** useful in that it may be passed as the first argument to an FTS5
254044 ** auxiliary function. */
254045 sqlite3_result_int64(pCtx, pCsr->iCsrId);
254046 }else if( iCol==pConfig->nCol+1 ){
 
254047 /* The value of the "rank" column. */
254048
254049 if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
254050 fts5PoslistBlob(pCtx, pCsr);
254051 }else if(
254052 pCsr->ePlan==FTS5_PLAN_MATCH
254053 || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
@@ -252909,24 +254054,31 @@
254054 ){
254055 if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
254056 fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
254057 }
254058 }
254059 }else{
254060 /* A column created by the user containing values. */
254061 int bNochange = sqlite3_vtab_nochange(pCtx);
254062
254063 if( fts5IsContentless(pTab) ){
254064 if( bNochange && pConfig->bContentlessDelete ){
254065 fts5ResultError(pCtx, "cannot UPDATE a subset of "
254066 "columns on fts5 contentless-delete table: %s", pConfig->zName
254067 );
254068 }
254069 }else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){
254070 pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
254071 rc = fts5SeekCursor(pCsr, 1);
254072 if( rc==SQLITE_OK ){
254073 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
254074 fts5ExtractValueFromColumn(pCtx, pConfig, iCol, pVal);
254075 }
254076 pConfig->pzErrmsg = 0;
254077 }
254078 }
254079
254080 return rc;
254081 }
254082
254083
254084 /*
@@ -253060,53 +254212,214 @@
254212 }
254213 }
254214
254215 return rc;
254216 }
254217
254218 /*
254219 ** This function is used by xCreateTokenizer_v2() and xCreateTokenizer().
254220 ** It allocates and partially populates a new Fts5TokenizerModule object.
254221 ** The new object is already linked into the Fts5Global context before
254222 ** returning.
254223 **
254224 ** If successful, SQLITE_OK is returned and a pointer to the new
254225 ** Fts5TokenizerModule object returned via output parameter (*ppNew). All
254226 ** that is required is for the caller to fill in the methods in
254227 ** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native
254228 ** as appropriate.
254229 **
254230 ** If an error occurs, an SQLite error code is returned and the final value
254231 ** of (*ppNew) undefined.
254232 */
254233 static int fts5NewTokenizerModule(
254234 Fts5Global *pGlobal, /* Global context (one per db handle) */
254235 const char *zName, /* Name of new function */
254236 void *pUserData, /* User data for aux. function */
254237 void(*xDestroy)(void*), /* Destructor for pUserData */
254238 Fts5TokenizerModule **ppNew
254239 ){
254240 int rc = SQLITE_OK;
254241 Fts5TokenizerModule *pNew;
254242 sqlite3_int64 nName; /* Size of zName and its \0 terminator */
254243 sqlite3_int64 nByte; /* Bytes of space to allocate */
254244
254245 nName = strlen(zName) + 1;
254246 nByte = sizeof(Fts5TokenizerModule) + nName;
254247 *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte);
254248 if( pNew ){
254249 pNew->zName = (char*)&pNew[1];
254250 memcpy(pNew->zName, zName, nName);
254251 pNew->pUserData = pUserData;
254252 pNew->xDestroy = xDestroy;
254253 pNew->pNext = pGlobal->pTok;
254254 pGlobal->pTok = pNew;
254255 if( pNew->pNext==0 ){
254256 pGlobal->pDfltTok = pNew;
254257 }
254258 }
254259
254260 return rc;
254261 }
254262
254263 /*
254264 ** An instance of this type is used as the Fts5Tokenizer object for
254265 ** wrapper tokenizers - those that provide access to a v1 tokenizer via
254266 ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
254267 ** via the fts5_tokenizer API.
254268 */
254269 typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
254270 struct Fts5VtoVTokenizer {
254271 Fts5TokenizerModule *pMod;
254272 Fts5Tokenizer *pReal;
254273 };
254274
254275 /*
254276 ** Create a wrapper tokenizer. The context argument pCtx points to the
254277 ** Fts5TokenizerModule object.
254278 */
254279 static int fts5VtoVCreate(
254280 void *pCtx,
254281 const char **azArg,
254282 int nArg,
254283 Fts5Tokenizer **ppOut
254284 ){
254285 Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx;
254286 Fts5VtoVTokenizer *pNew = 0;
254287 int rc = SQLITE_OK;
254288
254289 pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
254290 if( rc==SQLITE_OK ){
254291 pNew->pMod = pMod;
254292 if( pMod->bV2Native ){
254293 rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254294 }else{
254295 rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254296 }
254297 if( rc!=SQLITE_OK ){
254298 sqlite3_free(pNew);
254299 pNew = 0;
254300 }
254301 }
254302
254303 *ppOut = (Fts5Tokenizer*)pNew;
254304 return rc;
254305 }
254306
254307 /*
254308 ** Delete an Fts5VtoVTokenizer wrapper tokenizer.
254309 */
254310 static void fts5VtoVDelete(Fts5Tokenizer *pTok){
254311 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254312 if( p ){
254313 Fts5TokenizerModule *pMod = p->pMod;
254314 if( pMod->bV2Native ){
254315 pMod->x2.xDelete(p->pReal);
254316 }else{
254317 pMod->x1.xDelete(p->pReal);
254318 }
254319 sqlite3_free(p);
254320 }
254321 }
254322
254323
254324 /*
254325 ** xTokenizer method for a wrapper tokenizer that offers the v1 interface
254326 ** (no support for locales).
254327 */
254328 static int fts5V1toV2Tokenize(
254329 Fts5Tokenizer *pTok,
254330 void *pCtx, int flags,
254331 const char *pText, int nText,
254332 int (*xToken)(void*, int, const char*, int, int, int)
254333 ){
254334 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254335 Fts5TokenizerModule *pMod = p->pMod;
254336 assert( pMod->bV2Native );
254337 return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
254338 }
254339
254340 /*
254341 ** xTokenizer method for a wrapper tokenizer that offers the v2 interface
254342 ** (with locale support).
254343 */
254344 static int fts5V2toV1Tokenize(
254345 Fts5Tokenizer *pTok,
254346 void *pCtx, int flags,
254347 const char *pText, int nText,
254348 const char *pLocale, int nLocale,
254349 int (*xToken)(void*, int, const char*, int, int, int)
254350 ){
254351 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254352 Fts5TokenizerModule *pMod = p->pMod;
254353 assert( pMod->bV2Native==0 );
254354 return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254355 }
254356
254357 /*
254358 ** Register a new tokenizer. This is the implementation of the
254359 ** fts5_api.xCreateTokenizer_v2() method.
254360 */
254361 static int fts5CreateTokenizer_v2(
254362 fts5_api *pApi, /* Global context (one per db handle) */
254363 const char *zName, /* Name of new function */
254364 void *pUserData, /* User data for aux. function */
254365 fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */
254366 void(*xDestroy)(void*) /* Destructor for pUserData */
254367 ){
254368 Fts5Global *pGlobal = (Fts5Global*)pApi;
254369 int rc = SQLITE_OK;
254370
254371 if( pTokenizer->iVersion>2 ){
254372 rc = SQLITE_ERROR;
254373 }else{
254374 Fts5TokenizerModule *pNew = 0;
254375 rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew);
254376 if( pNew ){
254377 pNew->x2 = *pTokenizer;
254378 pNew->bV2Native = 1;
254379 pNew->x1.xCreate = fts5VtoVCreate;
254380 pNew->x1.xTokenize = fts5V1toV2Tokenize;
254381 pNew->x1.xDelete = fts5VtoVDelete;
254382 }
254383 }
254384
254385 return rc;
254386 }
254387
254388 /*
254389 ** The fts5_api.xCreateTokenizer() method.
254390 */
254391 static int fts5CreateTokenizer(
254392 fts5_api *pApi, /* Global context (one per db handle) */
254393 const char *zName, /* Name of new function */
254394 void *pUserData, /* User data for aux. function */
254395 fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
254396 void(*xDestroy)(void*) /* Destructor for pUserData */
254397 ){
254398 Fts5TokenizerModule *pNew = 0;
 
 
 
254399 int rc = SQLITE_OK;
254400
254401 rc = fts5NewTokenizerModule(
254402 (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew
254403 );
254404 if( pNew ){
254405 pNew->x1 = *pTokenizer;
254406 pNew->x2.xCreate = fts5VtoVCreate;
254407 pNew->x2.xTokenize = fts5V2toV1Tokenize;
254408 pNew->x2.xDelete = fts5VtoVDelete;
254409 }
 
 
 
 
 
 
 
 
 
 
254410 return rc;
254411 }
254412
254413 /*
254414 ** Search the global context passed as the first argument for a tokenizer
254415 ** module named zName. If found, return a pointer to the Fts5TokenizerModule
254416 ** object. Otherwise, return NULL.
254417 */
254418 static Fts5TokenizerModule *fts5LocateTokenizer(
254419 Fts5Global *pGlobal, /* Global (one per db handle) object */
254420 const char *zName /* Name of tokenizer module to find */
254421 ){
254422 Fts5TokenizerModule *pMod = 0;
254423
254424 if( zName==0 ){
254425 pMod = pGlobal->pDfltTok;
@@ -253116,10 +254429,40 @@
254429 }
254430 }
254431
254432 return pMod;
254433 }
254434
254435 /*
254436 ** Find a tokenizer. This is the implementation of the
254437 ** fts5_api.xFindTokenizer_v2() method.
254438 */
254439 static int fts5FindTokenizer_v2(
254440 fts5_api *pApi, /* Global context (one per db handle) */
254441 const char *zName, /* Name of tokenizer */
254442 void **ppUserData,
254443 fts5_tokenizer_v2 **ppTokenizer /* Populate this object */
254444 ){
254445 int rc = SQLITE_OK;
254446 Fts5TokenizerModule *pMod;
254447
254448 pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
254449 if( pMod ){
254450 if( pMod->bV2Native ){
254451 *ppUserData = pMod->pUserData;
254452 }else{
254453 *ppUserData = (void*)pMod;
254454 }
254455 *ppTokenizer = &pMod->x2;
254456 }else{
254457 *ppTokenizer = 0;
254458 *ppUserData = 0;
254459 rc = SQLITE_ERROR;
254460 }
254461
254462 return rc;
254463 }
254464
254465 /*
254466 ** Find a tokenizer. This is the implementation of the
254467 ** fts5_api.xFindTokenizer() method.
254468 */
@@ -253132,70 +254475,79 @@
254475 int rc = SQLITE_OK;
254476 Fts5TokenizerModule *pMod;
254477
254478 pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
254479 if( pMod ){
254480 if( pMod->bV2Native==0 ){
254481 *ppUserData = pMod->pUserData;
254482 }else{
254483 *ppUserData = (void*)pMod;
254484 }
254485 *pTokenizer = pMod->x1;
254486 }else{
254487 memset(pTokenizer, 0, sizeof(*pTokenizer));
254488 *ppUserData = 0;
254489 rc = SQLITE_ERROR;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254490 }
254491
254492 return rc;
254493 }
254494
254495 /*
254496 ** Attempt to instantiate the tokenizer.
254497 */
254498 static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
254499 const char **azArg = pConfig->t.azArg;
254500 const int nArg = pConfig->t.nArg;
254501 Fts5TokenizerModule *pMod = 0;
254502 int rc = SQLITE_OK;
254503
254504 pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]);
254505 if( pMod==0 ){
254506 assert( nArg>0 );
254507 rc = SQLITE_ERROR;
254508 sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]);
254509 }else{
254510 int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0;
254511 if( pMod->bV2Native ){
254512 xCreate = pMod->x2.xCreate;
254513 pConfig->t.pApi2 = &pMod->x2;
254514 }else{
254515 pConfig->t.pApi1 = &pMod->x1;
254516 xCreate = pMod->x1.xCreate;
254517 }
254518
254519 rc = xCreate(pMod->pUserData,
254520 (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
254521 );
254522
254523 if( rc!=SQLITE_OK ){
254524 if( rc!=SQLITE_NOMEM ){
254525 sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor");
254526 }
254527 }else if( pMod->bV2Native==0 ){
254528 pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
254529 pMod->x1.xCreate, pConfig->t.pTok
254530 );
254531 }
254532 }
254533
254534 if( rc!=SQLITE_OK ){
254535 pConfig->t.pApi1 = 0;
254536 pConfig->t.pApi2 = 0;
254537 pConfig->t.pTok = 0;
254538 }
254539
254540 return rc;
254541 }
254542
254543
254544 /*
254545 ** xDestroy callback passed to sqlite3_create_module(). This is invoked
254546 ** when the db handle is being closed. Free memory associated with
254547 ** tokenizers and aux functions registered with this db handle.
254548 */
254549 static void fts5ModuleDestroy(void *pCtx){
254550 Fts5TokenizerModule *pTok, *pNextTok;
254551 Fts5Auxiliary *pAux, *pNextAux;
254552 Fts5Global *pGlobal = (Fts5Global*)pCtx;
254553
@@ -253212,10 +254564,14 @@
254564 }
254565
254566 sqlite3_free(pGlobal);
254567 }
254568
254569 /*
254570 ** Implementation of the fts5() function used by clients to obtain the
254571 ** API pointer.
254572 */
254573 static void fts5Fts5Func(
254574 sqlite3_context *pCtx, /* Function call context */
254575 int nArg, /* Number of args */
254576 sqlite3_value **apArg /* Function arguments */
254577 ){
@@ -253235,11 +254591,74 @@
254591 int nArg, /* Number of args */
254592 sqlite3_value **apUnused /* Function arguments */
254593 ){
254594 assert( nArg==0 );
254595 UNUSED_PARAM2(nArg, apUnused);
254596 sqlite3_result_text(pCtx, "fts5: 2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b31f96", -1, SQLITE_TRANSIENT);
254597 }
254598
254599 /*
254600 ** Implementation of fts5_locale(LOCALE, TEXT) function.
254601 **
254602 ** If parameter LOCALE is NULL, or a zero-length string, then a copy of
254603 ** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
254604 ** text, and the value returned is a blob consisting of:
254605 **
254606 ** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER).
254607 ** * The LOCALE, as utf-8 text, followed by
254608 ** * 0x00, followed by
254609 ** * The TEXT, as utf-8 text.
254610 **
254611 ** There is no final nul-terminator following the TEXT value.
254612 */
254613 static void fts5LocaleFunc(
254614 sqlite3_context *pCtx, /* Function call context */
254615 int nArg, /* Number of args */
254616 sqlite3_value **apArg /* Function arguments */
254617 ){
254618 const char *zLocale = 0;
254619 int nLocale = 0;
254620 const char *zText = 0;
254621 int nText = 0;
254622
254623 assert( nArg==2 );
254624 UNUSED_PARAM(nArg);
254625
254626 zLocale = (const char*)sqlite3_value_text(apArg[0]);
254627 nLocale = sqlite3_value_bytes(apArg[0]);
254628
254629 zText = (const char*)sqlite3_value_text(apArg[1]);
254630 nText = sqlite3_value_bytes(apArg[1]);
254631
254632 if( zLocale==0 || zLocale[0]=='\0' ){
254633 sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
254634 }else{
254635 u8 *pBlob = 0;
254636 u8 *pCsr = 0;
254637 int nBlob = 0;
254638 const int nHdr = 4;
254639 assert( sizeof(FTS5_LOCALE_HEADER)==nHdr+1 );
254640
254641 nBlob = nHdr + nLocale + 1 + nText;
254642 pBlob = (u8*)sqlite3_malloc(nBlob);
254643 if( pBlob==0 ){
254644 sqlite3_result_error_nomem(pCtx);
254645 return;
254646 }
254647
254648 pCsr = pBlob;
254649 memcpy(pCsr, FTS5_LOCALE_HEADER, nHdr);
254650 pCsr += nHdr;
254651 memcpy(pCsr, zLocale, nLocale);
254652 pCsr += nLocale;
254653 (*pCsr++) = 0x00;
254654 if( zText ) memcpy(pCsr, zText, nText);
254655 assert( &pCsr[nText]==&pBlob[nBlob] );
254656
254657 sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
254658 sqlite3_result_subtype(pCtx, FTS5_LOCALE_SUBTYPE);
254659 }
254660 }
254661
254662 /*
254663 ** Return true if zName is the extension on one of the shadow tables used
254664 ** by this module.
@@ -253330,14 +254749,16 @@
254749 rc = SQLITE_NOMEM;
254750 }else{
254751 void *p = (void*)pGlobal;
254752 memset(pGlobal, 0, sizeof(Fts5Global));
254753 pGlobal->db = db;
254754 pGlobal->api.iVersion = 3;
254755 pGlobal->api.xCreateFunction = fts5CreateAux;
254756 pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
254757 pGlobal->api.xFindTokenizer = fts5FindTokenizer;
254758 pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
254759 pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
254760 rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
254761 if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
254762 if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
254763 if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
254764 if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -253351,10 +254772,17 @@
254772 rc = sqlite3_create_function(
254773 db, "fts5_source_id", 0,
254774 SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
254775 p, fts5SourceIdFunc, 0, 0
254776 );
254777 }
254778 if( rc==SQLITE_OK ){
254779 rc = sqlite3_create_function(
254780 db, "fts5_locale", 2,
254781 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
254782 p, fts5LocaleFunc, 0, 0
254783 );
254784 }
254785 }
254786
254787 /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
254788 ** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -253426,17 +254854,44 @@
254854
254855
254856
254857 /* #include "fts5Int.h" */
254858
254859 /*
254860 ** pSavedRow:
254861 ** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it
254862 ** does a by-rowid lookup to retrieve a single row from the %_content
254863 ** table or equivalent external-content table/view.
254864 **
254865 ** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original
254866 ** values for a row being UPDATEd. In that case, the SQL statement is
254867 ** not reset and pSavedRow is set to point at it. This is so that the
254868 ** insert operation that follows the delete may access the original
254869 ** row values for any new values for which sqlite3_value_nochange() returns
254870 ** true. i.e. if the user executes:
254871 **
254872 ** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1);
254873 ** ...
254874 ** UPDATE fts SET a=?, b=? WHERE rowid=?;
254875 **
254876 ** then the value passed to the xUpdate() method of this table as the
254877 ** new.c value is an sqlite3_value_nochange() value. So in this case it
254878 ** must be read from the saved row stored in Fts5Storage.pSavedRow.
254879 **
254880 ** This is necessary - using sqlite3_value_nochange() instead of just having
254881 ** SQLite pass the original value back via xUpdate() - so as not to discard
254882 ** any locale information associated with such values.
254883 **
254884 */
254885 struct Fts5Storage {
254886 Fts5Config *pConfig;
254887 Fts5Index *pIndex;
254888 int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
254889 i64 nTotalRow; /* Total number of rows in FTS table */
254890 i64 *aTotalSize; /* Total sizes of each column */
254891 sqlite3_stmt *pSavedRow;
254892 sqlite3_stmt *aStmt[12];
254893 };
254894
254895
254896 #if FTS5_STMT_SCAN_ASC!=0
254897 # error "FTS5_STMT_SCAN_ASC mismatch"
@@ -253446,18 +254901,19 @@
254901 #endif
254902 #if FTS5_STMT_LOOKUP!=2
254903 # error "FTS5_STMT_LOOKUP mismatch"
254904 #endif
254905
254906 #define FTS5_STMT_LOOKUP2 3
254907 #define FTS5_STMT_INSERT_CONTENT 4
254908 #define FTS5_STMT_REPLACE_CONTENT 5
254909 #define FTS5_STMT_DELETE_CONTENT 6
254910 #define FTS5_STMT_REPLACE_DOCSIZE 7
254911 #define FTS5_STMT_DELETE_DOCSIZE 8
254912 #define FTS5_STMT_LOOKUP_DOCSIZE 9
254913 #define FTS5_STMT_REPLACE_CONFIG 10
254914 #define FTS5_STMT_SCAN 11
254915
254916 /*
254917 ** Prepare the two insert statements - Fts5Storage.pInsertContent and
254918 ** Fts5Storage.pInsertDocsize - if they have not already been prepared.
254919 ** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -253483,10 +254939,11 @@
254939 if( p->aStmt[eStmt]==0 ){
254940 const char *azStmt[] = {
254941 "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
254942 "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
254943 "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
254944 "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */
254945
254946 "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
254947 "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
254948 "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
254949 "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */
@@ -253497,10 +254954,12 @@
254954 "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
254955 "SELECT %s FROM %s AS T", /* SCAN */
254956 };
254957 Fts5Config *pC = p->pConfig;
254958 char *zSql = 0;
254959
254960 assert( ArraySize(azStmt)==ArraySize(p->aStmt) );
254961
254962 switch( eStmt ){
254963 case FTS5_STMT_SCAN:
254964 zSql = sqlite3_mprintf(azStmt[eStmt],
254965 pC->zContentExprlist, pC->zContent
@@ -253514,10 +254973,11 @@
254973 pC->zContentRowid
254974 );
254975 break;
254976
254977 case FTS5_STMT_LOOKUP:
254978 case FTS5_STMT_LOOKUP2:
254979 zSql = sqlite3_mprintf(azStmt[eStmt],
254980 pC->zContentExprlist, pC->zContent, pC->zContentRowid
254981 );
254982 break;
254983
@@ -253560,11 +255020,11 @@
255020
255021 if( zSql==0 ){
255022 rc = SQLITE_NOMEM;
255023 }else{
255024 int f = SQLITE_PREPARE_PERSISTENT;
255025 if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB;
255026 p->pConfig->bLock++;
255027 rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
255028 p->pConfig->bLock--;
255029 sqlite3_free(zSql);
255030 if( rc!=SQLITE_OK && pzErrMsg ){
@@ -253808,74 +255268,141 @@
255268 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
255269 pCtx->szCol++;
255270 }
255271 return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
255272 }
255273
255274 /*
255275 ** This function is used as part of an UPDATE statement that modifies the
255276 ** rowid of a row. In that case, this function is called first to set
255277 ** Fts5Storage.pSavedRow to point to a statement that may be used to
255278 ** access the original values of the row being deleted - iDel.
255279 **
255280 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
255281 ** It is not considered an error if row iDel does not exist. In this case
255282 ** pSavedRow is not set and SQLITE_OK returned.
255283 */
255284 static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){
255285 int rc = SQLITE_OK;
255286 sqlite3_stmt *pSeek = 0;
255287
255288 assert( p->pSavedRow==0 );
255289 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0);
255290 if( rc==SQLITE_OK ){
255291 sqlite3_bind_int64(pSeek, 1, iDel);
255292 if( sqlite3_step(pSeek)!=SQLITE_ROW ){
255293 rc = sqlite3_reset(pSeek);
255294 }else{
255295 p->pSavedRow = pSeek;
255296 }
255297 }
255298
255299 return rc;
255300 }
255301
255302 /*
255303 ** If a row with rowid iDel is present in the %_content table, add the
255304 ** delete-markers to the FTS index necessary to delete it. Do not actually
255305 ** remove the %_content row at this time though.
255306 **
255307 ** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left
255308 ** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access
255309 ** the original values of the row being deleted. This is used by UPDATE
255310 ** statements.
255311 */
255312 static int fts5StorageDeleteFromIndex(
255313 Fts5Storage *p,
255314 i64 iDel,
255315 sqlite3_value **apVal,
255316 int bSaveRow /* True to set pSavedRow */
255317 ){
255318 Fts5Config *pConfig = p->pConfig;
255319 sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
255320 int rc = SQLITE_OK; /* Return code */
255321 int rc2; /* sqlite3_reset() return code */
255322 int iCol;
255323 Fts5InsertCtx ctx;
255324
255325 assert( bSaveRow==0 || apVal==0 );
255326 assert( bSaveRow==0 || bSaveRow==1 );
255327 assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 );
255328
255329 if( apVal==0 ){
255330 if( p->pSavedRow && bSaveRow ){
255331 pSeek = p->pSavedRow;
255332 p->pSavedRow = 0;
255333 }else{
255334 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0);
255335 if( rc!=SQLITE_OK ) return rc;
255336 sqlite3_bind_int64(pSeek, 1, iDel);
255337 if( sqlite3_step(pSeek)!=SQLITE_ROW ){
255338 return sqlite3_reset(pSeek);
255339 }
255340 }
255341 }
255342
255343 ctx.pStorage = p;
255344 ctx.iCol = -1;
255345 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
255346 if( pConfig->abUnindexed[iCol-1]==0 ){
255347 sqlite3_value *pVal = 0;
255348 const char *pText = 0;
255349 int nText = 0;
255350 int bReset = 0;
255351
255352 assert( pSeek==0 || apVal==0 );
255353 assert( pSeek!=0 || apVal!=0 );
255354 if( pSeek ){
255355 pVal = sqlite3_column_value(pSeek, iCol);
 
 
 
 
255356 }else{
255357 pVal = apVal[iCol-1];
255358 }
255359
255360 rc = sqlite3Fts5ExtractText(
255361 pConfig, pVal, pSeek!=0, &bReset, &pText, &nText
255362 );
255363 if( rc==SQLITE_OK ){
255364 ctx.szCol = 0;
255365 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
255366 pText, nText, (void*)&ctx, fts5StorageInsertCallback
255367 );
255368 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
255369 if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
255370 rc = FTS5_CORRUPT;
255371 }
255372 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255373 }
255374 }
255375 }
255376 if( rc==SQLITE_OK && p->nTotalRow<1 ){
255377 rc = FTS5_CORRUPT;
255378 }else{
255379 p->nTotalRow--;
255380 }
255381
255382 if( rc==SQLITE_OK && bSaveRow ){
255383 assert( p->pSavedRow==0 );
255384 p->pSavedRow = pSeek;
255385 }else{
255386 rc2 = sqlite3_reset(pSeek);
255387 if( rc==SQLITE_OK ) rc = rc2;
255388 }
255389 return rc;
255390 }
255391
255392 /*
255393 ** Reset any saved statement pSavedRow. Zero pSavedRow as well. This
255394 ** should be called by the xUpdate() method of the fts5 table before
255395 ** returning from any operation that may have set Fts5Storage.pSavedRow.
255396 */
255397 static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){
255398 assert( pStorage->pSavedRow==0
255399 || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2]
255400 );
255401 sqlite3_reset(pStorage->pSavedRow);
255402 pStorage->pSavedRow = 0;
255403 }
255404
255405 /*
255406 ** This function is called to process a DELETE on a contentless_delete=1
255407 ** table. It adds the tombstone required to delete the entry with rowid
255408 ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs,
@@ -253929,16 +255456,16 @@
255456 if( p->pConfig->bContentlessDelete ){
255457 i64 iOrigin = 0;
255458 rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
255459 sqlite3_bind_int64(pReplace, 3, iOrigin);
255460 }
255461 }
255462 if( rc==SQLITE_OK ){
255463 sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
255464 sqlite3_step(pReplace);
255465 rc = sqlite3_reset(pReplace);
255466 sqlite3_bind_null(pReplace, 2);
255467 }
255468 }
255469 return rc;
255470 }
255471
@@ -253988,11 +255515,16 @@
255515 }
255516
255517 /*
255518 ** Remove a row from the FTS table.
255519 */
255520 static int sqlite3Fts5StorageDelete(
255521 Fts5Storage *p, /* Storage object */
255522 i64 iDel, /* Rowid to delete from table */
255523 sqlite3_value **apVal, /* Optional - values to remove from index */
255524 int bSaveRow /* If true, set pSavedRow for deleted row */
255525 ){
255526 Fts5Config *pConfig = p->pConfig;
255527 int rc;
255528 sqlite3_stmt *pDel = 0;
255529
255530 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
@@ -254005,11 +255537,11 @@
255537
255538 if( rc==SQLITE_OK ){
255539 if( p->pConfig->bContentlessDelete ){
255540 rc = fts5StorageContentlessDelete(p, iDel);
255541 }else{
255542 rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow);
255543 }
255544 }
255545
255546 /* Delete the %_docsize record */
255547 if( rc==SQLITE_OK && pConfig->bColumnsize ){
@@ -254094,18 +255626,25 @@
255626 sqlite3Fts5BufferZero(&buf);
255627 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255628 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255629 ctx.szCol = 0;
255630 if( pConfig->abUnindexed[ctx.iCol]==0 ){
255631 int bReset = 0; /* True if tokenizer locale must be reset */
255632 int nText = 0; /* Size of pText in bytes */
255633 const char *pText = 0; /* Pointer to buffer containing text value */
255634 sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
255635
255636 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &pText, &nText);
255637 if( rc==SQLITE_OK ){
255638 rc = sqlite3Fts5Tokenize(pConfig,
255639 FTS5_TOKENIZE_DOCUMENT,
255640 pText, nText,
255641 (void*)&ctx,
255642 fts5StorageInsertCallback
255643 );
255644 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255645 }
255646 }
255647 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255648 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255649 }
255650 p->nTotalRow++;
@@ -254185,11 +255724,35 @@
255724 }else{
255725 sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
255726 int i; /* Counter variable */
255727 rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
255728 for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
255729 sqlite3_value *pVal = apVal[i];
255730 if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
255731 /* This is an UPDATE statement, and column (i-2) was not modified.
255732 ** Retrieve the value from Fts5Storage.pSavedRow instead. */
255733 pVal = sqlite3_column_value(p->pSavedRow, i-1);
255734 }else if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE ){
255735 assert( pConfig->bLocale );
255736 assert( i>1 );
255737 if( pConfig->abUnindexed[i-2] ){
255738 /* At attempt to insert an fts5_locale() value into an UNINDEXED
255739 ** column. Strip the locale away and just bind the text. */
255740 const char *pText = 0;
255741 int nText = 0;
255742 rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
255743 sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
255744 }else{
255745 const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
255746 int nBlob = sqlite3_value_bytes(pVal);
255747 assert( nBlob>4 );
255748 sqlite3_bind_blob(pInsert, i, pBlob+4, nBlob-4, SQLITE_TRANSIENT);
255749 }
255750 continue;
255751 }
255752
255753 rc = sqlite3_bind_value(pInsert, i, pVal);
255754 }
255755 if( rc==SQLITE_OK ){
255756 sqlite3_step(pInsert);
255757 rc = sqlite3_reset(pInsert);
255758 }
@@ -254220,18 +255783,28 @@
255783 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255784 }
255785 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255786 ctx.szCol = 0;
255787 if( pConfig->abUnindexed[ctx.iCol]==0 ){
255788 int bReset = 0; /* True if tokenizer locale must be reset */
255789 int nText = 0; /* Size of pText in bytes */
255790 const char *pText = 0; /* Pointer to buffer containing text value */
255791 sqlite3_value *pVal = apVal[ctx.iCol+2];
255792 int bDisk = 0;
255793 if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
255794 pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
255795 bDisk = 1;
255796 }
255797 rc = sqlite3Fts5ExtractText(pConfig, pVal, bDisk, &bReset, &pText,&nText);
255798 if( rc==SQLITE_OK ){
255799 assert( bReset==0 || pConfig->bLocale );
255800 rc = sqlite3Fts5Tokenize(pConfig,
255801 FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
255802 fts5StorageInsertCallback
255803 );
255804 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255805 }
255806 }
255807 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255808 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255809 }
255810 p->nTotalRow++;
@@ -254398,18 +255971,26 @@
255971 ctx.szCol = 0;
255972 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
255973 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
255974 }
255975 if( rc==SQLITE_OK ){
255976 int bReset = 0; /* True if tokenizer locale must be reset */
255977 int nText = 0; /* Size of pText in bytes */
255978 const char *pText = 0; /* Pointer to buffer containing text value */
255979
255980 rc = sqlite3Fts5ExtractText(pConfig,
255981 sqlite3_column_value(pScan, i+1), 1, &bReset, &pText, &nText
 
255982 );
255983 if( rc==SQLITE_OK ){
255984 rc = sqlite3Fts5Tokenize(pConfig,
255985 FTS5_TOKENIZE_DOCUMENT,
255986 pText, nText,
255987 (void*)&ctx,
255988 fts5StorageIntegrityCallback
255989 );
255990 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255991 }
255992 }
255993 if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
255994 rc = FTS5_CORRUPT;
255995 }
255996 aTotalSize[i] += ctx.szCol;
@@ -254720,11 +256301,11 @@
256301 rc = SQLITE_NOMEM;
256302 }else{
256303 int i;
256304 memset(p, 0, sizeof(AsciiTokenizer));
256305 memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
256306 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
256307 const char *zArg = azArg[i+1];
256308 if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
256309 fts5AsciiAddExceptions(p, zArg, 1);
256310 }else
256311 if( 0==sqlite3_stricmp(azArg[i], "separators") ){
@@ -254731,11 +256312,10 @@
256312 fts5AsciiAddExceptions(p, zArg, 0);
256313 }else{
256314 rc = SQLITE_ERROR;
256315 }
256316 }
 
256317 if( rc!=SQLITE_OK ){
256318 fts5AsciiDelete((Fts5Tokenizer*)p);
256319 p = 0;
256320 }
256321 }
@@ -255023,20 +256603,20 @@
256603 if( p->aFold==0 ){
256604 rc = SQLITE_NOMEM;
256605 }
256606
256607 /* Search for a "categories" argument */
256608 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
256609 if( 0==sqlite3_stricmp(azArg[i], "categories") ){
256610 zCat = azArg[i+1];
256611 }
256612 }
256613 if( rc==SQLITE_OK ){
256614 rc = unicodeSetCategories(p, zCat);
256615 }
256616
256617 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
256618 const char *zArg = azArg[i+1];
256619 if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
256620 if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
256621 rc = SQLITE_ERROR;
256622 }else{
@@ -255057,12 +256637,10 @@
256637 /* no-op */
256638 }else{
256639 rc = SQLITE_ERROR;
256640 }
256641 }
 
 
256642 }else{
256643 rc = SQLITE_NOMEM;
256644 }
256645 if( rc!=SQLITE_OK ){
256646 fts5UnicodeDelete((Fts5Tokenizer*)p);
@@ -255197,11 +256775,11 @@
256775 ** stemming. */
256776 #define FTS5_PORTER_MAX_TOKEN 64
256777
256778 typedef struct PorterTokenizer PorterTokenizer;
256779 struct PorterTokenizer {
256780 fts5_tokenizer_v2 tokenizer_v2; /* Parent tokenizer module */
256781 Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
256782 char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
256783 };
256784
256785 /*
@@ -255209,11 +256787,11 @@
256787 */
256788 static void fts5PorterDelete(Fts5Tokenizer *pTok){
256789 if( pTok ){
256790 PorterTokenizer *p = (PorterTokenizer*)pTok;
256791 if( p->pTokenizer ){
256792 p->tokenizer_v2.xDelete(p->pTokenizer);
256793 }
256794 sqlite3_free(p);
256795 }
256796 }
256797
@@ -255228,26 +256806,28 @@
256806 fts5_api *pApi = (fts5_api*)pCtx;
256807 int rc = SQLITE_OK;
256808 PorterTokenizer *pRet;
256809 void *pUserdata = 0;
256810 const char *zBase = "unicode61";
256811 fts5_tokenizer_v2 *pV2 = 0;
256812
256813 if( nArg>0 ){
256814 zBase = azArg[0];
256815 }
256816
256817 pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
256818 if( pRet ){
256819 memset(pRet, 0, sizeof(PorterTokenizer));
256820 rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2);
256821 }else{
256822 rc = SQLITE_NOMEM;
256823 }
256824 if( rc==SQLITE_OK ){
256825 int nArg2 = (nArg>0 ? nArg-1 : 0);
256826 const char **az2 = (nArg2 ? &azArg[1] : 0);
256827 memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2));
256828 rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer);
256829 }
256830
256831 if( rc!=SQLITE_OK ){
256832 fts5PorterDelete((Fts5Tokenizer*)pRet);
256833 pRet = 0;
@@ -255894,19 +257474,20 @@
257474 static int fts5PorterTokenize(
257475 Fts5Tokenizer *pTokenizer,
257476 void *pCtx,
257477 int flags,
257478 const char *pText, int nText,
257479 const char *pLoc, int nLoc,
257480 int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
257481 ){
257482 PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
257483 PorterContext sCtx;
257484 sCtx.xToken = xToken;
257485 sCtx.pCtx = pCtx;
257486 sCtx.aBuf = p->aBuf;
257487 return p->tokenizer_v2.xTokenize(
257488 p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb
257489 );
257490 }
257491
257492 /**************************************************************************
257493 ** Start of trigram implementation.
@@ -255932,45 +257513,50 @@
257513 const char **azArg,
257514 int nArg,
257515 Fts5Tokenizer **ppOut
257516 ){
257517 int rc = SQLITE_OK;
257518 TrigramTokenizer *pNew = 0;
257519 UNUSED_PARAM(pUnused);
257520 if( nArg%2 ){
257521 rc = SQLITE_ERROR;
257522 }else{
257523 int i;
257524 pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
257525 if( pNew==0 ){
257526 rc = SQLITE_NOMEM;
257527 }else{
257528 pNew->bFold = 1;
257529 pNew->iFoldParam = 0;
257530
257531 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
257532 const char *zArg = azArg[i+1];
257533 if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
257534 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
257535 rc = SQLITE_ERROR;
257536 }else{
257537 pNew->bFold = (zArg[0]=='0');
257538 }
257539 }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
257540 if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
257541 rc = SQLITE_ERROR;
257542 }else{
257543 pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
257544 }
257545 }else{
257546 rc = SQLITE_ERROR;
257547 }
257548 }
257549
257550 if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
257551 rc = SQLITE_ERROR;
257552 }
257553
257554 if( rc!=SQLITE_OK ){
257555 fts5TriDelete((Fts5Tokenizer*)pNew);
257556 pNew = 0;
257557 }
257558 }
257559 }
257560 *ppOut = (Fts5Tokenizer*)pNew;
257561 return rc;
257562 }
@@ -256091,11 +257677,10 @@
257677 const char *zName;
257678 fts5_tokenizer x;
257679 } aBuiltin[] = {
257680 { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
257681 { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
 
257682 { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
257683 };
257684
257685 int rc = SQLITE_OK; /* Return code */
257686 int i; /* To iterate through builtin functions */
@@ -256106,11 +257691,24 @@
257691 (void*)pApi,
257692 &aBuiltin[i].x,
257693 0
257694 );
257695 }
257696 if( rc==SQLITE_OK ){
257697 fts5_tokenizer_v2 sPorter = {
257698 2,
257699 fts5PorterCreate,
257700 fts5PorterDelete,
257701 fts5PorterTokenize
257702 };
257703 rc = pApi->xCreateTokenizer_v2(pApi,
257704 "porter",
257705 (void*)pApi,
257706 &sPorter,
257707 0
257708 );
257709 }
257710 return rc;
257711 }
257712
257713 /*
257714 ** 2012-05-25
@@ -256476,10 +258074,13 @@
258074 aArray[29] = 1;
258075 break;
258076 default: return 1; }
258077 break;
258078
258079
258080 default:
258081 return 1;
258082 }
258083 return 0;
258084 }
258085
258086 static u16 aFts5UnicodeBlock[] = {
258087
+124 -9
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.47.0"
150150
#define SQLITE_VERSION_NUMBER 3047000
151
-#define SQLITE_SOURCE_ID "2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9"
151
+#define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -7425,13 +7425,15 @@
74257425
**
74267426
** ^The estimatedRows value is an estimate of the number of rows that
74277427
** will be returned by the strategy.
74287428
**
74297429
** The xBestIndex method may optionally populate the idxFlags field with a
7430
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
7431
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
7432
-** assumes that the strategy may visit at most one row.
7430
+** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
7431
+** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
7432
+** output to show the idxNum has hex instead of as decimal. Another flag is
7433
+** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
7434
+** return at most one row.
74337435
**
74347436
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
74357437
** SQLite also assumes that if a call to the xUpdate() method is made as
74367438
** part of the same statement to delete or update a virtual table row and the
74377439
** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7491,11 +7493,13 @@
74917493
**
74927494
** Virtual table implementations are allowed to set the
74937495
** [sqlite3_index_info].idxFlags field to some combination of
74947496
** these bits.
74957497
*/
7496
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
7498
+#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
7499
+#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
7500
+ /* in EXPLAIN QUERY PLAN */
74977501
74987502
/*
74997503
** CAPI3REF: Virtual Table Constraint Operator Codes
75007504
**
75017505
** These macros define the allowed values for the
@@ -8328,10 +8332,11 @@
83288332
#define SQLITE_TESTCTRL_ALWAYS 13
83298333
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
83308334
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
83318335
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
83328336
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8337
+#define SQLITE_TESTCTRL_GETOPT 16
83338338
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
83348339
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
83358340
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
83368341
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
83378342
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13102,13 +13107,36 @@
1310213107
** It is the output of the tokenizer module. For tokendata=1 tables, this
1310313108
** includes any embedded 0x00 and trailing data.
1310413109
**
1310513110
** This API can be quite slow if used with an FTS5 table created with the
1310613111
** "detail=none" or "detail=column" option.
13112
+**
13113
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13114
+** If parameter iCol is less than zero, or greater than or equal to the
13115
+** number of columns in the table, SQLITE_RANGE is returned.
13116
+**
13117
+** Otherwise, this function attempts to retrieve the locale associated
13118
+** with column iCol of the current row. Usually, there is no associated
13119
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
13120
+** to NULL and 0, respectively. However, if the fts5_locale() function
13121
+** was used to associate a locale with the value when it was inserted
13122
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
13123
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
13124
+** is set to the size in bytes of the buffer, not including the
13125
+** nul-terminator.
13126
+**
13127
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
13128
+** SQLite error code is returned. The final value of the output parameters
13129
+** is undefined in this case.
13130
+**
13131
+** xTokenize_v2:
13132
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
13133
+** API is the same as the xTokenize() API, except that it allows a tokenizer
13134
+** locale to be specified.
1310713135
*/
1310813136
struct Fts5ExtensionApi {
13109
- int iVersion; /* Currently always set to 3 */
13137
+ int iVersion; /* Currently always set to 4 */
1311013138
1311113139
void *(*xUserData)(Fts5Context*);
1311213140
1311313141
int (*xColumnCount)(Fts5Context*);
1311413142
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13146,10 +13174,19 @@
1314613174
int (*xQueryToken)(Fts5Context*,
1314713175
int iPhrase, int iToken,
1314813176
const char **ppToken, int *pnToken
1314913177
);
1315013178
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13179
+
13180
+ /* Below this point are iVersion>=4 only */
13181
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
13182
+ int (*xTokenize_v2)(Fts5Context*,
13183
+ const char *pText, int nText, /* Text to tokenize */
13184
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
13185
+ void *pCtx, /* Context passed to xToken() */
13186
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
13187
+ );
1315113188
};
1315213189
1315313190
/*
1315413191
** CUSTOM AUXILIARY FUNCTIONS
1315513192
*************************************************************************/
@@ -13158,19 +13195,20 @@
1315813195
** CUSTOM TOKENIZERS
1315913196
**
1316013197
** Applications may also register custom tokenizer types. A tokenizer
1316113198
** is registered by providing fts5 with a populated instance of the
1316213199
** following structure. All structure methods must be defined, setting
13200
+**
1316313201
** any member of the fts5_tokenizer struct to NULL leads to undefined
1316413202
** behaviour. The structure methods are expected to function as follows:
1316513203
**
1316613204
** xCreate:
1316713205
** This function is used to allocate and initialize a tokenizer instance.
1316813206
** A tokenizer instance is required to actually tokenize text.
1316913207
**
1317013208
** The first argument passed to this function is a copy of the (void*)
13171
-** pointer provided by the application when the fts5_tokenizer object
13209
+** pointer provided by the application when the fts5_tokenizer_v2 object
1317213210
** was registered with FTS5 (the third argument to xCreateTokenizer()).
1317313211
** The second and third arguments are an array of nul-terminated strings
1317413212
** containing the tokenizer arguments, if any, specified following the
1317513213
** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
1317613214
** to create the FTS5 table.
@@ -13190,11 +13228,11 @@
1319013228
** This function is expected to tokenize the nText byte string indicated
1319113229
** by argument pText. pText may or may not be nul-terminated. The first
1319213230
** argument passed to this function is a pointer to an Fts5Tokenizer object
1319313231
** returned by an earlier call to xCreate().
1319413232
**
13195
-** The second argument indicates the reason that FTS5 is requesting
13233
+** The third argument indicates the reason that FTS5 is requesting
1319613234
** tokenization of the supplied text. This is always one of the following
1319713235
** four values:
1319813236
**
1319913237
** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
1320013238
** or removed from the FTS table. The tokenizer is being invoked to
@@ -13213,10 +13251,17 @@
1321313251
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
1321413252
** satisfy an fts5_api.xTokenize() request made by an auxiliary
1321513253
** function. Or an fts5_api.xColumnSize() request made by the same
1321613254
** on a columnsize=0 database.
1321713255
** </ul>
13256
+**
13257
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
13258
+** nLocale - are a pointer to a buffer containing the locale to use for
13259
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
13260
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
13261
+** which case nLocale is always 0) to indicate that the tokenizer should
13262
+** use its default locale.
1321813263
**
1321913264
** For each token in the input string, the supplied callback xToken() must
1322013265
** be invoked. The first argument to it should be a copy of the pointer
1322113266
** passed as the second argument to xTokenize(). The third and fourth
1322213267
** arguments are a pointer to a buffer containing the token text, and the
@@ -13236,10 +13281,33 @@
1323613281
** immediately return a copy of the xToken() return value. Or, if the
1323713282
** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
1323813283
** if an error occurs with the xTokenize() implementation itself, it
1323913284
** may abandon the tokenization and return any error code other than
1324013285
** SQLITE_OK or SQLITE_DONE.
13286
+**
13287
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
13288
+** then the xTokenize() method has two additional arguments - pLocale
13289
+** and nLocale. These specify the locale that the tokenizer should use
13290
+** for the current request. If pLocale and nLocale are both 0, then the
13291
+** tokenizer should use its default locale. Otherwise, pLocale points to
13292
+** an nLocale byte buffer containing the name of the locale to use as utf-8
13293
+** text. pLocale is not nul-terminated.
13294
+**
13295
+** FTS5_TOKENIZER
13296
+**
13297
+** There is also an fts5_tokenizer object. This is an older version of
13298
+** fts5_tokenizer_v2. It is similar except that:
13299
+**
13300
+** <ul>
13301
+** <li> There is no "iVersion" field, and
13302
+** <li> The xTokenize() method does not take a locale argument.
13303
+** </ul>
13304
+**
13305
+** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13306
+** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13307
+** registered using either API may be retrieved using both xFindTokenizer()
13308
+** and xFindTokenizer_v2().
1324113309
**
1324213310
** SYNONYM SUPPORT
1324313311
**
1324413312
** Custom tokenizers may also support synonyms. Consider a case in which a
1324513313
** user wishes to query for a phrase such as "first place". Using the
@@ -13345,10 +13413,37 @@
1334513413
** provide synonyms when tokenizing document text (method (3)) or query
1334613414
** text (method (2)), not both. Doing so will not cause any errors, but is
1334713415
** inefficient.
1334813416
*/
1334913417
typedef struct Fts5Tokenizer Fts5Tokenizer;
13418
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
13419
+struct fts5_tokenizer_v2 {
13420
+ int iVersion; /* Currently always 2 */
13421
+
13422
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13423
+ void (*xDelete)(Fts5Tokenizer*);
13424
+ int (*xTokenize)(Fts5Tokenizer*,
13425
+ void *pCtx,
13426
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
13427
+ const char *pText, int nText,
13428
+ const char *pLocale, int nLocale,
13429
+ int (*xToken)(
13430
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
13431
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
13432
+ const char *pToken, /* Pointer to buffer containing token */
13433
+ int nToken, /* Size of token in bytes */
13434
+ int iStart, /* Byte offset of token within input text */
13435
+ int iEnd /* Byte offset of end of token within input text */
13436
+ )
13437
+ );
13438
+};
13439
+
13440
+/*
13441
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
13442
+** implementations. The following type is included for legacy applications
13443
+** that still use it.
13444
+*/
1335013445
typedef struct fts5_tokenizer fts5_tokenizer;
1335113446
struct fts5_tokenizer {
1335213447
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
1335313448
void (*xDelete)(Fts5Tokenizer*);
1335413449
int (*xTokenize)(Fts5Tokenizer*,
@@ -13363,10 +13458,11 @@
1336313458
int iStart, /* Byte offset of token within input text */
1336413459
int iEnd /* Byte offset of end of token within input text */
1336513460
)
1336613461
);
1336713462
};
13463
+
1336813464
1336913465
/* Flags that may be passed as the third argument to xTokenize() */
1337013466
#define FTS5_TOKENIZE_QUERY 0x0001
1337113467
#define FTS5_TOKENIZE_PREFIX 0x0002
1337213468
#define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13383,11 +13479,11 @@
1338313479
/*************************************************************************
1338413480
** FTS5 EXTENSION REGISTRATION API
1338513481
*/
1338613482
typedef struct fts5_api fts5_api;
1338713483
struct fts5_api {
13388
- int iVersion; /* Currently always set to 2 */
13484
+ int iVersion; /* Currently always set to 3 */
1338913485
1339013486
/* Create a new tokenizer */
1339113487
int (*xCreateTokenizer)(
1339213488
fts5_api *pApi,
1339313489
const char *zName,
@@ -13410,10 +13506,29 @@
1341013506
const char *zName,
1341113507
void *pUserData,
1341213508
fts5_extension_function xFunction,
1341313509
void (*xDestroy)(void*)
1341413510
);
13511
+
13512
+ /* APIs below this point are only available if iVersion>=3 */
13513
+
13514
+ /* Create a new tokenizer */
13515
+ int (*xCreateTokenizer_v2)(
13516
+ fts5_api *pApi,
13517
+ const char *zName,
13518
+ void *pUserData,
13519
+ fts5_tokenizer_v2 *pTokenizer,
13520
+ void (*xDestroy)(void*)
13521
+ );
13522
+
13523
+ /* Find an existing tokenizer */
13524
+ int (*xFindTokenizer_v2)(
13525
+ fts5_api *pApi,
13526
+ const char *zName,
13527
+ void **ppUserData,
13528
+ fts5_tokenizer_v2 **ppTokenizer
13529
+ );
1341513530
};
1341613531
1341713532
/*
1341813533
** END OF REGISTRATION API
1341913534
*************************************************************************/
1342013535
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -7425,13 +7425,15 @@
7425 **
7426 ** ^The estimatedRows value is an estimate of the number of rows that
7427 ** will be returned by the strategy.
7428 **
7429 ** The xBestIndex method may optionally populate the idxFlags field with a
7430 ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
7431 ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
7432 ** assumes that the strategy may visit at most one row.
 
 
7433 **
7434 ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
7435 ** SQLite also assumes that if a call to the xUpdate() method is made as
7436 ** part of the same statement to delete or update a virtual table row and the
7437 ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7491,11 +7493,13 @@
7491 **
7492 ** Virtual table implementations are allowed to set the
7493 ** [sqlite3_index_info].idxFlags field to some combination of
7494 ** these bits.
7495 */
7496 #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
 
 
7497
7498 /*
7499 ** CAPI3REF: Virtual Table Constraint Operator Codes
7500 **
7501 ** These macros define the allowed values for the
@@ -8328,10 +8332,11 @@
8328 #define SQLITE_TESTCTRL_ALWAYS 13
8329 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8330 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8331 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8332 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
 
8333 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8334 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8335 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8336 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8337 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13102,13 +13107,36 @@
13102 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13103 ** includes any embedded 0x00 and trailing data.
13104 **
13105 ** This API can be quite slow if used with an FTS5 table created with the
13106 ** "detail=none" or "detail=column" option.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13107 */
13108 struct Fts5ExtensionApi {
13109 int iVersion; /* Currently always set to 3 */
13110
13111 void *(*xUserData)(Fts5Context*);
13112
13113 int (*xColumnCount)(Fts5Context*);
13114 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13146,10 +13174,19 @@
13146 int (*xQueryToken)(Fts5Context*,
13147 int iPhrase, int iToken,
13148 const char **ppToken, int *pnToken
13149 );
13150 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
 
 
 
 
 
 
 
 
 
13151 };
13152
13153 /*
13154 ** CUSTOM AUXILIARY FUNCTIONS
13155 *************************************************************************/
@@ -13158,19 +13195,20 @@
13158 ** CUSTOM TOKENIZERS
13159 **
13160 ** Applications may also register custom tokenizer types. A tokenizer
13161 ** is registered by providing fts5 with a populated instance of the
13162 ** following structure. All structure methods must be defined, setting
 
13163 ** any member of the fts5_tokenizer struct to NULL leads to undefined
13164 ** behaviour. The structure methods are expected to function as follows:
13165 **
13166 ** xCreate:
13167 ** This function is used to allocate and initialize a tokenizer instance.
13168 ** A tokenizer instance is required to actually tokenize text.
13169 **
13170 ** The first argument passed to this function is a copy of the (void*)
13171 ** pointer provided by the application when the fts5_tokenizer object
13172 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
13173 ** The second and third arguments are an array of nul-terminated strings
13174 ** containing the tokenizer arguments, if any, specified following the
13175 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
13176 ** to create the FTS5 table.
@@ -13190,11 +13228,11 @@
13190 ** This function is expected to tokenize the nText byte string indicated
13191 ** by argument pText. pText may or may not be nul-terminated. The first
13192 ** argument passed to this function is a pointer to an Fts5Tokenizer object
13193 ** returned by an earlier call to xCreate().
13194 **
13195 ** The second argument indicates the reason that FTS5 is requesting
13196 ** tokenization of the supplied text. This is always one of the following
13197 ** four values:
13198 **
13199 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
13200 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -13213,10 +13251,17 @@
13213 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
13214 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
13215 ** function. Or an fts5_api.xColumnSize() request made by the same
13216 ** on a columnsize=0 database.
13217 ** </ul>
 
 
 
 
 
 
 
13218 **
13219 ** For each token in the input string, the supplied callback xToken() must
13220 ** be invoked. The first argument to it should be a copy of the pointer
13221 ** passed as the second argument to xTokenize(). The third and fourth
13222 ** arguments are a pointer to a buffer containing the token text, and the
@@ -13236,10 +13281,33 @@
13236 ** immediately return a copy of the xToken() return value. Or, if the
13237 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
13238 ** if an error occurs with the xTokenize() implementation itself, it
13239 ** may abandon the tokenization and return any error code other than
13240 ** SQLITE_OK or SQLITE_DONE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13241 **
13242 ** SYNONYM SUPPORT
13243 **
13244 ** Custom tokenizers may also support synonyms. Consider a case in which a
13245 ** user wishes to query for a phrase such as "first place". Using the
@@ -13345,10 +13413,37 @@
13345 ** provide synonyms when tokenizing document text (method (3)) or query
13346 ** text (method (2)), not both. Doing so will not cause any errors, but is
13347 ** inefficient.
13348 */
13349 typedef struct Fts5Tokenizer Fts5Tokenizer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13350 typedef struct fts5_tokenizer fts5_tokenizer;
13351 struct fts5_tokenizer {
13352 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13353 void (*xDelete)(Fts5Tokenizer*);
13354 int (*xTokenize)(Fts5Tokenizer*,
@@ -13363,10 +13458,11 @@
13363 int iStart, /* Byte offset of token within input text */
13364 int iEnd /* Byte offset of end of token within input text */
13365 )
13366 );
13367 };
 
13368
13369 /* Flags that may be passed as the third argument to xTokenize() */
13370 #define FTS5_TOKENIZE_QUERY 0x0001
13371 #define FTS5_TOKENIZE_PREFIX 0x0002
13372 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13383,11 +13479,11 @@
13383 /*************************************************************************
13384 ** FTS5 EXTENSION REGISTRATION API
13385 */
13386 typedef struct fts5_api fts5_api;
13387 struct fts5_api {
13388 int iVersion; /* Currently always set to 2 */
13389
13390 /* Create a new tokenizer */
13391 int (*xCreateTokenizer)(
13392 fts5_api *pApi,
13393 const char *zName,
@@ -13410,10 +13506,29 @@
13410 const char *zName,
13411 void *pUserData,
13412 fts5_extension_function xFunction,
13413 void (*xDestroy)(void*)
13414 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13415 };
13416
13417 /*
13418 ** END OF REGISTRATION API
13419 *************************************************************************/
13420
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -7425,13 +7425,15 @@
7425 **
7426 ** ^The estimatedRows value is an estimate of the number of rows that
7427 ** will be returned by the strategy.
7428 **
7429 ** The xBestIndex method may optionally populate the idxFlags field with a
7430 ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
7431 ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
7432 ** output to show the idxNum has hex instead of as decimal. Another flag is
7433 ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
7434 ** return at most one row.
7435 **
7436 ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
7437 ** SQLite also assumes that if a call to the xUpdate() method is made as
7438 ** part of the same statement to delete or update a virtual table row and the
7439 ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
@@ -7491,11 +7493,13 @@
7493 **
7494 ** Virtual table implementations are allowed to set the
7495 ** [sqlite3_index_info].idxFlags field to some combination of
7496 ** these bits.
7497 */
7498 #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
7499 #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
7500 /* in EXPLAIN QUERY PLAN */
7501
7502 /*
7503 ** CAPI3REF: Virtual Table Constraint Operator Codes
7504 **
7505 ** These macros define the allowed values for the
@@ -8328,10 +8332,11 @@
8332 #define SQLITE_TESTCTRL_ALWAYS 13
8333 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8334 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8335 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8336 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8337 #define SQLITE_TESTCTRL_GETOPT 16
8338 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8339 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8340 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8341 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8342 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -13102,13 +13107,36 @@
13107 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13108 ** includes any embedded 0x00 and trailing data.
13109 **
13110 ** This API can be quite slow if used with an FTS5 table created with the
13111 ** "detail=none" or "detail=column" option.
13112 **
13113 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13114 ** If parameter iCol is less than zero, or greater than or equal to the
13115 ** number of columns in the table, SQLITE_RANGE is returned.
13116 **
13117 ** Otherwise, this function attempts to retrieve the locale associated
13118 ** with column iCol of the current row. Usually, there is no associated
13119 ** locale, and output parameters (*pzLocale) and (*pnLocale) are set
13120 ** to NULL and 0, respectively. However, if the fts5_locale() function
13121 ** was used to associate a locale with the value when it was inserted
13122 ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
13123 ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
13124 ** is set to the size in bytes of the buffer, not including the
13125 ** nul-terminator.
13126 **
13127 ** If successful, SQLITE_OK is returned. Or, if an error occurs, an
13128 ** SQLite error code is returned. The final value of the output parameters
13129 ** is undefined in this case.
13130 **
13131 ** xTokenize_v2:
13132 ** Tokenize text using the tokenizer belonging to the FTS5 table. This
13133 ** API is the same as the xTokenize() API, except that it allows a tokenizer
13134 ** locale to be specified.
13135 */
13136 struct Fts5ExtensionApi {
13137 int iVersion; /* Currently always set to 4 */
13138
13139 void *(*xUserData)(Fts5Context*);
13140
13141 int (*xColumnCount)(Fts5Context*);
13142 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13146,10 +13174,19 @@
13174 int (*xQueryToken)(Fts5Context*,
13175 int iPhrase, int iToken,
13176 const char **ppToken, int *pnToken
13177 );
13178 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13179
13180 /* Below this point are iVersion>=4 only */
13181 int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
13182 int (*xTokenize_v2)(Fts5Context*,
13183 const char *pText, int nText, /* Text to tokenize */
13184 const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
13185 void *pCtx, /* Context passed to xToken() */
13186 int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
13187 );
13188 };
13189
13190 /*
13191 ** CUSTOM AUXILIARY FUNCTIONS
13192 *************************************************************************/
@@ -13158,19 +13195,20 @@
13195 ** CUSTOM TOKENIZERS
13196 **
13197 ** Applications may also register custom tokenizer types. A tokenizer
13198 ** is registered by providing fts5 with a populated instance of the
13199 ** following structure. All structure methods must be defined, setting
13200 **
13201 ** any member of the fts5_tokenizer struct to NULL leads to undefined
13202 ** behaviour. The structure methods are expected to function as follows:
13203 **
13204 ** xCreate:
13205 ** This function is used to allocate and initialize a tokenizer instance.
13206 ** A tokenizer instance is required to actually tokenize text.
13207 **
13208 ** The first argument passed to this function is a copy of the (void*)
13209 ** pointer provided by the application when the fts5_tokenizer_v2 object
13210 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
13211 ** The second and third arguments are an array of nul-terminated strings
13212 ** containing the tokenizer arguments, if any, specified following the
13213 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
13214 ** to create the FTS5 table.
@@ -13190,11 +13228,11 @@
13228 ** This function is expected to tokenize the nText byte string indicated
13229 ** by argument pText. pText may or may not be nul-terminated. The first
13230 ** argument passed to this function is a pointer to an Fts5Tokenizer object
13231 ** returned by an earlier call to xCreate().
13232 **
13233 ** The third argument indicates the reason that FTS5 is requesting
13234 ** tokenization of the supplied text. This is always one of the following
13235 ** four values:
13236 **
13237 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
13238 ** or removed from the FTS table. The tokenizer is being invoked to
@@ -13213,10 +13251,17 @@
13251 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
13252 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
13253 ** function. Or an fts5_api.xColumnSize() request made by the same
13254 ** on a columnsize=0 database.
13255 ** </ul>
13256 **
13257 ** The sixth and seventh arguments passed to xTokenize() - pLocale and
13258 ** nLocale - are a pointer to a buffer containing the locale to use for
13259 ** tokenization (e.g. "en_US") and its size in bytes, respectively. The
13260 ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
13261 ** which case nLocale is always 0) to indicate that the tokenizer should
13262 ** use its default locale.
13263 **
13264 ** For each token in the input string, the supplied callback xToken() must
13265 ** be invoked. The first argument to it should be a copy of the pointer
13266 ** passed as the second argument to xTokenize(). The third and fourth
13267 ** arguments are a pointer to a buffer containing the token text, and the
@@ -13236,10 +13281,33 @@
13281 ** immediately return a copy of the xToken() return value. Or, if the
13282 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
13283 ** if an error occurs with the xTokenize() implementation itself, it
13284 ** may abandon the tokenization and return any error code other than
13285 ** SQLITE_OK or SQLITE_DONE.
13286 **
13287 ** If the tokenizer is registered using an fts5_tokenizer_v2 object,
13288 ** then the xTokenize() method has two additional arguments - pLocale
13289 ** and nLocale. These specify the locale that the tokenizer should use
13290 ** for the current request. If pLocale and nLocale are both 0, then the
13291 ** tokenizer should use its default locale. Otherwise, pLocale points to
13292 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13293 ** text. pLocale is not nul-terminated.
13294 **
13295 ** FTS5_TOKENIZER
13296 **
13297 ** There is also an fts5_tokenizer object. This is an older version of
13298 ** fts5_tokenizer_v2. It is similar except that:
13299 **
13300 ** <ul>
13301 ** <li> There is no "iVersion" field, and
13302 ** <li> The xTokenize() method does not take a locale argument.
13303 ** </ul>
13304 **
13305 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13306 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13307 ** registered using either API may be retrieved using both xFindTokenizer()
13308 ** and xFindTokenizer_v2().
13309 **
13310 ** SYNONYM SUPPORT
13311 **
13312 ** Custom tokenizers may also support synonyms. Consider a case in which a
13313 ** user wishes to query for a phrase such as "first place". Using the
@@ -13345,10 +13413,37 @@
13413 ** provide synonyms when tokenizing document text (method (3)) or query
13414 ** text (method (2)), not both. Doing so will not cause any errors, but is
13415 ** inefficient.
13416 */
13417 typedef struct Fts5Tokenizer Fts5Tokenizer;
13418 typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
13419 struct fts5_tokenizer_v2 {
13420 int iVersion; /* Currently always 2 */
13421
13422 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13423 void (*xDelete)(Fts5Tokenizer*);
13424 int (*xTokenize)(Fts5Tokenizer*,
13425 void *pCtx,
13426 int flags, /* Mask of FTS5_TOKENIZE_* flags */
13427 const char *pText, int nText,
13428 const char *pLocale, int nLocale,
13429 int (*xToken)(
13430 void *pCtx, /* Copy of 2nd argument to xTokenize() */
13431 int tflags, /* Mask of FTS5_TOKEN_* flags */
13432 const char *pToken, /* Pointer to buffer containing token */
13433 int nToken, /* Size of token in bytes */
13434 int iStart, /* Byte offset of token within input text */
13435 int iEnd /* Byte offset of end of token within input text */
13436 )
13437 );
13438 };
13439
13440 /*
13441 ** New code should use the fts5_tokenizer_v2 type to define tokenizer
13442 ** implementations. The following type is included for legacy applications
13443 ** that still use it.
13444 */
13445 typedef struct fts5_tokenizer fts5_tokenizer;
13446 struct fts5_tokenizer {
13447 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
13448 void (*xDelete)(Fts5Tokenizer*);
13449 int (*xTokenize)(Fts5Tokenizer*,
@@ -13363,10 +13458,11 @@
13458 int iStart, /* Byte offset of token within input text */
13459 int iEnd /* Byte offset of end of token within input text */
13460 )
13461 );
13462 };
13463
13464
13465 /* Flags that may be passed as the third argument to xTokenize() */
13466 #define FTS5_TOKENIZE_QUERY 0x0001
13467 #define FTS5_TOKENIZE_PREFIX 0x0002
13468 #define FTS5_TOKENIZE_DOCUMENT 0x0004
@@ -13383,11 +13479,11 @@
13479 /*************************************************************************
13480 ** FTS5 EXTENSION REGISTRATION API
13481 */
13482 typedef struct fts5_api fts5_api;
13483 struct fts5_api {
13484 int iVersion; /* Currently always set to 3 */
13485
13486 /* Create a new tokenizer */
13487 int (*xCreateTokenizer)(
13488 fts5_api *pApi,
13489 const char *zName,
@@ -13410,10 +13506,29 @@
13506 const char *zName,
13507 void *pUserData,
13508 fts5_extension_function xFunction,
13509 void (*xDestroy)(void*)
13510 );
13511
13512 /* APIs below this point are only available if iVersion>=3 */
13513
13514 /* Create a new tokenizer */
13515 int (*xCreateTokenizer_v2)(
13516 fts5_api *pApi,
13517 const char *zName,
13518 void *pUserData,
13519 fts5_tokenizer_v2 *pTokenizer,
13520 void (*xDestroy)(void*)
13521 );
13522
13523 /* Find an existing tokenizer */
13524 int (*xFindTokenizer_v2)(
13525 fts5_api *pApi,
13526 const char *zName,
13527 void **ppUserData,
13528 fts5_tokenizer_v2 **ppTokenizer
13529 );
13530 };
13531
13532 /*
13533 ** END OF REGISTRATION API
13534 *************************************************************************/
13535

Keyboard Shortcuts

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