Fossil SCM

Change the built-in SQLite to the latest tip of the enhanced-stat1 branch. This is to facilitate testing of that branch in SQLite in a real-world app.

drh 2023-12-31 13:59 trunk
Commit 4c353662cfe0af45722e316829762156d69bb6b788d96e3e5d9993a09ee8c958
+1 -1
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -22170,11 +22170,10 @@
2217022170
sqlite3_open_v2(zDbFilename, &p->db,
2217122171
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
2217222172
break;
2217322173
}
2217422174
}
22175
- globalDb = p->db;
2217622175
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
2217722176
eputf("Error: unable to open database \"%s\": %s\n",
2217822177
zDbFilename, sqlite3_errmsg(p->db));
2217922178
if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
2218022179
exit(1);
@@ -22187,10 +22186,11 @@
2218722186
}else{
2218822187
eputf("Notice: using substitute in-memory database instead of \"%s\"\n",
2218922188
zDbFilename);
2219022189
}
2219122190
}
22191
+ globalDb = p->db;
2219222192
sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
2219322193
2219422194
/* Reflect the use or absence of --unsafe-testing invocation. */
2219522195
{
2219622196
int testmode_on = ShellHasFlag(p,SHFLG_TestingMode);
2219722197
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -22170,11 +22170,10 @@
22170 sqlite3_open_v2(zDbFilename, &p->db,
22171 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
22172 break;
22173 }
22174 }
22175 globalDb = p->db;
22176 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
22177 eputf("Error: unable to open database \"%s\": %s\n",
22178 zDbFilename, sqlite3_errmsg(p->db));
22179 if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
22180 exit(1);
@@ -22187,10 +22186,11 @@
22187 }else{
22188 eputf("Notice: using substitute in-memory database instead of \"%s\"\n",
22189 zDbFilename);
22190 }
22191 }
 
22192 sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
22193
22194 /* Reflect the use or absence of --unsafe-testing invocation. */
22195 {
22196 int testmode_on = ShellHasFlag(p,SHFLG_TestingMode);
22197
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -22170,11 +22170,10 @@
22170 sqlite3_open_v2(zDbFilename, &p->db,
22171 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
22172 break;
22173 }
22174 }
 
22175 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
22176 eputf("Error: unable to open database \"%s\": %s\n",
22177 zDbFilename, sqlite3_errmsg(p->db));
22178 if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
22179 exit(1);
@@ -22187,10 +22186,11 @@
22186 }else{
22187 eputf("Notice: using substitute in-memory database instead of \"%s\"\n",
22188 zDbFilename);
22189 }
22190 }
22191 globalDb = p->db;
22192 sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
22193
22194 /* Reflect the use or absence of --unsafe-testing invocation. */
22195 {
22196 int testmode_on = ShellHasFlag(p,SHFLG_TestingMode);
22197
+468 -216
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 27d4a89a5ff96b7b7fc5dc9650e1269f7c7e.
21
+** c216921b115169ebfd239267b4ab5ad0fc96.
2222
*/
2323
#define SQLITE_CORE 1
2424
#define SQLITE_AMALGAMATION 1
2525
#ifndef SQLITE_PRIVATE
2626
# define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459459
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460460
** [sqlite_version()] and [sqlite_source_id()].
461461
*/
462462
#define SQLITE_VERSION "3.45.0"
463463
#define SQLITE_VERSION_NUMBER 3045000
464
-#define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
464
+#define SQLITE_SOURCE_ID "2023-12-31 12:38:43 c216921b115169ebfd239267b4ab5ad0fc960ffadce09044b68812f49110d607"
465465
466466
/*
467467
** CAPI3REF: Run-Time Library Version Numbers
468468
** KEYWORDS: sqlite3_version sqlite3_sourceid
469469
**
@@ -8350,13 +8350,15 @@
83508350
** can enter.)^ If the same thread tries to enter any mutex other
83518351
** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
83528352
**
83538353
** ^(Some systems (for example, Windows 95) do not support the operation
83548354
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8355
-** will always return SQLITE_BUSY. The SQLite core only ever uses
8356
-** sqlite3_mutex_try() as an optimization so this is acceptable
8357
-** behavior.)^
8355
+** will always return SQLITE_BUSY. In most cases the SQLite core only uses
8356
+** sqlite3_mutex_try() as an optimization, so this is acceptable
8357
+** behavior. The exceptions are unix builds that set the
8358
+** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
8359
+** sqlite3_mutex_try() is required.)^
83588360
**
83598361
** ^The sqlite3_mutex_leave() routine exits a mutex that was
83608362
** previously entered by the same thread. The behavior
83618363
** is undefined if the mutex is not currently entered by the
83628364
** calling thread or is not currently allocated.
@@ -13125,23 +13127,28 @@
1312513127
**
1312613128
** This function may be quite inefficient if used with an FTS5 table
1312713129
** created with the "columnsize=0" option.
1312813130
**
1312913131
** xColumnText:
13130
-** This function attempts to retrieve the text of column iCol of the
13131
-** current document. If successful, (*pz) is set to point to a buffer
13132
+** If parameter iCol is less than zero, or greater than or equal to the
13133
+** number of columns in the table, SQLITE_RANGE is returned.
13134
+**
13135
+** Otherwise, this function attempts to retrieve the text of column iCol of
13136
+** the current document. If successful, (*pz) is set to point to a buffer
1313213137
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
1313313138
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
1313413139
** if an error occurs, an SQLite error code is returned and the final values
1313513140
** of (*pz) and (*pn) are undefined.
1313613141
**
1313713142
** xPhraseCount:
1313813143
** Returns the number of phrases in the current query expression.
1313913144
**
1314013145
** xPhraseSize:
13141
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
13142
-** are numbered starting from zero.
13146
+** If parameter iCol is less than zero, or greater than or equal to the
13147
+** number of phrases in the current query, as returned by xPhraseCount,
13148
+** 0 is returned. Otherwise, this function returns the number of tokens in
13149
+** phrase iPhrase of the query. Phrases are numbered starting from zero.
1314313150
**
1314413151
** xInstCount:
1314513152
** Set *pnInst to the total number of occurrences of all phrases within
1314613153
** the query within the current row. Return SQLITE_OK if successful, or
1314713154
** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -13153,16 +13160,17 @@
1315313160
**
1315413161
** xInst:
1315513162
** Query for the details of phrase match iIdx within the current row.
1315613163
** Phrase matches are numbered starting from zero, so the iIdx argument
1315713164
** should be greater than or equal to zero and smaller than the value
13158
-** output by xInstCount().
13165
+** output by xInstCount(). If iIdx is less than zero or greater than
13166
+** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
1315913167
**
13160
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
13168
+** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
1316113169
** to the column in which it occurs and *piOff the token offset of the
13162
-** first token of the phrase. Returns SQLITE_OK if successful, or an error
13163
-** code (i.e. SQLITE_NOMEM) if an error occurs.
13170
+** first token of the phrase. SQLITE_OK is returned if successful, or an
13171
+** error code (i.e. SQLITE_NOMEM) if an error occurs.
1316413172
**
1316513173
** This API can be quite slow if used with an FTS5 table created with the
1316613174
** "detail=none" or "detail=column" option.
1316713175
**
1316813176
** xRowid:
@@ -13183,10 +13191,14 @@
1318313191
** row visited, the callback function passed as the fourth argument
1318413192
** is invoked. The context and API objects passed to the callback
1318513193
** function may be used to access the properties of each matched row.
1318613194
** Invoking Api.xUserData() returns a copy of the pointer passed as
1318713195
** the third argument to pUserData.
13196
+**
13197
+** If parameter iPhrase is less than zero, or greater than or equal to
13198
+** the number of phrases in the query, as returned by xPhraseCount(),
13199
+** this function returns SQLITE_RANGE.
1318813200
**
1318913201
** If the callback function returns any value other than SQLITE_OK, the
1319013202
** query is abandoned and the xQueryPhrase function returns immediately.
1319113203
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
1319213204
** Otherwise, the error code is propagated upwards.
@@ -13304,22 +13316,30 @@
1330413316
** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
1330513317
** This is used to access token iToken of phrase iPhrase of the current
1330613318
** query. Before returning, output parameter *ppToken is set to point
1330713319
** to a buffer containing the requested token, and *pnToken to the
1330813320
** size of this buffer in bytes.
13321
+**
13322
+** If iPhrase or iToken are less than zero, or if iPhrase is greater than
13323
+** or equal to the number of phrases in the query as reported by
13324
+** xPhraseCount(), or if iToken is equal to or greater than the number of
13325
+** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
13326
+ are both zeroed.
1330913327
**
1331013328
** The output text is not a copy of the query text that specified the
1331113329
** token. It is the output of the tokenizer module. For tokendata=1
1331213330
** tables, this includes any embedded 0x00 and trailing data.
1331313331
**
1331413332
** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
1331513333
** This is used to access token iToken of phrase hit iIdx within the
13316
-** current row. Output variable (*ppToken) is set to point to a buffer
13317
-** containing the matching document token, and (*pnToken) to the size
13318
-** of that buffer in bytes. This API is not available if the specified
13319
-** token matches a prefix query term. In that case both output variables
13320
-** are always set to 0.
13334
+** current row. If iIdx is less than zero or greater than or equal to the
13335
+** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13336
+** output variable (*ppToken) is set to point to a buffer containing the
13337
+** matching document token, and (*pnToken) to the size of that buffer in
13338
+** bytes. This API is not available if the specified token matches a
13339
+** prefix query term. In that case both output variables are always set
13340
+** to 0.
1332113341
**
1332213342
** The output text is not a copy of the document text that was tokenized.
1332313343
** It is the output of the tokenizer module. For tokendata=1 tables, this
1332413344
** includes any embedded 0x00 and trailing data.
1332513345
**
@@ -13991,10 +14011,23 @@
1399114011
#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH)
1399214012
# define SQLITE_USE_SEH 1
1399314013
#else
1399414014
# undef SQLITE_USE_SEH
1399514015
#endif
14016
+
14017
+/*
14018
+** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly
14019
+** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0
14020
+*/
14021
+#if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1
14022
+ /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */
14023
+# undef SQLITE_DIRECT_OVERFLOW_READ
14024
+#else
14025
+ /* In all other cases, enable */
14026
+# define SQLITE_DIRECT_OVERFLOW_READ 1
14027
+#endif
14028
+
1399614029
1399714030
/*
1399814031
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
1399914032
** 0 means mutexes are permanently disable and the library is never
1400014033
** threadsafe. 1 means the library is serialized which is the highest
@@ -15874,11 +15907,11 @@
1587415907
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
1587515908
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
1587615909
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
1587715910
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
1587815911
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
15879
-SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
15912
+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*);
1588015913
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
1588115914
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
1588215915
1588315916
/* Functions used to truncate the database file. */
1588415917
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
@@ -18630,10 +18663,11 @@
1863018663
unsigned isResized:1; /* True if resizeIndexObject() has been called */
1863118664
unsigned isCovering:1; /* True if this is a covering index */
1863218665
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
1863318666
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
1863418667
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
18668
+ unsigned bSlow:1; /* This index is not good for equality lookups */
1863518669
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
1863618670
unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
1863718671
unsigned bHasExpr:1; /* Index contains an expression, either a literal
1863818672
** expression, or a reference to a VIRTUAL column */
1863918673
#ifdef SQLITE_ENABLE_STAT4
@@ -24028,11 +24062,11 @@
2402824062
/* no break */ deliberate_fall_through
2402924063
case SQLITE_DBSTATUS_CACHE_HIT:
2403024064
case SQLITE_DBSTATUS_CACHE_MISS:
2403124065
case SQLITE_DBSTATUS_CACHE_WRITE:{
2403224066
int i;
24033
- int nRet = 0;
24067
+ u64 nRet = 0;
2403424068
assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
2403524069
assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
2403624070
2403724071
for(i=0; i<db->nDb; i++){
2403824072
if( db->aDb[i].pBt ){
@@ -24041,11 +24075,11 @@
2404124075
}
2404224076
}
2404324077
*pHighwater = 0; /* IMP: R-42420-56072 */
2404424078
/* IMP: R-54100-20147 */
2404524079
/* IMP: R-29431-39229 */
24046
- *pCurrent = nRet;
24080
+ *pCurrent = (int)nRet & 0x7fffffff;
2404724081
break;
2404824082
}
2404924083
2405024084
/* Set *pCurrent to non-zero if there are unresolved deferred foreign
2405124085
** key constraints. Set *pCurrent to zero if all foreign key constraints
@@ -34677,11 +34711,11 @@
3467734711
** Load the sqlite3.iSysErrno field if that is an appropriate thing
3467834712
** to do based on the SQLite error code in rc.
3467934713
*/
3468034714
SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
3468134715
if( rc==SQLITE_IOERR_NOMEM ) return;
34682
-#ifdef SQLITE_USE_SEH
34716
+#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
3468334717
if( rc==SQLITE_IOERR_IN_PAGE ){
3468434718
int ii;
3468534719
int iErr;
3468634720
sqlite3BtreeEnterAll(db);
3468734721
for(ii=0; ii<db->nDb; ii++){
@@ -42365,13 +42399,19 @@
4236542399
struct flock f; /* The posix advisory locking structure */
4236642400
int rc = SQLITE_OK; /* Result code form fcntl() */
4236742401
4236842402
pShmNode = pFile->pInode->pShmNode;
4236942403
42370
- /* Assert that the correct mutex or mutexes are held. */
42371
- if( pShmNode->nRef==0 ){
42372
- assert( ofst==UNIX_SHM_DMS && n==1 && unixMutexHeld() );
42404
+ /* Assert that the parameters are within expected range and that the
42405
+ ** correct mutex or mutexes are held. */
42406
+ assert( pShmNode->nRef>=0 );
42407
+ assert( (ofst==UNIX_SHM_DMS && n==1)
42408
+ || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK))
42409
+ );
42410
+ if( ofst==UNIX_SHM_DMS ){
42411
+ assert( pShmNode->nRef>0 || unixMutexHeld() );
42412
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
4237342413
}else{
4237442414
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
4237542415
int ii;
4237642416
for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
4237742417
assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
@@ -57333,11 +57373,11 @@
5733357373
i64 journalSizeLimit; /* Size limit for persistent journal files */
5733457374
char *zFilename; /* Name of the database file */
5733557375
char *zJournal; /* Name of the journal file */
5733657376
int (*xBusyHandler)(void*); /* Function to call when busy */
5733757377
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
57338
- int aStat[4]; /* Total cache hits, misses, writes, spills */
57378
+ u32 aStat[4]; /* Total cache hits, misses, writes, spills */
5733957379
#ifdef SQLITE_TEST
5734057380
int nRead; /* Database pages read */
5734157381
#endif
5734257382
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
5734357383
int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
@@ -63477,15 +63517,15 @@
6347763517
a[1] = sqlite3PcachePagecount(pPager->pPCache);
6347863518
a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
6347963519
a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
6348063520
a[4] = pPager->eState;
6348163521
a[5] = pPager->errCode;
63482
- a[6] = pPager->aStat[PAGER_STAT_HIT];
63483
- a[7] = pPager->aStat[PAGER_STAT_MISS];
63522
+ a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff;
63523
+ a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff;
6348463524
a[8] = 0; /* Used to be pPager->nOvfl */
6348563525
a[9] = pPager->nRead;
63486
- a[10] = pPager->aStat[PAGER_STAT_WRITE];
63526
+ a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff;
6348763527
return a;
6348863528
}
6348963529
#endif
6349063530
6349163531
/*
@@ -63497,11 +63537,11 @@
6349763537
** Before returning, *pnVal is incremented by the
6349863538
** current cache hit or miss count, according to the value of eStat. If the
6349963539
** reset parameter is non-zero, the cache hit or miss count is zeroed before
6350063540
** returning.
6350163541
*/
63502
-SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
63542
+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){
6350363543
6350463544
assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
6350563545
|| eStat==SQLITE_DBSTATUS_CACHE_MISS
6350663546
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE
6350763547
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
@@ -64437,11 +64477,11 @@
6443764477
assert( pPager->eState>=PAGER_READER );
6443864478
return sqlite3WalFramesize(pPager->pWal);
6443964479
}
6444064480
#endif
6444164481
64442
-#ifdef SQLITE_USE_SEH
64482
+#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
6444364483
SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){
6444464484
return sqlite3WalSystemErrno(pPager->pWal);
6444564485
}
6444664486
#endif
6444764487
@@ -106789,10 +106829,11 @@
106789106829
sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
106790106830
}
106791106831
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
106792106832
pParse->checkSchema = 1;
106793106833
pTopNC->nNcErr++;
106834
+ eNewExprOp = TK_NULL;
106794106835
}
106795106836
assert( pFJMatch==0 );
106796106837
106797106838
/* Remove all substructure from pExpr */
106798106839
if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
@@ -110976,13 +111017,14 @@
110976111017
case TK_BLOB:
110977111018
return 0;
110978111019
case TK_COLUMN:
110979111020
assert( ExprUseYTab(p) );
110980111021
return ExprHasProperty(p, EP_CanBeNull) ||
110981
- p->y.pTab==0 || /* Reference to column of index on expression */
111022
+ NEVER(p->y.pTab==0) || /* Reference to column of index on expr */
110982111023
(p->iColumn>=0
110983111024
&& p->y.pTab->aCol!=0 /* Possible due to prior error */
111025
+ && ALWAYS(p->iColumn<p->y.pTab->nCol)
110984111026
&& p->y.pTab->aCol[p->iColumn].notNull==0);
110985111027
default:
110986111028
return 1;
110987111029
}
110988111030
}
@@ -113560,12 +113602,14 @@
113560113602
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
113561113603
if( pParse->pVdbe==0 ) return;
113562113604
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
113563113605
if( inReg!=target ){
113564113606
u8 op;
113565
- if( ALWAYS(pExpr)
113566
- && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER)
113607
+ Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr);
113608
+ testcase( pX!=pExpr );
113609
+ if( ALWAYS(pX)
113610
+ && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER)
113567113611
){
113568113612
op = OP_Copy;
113569113613
}else{
113570113614
op = OP_SCopy;
113571113615
}
@@ -117827,10 +117871,11 @@
117827117871
typedef struct StatAccum StatAccum;
117828117872
typedef struct StatSample StatSample;
117829117873
struct StatSample {
117830117874
tRowcnt *anEq; /* sqlite_stat4.nEq */
117831117875
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
117876
+ tRowcnt *amxEq; /* Maximum length run of equal values */
117832117877
#ifdef SQLITE_ENABLE_STAT4
117833117878
tRowcnt *anLt; /* sqlite_stat4.nLt */
117834117879
union {
117835117880
i64 iRowid; /* Rowid in main table of the key */
117836117881
u8 *aRowid; /* Key for WITHOUT ROWID tables */
@@ -117986,10 +118031,11 @@
117986118031
assert( nKeyCol>0 );
117987118032
117988118033
/* Allocate the space required for the StatAccum object */
117989118034
n = sizeof(*p)
117990118035
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
118036
+ + sizeof(tRowcnt)*nColUp /* StatAccum.amxEq */
117991118037
+ sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
117992118038
#ifdef SQLITE_ENABLE_STAT4
117993118039
if( mxSample ){
117994118040
n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
117995118041
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
@@ -118008,11 +118054,12 @@
118008118054
p->nLimit = sqlite3_value_int64(argv[3]);
118009118055
p->nCol = nCol;
118010118056
p->nKeyCol = nKeyCol;
118011118057
p->nSkipAhead = 0;
118012118058
p->current.anDLt = (tRowcnt*)&p[1];
118013
- p->current.anEq = &p->current.anDLt[nColUp];
118059
+ p->current.amxEq = &p->current.anDLt[nColUp];
118060
+ p->current.anEq = &p->current.amxEq[nColUp];
118014118061
118015118062
#ifdef SQLITE_ENABLE_STAT4
118016118063
p->mxSample = p->nLimit==0 ? mxSample : 0;
118017118064
if( mxSample ){
118018118065
u8 *pSpace; /* Allocated space not yet assigned */
@@ -118277,11 +118324,14 @@
118277118324
assert( p->nCol>0 );
118278118325
assert( iChng<p->nCol );
118279118326
118280118327
if( p->nRow==0 ){
118281118328
/* This is the first call to this function. Do initialization. */
118282
- for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
118329
+ for(i=0; i<p->nCol; i++){
118330
+ p->current.anEq[i] = 1;
118331
+ p->current.amxEq[i] = 1;
118332
+ }
118283118333
}else{
118284118334
/* Second and subsequent calls get processed here */
118285118335
#ifdef SQLITE_ENABLE_STAT4
118286118336
if( p->mxSample ) samplePushPrevious(p, iChng);
118287118337
#endif
@@ -118294,10 +118344,13 @@
118294118344
for(i=iChng; i<p->nCol; i++){
118295118345
p->current.anDLt[i]++;
118296118346
#ifdef SQLITE_ENABLE_STAT4
118297118347
if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
118298118348
#endif
118349
+ if( p->current.amxEq[i]<p->current.anEq[i] ){
118350
+ p->current.amxEq[i] = p->current.anEq[i];
118351
+ }
118299118352
p->current.anEq[i] = 1;
118300118353
}
118301118354
}
118302118355
118303118356
p->nRow++;
@@ -118402,37 +118455,65 @@
118402118455
** for each indexed column. This additional integer is an estimate of
118403118456
** the number of rows matched by a equality query on the index using
118404118457
** a key with the corresponding number of fields. In other words,
118405118458
** if the index is on columns (a,b) and the sqlite_stat1 value is
118406118459
** "100 10 2", then SQLite estimates that:
118407
- **
118408
- ** * the index contains 100 rows,
118409
- ** * "WHERE a=?" matches 10 rows, and
118410
- ** * "WHERE a=? AND b=?" matches 2 rows.
118460
+ ** | | |
118461
+ ** | | `-- "WHERE a=? AND b=?" matches approximately 2 rows
118462
+ ** | `---- "WHERE a=?" matches approximately 10 rows
118463
+ ** `-------- There are approximately 100 rows in the index total
118411118464
**
118412118465
** If D is the count of distinct values and K is the total number of
118413118466
** rows, then each estimate is usually computed as:
118414118467
**
118415118468
** I = (K+D-1)/D
118416118469
**
118417
- ** In other words, I is K/D rounded up to the next whole integer.
118418
- ** However, if I is between 1.0 and 1.1 (in other words if I is
118419
- ** close to 1.0 but just a little larger) then do not round up but
118420
- ** instead keep the I value at 1.0.
118470
+ ** Adjustments to the I value are made in some cases. See comments
118471
+ ** in-line below.
118421118472
*/
118422118473
sqlite3_str sStat; /* Text of the constructed "stat" line */
118423118474
int i; /* Loop counter */
118475
+ int iUneven = 1; /* max/avg */
118476
+ u64 nRow; /* Number of rows in the index */
118424118477
118425118478
sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100);
118426
- sqlite3_str_appendf(&sStat, "%llu",
118427
- p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
118479
+ nRow = p->nSkipAhead ? p->nEst : p->nRow;
118480
+ sqlite3_str_appendf(&sStat, "%llu", nRow);
118428118481
for(i=0; i<p->nKeyCol; i++){
118429118482
u64 nDistinct = p->current.anDLt[i] + 1;
118430118483
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
118431
- if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
118484
+ u64 mx = p->current.amxEq[i];
118485
+ if( nDistinct==1 && p->nLimit>0 ){
118486
+ /* If we never saw more than a single value in a PRAGMA analysis_limit
118487
+ ** search, then set the estimated number of matching rows to the
118488
+ ** estimated number of rows in the index. */
118489
+ iVal = p->nEst;
118490
+ }else if( iVal<mx/10 ){
118491
+ /* Report uneven= if the maximum run of identical values ever
118492
+ ** reaches or exceeds 10 times the average run */
118493
+ int iRatio = mx/iVal;
118494
+ if( iUneven<iRatio ) iUneven = iRatio;
118495
+ }else if( iVal==2 && p->nRow*10 <= nDistinct*11 ){
118496
+ /* If the value is less than or equal to 1.1, round it down to 1.0 */
118497
+ iVal = 1;
118498
+ }
118432118499
sqlite3_str_appendf(&sStat, " %llu", iVal);
118433118500
assert( p->current.anEq[i] );
118501
+
118502
+ /* Add the "slow" argument if the peak number of rows obtained
118503
+ ** from a full equality match is so large that a full table scan
118504
+ ** seems likely to be faster.
118505
+ */
118506
+ if( i==p->nKeyCol-1
118507
+ && nRow > 1000
118508
+ && nRow <= iVal*iUneven + sqlite3LogEst(nRow*2/3)
118509
+ ){
118510
+ sqlite3_str_appendf(&sStat, " slow");
118511
+ }
118512
+ }
118513
+ if( iUneven>1 ){
118514
+ sqlite3_str_appendf(&sStat, " uneven=%d", iUneven);
118434118515
}
118435118516
sqlite3ResultStrAccum(context, &sStat);
118436118517
}
118437118518
#ifdef SQLITE_ENABLE_STAT4
118438118519
else if( eCall==STAT_GET_ROWID ){
@@ -119075,11 +119156,11 @@
119075119156
#ifdef SQLITE_ENABLE_STAT4
119076119157
if( z==0 ) z = "";
119077119158
#else
119078119159
assert( z!=0 );
119079119160
#endif
119080
- for(i=0; *z && i<nOut; i++){
119161
+ for(i=0; i<nOut; i++){
119081119162
v = 0;
119082119163
while( (c=z[0])>='0' && c<='9' ){
119083119164
v = v*10 + c - '0';
119084119165
z++;
119085119166
}
@@ -119099,19 +119180,38 @@
119099119180
#else
119100119181
if( pIndex ){
119101119182
#endif
119102119183
pIndex->bUnordered = 0;
119103119184
pIndex->noSkipScan = 0;
119185
+ pIndex->bSlow = 0;
119104119186
while( z[0] ){
119105119187
if( sqlite3_strglob("unordered*", z)==0 ){
119106119188
pIndex->bUnordered = 1;
119107119189
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
119108119190
int sz = sqlite3Atoi(z+3);
119109119191
if( sz<2 ) sz = 2;
119110119192
pIndex->szIdxRow = sqlite3LogEst(sz);
119111119193
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
119112119194
pIndex->noSkipScan = 1;
119195
+ }else if( sqlite3_strglob("slow*", z)==0 ){
119196
+ pIndex->bSlow = 1;
119197
+ }else if( sqlite3_strglob("uneven=[0-9]*", z)==0 ){
119198
+ /* An argument of "uneven=NNN" means that the maximum length
119199
+ ** run of the same value is NNN times longer than the average.
119200
+ ** Go through the iaRowLogEst[] values for the index and increase
119201
+ ** them so that so that they are each no less than 1/8th the
119202
+ ** maximum value. */
119203
+ LogEst scale = sqlite3LogEst(sqlite3Atoi(z+7)) - 30;
119204
+ if( scale>0 ){
119205
+ LogEst mx = aLog[0];
119206
+ int jj;
119207
+ for(jj=1; jj<pIndex->nKeyCol; jj++){
119208
+ LogEst x = aLog[jj] + scale;
119209
+ if( x>mx ) x = mx;
119210
+ aLog[jj] = x;
119211
+ }
119212
+ }
119113119213
}
119114119214
#ifdef SQLITE_ENABLE_COSTMULT
119115119215
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
119116119216
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
119117119217
}
@@ -148743,11 +148843,11 @@
148743148843
pSub->pPrior = 0;
148744148844
pSub->pNext = 0;
148745148845
pSub->selFlags |= SF_Aggregate;
148746148846
pSub->selFlags &= ~SF_Compound;
148747148847
pSub->nSelectRow = 0;
148748
- sqlite3ExprListDelete(db, pSub->pEList);
148848
+ sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList);
148749148849
pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
148750148850
pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
148751148851
pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
148752148852
sqlite3PExprAddSelect(pParse, pTerm, pSub);
148753148853
if( pExpr==0 ){
@@ -154295,11 +154395,10 @@
154295154395
assert( sqlite3BtreeHoldsAllMutexes(db) );
154296154396
assert( sqlite3_mutex_held(db->mutex) );
154297154397
154298154398
if( p ){
154299154399
db->pDisconnect = 0;
154300
- sqlite3ExpirePreparedStatements(db, 0);
154301154400
do {
154302154401
VTable *pNext = p->pNext;
154303154402
sqlite3VtabUnlock(p);
154304154403
p = pNext;
154305154404
}while( p );
@@ -155861,11 +155960,11 @@
155861155960
*/
155862155961
SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
155863155962
#ifdef WHERETRACE_ENABLED
155864155963
SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
155865155964
SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm);
155866
-SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC);
155965
+SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC);
155867155966
#endif
155868155967
SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
155869155968
WhereClause *pWC, /* The WHERE clause to be searched */
155870155969
int iCur, /* Cursor number of LHS */
155871155970
int iColumn, /* Column number of LHS */
@@ -162890,21 +162989,38 @@
162890162989
#endif
162891162990
162892162991
#ifdef WHERETRACE_ENABLED
162893162992
/*
162894162993
** Print a WhereLoop object for debugging purposes
162994
+**
162995
+** Format example:
162996
+**
162997
+** .--- Position in WHERE clause rSetup, rRun, nOut ---.
162998
+** | |
162999
+** | .--- selfMask nTerm ------. |
163000
+** | | | |
163001
+** | | .-- prereq Idx wsFlags----. | |
163002
+** | | | Name | | |
163003
+** | | | __|__ nEq ---. ___|__ | __|__
163004
+** | / \ / \ / \ | / \ / \ / \
163005
+** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
162895163006
*/
162896
-SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
162897
- WhereInfo *pWInfo = pWC->pWInfo;
162898
- int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
162899
- SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
162900
- Table *pTab = pItem->pTab;
162901
- Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
162902
- sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
162903
- p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
162904
- sqlite3DebugPrintf(" %12s",
162905
- pItem->zAlias ? pItem->zAlias : pTab->zName);
163007
+SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
163008
+ if( pWC ){
163009
+ WhereInfo *pWInfo = pWC->pWInfo;
163010
+ int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
163011
+ SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
163012
+ Table *pTab = pItem->pTab;
163013
+ Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
163014
+ sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
163015
+ p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
163016
+ sqlite3DebugPrintf(" %12s",
163017
+ pItem->zAlias ? pItem->zAlias : pTab->zName);
163018
+ }else{
163019
+ sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d",
163020
+ p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab);
163021
+ }
162906163022
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
162907163023
const char *zName;
162908163024
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
162909163025
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
162910163026
int i = sqlite3Strlen30(zName) - 1;
@@ -162936,10 +163052,19 @@
162936163052
int i;
162937163053
for(i=0; i<p->nLTerm; i++){
162938163054
sqlite3WhereTermPrint(p->aLTerm[i], i);
162939163055
}
162940163056
}
163057
+}
163058
+SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){
163059
+ if( p ) sqlite3WhereLoopPrint(p, 0);
163060
+}
163061
+SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){
163062
+ while( p ){
163063
+ sqlite3ShowWhereLoop(p);
163064
+ p = p->pNextLoop;
163065
+ }
162941163066
}
162942163067
#endif
162943163068
162944163069
/*
162945163070
** Convert bulk memory into a valid WhereLoop that can be passed
@@ -163049,50 +163174,64 @@
163049163174
}
163050163175
sqlite3DbNNFreeNN(db, pWInfo);
163051163176
}
163052163177
163053163178
/*
163054
-** Return TRUE if all of the following are true:
163055
-**
163056
-** (1) X has the same or lower cost, or returns the same or fewer rows,
163057
-** than Y.
163058
-** (2) X uses fewer WHERE clause terms than Y
163059
-** (3) Every WHERE clause term used by X is also used by Y
163060
-** (4) X skips at least as many columns as Y
163061
-** (5) If X is a covering index, than Y is too
163062
-**
163063
-** Conditions (2) and (3) mean that X is a "proper subset" of Y.
163064
-** If X is a proper subset of Y then Y is a better choice and ought
163065
-** to have a lower cost. This routine returns TRUE when that cost
163066
-** relationship is inverted and needs to be adjusted. Constraint (4)
163067
-** was added because if X uses skip-scan less than Y it still might
163068
-** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
163069
-** was added because a covering index probably deserves to have a lower cost
163070
-** than a non-covering index even if it is a proper subset.
163179
+** Return TRUE if X is a proper subset of Y but is of equal or less cost.
163180
+** In other words, return true if all constraints of X are also part of Y
163181
+** and Y has additional constraints that might speed the search that X lacks
163182
+** but the cost of running X is not more than the cost of running Y.
163183
+**
163184
+** In other words, return true if the cost relationwship between X and Y
163185
+** is inverted and needs to be adjusted.
163186
+**
163187
+** Case 1:
163188
+**
163189
+** (1a) X and Y use the same index.
163190
+** (1b) X has fewer == terms than Y
163191
+** (1c) Neither X nor Y use skip-scan
163192
+** (1d) X does not have a a greater cost than Y
163193
+**
163194
+** Case 2:
163195
+**
163196
+** (2a) X has the same or lower cost, or returns the same or fewer rows,
163197
+** than Y.
163198
+** (2b) X uses fewer WHERE clause terms than Y
163199
+** (2c) Every WHERE clause term used by X is also used by Y
163200
+** (2d) X skips at least as many columns as Y
163201
+** (2e) If X is a covering index, than Y is too
163071163202
*/
163072163203
static int whereLoopCheaperProperSubset(
163073163204
const WhereLoop *pX, /* First WhereLoop to compare */
163074163205
const WhereLoop *pY /* Compare against this WhereLoop */
163075163206
){
163076163207
int i, j;
163208
+ if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */
163209
+ assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 );
163210
+ assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 );
163211
+ if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */
163212
+ && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */
163213
+ && pX->nSkip==0 && pY->nSkip==0 /* (1c) */
163214
+ ){
163215
+ return 1; /* Case 1 is true */
163216
+ }
163077163217
if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
163078
- return 0; /* X is not a subset of Y */
163218
+ return 0; /* (2b) */
163079163219
}
163080
- if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0;
163081
- if( pY->nSkip > pX->nSkip ) return 0;
163220
+ if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */
163082163221
for(i=pX->nLTerm-1; i>=0; i--){
163083163222
if( pX->aLTerm[i]==0 ) continue;
163084163223
for(j=pY->nLTerm-1; j>=0; j--){
163085163224
if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
163086163225
}
163087
- if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
163226
+ if( j<0 ) return 0; /* (2c) */
163088163227
}
163089163228
if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
163090163229
&& (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
163091
- return 0; /* Constraint (5) */
163230
+ return 0; /* (2e) */
163092163231
}
163093
- return 1; /* All conditions meet */
163232
+ return 1; /* Case 2 is true */
163094163233
}
163095163234
163096163235
/*
163097163236
** Try to adjust the cost and number of output rows of WhereLoop pTemplate
163098163237
** upwards or downwards so that:
@@ -163578,11 +163717,14 @@
163578163717
opMask = WO_LT|WO_LE;
163579163718
}else{
163580163719
assert( pNew->u.btree.nBtm==0 );
163581163720
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
163582163721
}
163583
- if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
163722
+ if( pProbe->bUnordered || pProbe->bSlow ){
163723
+ if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
163724
+ if( pProbe->bSlow ) opMask &= ~(WO_EQ|WO_IN|WO_IS);
163725
+ }
163584163726
163585163727
assert( pNew->u.btree.nEq<pProbe->nColumn );
163586163728
assert( pNew->u.btree.nEq<pProbe->nKeyCol
163587163729
|| pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
163588163730
@@ -166683,11 +166825,14 @@
166683166825
** struct, the contents of WhereInfo.a[], the WhereClause structure
166684166826
** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
166685166827
** field (type Bitmask) it must be aligned on an 8-byte boundary on
166686166828
** some architectures. Hence the ROUND8() below.
166687166829
*/
166688
- nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
166830
+ nByteWInfo = ROUND8P(sizeof(WhereInfo));
166831
+ if( nTabList>1 ){
166832
+ nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel));
166833
+ }
166689166834
pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
166690166835
if( db->mallocFailed ){
166691166836
sqlite3DbFree(db, pWInfo);
166692166837
pWInfo = 0;
166693166838
goto whereBeginError;
@@ -167245,10 +167390,15 @@
167245167390
whereBeginError:
167246167391
if( pWInfo ){
167247167392
pParse->nQueryLoop = pWInfo->savedNQueryLoop;
167248167393
whereInfoFree(db, pWInfo);
167249167394
}
167395
+#ifdef WHERETRACE_ENABLED
167396
+ /* Prevent harmless compiler warnings about debugging routines
167397
+ ** being declared but never used */
167398
+ sqlite3ShowWhereLoopList(0);
167399
+#endif /* WHERETRACE_ENABLED */
167250167400
return 0;
167251167401
}
167252167402
167253167403
/*
167254167404
** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
@@ -203027,13 +203177,13 @@
203027203177
** The original design stored all JSON as pure text, canonical RFC-8259.
203028203178
** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
203029203179
** All generated JSON text still conforms strictly to RFC-8259, but text
203030203180
** with JSON-5 extensions is accepted as input.
203031203181
**
203032
-** Beginning with version 3.45.0 (pending), these routines also accept
203033
-** BLOB values that have JSON encoded using a binary representation we
203034
-** call JSONB. The name JSONB comes from PostgreSQL, however the on-disk
203182
+** Beginning with version 3.45.0 (circa 2024-01-01), these routines also
203183
+** accept BLOB values that have JSON encoded using a binary representation
203184
+** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk
203035203185
** format SQLite JSONB is completely different and incompatible with
203036203186
** PostgreSQL JSONB.
203037203187
**
203038203188
** Decoding and interpreting JSONB is still O(N) where N is the size of
203039203189
** the input, the same as text JSON. However, the constant of proportionality
@@ -203120,10 +203270,13 @@
203120203270
** code is between 0 and 12 and that the total size of the element
203121203271
** (header plus payload) is the same as the size of the BLOB. If those
203122203272
** checks are true, the BLOB is assumed to be JSONB and processing continues.
203123203273
** Errors are only raised if some other miscoding is discovered during
203124203274
** processing.
203275
+**
203276
+** Additional information can be found in the doc/jsonb.md file of the
203277
+** canonical SQLite source tree.
203125203278
*/
203126203279
#ifndef SQLITE_OMIT_JSON
203127203280
/* #include "sqliteInt.h" */
203128203281
203129203282
/* JSONB element types
@@ -203218,18 +203371,26 @@
203218203371
** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
203219203372
*/
203220203373
#define JSON_CACHE_ID (-429938) /* Cache entry */
203221203374
#define JSON_CACHE_SIZE 4 /* Max number of cache entries */
203222203375
203376
+/*
203377
+** jsonUnescapeOneChar() returns this invalid code point if it encounters
203378
+** a syntax error.
203379
+*/
203380
+#define JSON_INVALID_CHAR 0x99999
203381
+
203223203382
/* A cache mapping JSON text into JSONB blobs.
203224203383
**
203225203384
** Each cache entry is a JsonParse object with the following restrictions:
203226203385
**
203227203386
** * The bReadOnly flag must be set
203228203387
**
203229203388
** * The aBlob[] array must be owned by the JsonParse object. In other
203230203389
** words, nBlobAlloc must be non-zero.
203390
+**
203391
+** * eEdit and delta must be zero.
203231203392
**
203232203393
** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
203233203394
*/
203234203395
struct JsonCache {
203235203396
sqlite3 *db; /* Database connection */
@@ -203286,27 +203447,27 @@
203286203447
**
203287203448
** 3. Zero or more changes are made to aBlob[] (via json_remove() or
203288203449
** json_replace() or json_patch() or similar).
203289203450
**
203290203451
** 4. New JSON text is generated from the aBlob[] for output. This step
203291
-** is skipped the function is one of the jsonb_* functions that returns
203292
-** JSONB instead of text JSON.
203452
+** is skipped if the function is one of the jsonb_* functions that
203453
+** returns JSONB instead of text JSON.
203293203454
*/
203294203455
struct JsonParse {
203295203456
u8 *aBlob; /* JSONB representation of JSON value */
203296203457
u32 nBlob; /* Bytes of aBlob[] actually used */
203297203458
u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
203298203459
char *zJson; /* Json text used for parsing */
203299203460
int nJson; /* Length of the zJson string in bytes */
203461
+ u32 nJPRef; /* Number of references to this object */
203462
+ u32 iErr; /* Error location in zJson[] */
203300203463
u16 iDepth; /* Nesting depth */
203301203464
u8 nErr; /* Number of errors seen */
203302203465
u8 oom; /* Set to true if out of memory */
203303203466
u8 bJsonIsRCStr; /* True if zJson is an RCStr */
203304203467
u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
203305203468
u8 bReadOnly; /* Do not modify. */
203306
- u32 nJPRef; /* Number of references to this object */
203307
- u32 iErr; /* Error location in zJson[] */
203308203469
/* Search and edit information. See jsonLookupStep() */
203309203470
u8 eEdit; /* Edit operation to apply */
203310203471
int delta; /* Size change due to the edit */
203311203472
u32 nIns; /* Number of bytes to insert */
203312203473
u32 iLabel; /* Location of label if search landed on an object value */
@@ -203341,11 +203502,11 @@
203341203502
/**************************************************************************
203342203503
** Forward references
203343203504
**************************************************************************/
203344203505
static void jsonReturnStringAsBlob(JsonString*);
203345203506
static int jsonFuncArgMightBeBinary(sqlite3_value *pJson);
203346
-static u32 jsonXlateBlobToText(const JsonParse*,u32,JsonString*);
203507
+static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*);
203347203508
static void jsonReturnParse(sqlite3_context*,JsonParse*);
203348203509
static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
203349203510
static void jsonParseFree(JsonParse*);
203350203511
static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
203351203512
static u32 jsonUnescapeOneChar(const char*, u32, u32*);
@@ -203381,10 +203542,11 @@
203381203542
){
203382203543
JsonCache *p;
203383203544
203384203545
assert( pParse->zJson!=0 );
203385203546
assert( pParse->bJsonIsRCStr );
203547
+ assert( pParse->delta==0 );
203386203548
p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203387203549
if( p==0 ){
203388203550
sqlite3 *db = sqlite3_context_db_handle(ctx);
203389203551
p = sqlite3DbMallocZero(db, sizeof(*p));
203390203552
if( p==0 ) return SQLITE_NOMEM;
@@ -203453,10 +203615,11 @@
203453203615
JsonParse *tmp = p->a[i];
203454203616
memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
203455203617
p->a[p->nUsed-1] = tmp;
203456203618
i = p->nUsed - 1;
203457203619
}
203620
+ assert( p->a[i]->delta==0 );
203458203621
return p->a[i];
203459203622
}else{
203460203623
return 0;
203461203624
}
203462203625
}
@@ -203621,12 +203784,37 @@
203621203784
if( z==0 ) return;
203622203785
if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
203623203786
p->zBuf[p->nUsed++] = '"';
203624203787
while( 1 /*exit-by-break*/ ){
203625203788
k = 0;
203626
- while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; } /* <--, */
203627
- while( k<N && jsonIsOk[z[k]] ){ k++; } /* <-- loop unwound for speed */
203789
+ /* The following while() is the 4-way unwound equivalent of
203790
+ **
203791
+ ** while( k<N && jsonIsOk[z[k]] ){ k++; }
203792
+ */
203793
+ while( 1 /* Exit by break */ ){
203794
+ if( k+3>=N ){
203795
+ while( k<N && jsonIsOk[z[k]] ){ k++; }
203796
+ break;
203797
+ }
203798
+ if( !jsonIsOk[z[k]] ){
203799
+ break;
203800
+ }
203801
+ if( !jsonIsOk[z[k+1]] ){
203802
+ k += 1;
203803
+ break;
203804
+ }
203805
+ if( !jsonIsOk[z[k+2]] ){
203806
+ k += 2;
203807
+ break;
203808
+ }
203809
+ if( !jsonIsOk[z[k+3]] ){
203810
+ k += 3;
203811
+ break;
203812
+ }else{
203813
+ k += 4;
203814
+ }
203815
+ }
203628203816
if( k>=N ){
203629203817
if( k>0 ){
203630203818
memcpy(&p->zBuf[p->nUsed], z, k);
203631203819
p->nUsed += k;
203632203820
}
@@ -203714,11 +203902,11 @@
203714203902
if( jsonFuncArgMightBeBinary(pValue) ){
203715203903
JsonParse px;
203716203904
memset(&px, 0, sizeof(px));
203717203905
px.aBlob = (u8*)sqlite3_value_blob(pValue);
203718203906
px.nBlob = sqlite3_value_bytes(pValue);
203719
- jsonXlateBlobToText(&px, 0, p);
203907
+ jsonTranslateBlobToText(&px, 0, p);
203720203908
}else if( p->eErr==0 ){
203721203909
sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203722203910
p->eErr = JSTRING_ERR;
203723203911
jsonStringReset(p);
203724203912
}
@@ -204231,18 +204419,14 @@
204231204419
** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
204232204420
** any changes to *pOp and return false.
204233204421
*/
204234204422
static int jsonIs4HexB(const char *z, int *pOp){
204235204423
if( z[0]!='u' ) return 0;
204236
- if( !sqlite3Isxdigit(z[1]) ) return 0;
204237
- if( !sqlite3Isxdigit(z[2]) ) return 0;
204238
- if( !sqlite3Isxdigit(z[3]) ) return 0;
204239
- if( !sqlite3Isxdigit(z[4]) ) return 0;
204424
+ if( !jsonIs4Hex(&z[1]) ) return 0;
204240204425
*pOp = JSONB_TEXTJ;
204241204426
return 1;
204242204427
}
204243
-
204244204428
204245204429
/*
204246204430
** Check a single element of the JSONB in pParse for validity.
204247204431
**
204248204432
** The element to be checked starts at offset i and must end at on the
@@ -204384,11 +204568,11 @@
204384204568
}else if( x!=JSONB_TEXT5 ){
204385204569
return j+1;
204386204570
}else{
204387204571
u32 c = 0;
204388204572
u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
204389
- if( c==0xfffd ) return j+1;
204573
+ if( c==JSON_INVALID_CHAR ) return j+1;
204390204574
j += szC - 1;
204391204575
}
204392204576
}
204393204577
j++;
204394204578
}
@@ -204456,11 +204640,11 @@
204456204640
** -2 '}' seen \
204457204641
** -3 ']' seen \___ For these returns, pParse->iErr is set to
204458204642
** -4 ',' seen / the index in zJson[] of the seen character
204459204643
** -5 ':' seen /
204460204644
*/
204461
-static int jsonXlateTextToBlob(JsonParse *pParse, u32 i){
204645
+static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
204462204646
char c;
204463204647
u32 j;
204464204648
u32 iThis, iStart;
204465204649
int x;
204466204650
u8 t;
@@ -204476,11 +204660,11 @@
204476204660
return -1;
204477204661
}
204478204662
iStart = pParse->nBlob;
204479204663
for(j=i+1;;j++){
204480204664
u32 iBlob = pParse->nBlob;
204481
- x = jsonXlateTextToBlob(pParse, j);
204665
+ x = jsonTranslateTextToBlob(pParse, j);
204482204666
if( x<=0 ){
204483204667
int op;
204484204668
if( x==(-2) ){
204485204669
j = pParse->iErr;
204486204670
if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
@@ -204522,19 +204706,19 @@
204522204706
if( z[j]==':' ){
204523204707
j++;
204524204708
goto parse_object_value;
204525204709
}
204526204710
}
204527
- x = jsonXlateTextToBlob(pParse, j);
204711
+ x = jsonTranslateTextToBlob(pParse, j);
204528204712
if( x!=(-5) ){
204529204713
if( x!=(-1) ) pParse->iErr = j;
204530204714
return -1;
204531204715
}
204532204716
j = pParse->iErr+1;
204533204717
}
204534204718
parse_object_value:
204535
- x = jsonXlateTextToBlob(pParse, j);
204719
+ x = jsonTranslateTextToBlob(pParse, j);
204536204720
if( x<=0 ){
204537204721
if( x!=(-1) ) pParse->iErr = j;
204538204722
return -1;
204539204723
}
204540204724
j = x;
@@ -204549,11 +204733,11 @@
204549204733
continue;
204550204734
}else if( z[j]=='}' ){
204551204735
break;
204552204736
}
204553204737
}
204554
- x = jsonXlateTextToBlob(pParse, j);
204738
+ x = jsonTranslateTextToBlob(pParse, j);
204555204739
if( x==(-4) ){
204556204740
j = pParse->iErr;
204557204741
continue;
204558204742
}
204559204743
if( x==(-2) ){
@@ -204577,11 +204761,11 @@
204577204761
if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204578204762
pParse->iErr = i;
204579204763
return -1;
204580204764
}
204581204765
for(j=i+1;;j++){
204582
- x = jsonXlateTextToBlob(pParse, j);
204766
+ x = jsonTranslateTextToBlob(pParse, j);
204583204767
if( x<=0 ){
204584204768
if( x==(-3) ){
204585204769
j = pParse->iErr;
204586204770
if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
204587204771
break;
@@ -204601,11 +204785,11 @@
204601204785
continue;
204602204786
}else if( z[j]==']' ){
204603204787
break;
204604204788
}
204605204789
}
204606
- x = jsonXlateTextToBlob(pParse, j);
204790
+ x = jsonTranslateTextToBlob(pParse, j);
204607204791
if( x==(-4) ){
204608204792
j = pParse->iErr;
204609204793
continue;
204610204794
}
204611204795
if( x==(-3) ){
@@ -204924,11 +205108,11 @@
204924205108
JsonParse *pParse, /* Initialize and fill this JsonParse object */
204925205109
sqlite3_context *pCtx /* Report errors here */
204926205110
){
204927205111
int i;
204928205112
const char *zJson = pParse->zJson;
204929
- i = jsonXlateTextToBlob(pParse, 0);
205113
+ i = jsonTranslateTextToBlob(pParse, 0);
204930205114
if( pParse->oom ) i = -1;
204931205115
if( i>0 ){
204932205116
#ifdef SQLITE_DEBUG
204933205117
assert( pParse->iDepth==0 );
204934205118
if( sqlite3Config.bJsonSelfcheck ){
@@ -204969,11 +205153,11 @@
204969205153
JsonParse px;
204970205154
memset(&px, 0, sizeof(px));
204971205155
jsonStringTerminate(pStr);
204972205156
px.zJson = pStr->zBuf;
204973205157
px.nJson = pStr->nUsed;
204974
- (void)jsonXlateTextToBlob(&px, 0);
205158
+ (void)jsonTranslateTextToBlob(&px, 0);
204975205159
if( px.oom ){
204976205160
sqlite3_free(px.aBlob);
204977205161
sqlite3_result_error_nomem(pStr->pCtx);
204978205162
}else{
204979205163
assert( px.nBlobAlloc>0 );
@@ -205057,11 +205241,11 @@
205057205241
** are detected. So a malformed JSONB input might either result
205058205242
** in an error, or in incorrect JSON.
205059205243
**
205060205244
** The pOut->eErr JSTRING_OOM flag is set on a OOM.
205061205245
*/
205062
-static u32 jsonXlateBlobToText(
205246
+static u32 jsonTranslateBlobToText(
205063205247
const JsonParse *pParse, /* the complete parse of the JSON */
205064205248
u32 i, /* Start rendering at this index */
205065205249
JsonString *pOut /* Write JSON here */
205066205250
){
205067205251
u32 sz, n, j, iEnd;
@@ -205228,11 +205412,11 @@
205228205412
case JSONB_ARRAY: {
205229205413
jsonAppendChar(pOut, '[');
205230205414
j = i+n;
205231205415
iEnd = j+sz;
205232205416
while( j<iEnd ){
205233
- j = jsonXlateBlobToText(pParse, j, pOut);
205417
+ j = jsonTranslateBlobToText(pParse, j, pOut);
205234205418
jsonAppendChar(pOut, ',');
205235205419
}
205236205420
if( sz>0 ) pOut->nUsed--;
205237205421
jsonAppendChar(pOut, ']');
205238205422
break;
@@ -205241,11 +205425,11 @@
205241205425
int x = 0;
205242205426
jsonAppendChar(pOut, '{');
205243205427
j = i+n;
205244205428
iEnd = j+sz;
205245205429
while( j<iEnd ){
205246
- j = jsonXlateBlobToText(pParse, j, pOut);
205430
+ j = jsonTranslateBlobToText(pParse, j, pOut);
205247205431
jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
205248205432
}
205249205433
if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
205250205434
if( sz>0 ) pOut->nUsed--;
205251205435
jsonAppendChar(pOut, '}');
@@ -205394,23 +205578,27 @@
205394205578
205395205579
/*
205396205580
** Input z[0..n] defines JSON escape sequence including the leading '\\'.
205397205581
** Decode that escape sequence into a single character. Write that
205398205582
** character into *piOut. Return the number of bytes in the escape sequence.
205583
+**
205584
+** If there is a syntax error of some kind (for example too few characters
205585
+** after the '\\' to complete the encoding) then *piOut is set to
205586
+** JSON_INVALID_CHAR.
205399205587
*/
205400205588
static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
205401205589
assert( n>0 );
205402205590
assert( z[0]=='\\' );
205403205591
if( n<2 ){
205404
- *piOut = 0xFFFD;
205592
+ *piOut = JSON_INVALID_CHAR;
205405205593
return n;
205406205594
}
205407205595
switch( (u8)z[1] ){
205408205596
case 'u': {
205409205597
u32 v, vlo;
205410205598
if( n<6 ){
205411
- *piOut = 0xFFFD;
205599
+ *piOut = JSON_INVALID_CHAR;
205412205600
return n;
205413205601
}
205414205602
v = jsonHexToInt4(&z[2]);
205415205603
if( (v & 0xfc00)==0xd800
205416205604
&& n>=12
@@ -205436,11 +205624,11 @@
205436205624
case '"':
205437205625
case '/':
205438205626
case '\\':{ *piOut = z[1]; return 2; }
205439205627
case 'x': {
205440205628
if( n<4 ){
205441
- *piOut = 0xFFFD;
205629
+ *piOut = JSON_INVALID_CHAR;
205442205630
return n;
205443205631
}
205444205632
*piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
205445205633
return 4;
205446205634
}
@@ -205447,11 +205635,11 @@
205447205635
case 0xe2:
205448205636
case '\r':
205449205637
case '\n': {
205450205638
u32 nSkip = jsonBytesToBypass(z, n);
205451205639
if( nSkip==0 ){
205452
- *piOut = 0xFFFD;
205640
+ *piOut = JSON_INVALID_CHAR;
205453205641
return n;
205454205642
}else if( nSkip==n ){
205455205643
*piOut = 0;
205456205644
return n;
205457205645
}else if( z[nSkip]=='\\' ){
@@ -205460,11 +205648,11 @@
205460205648
int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
205461205649
return nSkip + sz;
205462205650
}
205463205651
}
205464205652
default: {
205465
- *piOut = 0xFFFD;
205653
+ *piOut = JSON_INVALID_CHAR;
205466205654
return 2;
205467205655
}
205468205656
}
205469205657
}
205470205658
@@ -205823,11 +206011,11 @@
205823206011
if( NEVER(aBlob==0) ) return;
205824206012
memset(&x, 0, sizeof(x));
205825206013
x.aBlob = (u8*)aBlob;
205826206014
x.nBlob = nBlob;
205827206015
jsonStringInit(&s, ctx);
205828
- jsonXlateBlobToText(&x, 0, &s);
206016
+ jsonTranslateBlobToText(&x, 0, &s);
205829206017
jsonReturnString(&s, 0, 0);
205830206018
}
205831206019
205832206020
205833206021
/*
@@ -205934,21 +206122,21 @@
205934206122
if( c=='\\' ){
205935206123
u32 v;
205936206124
u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
205937206125
if( v<=0x7f ){
205938206126
zOut[iOut++] = (char)v;
205939
- }else if( v==0xfffd ){
205940
- /* Silently ignore illegal unicode */
205941206127
}else if( v<=0x7ff ){
205942206128
assert( szEscape>=2 );
205943206129
zOut[iOut++] = (char)(0xc0 | (v>>6));
205944206130
zOut[iOut++] = 0x80 | (v&0x3f);
205945206131
}else if( v<0x10000 ){
205946206132
assert( szEscape>=3 );
205947206133
zOut[iOut++] = 0xe0 | (v>>12);
205948206134
zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205949206135
zOut[iOut++] = 0x80 | (v&0x3f);
206136
+ }else if( v==JSON_INVALID_CHAR ){
206137
+ /* Silently ignore illegal unicode */
205950206138
}else{
205951206139
assert( szEscape>=4 );
205952206140
zOut[iOut++] = 0xf0 | (v>>18);
205953206141
zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
205954206142
zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
@@ -206046,17 +206234,33 @@
206046206234
}else{
206047206235
jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
206048206236
}
206049206237
break;
206050206238
}
206051
- case SQLITE_FLOAT:
206239
+ case SQLITE_FLOAT: {
206240
+ double r = sqlite3_value_double(pArg);
206241
+ if( NEVER(sqlite3IsNaN(r)) ){
206242
+ jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0);
206243
+ }else{
206244
+ int n = sqlite3_value_bytes(pArg);
206245
+ const char *z = (const char*)sqlite3_value_text(pArg);
206246
+ if( z==0 ) return 1;
206247
+ if( z[0]=='I' ){
206248
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
206249
+ }else if( z[0]=='-' && z[1]=='I' ){
206250
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
206251
+ }else{
206252
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z);
206253
+ }
206254
+ }
206255
+ break;
206256
+ }
206052206257
case SQLITE_INTEGER: {
206053206258
int n = sqlite3_value_bytes(pArg);
206054206259
const char *z = (const char*)sqlite3_value_text(pArg);
206055
- int e = eType==SQLITE_INTEGER ? JSONB_INT : JSONB_FLOAT;
206056206260
if( z==0 ) return 1;
206057
- jsonBlobAppendNode(pParse, e, n, z);
206261
+ jsonBlobAppendNode(pParse, JSONB_INT, n, z);
206058206262
break;
206059206263
}
206060206264
}
206061206265
if( pParse->oom ){
206062206266
sqlite3_result_error_nomem(ctx);
@@ -206153,15 +206357,10 @@
206153206357
}else{
206154206358
jsonBadPathError(ctx, zPath);
206155206359
}
206156206360
return;
206157206361
}
206158
-
206159
-/*
206160
-** Make a copy of a JsonParse object. The copy will be editable.
206161
-*/
206162
-
206163206362
206164206363
/*
206165206364
** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
206166206365
** from the SQL function argument pArg. Return a pointer to the new
206167206366
** JsonParse object.
@@ -206313,11 +206512,12 @@
206313206512
sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
206314206513
}
206315206514
}else{
206316206515
JsonString s;
206317206516
jsonStringInit(&s, ctx);
206318
- jsonXlateBlobToText(p, 0, &s);
206517
+ p->delta = 0;
206518
+ jsonTranslateBlobToText(p, 0, &s);
206319206519
jsonReturnString(&s, p, ctx);
206320206520
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206321206521
}
206322206522
}
206323206523
@@ -206333,29 +206533,32 @@
206333206533
*/
206334206534
static void jsonDebugPrintBlob(
206335206535
JsonParse *pParse, /* JSON content */
206336206536
u32 iStart, /* Start rendering here */
206337206537
u32 iEnd, /* Do not render this byte or any byte after this one */
206338
- int nIndent /* Indent by this many spaces */
206538
+ int nIndent, /* Indent by this many spaces */
206539
+ sqlite3_str *pOut /* Generate output into this sqlite3_str object */
206339206540
){
206340206541
while( iStart<iEnd ){
206341206542
u32 i, n, nn, sz = 0;
206342206543
int showContent = 1;
206343206544
u8 x = pParse->aBlob[iStart] & 0x0f;
206344206545
u32 savedNBlob = pParse->nBlob;
206345
- printf("%5d:%*s", iStart, nIndent, "");
206546
+ sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, "");
206346206547
if( pParse->nBlobAlloc>pParse->nBlob ){
206347206548
pParse->nBlob = pParse->nBlobAlloc;
206348206549
}
206349206550
nn = n = jsonbPayloadSize(pParse, iStart, &sz);
206350206551
if( nn==0 ) nn = 1;
206351206552
if( sz>0 && x<JSONB_ARRAY ){
206352206553
nn += sz;
206353206554
}
206354
- for(i=0; i<nn; i++) printf(" %02x", pParse->aBlob[iStart+i]);
206555
+ for(i=0; i<nn; i++){
206556
+ sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]);
206557
+ }
206355206558
if( n==0 ){
206356
- printf(" ERROR invalid node size\n");
206559
+ sqlite3_str_appendf(pOut, " ERROR invalid node size\n");
206357206560
iStart = n==0 ? iStart+1 : iEnd;
206358206561
continue;
206359206562
}
206360206563
pParse->nBlob = savedNBlob;
206361206564
if( iStart+n+sz>iEnd ){
@@ -206366,59 +206569,61 @@
206366206569
}else{
206367206570
iEnd = pParse->nBlob;
206368206571
}
206369206572
}
206370206573
}
206371
- printf(" <-- ");
206574
+ sqlite3_str_appendall(pOut," <-- ");
206372206575
switch( x ){
206373
- case JSONB_NULL: printf("null"); break;
206374
- case JSONB_TRUE: printf("true"); break;
206375
- case JSONB_FALSE: printf("false"); break;
206376
- case JSONB_INT: printf("int"); break;
206377
- case JSONB_INT5: printf("int5"); break;
206378
- case JSONB_FLOAT: printf("float"); break;
206379
- case JSONB_FLOAT5: printf("float5"); break;
206380
- case JSONB_TEXT: printf("text"); break;
206381
- case JSONB_TEXTJ: printf("textj"); break;
206382
- case JSONB_TEXT5: printf("text5"); break;
206383
- case JSONB_TEXTRAW: printf("textraw"); break;
206576
+ case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break;
206577
+ case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break;
206578
+ case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break;
206579
+ case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break;
206580
+ case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break;
206581
+ case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break;
206582
+ case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break;
206583
+ case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break;
206584
+ case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break;
206585
+ case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break;
206586
+ case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break;
206384206587
case JSONB_ARRAY: {
206385
- printf("array, %u bytes\n", sz);
206386
- jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206588
+ sqlite3_str_appendf(pOut,"array, %u bytes\n", sz);
206589
+ jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
206387206590
showContent = 0;
206388206591
break;
206389206592
}
206390206593
case JSONB_OBJECT: {
206391
- printf("object, %u bytes\n", sz);
206392
- jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206594
+ sqlite3_str_appendf(pOut, "object, %u bytes\n", sz);
206595
+ jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
206393206596
showContent = 0;
206394206597
break;
206395206598
}
206396206599
default: {
206397
- printf("ERROR: unknown node type\n");
206600
+ sqlite3_str_appendall(pOut, "ERROR: unknown node type\n");
206398206601
showContent = 0;
206399206602
break;
206400206603
}
206401206604
}
206402206605
if( showContent ){
206403206606
if( sz==0 && x<=JSONB_FALSE ){
206404
- printf("\n");
206607
+ sqlite3_str_append(pOut, "\n", 1);
206405206608
}else{
206406206609
u32 i;
206407
- printf(": \"");
206610
+ sqlite3_str_appendall(pOut, ": \"");
206408206611
for(i=iStart+n; i<iStart+n+sz; i++){
206409206612
u8 c = pParse->aBlob[i];
206410206613
if( c<0x20 || c>=0x7f ) c = '.';
206411
- putchar(c);
206614
+ sqlite3_str_append(pOut, (char*)&c, 1);
206412206615
}
206413
- printf("\"\n");
206616
+ sqlite3_str_append(pOut, "\"\n", 2);
206414206617
}
206415206618
}
206416206619
iStart += n + sz;
206417206620
}
206418206621
}
206419206622
static void jsonShowParse(JsonParse *pParse){
206623
+ sqlite3_str out;
206624
+ char zBuf[1000];
206420206625
if( pParse==0 ){
206421206626
printf("NULL pointer\n");
206422206627
return;
206423206628
}else{
206424206629
printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
@@ -206425,31 +206630,42 @@
206425206630
printf("nBlob = %u\n", pParse->nBlob);
206426206631
printf("delta = %d\n", pParse->delta);
206427206632
if( pParse->nBlob==0 ) return;
206428206633
printf("content (bytes 0..%u):\n", pParse->nBlob-1);
206429206634
}
206430
- jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0);
206635
+ sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000);
206636
+ jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out);
206637
+ printf("%s", sqlite3_str_value(&out));
206638
+ sqlite3_str_reset(&out);
206431206639
}
206432206640
#endif /* SQLITE_DEBUG */
206433206641
206434206642
#ifdef SQLITE_DEBUG
206435206643
/*
206436206644
** SQL function: json_parse(JSON)
206437206645
**
206438
-** Parse JSON using jsonParseFuncArg(). Then print a dump of that
206439
-** parse on standard output.
206646
+** Parse JSON using jsonParseFuncArg(). Return text that is a
206647
+** human-readable dump of the binary JSONB for the input parameter.
206440206648
*/
206441206649
static void jsonParseFunc(
206442206650
sqlite3_context *ctx,
206443206651
int argc,
206444206652
sqlite3_value **argv
206445206653
){
206446206654
JsonParse *p; /* The parse */
206655
+ sqlite3_str out;
206447206656
206448
- assert( argc==1 );
206657
+ assert( argc>=1 );
206658
+ sqlite3StrAccumInit(&out, 0, 0, 0, 1000000);
206449206659
p = jsonParseFuncArg(ctx, argv[0], 0);
206450
- jsonShowParse(p);
206660
+ if( p==0 ) return;
206661
+ if( argc==1 ){
206662
+ jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out);
206663
+ sqlite3_result_text64(ctx, out.zText, out.nChar, sqlite3_free, SQLITE_UTF8);
206664
+ }else{
206665
+ jsonShowParse(p);
206666
+ }
206451206667
jsonParseFree(p);
206452206668
}
206453206669
#endif /* SQLITE_DEBUG */
206454206670
206455206671
/****************************************************************************
@@ -206641,11 +206857,11 @@
206641206857
}
206642206858
if( j<p->nBlob ){
206643206859
if( argc==2 ){
206644206860
if( flags & JSON_JSON ){
206645206861
jsonStringInit(&jx, ctx);
206646
- jsonXlateBlobToText(p, j, &jx);
206862
+ jsonTranslateBlobToText(p, j, &jx);
206647206863
jsonReturnString(&jx, 0, 0);
206648206864
jsonStringReset(&jx);
206649206865
assert( (flags & JSON_BLOB)==0 );
206650206866
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206651206867
}else{
@@ -206656,11 +206872,11 @@
206656206872
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206657206873
}
206658206874
}
206659206875
}else{
206660206876
jsonAppendSeparator(&jx);
206661
- jsonXlateBlobToText(p, j, &jx);
206877
+ jsonTranslateBlobToText(p, j, &jx);
206662206878
}
206663206879
}else if( j==JSON_LOOKUP_NOTFOUND ){
206664206880
if( argc==2 ){
206665206881
goto json_extract_error; /* Return NULL if not found */
206666206882
}else{
@@ -229267,23 +229483,28 @@
229267229483
**
229268229484
** This function may be quite inefficient if used with an FTS5 table
229269229485
** created with the "columnsize=0" option.
229270229486
**
229271229487
** xColumnText:
229272
-** This function attempts to retrieve the text of column iCol of the
229273
-** current document. If successful, (*pz) is set to point to a buffer
229488
+** If parameter iCol is less than zero, or greater than or equal to the
229489
+** number of columns in the table, SQLITE_RANGE is returned.
229490
+**
229491
+** Otherwise, this function attempts to retrieve the text of column iCol of
229492
+** the current document. If successful, (*pz) is set to point to a buffer
229274229493
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
229275229494
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
229276229495
** if an error occurs, an SQLite error code is returned and the final values
229277229496
** of (*pz) and (*pn) are undefined.
229278229497
**
229279229498
** xPhraseCount:
229280229499
** Returns the number of phrases in the current query expression.
229281229500
**
229282229501
** xPhraseSize:
229283
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
229284
-** are numbered starting from zero.
229502
+** If parameter iCol is less than zero, or greater than or equal to the
229503
+** number of phrases in the current query, as returned by xPhraseCount,
229504
+** 0 is returned. Otherwise, this function returns the number of tokens in
229505
+** phrase iPhrase of the query. Phrases are numbered starting from zero.
229285229506
**
229286229507
** xInstCount:
229287229508
** Set *pnInst to the total number of occurrences of all phrases within
229288229509
** the query within the current row. Return SQLITE_OK if successful, or
229289229510
** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -229295,16 +229516,17 @@
229295229516
**
229296229517
** xInst:
229297229518
** Query for the details of phrase match iIdx within the current row.
229298229519
** Phrase matches are numbered starting from zero, so the iIdx argument
229299229520
** should be greater than or equal to zero and smaller than the value
229300
-** output by xInstCount().
229521
+** output by xInstCount(). If iIdx is less than zero or greater than
229522
+** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
229301229523
**
229302
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
229524
+** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
229303229525
** to the column in which it occurs and *piOff the token offset of the
229304
-** first token of the phrase. Returns SQLITE_OK if successful, or an error
229305
-** code (i.e. SQLITE_NOMEM) if an error occurs.
229526
+** first token of the phrase. SQLITE_OK is returned if successful, or an
229527
+** error code (i.e. SQLITE_NOMEM) if an error occurs.
229306229528
**
229307229529
** This API can be quite slow if used with an FTS5 table created with the
229308229530
** "detail=none" or "detail=column" option.
229309229531
**
229310229532
** xRowid:
@@ -229325,10 +229547,14 @@
229325229547
** row visited, the callback function passed as the fourth argument
229326229548
** is invoked. The context and API objects passed to the callback
229327229549
** function may be used to access the properties of each matched row.
229328229550
** Invoking Api.xUserData() returns a copy of the pointer passed as
229329229551
** the third argument to pUserData.
229552
+**
229553
+** If parameter iPhrase is less than zero, or greater than or equal to
229554
+** the number of phrases in the query, as returned by xPhraseCount(),
229555
+** this function returns SQLITE_RANGE.
229330229556
**
229331229557
** If the callback function returns any value other than SQLITE_OK, the
229332229558
** query is abandoned and the xQueryPhrase function returns immediately.
229333229559
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
229334229560
** Otherwise, the error code is propagated upwards.
@@ -229446,22 +229672,30 @@
229446229672
** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
229447229673
** This is used to access token iToken of phrase iPhrase of the current
229448229674
** query. Before returning, output parameter *ppToken is set to point
229449229675
** to a buffer containing the requested token, and *pnToken to the
229450229676
** size of this buffer in bytes.
229677
+**
229678
+** If iPhrase or iToken are less than zero, or if iPhrase is greater than
229679
+** or equal to the number of phrases in the query as reported by
229680
+** xPhraseCount(), or if iToken is equal to or greater than the number of
229681
+** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
229682
+ are both zeroed.
229451229683
**
229452229684
** The output text is not a copy of the query text that specified the
229453229685
** token. It is the output of the tokenizer module. For tokendata=1
229454229686
** tables, this includes any embedded 0x00 and trailing data.
229455229687
**
229456229688
** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
229457229689
** This is used to access token iToken of phrase hit iIdx within the
229458
-** current row. Output variable (*ppToken) is set to point to a buffer
229459
-** containing the matching document token, and (*pnToken) to the size
229460
-** of that buffer in bytes. This API is not available if the specified
229461
-** token matches a prefix query term. In that case both output variables
229462
-** are always set to 0.
229690
+** current row. If iIdx is less than zero or greater than or equal to the
229691
+** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
229692
+** output variable (*ppToken) is set to point to a buffer containing the
229693
+** matching document token, and (*pnToken) to the size of that buffer in
229694
+** bytes. This API is not available if the specified token matches a
229695
+** prefix query term. In that case both output variables are always set
229696
+** to 0.
229463229697
**
229464229698
** The output text is not a copy of the document text that was tokenized.
229465229699
** It is the output of the tokenizer module. For tokendata=1 tables, this
229466229700
** includes any embedded 0x00 and trailing data.
229467229701
**
@@ -232433,12 +232667,14 @@
232433232667
memset(&ctx, 0, sizeof(HighlightContext));
232434232668
ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
232435232669
ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
232436232670
ctx.iRangeEnd = -1;
232437232671
rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
232438
-
232439
- if( ctx.zIn ){
232672
+ if( rc==SQLITE_RANGE ){
232673
+ sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
232674
+ rc = SQLITE_OK;
232675
+ }else if( ctx.zIn ){
232440232676
if( rc==SQLITE_OK ){
232441232677
rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
232442232678
}
232443232679
232444232680
if( rc==SQLITE_OK ){
@@ -236273,15 +236509,19 @@
236273236509
Fts5Expr *pExpr,
236274236510
int iPhrase,
236275236511
Fts5Expr **ppNew
236276236512
){
236277236513
int rc = SQLITE_OK; /* Return code */
236278
- Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
236514
+ Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */
236279236515
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
236280236516
TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
236281
- pOrig = pExpr->apExprPhrase[iPhrase];
236282
- pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
236517
+ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
236518
+ rc = SQLITE_RANGE;
236519
+ }else{
236520
+ pOrig = pExpr->apExprPhrase[iPhrase];
236521
+ pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
236522
+ }
236283236523
if( rc==SQLITE_OK ){
236284236524
pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
236285236525
sizeof(Fts5ExprPhrase*));
236286236526
}
236287236527
if( rc==SQLITE_OK ){
@@ -236290,11 +236530,11 @@
236290236530
}
236291236531
if( rc==SQLITE_OK ){
236292236532
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
236293236533
sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
236294236534
}
236295
- if( rc==SQLITE_OK ){
236535
+ if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){
236296236536
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
236297236537
if( pColsetOrig ){
236298236538
sqlite3_int64 nByte;
236299236539
Fts5Colset *pColset;
236300236540
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
@@ -236304,29 +236544,31 @@
236304236544
}
236305236545
pNew->pRoot->pNear->pColset = pColset;
236306236546
}
236307236547
}
236308236548
236309
- if( pOrig->nTerm ){
236310
- int i; /* Used to iterate through phrase terms */
236311
- sCtx.pConfig = pExpr->pConfig;
236312
- for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
236313
- int tflags = 0;
236314
- Fts5ExprTerm *p;
236315
- for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
236316
- rc = fts5ParseTokenize((void*)&sCtx, tflags, p->pTerm,p->nFullTerm,0,0);
236317
- tflags = FTS5_TOKEN_COLOCATED;
236318
- }
236319
- if( rc==SQLITE_OK ){
236320
- sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
236321
- sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
236322
- }
236323
- }
236324
- }else{
236325
- /* This happens when parsing a token or quoted phrase that contains
236326
- ** no token characters at all. (e.g ... MATCH '""'). */
236327
- sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
236549
+ if( rc==SQLITE_OK ){
236550
+ if( pOrig->nTerm ){
236551
+ int i; /* Used to iterate through phrase terms */
236552
+ sCtx.pConfig = pExpr->pConfig;
236553
+ for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
236554
+ int tflags = 0;
236555
+ Fts5ExprTerm *p;
236556
+ for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
236557
+ rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0);
236558
+ tflags = FTS5_TOKEN_COLOCATED;
236559
+ }
236560
+ if( rc==SQLITE_OK ){
236561
+ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
236562
+ sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
236563
+ }
236564
+ }
236565
+ }else{
236566
+ /* This happens when parsing a token or quoted phrase that contains
236567
+ ** no token characters at all. (e.g ... MATCH '""'). */
236568
+ sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
236569
+ }
236328236570
}
236329236571
236330236572
if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
236331236573
/* All the allocations succeeded. Put the expression object together. */
236332236574
pNew->pIndex = pExpr->pIndex;
@@ -239776,13 +240018,13 @@
239776240018
for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
239777240019
if( pData->p[iOff] ) break;
239778240020
}
239779240021
239780240022
if( iOff<pData->nn ){
239781
- i64 iVal;
240023
+ u64 iVal;
239782240024
pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
239783
- iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
240025
+ iOff += fts5GetVarint(&pData->p[iOff], &iVal);
239784240026
pLvl->iRowid += iVal;
239785240027
pLvl->iOff = iOff;
239786240028
}else{
239787240029
pLvl->bEof = 1;
239788240030
}
@@ -246173,20 +246415,20 @@
246173246415
fts5DataRelease(pLeaf);
246174246416
}
246175246417
}
246176246418
246177246419
static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
246178
- int iTermOff = 0;
246420
+ i64 iTermOff = 0;
246179246421
int ii;
246180246422
246181246423
Fts5Buffer buf1 = {0,0,0};
246182246424
Fts5Buffer buf2 = {0,0,0};
246183246425
246184246426
ii = pLeaf->szLeaf;
246185246427
while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
246186246428
int res;
246187
- int iOff;
246429
+ i64 iOff;
246188246430
int nIncr;
246189246431
246190246432
ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
246191246433
iTermOff += nIncr;
246192246434
iOff = iTermOff;
@@ -249207,11 +249449,14 @@
249207249449
const char **pz,
249208249450
int *pn
249209249451
){
249210249452
int rc = SQLITE_OK;
249211249453
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249212
- if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
249454
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
249455
+ if( iCol<0 || iCol>=pTab->pConfig->nCol ){
249456
+ rc = SQLITE_RANGE;
249457
+ }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
249213249458
|| pCsr->ePlan==FTS5_PLAN_SPECIAL
249214249459
){
249215249460
*pz = 0;
249216249461
*pn = 0;
249217249462
}else{
@@ -249232,12 +249477,13 @@
249232249477
){
249233249478
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
249234249479
int rc = SQLITE_OK;
249235249480
int bLive = (pCsr->pSorter==0);
249236249481
249237
- if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
249238
-
249482
+ if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
249483
+ rc = SQLITE_RANGE;
249484
+ }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
249239249485
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
249240249486
Fts5PoslistPopulator *aPopulator;
249241249487
int i;
249242249488
aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
249243249489
if( aPopulator==0 ) rc = SQLITE_NOMEM;
@@ -249257,18 +249503,24 @@
249257249503
}
249258249504
}
249259249505
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
249260249506
}
249261249507
249262
- if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
249263
- Fts5Sorter *pSorter = pCsr->pSorter;
249264
- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
249265
- *pn = pSorter->aIdx[iPhrase] - i1;
249266
- *pa = &pSorter->aPoslist[i1];
249508
+ if( rc==SQLITE_OK ){
249509
+ if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
249510
+ Fts5Sorter *pSorter = pCsr->pSorter;
249511
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
249512
+ *pn = pSorter->aIdx[iPhrase] - i1;
249513
+ *pa = &pSorter->aPoslist[i1];
249514
+ }else{
249515
+ *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
249516
+ }
249267249517
}else{
249268
- *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
249518
+ *pa = 0;
249519
+ *pn = 0;
249269249520
}
249521
+
249270249522
249271249523
return rc;
249272249524
}
249273249525
249274249526
/*
@@ -250223,11 +250475,11 @@
250223250475
int nArg, /* Number of args */
250224250476
sqlite3_value **apUnused /* Function arguments */
250225250477
){
250226250478
assert( nArg==0 );
250227250479
UNUSED_PARAM2(nArg, apUnused);
250228
- sqlite3_result_text(pCtx, "fts5: 2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9", -1, SQLITE_TRANSIENT);
250480
+ sqlite3_result_text(pCtx, "fts5: 2023-12-29 19:03:01 4b70b94616ef37bac969051eee3ea6913a28f30520cdd4fc3a19e848f2cf12b7", -1, SQLITE_TRANSIENT);
250229250481
}
250230250482
250231250483
/*
250232250484
** Return true if zName is the extension on one of the shadow tables used
250233250485
** by this module.
250234250486
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 27d4a89a5ff96b7b7fc5dc9650e1269f7c7e.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.45.0"
463 #define SQLITE_VERSION_NUMBER 3045000
464 #define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -8350,13 +8350,15 @@
8350 ** can enter.)^ If the same thread tries to enter any mutex other
8351 ** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
8352 **
8353 ** ^(Some systems (for example, Windows 95) do not support the operation
8354 ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8355 ** will always return SQLITE_BUSY. The SQLite core only ever uses
8356 ** sqlite3_mutex_try() as an optimization so this is acceptable
8357 ** behavior.)^
 
 
8358 **
8359 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
8360 ** previously entered by the same thread. The behavior
8361 ** is undefined if the mutex is not currently entered by the
8362 ** calling thread or is not currently allocated.
@@ -13125,23 +13127,28 @@
13125 **
13126 ** This function may be quite inefficient if used with an FTS5 table
13127 ** created with the "columnsize=0" option.
13128 **
13129 ** xColumnText:
13130 ** This function attempts to retrieve the text of column iCol of the
13131 ** current document. If successful, (*pz) is set to point to a buffer
 
 
 
13132 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
13133 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
13134 ** if an error occurs, an SQLite error code is returned and the final values
13135 ** of (*pz) and (*pn) are undefined.
13136 **
13137 ** xPhraseCount:
13138 ** Returns the number of phrases in the current query expression.
13139 **
13140 ** xPhraseSize:
13141 ** Returns the number of tokens in phrase iPhrase of the query. Phrases
13142 ** are numbered starting from zero.
 
 
13143 **
13144 ** xInstCount:
13145 ** Set *pnInst to the total number of occurrences of all phrases within
13146 ** the query within the current row. Return SQLITE_OK if successful, or
13147 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -13153,16 +13160,17 @@
13153 **
13154 ** xInst:
13155 ** Query for the details of phrase match iIdx within the current row.
13156 ** Phrase matches are numbered starting from zero, so the iIdx argument
13157 ** should be greater than or equal to zero and smaller than the value
13158 ** output by xInstCount().
 
13159 **
13160 ** Usually, output parameter *piPhrase is set to the phrase number, *piCol
13161 ** to the column in which it occurs and *piOff the token offset of the
13162 ** first token of the phrase. Returns SQLITE_OK if successful, or an error
13163 ** code (i.e. SQLITE_NOMEM) if an error occurs.
13164 **
13165 ** This API can be quite slow if used with an FTS5 table created with the
13166 ** "detail=none" or "detail=column" option.
13167 **
13168 ** xRowid:
@@ -13183,10 +13191,14 @@
13183 ** row visited, the callback function passed as the fourth argument
13184 ** is invoked. The context and API objects passed to the callback
13185 ** function may be used to access the properties of each matched row.
13186 ** Invoking Api.xUserData() returns a copy of the pointer passed as
13187 ** the third argument to pUserData.
 
 
 
 
13188 **
13189 ** If the callback function returns any value other than SQLITE_OK, the
13190 ** query is abandoned and the xQueryPhrase function returns immediately.
13191 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
13192 ** Otherwise, the error code is propagated upwards.
@@ -13304,22 +13316,30 @@
13304 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
13305 ** This is used to access token iToken of phrase iPhrase of the current
13306 ** query. Before returning, output parameter *ppToken is set to point
13307 ** to a buffer containing the requested token, and *pnToken to the
13308 ** size of this buffer in bytes.
 
 
 
 
 
 
13309 **
13310 ** The output text is not a copy of the query text that specified the
13311 ** token. It is the output of the tokenizer module. For tokendata=1
13312 ** tables, this includes any embedded 0x00 and trailing data.
13313 **
13314 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13315 ** This is used to access token iToken of phrase hit iIdx within the
13316 ** current row. Output variable (*ppToken) is set to point to a buffer
13317 ** containing the matching document token, and (*pnToken) to the size
13318 ** of that buffer in bytes. This API is not available if the specified
13319 ** token matches a prefix query term. In that case both output variables
13320 ** are always set to 0.
 
 
13321 **
13322 ** The output text is not a copy of the document text that was tokenized.
13323 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13324 ** includes any embedded 0x00 and trailing data.
13325 **
@@ -13991,10 +14011,23 @@
13991 #if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH)
13992 # define SQLITE_USE_SEH 1
13993 #else
13994 # undef SQLITE_USE_SEH
13995 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
13996
13997 /*
13998 ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
13999 ** 0 means mutexes are permanently disable and the library is never
14000 ** threadsafe. 1 means the library is serialized which is the highest
@@ -15874,11 +15907,11 @@
15874 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
15875 SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
15876 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
15877 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
15878 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
15879 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
15880 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
15881 SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
15882
15883 /* Functions used to truncate the database file. */
15884 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
@@ -18630,10 +18663,11 @@
18630 unsigned isResized:1; /* True if resizeIndexObject() has been called */
18631 unsigned isCovering:1; /* True if this is a covering index */
18632 unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
18633 unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
18634 unsigned bNoQuery:1; /* Do not use this index to optimize queries */
 
18635 unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
18636 unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
18637 unsigned bHasExpr:1; /* Index contains an expression, either a literal
18638 ** expression, or a reference to a VIRTUAL column */
18639 #ifdef SQLITE_ENABLE_STAT4
@@ -24028,11 +24062,11 @@
24028 /* no break */ deliberate_fall_through
24029 case SQLITE_DBSTATUS_CACHE_HIT:
24030 case SQLITE_DBSTATUS_CACHE_MISS:
24031 case SQLITE_DBSTATUS_CACHE_WRITE:{
24032 int i;
24033 int nRet = 0;
24034 assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
24035 assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
24036
24037 for(i=0; i<db->nDb; i++){
24038 if( db->aDb[i].pBt ){
@@ -24041,11 +24075,11 @@
24041 }
24042 }
24043 *pHighwater = 0; /* IMP: R-42420-56072 */
24044 /* IMP: R-54100-20147 */
24045 /* IMP: R-29431-39229 */
24046 *pCurrent = nRet;
24047 break;
24048 }
24049
24050 /* Set *pCurrent to non-zero if there are unresolved deferred foreign
24051 ** key constraints. Set *pCurrent to zero if all foreign key constraints
@@ -34677,11 +34711,11 @@
34677 ** Load the sqlite3.iSysErrno field if that is an appropriate thing
34678 ** to do based on the SQLite error code in rc.
34679 */
34680 SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
34681 if( rc==SQLITE_IOERR_NOMEM ) return;
34682 #ifdef SQLITE_USE_SEH
34683 if( rc==SQLITE_IOERR_IN_PAGE ){
34684 int ii;
34685 int iErr;
34686 sqlite3BtreeEnterAll(db);
34687 for(ii=0; ii<db->nDb; ii++){
@@ -42365,13 +42399,19 @@
42365 struct flock f; /* The posix advisory locking structure */
42366 int rc = SQLITE_OK; /* Result code form fcntl() */
42367
42368 pShmNode = pFile->pInode->pShmNode;
42369
42370 /* Assert that the correct mutex or mutexes are held. */
42371 if( pShmNode->nRef==0 ){
42372 assert( ofst==UNIX_SHM_DMS && n==1 && unixMutexHeld() );
 
 
 
 
 
 
42373 }else{
42374 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42375 int ii;
42376 for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
42377 assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
@@ -57333,11 +57373,11 @@
57333 i64 journalSizeLimit; /* Size limit for persistent journal files */
57334 char *zFilename; /* Name of the database file */
57335 char *zJournal; /* Name of the journal file */
57336 int (*xBusyHandler)(void*); /* Function to call when busy */
57337 void *pBusyHandlerArg; /* Context argument for xBusyHandler */
57338 int aStat[4]; /* Total cache hits, misses, writes, spills */
57339 #ifdef SQLITE_TEST
57340 int nRead; /* Database pages read */
57341 #endif
57342 void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
57343 int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
@@ -63477,15 +63517,15 @@
63477 a[1] = sqlite3PcachePagecount(pPager->pPCache);
63478 a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
63479 a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
63480 a[4] = pPager->eState;
63481 a[5] = pPager->errCode;
63482 a[6] = pPager->aStat[PAGER_STAT_HIT];
63483 a[7] = pPager->aStat[PAGER_STAT_MISS];
63484 a[8] = 0; /* Used to be pPager->nOvfl */
63485 a[9] = pPager->nRead;
63486 a[10] = pPager->aStat[PAGER_STAT_WRITE];
63487 return a;
63488 }
63489 #endif
63490
63491 /*
@@ -63497,11 +63537,11 @@
63497 ** Before returning, *pnVal is incremented by the
63498 ** current cache hit or miss count, according to the value of eStat. If the
63499 ** reset parameter is non-zero, the cache hit or miss count is zeroed before
63500 ** returning.
63501 */
63502 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
63503
63504 assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
63505 || eStat==SQLITE_DBSTATUS_CACHE_MISS
63506 || eStat==SQLITE_DBSTATUS_CACHE_WRITE
63507 || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
@@ -64437,11 +64477,11 @@
64437 assert( pPager->eState>=PAGER_READER );
64438 return sqlite3WalFramesize(pPager->pWal);
64439 }
64440 #endif
64441
64442 #ifdef SQLITE_USE_SEH
64443 SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){
64444 return sqlite3WalSystemErrno(pPager->pWal);
64445 }
64446 #endif
64447
@@ -106789,10 +106829,11 @@
106789 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
106790 }
106791 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
106792 pParse->checkSchema = 1;
106793 pTopNC->nNcErr++;
 
106794 }
106795 assert( pFJMatch==0 );
106796
106797 /* Remove all substructure from pExpr */
106798 if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
@@ -110976,13 +111017,14 @@
110976 case TK_BLOB:
110977 return 0;
110978 case TK_COLUMN:
110979 assert( ExprUseYTab(p) );
110980 return ExprHasProperty(p, EP_CanBeNull) ||
110981 p->y.pTab==0 || /* Reference to column of index on expression */
110982 (p->iColumn>=0
110983 && p->y.pTab->aCol!=0 /* Possible due to prior error */
 
110984 && p->y.pTab->aCol[p->iColumn].notNull==0);
110985 default:
110986 return 1;
110987 }
110988 }
@@ -113560,12 +113602,14 @@
113560 assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
113561 if( pParse->pVdbe==0 ) return;
113562 inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
113563 if( inReg!=target ){
113564 u8 op;
113565 if( ALWAYS(pExpr)
113566 && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER)
 
 
113567 ){
113568 op = OP_Copy;
113569 }else{
113570 op = OP_SCopy;
113571 }
@@ -117827,10 +117871,11 @@
117827 typedef struct StatAccum StatAccum;
117828 typedef struct StatSample StatSample;
117829 struct StatSample {
117830 tRowcnt *anEq; /* sqlite_stat4.nEq */
117831 tRowcnt *anDLt; /* sqlite_stat4.nDLt */
 
117832 #ifdef SQLITE_ENABLE_STAT4
117833 tRowcnt *anLt; /* sqlite_stat4.nLt */
117834 union {
117835 i64 iRowid; /* Rowid in main table of the key */
117836 u8 *aRowid; /* Key for WITHOUT ROWID tables */
@@ -117986,10 +118031,11 @@
117986 assert( nKeyCol>0 );
117987
117988 /* Allocate the space required for the StatAccum object */
117989 n = sizeof(*p)
117990 + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
 
117991 + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
117992 #ifdef SQLITE_ENABLE_STAT4
117993 if( mxSample ){
117994 n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
117995 + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
@@ -118008,11 +118054,12 @@
118008 p->nLimit = sqlite3_value_int64(argv[3]);
118009 p->nCol = nCol;
118010 p->nKeyCol = nKeyCol;
118011 p->nSkipAhead = 0;
118012 p->current.anDLt = (tRowcnt*)&p[1];
118013 p->current.anEq = &p->current.anDLt[nColUp];
 
118014
118015 #ifdef SQLITE_ENABLE_STAT4
118016 p->mxSample = p->nLimit==0 ? mxSample : 0;
118017 if( mxSample ){
118018 u8 *pSpace; /* Allocated space not yet assigned */
@@ -118277,11 +118324,14 @@
118277 assert( p->nCol>0 );
118278 assert( iChng<p->nCol );
118279
118280 if( p->nRow==0 ){
118281 /* This is the first call to this function. Do initialization. */
118282 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
 
 
 
118283 }else{
118284 /* Second and subsequent calls get processed here */
118285 #ifdef SQLITE_ENABLE_STAT4
118286 if( p->mxSample ) samplePushPrevious(p, iChng);
118287 #endif
@@ -118294,10 +118344,13 @@
118294 for(i=iChng; i<p->nCol; i++){
118295 p->current.anDLt[i]++;
118296 #ifdef SQLITE_ENABLE_STAT4
118297 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
118298 #endif
 
 
 
118299 p->current.anEq[i] = 1;
118300 }
118301 }
118302
118303 p->nRow++;
@@ -118402,37 +118455,65 @@
118402 ** for each indexed column. This additional integer is an estimate of
118403 ** the number of rows matched by a equality query on the index using
118404 ** a key with the corresponding number of fields. In other words,
118405 ** if the index is on columns (a,b) and the sqlite_stat1 value is
118406 ** "100 10 2", then SQLite estimates that:
118407 **
118408 ** * the index contains 100 rows,
118409 ** * "WHERE a=?" matches 10 rows, and
118410 ** * "WHERE a=? AND b=?" matches 2 rows.
118411 **
118412 ** If D is the count of distinct values and K is the total number of
118413 ** rows, then each estimate is usually computed as:
118414 **
118415 ** I = (K+D-1)/D
118416 **
118417 ** In other words, I is K/D rounded up to the next whole integer.
118418 ** However, if I is between 1.0 and 1.1 (in other words if I is
118419 ** close to 1.0 but just a little larger) then do not round up but
118420 ** instead keep the I value at 1.0.
118421 */
118422 sqlite3_str sStat; /* Text of the constructed "stat" line */
118423 int i; /* Loop counter */
 
 
118424
118425 sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100);
118426 sqlite3_str_appendf(&sStat, "%llu",
118427 p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
118428 for(i=0; i<p->nKeyCol; i++){
118429 u64 nDistinct = p->current.anDLt[i] + 1;
118430 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
118431 if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118432 sqlite3_str_appendf(&sStat, " %llu", iVal);
118433 assert( p->current.anEq[i] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118434 }
118435 sqlite3ResultStrAccum(context, &sStat);
118436 }
118437 #ifdef SQLITE_ENABLE_STAT4
118438 else if( eCall==STAT_GET_ROWID ){
@@ -119075,11 +119156,11 @@
119075 #ifdef SQLITE_ENABLE_STAT4
119076 if( z==0 ) z = "";
119077 #else
119078 assert( z!=0 );
119079 #endif
119080 for(i=0; *z && i<nOut; i++){
119081 v = 0;
119082 while( (c=z[0])>='0' && c<='9' ){
119083 v = v*10 + c - '0';
119084 z++;
119085 }
@@ -119099,19 +119180,38 @@
119099 #else
119100 if( pIndex ){
119101 #endif
119102 pIndex->bUnordered = 0;
119103 pIndex->noSkipScan = 0;
 
119104 while( z[0] ){
119105 if( sqlite3_strglob("unordered*", z)==0 ){
119106 pIndex->bUnordered = 1;
119107 }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
119108 int sz = sqlite3Atoi(z+3);
119109 if( sz<2 ) sz = 2;
119110 pIndex->szIdxRow = sqlite3LogEst(sz);
119111 }else if( sqlite3_strglob("noskipscan*", z)==0 ){
119112 pIndex->noSkipScan = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119113 }
119114 #ifdef SQLITE_ENABLE_COSTMULT
119115 else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
119116 pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
119117 }
@@ -148743,11 +148843,11 @@
148743 pSub->pPrior = 0;
148744 pSub->pNext = 0;
148745 pSub->selFlags |= SF_Aggregate;
148746 pSub->selFlags &= ~SF_Compound;
148747 pSub->nSelectRow = 0;
148748 sqlite3ExprListDelete(db, pSub->pEList);
148749 pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
148750 pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
148751 pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
148752 sqlite3PExprAddSelect(pParse, pTerm, pSub);
148753 if( pExpr==0 ){
@@ -154295,11 +154395,10 @@
154295 assert( sqlite3BtreeHoldsAllMutexes(db) );
154296 assert( sqlite3_mutex_held(db->mutex) );
154297
154298 if( p ){
154299 db->pDisconnect = 0;
154300 sqlite3ExpirePreparedStatements(db, 0);
154301 do {
154302 VTable *pNext = p->pNext;
154303 sqlite3VtabUnlock(p);
154304 p = pNext;
154305 }while( p );
@@ -155861,11 +155960,11 @@
155861 */
155862 SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
155863 #ifdef WHERETRACE_ENABLED
155864 SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
155865 SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm);
155866 SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC);
155867 #endif
155868 SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
155869 WhereClause *pWC, /* The WHERE clause to be searched */
155870 int iCur, /* Cursor number of LHS */
155871 int iColumn, /* Column number of LHS */
@@ -162890,21 +162989,38 @@
162890 #endif
162891
162892 #ifdef WHERETRACE_ENABLED
162893 /*
162894 ** Print a WhereLoop object for debugging purposes
 
 
 
 
 
 
 
 
 
 
 
 
162895 */
162896 SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
162897 WhereInfo *pWInfo = pWC->pWInfo;
162898 int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
162899 SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
162900 Table *pTab = pItem->pTab;
162901 Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
162902 sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
162903 p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
162904 sqlite3DebugPrintf(" %12s",
162905 pItem->zAlias ? pItem->zAlias : pTab->zName);
 
 
 
 
 
162906 if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
162907 const char *zName;
162908 if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
162909 if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
162910 int i = sqlite3Strlen30(zName) - 1;
@@ -162936,10 +163052,19 @@
162936 int i;
162937 for(i=0; i<p->nLTerm; i++){
162938 sqlite3WhereTermPrint(p->aLTerm[i], i);
162939 }
162940 }
 
 
 
 
 
 
 
 
 
162941 }
162942 #endif
162943
162944 /*
162945 ** Convert bulk memory into a valid WhereLoop that can be passed
@@ -163049,50 +163174,64 @@
163049 }
163050 sqlite3DbNNFreeNN(db, pWInfo);
163051 }
163052
163053 /*
163054 ** Return TRUE if all of the following are true:
163055 **
163056 ** (1) X has the same or lower cost, or returns the same or fewer rows,
163057 ** than Y.
163058 ** (2) X uses fewer WHERE clause terms than Y
163059 ** (3) Every WHERE clause term used by X is also used by Y
163060 ** (4) X skips at least as many columns as Y
163061 ** (5) If X is a covering index, than Y is too
163062 **
163063 ** Conditions (2) and (3) mean that X is a "proper subset" of Y.
163064 ** If X is a proper subset of Y then Y is a better choice and ought
163065 ** to have a lower cost. This routine returns TRUE when that cost
163066 ** relationship is inverted and needs to be adjusted. Constraint (4)
163067 ** was added because if X uses skip-scan less than Y it still might
163068 ** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
163069 ** was added because a covering index probably deserves to have a lower cost
163070 ** than a non-covering index even if it is a proper subset.
 
 
 
 
 
 
163071 */
163072 static int whereLoopCheaperProperSubset(
163073 const WhereLoop *pX, /* First WhereLoop to compare */
163074 const WhereLoop *pY /* Compare against this WhereLoop */
163075 ){
163076 int i, j;
 
 
 
 
 
 
 
 
 
163077 if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
163078 return 0; /* X is not a subset of Y */
163079 }
163080 if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0;
163081 if( pY->nSkip > pX->nSkip ) return 0;
163082 for(i=pX->nLTerm-1; i>=0; i--){
163083 if( pX->aLTerm[i]==0 ) continue;
163084 for(j=pY->nLTerm-1; j>=0; j--){
163085 if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
163086 }
163087 if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
163088 }
163089 if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
163090 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
163091 return 0; /* Constraint (5) */
163092 }
163093 return 1; /* All conditions meet */
163094 }
163095
163096 /*
163097 ** Try to adjust the cost and number of output rows of WhereLoop pTemplate
163098 ** upwards or downwards so that:
@@ -163578,11 +163717,14 @@
163578 opMask = WO_LT|WO_LE;
163579 }else{
163580 assert( pNew->u.btree.nBtm==0 );
163581 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
163582 }
163583 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
 
 
 
163584
163585 assert( pNew->u.btree.nEq<pProbe->nColumn );
163586 assert( pNew->u.btree.nEq<pProbe->nKeyCol
163587 || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
163588
@@ -166683,11 +166825,14 @@
166683 ** struct, the contents of WhereInfo.a[], the WhereClause structure
166684 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
166685 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
166686 ** some architectures. Hence the ROUND8() below.
166687 */
166688 nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
 
 
 
166689 pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
166690 if( db->mallocFailed ){
166691 sqlite3DbFree(db, pWInfo);
166692 pWInfo = 0;
166693 goto whereBeginError;
@@ -167245,10 +167390,15 @@
167245 whereBeginError:
167246 if( pWInfo ){
167247 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
167248 whereInfoFree(db, pWInfo);
167249 }
 
 
 
 
 
167250 return 0;
167251 }
167252
167253 /*
167254 ** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
@@ -203027,13 +203177,13 @@
203027 ** The original design stored all JSON as pure text, canonical RFC-8259.
203028 ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
203029 ** All generated JSON text still conforms strictly to RFC-8259, but text
203030 ** with JSON-5 extensions is accepted as input.
203031 **
203032 ** Beginning with version 3.45.0 (pending), these routines also accept
203033 ** BLOB values that have JSON encoded using a binary representation we
203034 ** call JSONB. The name JSONB comes from PostgreSQL, however the on-disk
203035 ** format SQLite JSONB is completely different and incompatible with
203036 ** PostgreSQL JSONB.
203037 **
203038 ** Decoding and interpreting JSONB is still O(N) where N is the size of
203039 ** the input, the same as text JSON. However, the constant of proportionality
@@ -203120,10 +203270,13 @@
203120 ** code is between 0 and 12 and that the total size of the element
203121 ** (header plus payload) is the same as the size of the BLOB. If those
203122 ** checks are true, the BLOB is assumed to be JSONB and processing continues.
203123 ** Errors are only raised if some other miscoding is discovered during
203124 ** processing.
 
 
 
203125 */
203126 #ifndef SQLITE_OMIT_JSON
203127 /* #include "sqliteInt.h" */
203128
203129 /* JSONB element types
@@ -203218,18 +203371,26 @@
203218 ** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
203219 */
203220 #define JSON_CACHE_ID (-429938) /* Cache entry */
203221 #define JSON_CACHE_SIZE 4 /* Max number of cache entries */
203222
 
 
 
 
 
 
203223 /* A cache mapping JSON text into JSONB blobs.
203224 **
203225 ** Each cache entry is a JsonParse object with the following restrictions:
203226 **
203227 ** * The bReadOnly flag must be set
203228 **
203229 ** * The aBlob[] array must be owned by the JsonParse object. In other
203230 ** words, nBlobAlloc must be non-zero.
 
 
203231 **
203232 ** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
203233 */
203234 struct JsonCache {
203235 sqlite3 *db; /* Database connection */
@@ -203286,27 +203447,27 @@
203286 **
203287 ** 3. Zero or more changes are made to aBlob[] (via json_remove() or
203288 ** json_replace() or json_patch() or similar).
203289 **
203290 ** 4. New JSON text is generated from the aBlob[] for output. This step
203291 ** is skipped the function is one of the jsonb_* functions that returns
203292 ** JSONB instead of text JSON.
203293 */
203294 struct JsonParse {
203295 u8 *aBlob; /* JSONB representation of JSON value */
203296 u32 nBlob; /* Bytes of aBlob[] actually used */
203297 u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
203298 char *zJson; /* Json text used for parsing */
203299 int nJson; /* Length of the zJson string in bytes */
 
 
203300 u16 iDepth; /* Nesting depth */
203301 u8 nErr; /* Number of errors seen */
203302 u8 oom; /* Set to true if out of memory */
203303 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
203304 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
203305 u8 bReadOnly; /* Do not modify. */
203306 u32 nJPRef; /* Number of references to this object */
203307 u32 iErr; /* Error location in zJson[] */
203308 /* Search and edit information. See jsonLookupStep() */
203309 u8 eEdit; /* Edit operation to apply */
203310 int delta; /* Size change due to the edit */
203311 u32 nIns; /* Number of bytes to insert */
203312 u32 iLabel; /* Location of label if search landed on an object value */
@@ -203341,11 +203502,11 @@
203341 /**************************************************************************
203342 ** Forward references
203343 **************************************************************************/
203344 static void jsonReturnStringAsBlob(JsonString*);
203345 static int jsonFuncArgMightBeBinary(sqlite3_value *pJson);
203346 static u32 jsonXlateBlobToText(const JsonParse*,u32,JsonString*);
203347 static void jsonReturnParse(sqlite3_context*,JsonParse*);
203348 static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
203349 static void jsonParseFree(JsonParse*);
203350 static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
203351 static u32 jsonUnescapeOneChar(const char*, u32, u32*);
@@ -203381,10 +203542,11 @@
203381 ){
203382 JsonCache *p;
203383
203384 assert( pParse->zJson!=0 );
203385 assert( pParse->bJsonIsRCStr );
 
203386 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203387 if( p==0 ){
203388 sqlite3 *db = sqlite3_context_db_handle(ctx);
203389 p = sqlite3DbMallocZero(db, sizeof(*p));
203390 if( p==0 ) return SQLITE_NOMEM;
@@ -203453,10 +203615,11 @@
203453 JsonParse *tmp = p->a[i];
203454 memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
203455 p->a[p->nUsed-1] = tmp;
203456 i = p->nUsed - 1;
203457 }
 
203458 return p->a[i];
203459 }else{
203460 return 0;
203461 }
203462 }
@@ -203621,12 +203784,37 @@
203621 if( z==0 ) return;
203622 if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
203623 p->zBuf[p->nUsed++] = '"';
203624 while( 1 /*exit-by-break*/ ){
203625 k = 0;
203626 while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; } /* <--, */
203627 while( k<N && jsonIsOk[z[k]] ){ k++; } /* <-- loop unwound for speed */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203628 if( k>=N ){
203629 if( k>0 ){
203630 memcpy(&p->zBuf[p->nUsed], z, k);
203631 p->nUsed += k;
203632 }
@@ -203714,11 +203902,11 @@
203714 if( jsonFuncArgMightBeBinary(pValue) ){
203715 JsonParse px;
203716 memset(&px, 0, sizeof(px));
203717 px.aBlob = (u8*)sqlite3_value_blob(pValue);
203718 px.nBlob = sqlite3_value_bytes(pValue);
203719 jsonXlateBlobToText(&px, 0, p);
203720 }else if( p->eErr==0 ){
203721 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203722 p->eErr = JSTRING_ERR;
203723 jsonStringReset(p);
203724 }
@@ -204231,18 +204419,14 @@
204231 ** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
204232 ** any changes to *pOp and return false.
204233 */
204234 static int jsonIs4HexB(const char *z, int *pOp){
204235 if( z[0]!='u' ) return 0;
204236 if( !sqlite3Isxdigit(z[1]) ) return 0;
204237 if( !sqlite3Isxdigit(z[2]) ) return 0;
204238 if( !sqlite3Isxdigit(z[3]) ) return 0;
204239 if( !sqlite3Isxdigit(z[4]) ) return 0;
204240 *pOp = JSONB_TEXTJ;
204241 return 1;
204242 }
204243
204244
204245 /*
204246 ** Check a single element of the JSONB in pParse for validity.
204247 **
204248 ** The element to be checked starts at offset i and must end at on the
@@ -204384,11 +204568,11 @@
204384 }else if( x!=JSONB_TEXT5 ){
204385 return j+1;
204386 }else{
204387 u32 c = 0;
204388 u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
204389 if( c==0xfffd ) return j+1;
204390 j += szC - 1;
204391 }
204392 }
204393 j++;
204394 }
@@ -204456,11 +204640,11 @@
204456 ** -2 '}' seen \
204457 ** -3 ']' seen \___ For these returns, pParse->iErr is set to
204458 ** -4 ',' seen / the index in zJson[] of the seen character
204459 ** -5 ':' seen /
204460 */
204461 static int jsonXlateTextToBlob(JsonParse *pParse, u32 i){
204462 char c;
204463 u32 j;
204464 u32 iThis, iStart;
204465 int x;
204466 u8 t;
@@ -204476,11 +204660,11 @@
204476 return -1;
204477 }
204478 iStart = pParse->nBlob;
204479 for(j=i+1;;j++){
204480 u32 iBlob = pParse->nBlob;
204481 x = jsonXlateTextToBlob(pParse, j);
204482 if( x<=0 ){
204483 int op;
204484 if( x==(-2) ){
204485 j = pParse->iErr;
204486 if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
@@ -204522,19 +204706,19 @@
204522 if( z[j]==':' ){
204523 j++;
204524 goto parse_object_value;
204525 }
204526 }
204527 x = jsonXlateTextToBlob(pParse, j);
204528 if( x!=(-5) ){
204529 if( x!=(-1) ) pParse->iErr = j;
204530 return -1;
204531 }
204532 j = pParse->iErr+1;
204533 }
204534 parse_object_value:
204535 x = jsonXlateTextToBlob(pParse, j);
204536 if( x<=0 ){
204537 if( x!=(-1) ) pParse->iErr = j;
204538 return -1;
204539 }
204540 j = x;
@@ -204549,11 +204733,11 @@
204549 continue;
204550 }else if( z[j]=='}' ){
204551 break;
204552 }
204553 }
204554 x = jsonXlateTextToBlob(pParse, j);
204555 if( x==(-4) ){
204556 j = pParse->iErr;
204557 continue;
204558 }
204559 if( x==(-2) ){
@@ -204577,11 +204761,11 @@
204577 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204578 pParse->iErr = i;
204579 return -1;
204580 }
204581 for(j=i+1;;j++){
204582 x = jsonXlateTextToBlob(pParse, j);
204583 if( x<=0 ){
204584 if( x==(-3) ){
204585 j = pParse->iErr;
204586 if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
204587 break;
@@ -204601,11 +204785,11 @@
204601 continue;
204602 }else if( z[j]==']' ){
204603 break;
204604 }
204605 }
204606 x = jsonXlateTextToBlob(pParse, j);
204607 if( x==(-4) ){
204608 j = pParse->iErr;
204609 continue;
204610 }
204611 if( x==(-3) ){
@@ -204924,11 +205108,11 @@
204924 JsonParse *pParse, /* Initialize and fill this JsonParse object */
204925 sqlite3_context *pCtx /* Report errors here */
204926 ){
204927 int i;
204928 const char *zJson = pParse->zJson;
204929 i = jsonXlateTextToBlob(pParse, 0);
204930 if( pParse->oom ) i = -1;
204931 if( i>0 ){
204932 #ifdef SQLITE_DEBUG
204933 assert( pParse->iDepth==0 );
204934 if( sqlite3Config.bJsonSelfcheck ){
@@ -204969,11 +205153,11 @@
204969 JsonParse px;
204970 memset(&px, 0, sizeof(px));
204971 jsonStringTerminate(pStr);
204972 px.zJson = pStr->zBuf;
204973 px.nJson = pStr->nUsed;
204974 (void)jsonXlateTextToBlob(&px, 0);
204975 if( px.oom ){
204976 sqlite3_free(px.aBlob);
204977 sqlite3_result_error_nomem(pStr->pCtx);
204978 }else{
204979 assert( px.nBlobAlloc>0 );
@@ -205057,11 +205241,11 @@
205057 ** are detected. So a malformed JSONB input might either result
205058 ** in an error, or in incorrect JSON.
205059 **
205060 ** The pOut->eErr JSTRING_OOM flag is set on a OOM.
205061 */
205062 static u32 jsonXlateBlobToText(
205063 const JsonParse *pParse, /* the complete parse of the JSON */
205064 u32 i, /* Start rendering at this index */
205065 JsonString *pOut /* Write JSON here */
205066 ){
205067 u32 sz, n, j, iEnd;
@@ -205228,11 +205412,11 @@
205228 case JSONB_ARRAY: {
205229 jsonAppendChar(pOut, '[');
205230 j = i+n;
205231 iEnd = j+sz;
205232 while( j<iEnd ){
205233 j = jsonXlateBlobToText(pParse, j, pOut);
205234 jsonAppendChar(pOut, ',');
205235 }
205236 if( sz>0 ) pOut->nUsed--;
205237 jsonAppendChar(pOut, ']');
205238 break;
@@ -205241,11 +205425,11 @@
205241 int x = 0;
205242 jsonAppendChar(pOut, '{');
205243 j = i+n;
205244 iEnd = j+sz;
205245 while( j<iEnd ){
205246 j = jsonXlateBlobToText(pParse, j, pOut);
205247 jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
205248 }
205249 if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
205250 if( sz>0 ) pOut->nUsed--;
205251 jsonAppendChar(pOut, '}');
@@ -205394,23 +205578,27 @@
205394
205395 /*
205396 ** Input z[0..n] defines JSON escape sequence including the leading '\\'.
205397 ** Decode that escape sequence into a single character. Write that
205398 ** character into *piOut. Return the number of bytes in the escape sequence.
 
 
 
 
205399 */
205400 static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
205401 assert( n>0 );
205402 assert( z[0]=='\\' );
205403 if( n<2 ){
205404 *piOut = 0xFFFD;
205405 return n;
205406 }
205407 switch( (u8)z[1] ){
205408 case 'u': {
205409 u32 v, vlo;
205410 if( n<6 ){
205411 *piOut = 0xFFFD;
205412 return n;
205413 }
205414 v = jsonHexToInt4(&z[2]);
205415 if( (v & 0xfc00)==0xd800
205416 && n>=12
@@ -205436,11 +205624,11 @@
205436 case '"':
205437 case '/':
205438 case '\\':{ *piOut = z[1]; return 2; }
205439 case 'x': {
205440 if( n<4 ){
205441 *piOut = 0xFFFD;
205442 return n;
205443 }
205444 *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
205445 return 4;
205446 }
@@ -205447,11 +205635,11 @@
205447 case 0xe2:
205448 case '\r':
205449 case '\n': {
205450 u32 nSkip = jsonBytesToBypass(z, n);
205451 if( nSkip==0 ){
205452 *piOut = 0xFFFD;
205453 return n;
205454 }else if( nSkip==n ){
205455 *piOut = 0;
205456 return n;
205457 }else if( z[nSkip]=='\\' ){
@@ -205460,11 +205648,11 @@
205460 int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
205461 return nSkip + sz;
205462 }
205463 }
205464 default: {
205465 *piOut = 0xFFFD;
205466 return 2;
205467 }
205468 }
205469 }
205470
@@ -205823,11 +206011,11 @@
205823 if( NEVER(aBlob==0) ) return;
205824 memset(&x, 0, sizeof(x));
205825 x.aBlob = (u8*)aBlob;
205826 x.nBlob = nBlob;
205827 jsonStringInit(&s, ctx);
205828 jsonXlateBlobToText(&x, 0, &s);
205829 jsonReturnString(&s, 0, 0);
205830 }
205831
205832
205833 /*
@@ -205934,21 +206122,21 @@
205934 if( c=='\\' ){
205935 u32 v;
205936 u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
205937 if( v<=0x7f ){
205938 zOut[iOut++] = (char)v;
205939 }else if( v==0xfffd ){
205940 /* Silently ignore illegal unicode */
205941 }else if( v<=0x7ff ){
205942 assert( szEscape>=2 );
205943 zOut[iOut++] = (char)(0xc0 | (v>>6));
205944 zOut[iOut++] = 0x80 | (v&0x3f);
205945 }else if( v<0x10000 ){
205946 assert( szEscape>=3 );
205947 zOut[iOut++] = 0xe0 | (v>>12);
205948 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205949 zOut[iOut++] = 0x80 | (v&0x3f);
 
 
205950 }else{
205951 assert( szEscape>=4 );
205952 zOut[iOut++] = 0xf0 | (v>>18);
205953 zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
205954 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
@@ -206046,17 +206234,33 @@
206046 }else{
206047 jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
206048 }
206049 break;
206050 }
206051 case SQLITE_FLOAT:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206052 case SQLITE_INTEGER: {
206053 int n = sqlite3_value_bytes(pArg);
206054 const char *z = (const char*)sqlite3_value_text(pArg);
206055 int e = eType==SQLITE_INTEGER ? JSONB_INT : JSONB_FLOAT;
206056 if( z==0 ) return 1;
206057 jsonBlobAppendNode(pParse, e, n, z);
206058 break;
206059 }
206060 }
206061 if( pParse->oom ){
206062 sqlite3_result_error_nomem(ctx);
@@ -206153,15 +206357,10 @@
206153 }else{
206154 jsonBadPathError(ctx, zPath);
206155 }
206156 return;
206157 }
206158
206159 /*
206160 ** Make a copy of a JsonParse object. The copy will be editable.
206161 */
206162
206163
206164 /*
206165 ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
206166 ** from the SQL function argument pArg. Return a pointer to the new
206167 ** JsonParse object.
@@ -206313,11 +206512,12 @@
206313 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
206314 }
206315 }else{
206316 JsonString s;
206317 jsonStringInit(&s, ctx);
206318 jsonXlateBlobToText(p, 0, &s);
 
206319 jsonReturnString(&s, p, ctx);
206320 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206321 }
206322 }
206323
@@ -206333,29 +206533,32 @@
206333 */
206334 static void jsonDebugPrintBlob(
206335 JsonParse *pParse, /* JSON content */
206336 u32 iStart, /* Start rendering here */
206337 u32 iEnd, /* Do not render this byte or any byte after this one */
206338 int nIndent /* Indent by this many spaces */
 
206339 ){
206340 while( iStart<iEnd ){
206341 u32 i, n, nn, sz = 0;
206342 int showContent = 1;
206343 u8 x = pParse->aBlob[iStart] & 0x0f;
206344 u32 savedNBlob = pParse->nBlob;
206345 printf("%5d:%*s", iStart, nIndent, "");
206346 if( pParse->nBlobAlloc>pParse->nBlob ){
206347 pParse->nBlob = pParse->nBlobAlloc;
206348 }
206349 nn = n = jsonbPayloadSize(pParse, iStart, &sz);
206350 if( nn==0 ) nn = 1;
206351 if( sz>0 && x<JSONB_ARRAY ){
206352 nn += sz;
206353 }
206354 for(i=0; i<nn; i++) printf(" %02x", pParse->aBlob[iStart+i]);
 
 
206355 if( n==0 ){
206356 printf(" ERROR invalid node size\n");
206357 iStart = n==0 ? iStart+1 : iEnd;
206358 continue;
206359 }
206360 pParse->nBlob = savedNBlob;
206361 if( iStart+n+sz>iEnd ){
@@ -206366,59 +206569,61 @@
206366 }else{
206367 iEnd = pParse->nBlob;
206368 }
206369 }
206370 }
206371 printf(" <-- ");
206372 switch( x ){
206373 case JSONB_NULL: printf("null"); break;
206374 case JSONB_TRUE: printf("true"); break;
206375 case JSONB_FALSE: printf("false"); break;
206376 case JSONB_INT: printf("int"); break;
206377 case JSONB_INT5: printf("int5"); break;
206378 case JSONB_FLOAT: printf("float"); break;
206379 case JSONB_FLOAT5: printf("float5"); break;
206380 case JSONB_TEXT: printf("text"); break;
206381 case JSONB_TEXTJ: printf("textj"); break;
206382 case JSONB_TEXT5: printf("text5"); break;
206383 case JSONB_TEXTRAW: printf("textraw"); break;
206384 case JSONB_ARRAY: {
206385 printf("array, %u bytes\n", sz);
206386 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206387 showContent = 0;
206388 break;
206389 }
206390 case JSONB_OBJECT: {
206391 printf("object, %u bytes\n", sz);
206392 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206393 showContent = 0;
206394 break;
206395 }
206396 default: {
206397 printf("ERROR: unknown node type\n");
206398 showContent = 0;
206399 break;
206400 }
206401 }
206402 if( showContent ){
206403 if( sz==0 && x<=JSONB_FALSE ){
206404 printf("\n");
206405 }else{
206406 u32 i;
206407 printf(": \"");
206408 for(i=iStart+n; i<iStart+n+sz; i++){
206409 u8 c = pParse->aBlob[i];
206410 if( c<0x20 || c>=0x7f ) c = '.';
206411 putchar(c);
206412 }
206413 printf("\"\n");
206414 }
206415 }
206416 iStart += n + sz;
206417 }
206418 }
206419 static void jsonShowParse(JsonParse *pParse){
 
 
206420 if( pParse==0 ){
206421 printf("NULL pointer\n");
206422 return;
206423 }else{
206424 printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
@@ -206425,31 +206630,42 @@
206425 printf("nBlob = %u\n", pParse->nBlob);
206426 printf("delta = %d\n", pParse->delta);
206427 if( pParse->nBlob==0 ) return;
206428 printf("content (bytes 0..%u):\n", pParse->nBlob-1);
206429 }
206430 jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0);
 
 
 
206431 }
206432 #endif /* SQLITE_DEBUG */
206433
206434 #ifdef SQLITE_DEBUG
206435 /*
206436 ** SQL function: json_parse(JSON)
206437 **
206438 ** Parse JSON using jsonParseFuncArg(). Then print a dump of that
206439 ** parse on standard output.
206440 */
206441 static void jsonParseFunc(
206442 sqlite3_context *ctx,
206443 int argc,
206444 sqlite3_value **argv
206445 ){
206446 JsonParse *p; /* The parse */
 
206447
206448 assert( argc==1 );
 
206449 p = jsonParseFuncArg(ctx, argv[0], 0);
206450 jsonShowParse(p);
 
 
 
 
 
 
206451 jsonParseFree(p);
206452 }
206453 #endif /* SQLITE_DEBUG */
206454
206455 /****************************************************************************
@@ -206641,11 +206857,11 @@
206641 }
206642 if( j<p->nBlob ){
206643 if( argc==2 ){
206644 if( flags & JSON_JSON ){
206645 jsonStringInit(&jx, ctx);
206646 jsonXlateBlobToText(p, j, &jx);
206647 jsonReturnString(&jx, 0, 0);
206648 jsonStringReset(&jx);
206649 assert( (flags & JSON_BLOB)==0 );
206650 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206651 }else{
@@ -206656,11 +206872,11 @@
206656 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206657 }
206658 }
206659 }else{
206660 jsonAppendSeparator(&jx);
206661 jsonXlateBlobToText(p, j, &jx);
206662 }
206663 }else if( j==JSON_LOOKUP_NOTFOUND ){
206664 if( argc==2 ){
206665 goto json_extract_error; /* Return NULL if not found */
206666 }else{
@@ -229267,23 +229483,28 @@
229267 **
229268 ** This function may be quite inefficient if used with an FTS5 table
229269 ** created with the "columnsize=0" option.
229270 **
229271 ** xColumnText:
229272 ** This function attempts to retrieve the text of column iCol of the
229273 ** current document. If successful, (*pz) is set to point to a buffer
 
 
 
229274 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
229275 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
229276 ** if an error occurs, an SQLite error code is returned and the final values
229277 ** of (*pz) and (*pn) are undefined.
229278 **
229279 ** xPhraseCount:
229280 ** Returns the number of phrases in the current query expression.
229281 **
229282 ** xPhraseSize:
229283 ** Returns the number of tokens in phrase iPhrase of the query. Phrases
229284 ** are numbered starting from zero.
 
 
229285 **
229286 ** xInstCount:
229287 ** Set *pnInst to the total number of occurrences of all phrases within
229288 ** the query within the current row. Return SQLITE_OK if successful, or
229289 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -229295,16 +229516,17 @@
229295 **
229296 ** xInst:
229297 ** Query for the details of phrase match iIdx within the current row.
229298 ** Phrase matches are numbered starting from zero, so the iIdx argument
229299 ** should be greater than or equal to zero and smaller than the value
229300 ** output by xInstCount().
 
229301 **
229302 ** Usually, output parameter *piPhrase is set to the phrase number, *piCol
229303 ** to the column in which it occurs and *piOff the token offset of the
229304 ** first token of the phrase. Returns SQLITE_OK if successful, or an error
229305 ** code (i.e. SQLITE_NOMEM) if an error occurs.
229306 **
229307 ** This API can be quite slow if used with an FTS5 table created with the
229308 ** "detail=none" or "detail=column" option.
229309 **
229310 ** xRowid:
@@ -229325,10 +229547,14 @@
229325 ** row visited, the callback function passed as the fourth argument
229326 ** is invoked. The context and API objects passed to the callback
229327 ** function may be used to access the properties of each matched row.
229328 ** Invoking Api.xUserData() returns a copy of the pointer passed as
229329 ** the third argument to pUserData.
 
 
 
 
229330 **
229331 ** If the callback function returns any value other than SQLITE_OK, the
229332 ** query is abandoned and the xQueryPhrase function returns immediately.
229333 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
229334 ** Otherwise, the error code is propagated upwards.
@@ -229446,22 +229672,30 @@
229446 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
229447 ** This is used to access token iToken of phrase iPhrase of the current
229448 ** query. Before returning, output parameter *ppToken is set to point
229449 ** to a buffer containing the requested token, and *pnToken to the
229450 ** size of this buffer in bytes.
 
 
 
 
 
 
229451 **
229452 ** The output text is not a copy of the query text that specified the
229453 ** token. It is the output of the tokenizer module. For tokendata=1
229454 ** tables, this includes any embedded 0x00 and trailing data.
229455 **
229456 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
229457 ** This is used to access token iToken of phrase hit iIdx within the
229458 ** current row. Output variable (*ppToken) is set to point to a buffer
229459 ** containing the matching document token, and (*pnToken) to the size
229460 ** of that buffer in bytes. This API is not available if the specified
229461 ** token matches a prefix query term. In that case both output variables
229462 ** are always set to 0.
 
 
229463 **
229464 ** The output text is not a copy of the document text that was tokenized.
229465 ** It is the output of the tokenizer module. For tokendata=1 tables, this
229466 ** includes any embedded 0x00 and trailing data.
229467 **
@@ -232433,12 +232667,14 @@
232433 memset(&ctx, 0, sizeof(HighlightContext));
232434 ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
232435 ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
232436 ctx.iRangeEnd = -1;
232437 rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
232438
232439 if( ctx.zIn ){
 
 
232440 if( rc==SQLITE_OK ){
232441 rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
232442 }
232443
232444 if( rc==SQLITE_OK ){
@@ -236273,15 +236509,19 @@
236273 Fts5Expr *pExpr,
236274 int iPhrase,
236275 Fts5Expr **ppNew
236276 ){
236277 int rc = SQLITE_OK; /* Return code */
236278 Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
236279 Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
236280 TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
236281 pOrig = pExpr->apExprPhrase[iPhrase];
236282 pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
 
 
 
 
236283 if( rc==SQLITE_OK ){
236284 pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
236285 sizeof(Fts5ExprPhrase*));
236286 }
236287 if( rc==SQLITE_OK ){
@@ -236290,11 +236530,11 @@
236290 }
236291 if( rc==SQLITE_OK ){
236292 pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
236293 sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
236294 }
236295 if( rc==SQLITE_OK ){
236296 Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
236297 if( pColsetOrig ){
236298 sqlite3_int64 nByte;
236299 Fts5Colset *pColset;
236300 nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
@@ -236304,29 +236544,31 @@
236304 }
236305 pNew->pRoot->pNear->pColset = pColset;
236306 }
236307 }
236308
236309 if( pOrig->nTerm ){
236310 int i; /* Used to iterate through phrase terms */
236311 sCtx.pConfig = pExpr->pConfig;
236312 for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
236313 int tflags = 0;
236314 Fts5ExprTerm *p;
236315 for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
236316 rc = fts5ParseTokenize((void*)&sCtx, tflags, p->pTerm,p->nFullTerm,0,0);
236317 tflags = FTS5_TOKEN_COLOCATED;
236318 }
236319 if( rc==SQLITE_OK ){
236320 sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
236321 sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
236322 }
236323 }
236324 }else{
236325 /* This happens when parsing a token or quoted phrase that contains
236326 ** no token characters at all. (e.g ... MATCH '""'). */
236327 sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
 
 
236328 }
236329
236330 if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
236331 /* All the allocations succeeded. Put the expression object together. */
236332 pNew->pIndex = pExpr->pIndex;
@@ -239776,13 +240018,13 @@
239776 for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
239777 if( pData->p[iOff] ) break;
239778 }
239779
239780 if( iOff<pData->nn ){
239781 i64 iVal;
239782 pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
239783 iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
239784 pLvl->iRowid += iVal;
239785 pLvl->iOff = iOff;
239786 }else{
239787 pLvl->bEof = 1;
239788 }
@@ -246173,20 +246415,20 @@
246173 fts5DataRelease(pLeaf);
246174 }
246175 }
246176
246177 static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
246178 int iTermOff = 0;
246179 int ii;
246180
246181 Fts5Buffer buf1 = {0,0,0};
246182 Fts5Buffer buf2 = {0,0,0};
246183
246184 ii = pLeaf->szLeaf;
246185 while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
246186 int res;
246187 int iOff;
246188 int nIncr;
246189
246190 ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
246191 iTermOff += nIncr;
246192 iOff = iTermOff;
@@ -249207,11 +249449,14 @@
249207 const char **pz,
249208 int *pn
249209 ){
249210 int rc = SQLITE_OK;
249211 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249212 if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
 
 
 
249213 || pCsr->ePlan==FTS5_PLAN_SPECIAL
249214 ){
249215 *pz = 0;
249216 *pn = 0;
249217 }else{
@@ -249232,12 +249477,13 @@
249232 ){
249233 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
249234 int rc = SQLITE_OK;
249235 int bLive = (pCsr->pSorter==0);
249236
249237 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
249238
 
249239 if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
249240 Fts5PoslistPopulator *aPopulator;
249241 int i;
249242 aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
249243 if( aPopulator==0 ) rc = SQLITE_NOMEM;
@@ -249257,18 +249503,24 @@
249257 }
249258 }
249259 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
249260 }
249261
249262 if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
249263 Fts5Sorter *pSorter = pCsr->pSorter;
249264 int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
249265 *pn = pSorter->aIdx[iPhrase] - i1;
249266 *pa = &pSorter->aPoslist[i1];
 
 
 
 
249267 }else{
249268 *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
 
249269 }
 
249270
249271 return rc;
249272 }
249273
249274 /*
@@ -250223,11 +250475,11 @@
250223 int nArg, /* Number of args */
250224 sqlite3_value **apUnused /* Function arguments */
250225 ){
250226 assert( nArg==0 );
250227 UNUSED_PARAM2(nArg, apUnused);
250228 sqlite3_result_text(pCtx, "fts5: 2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9", -1, SQLITE_TRANSIENT);
250229 }
250230
250231 /*
250232 ** Return true if zName is the extension on one of the shadow tables used
250233 ** by this module.
250234
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** c216921b115169ebfd239267b4ab5ad0fc96.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.45.0"
463 #define SQLITE_VERSION_NUMBER 3045000
464 #define SQLITE_SOURCE_ID "2023-12-31 12:38:43 c216921b115169ebfd239267b4ab5ad0fc960ffadce09044b68812f49110d607"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -8350,13 +8350,15 @@
8350 ** can enter.)^ If the same thread tries to enter any mutex other
8351 ** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
8352 **
8353 ** ^(Some systems (for example, Windows 95) do not support the operation
8354 ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8355 ** will always return SQLITE_BUSY. In most cases the SQLite core only uses
8356 ** sqlite3_mutex_try() as an optimization, so this is acceptable
8357 ** behavior. The exceptions are unix builds that set the
8358 ** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
8359 ** sqlite3_mutex_try() is required.)^
8360 **
8361 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
8362 ** previously entered by the same thread. The behavior
8363 ** is undefined if the mutex is not currently entered by the
8364 ** calling thread or is not currently allocated.
@@ -13125,23 +13127,28 @@
13127 **
13128 ** This function may be quite inefficient if used with an FTS5 table
13129 ** created with the "columnsize=0" option.
13130 **
13131 ** xColumnText:
13132 ** If parameter iCol is less than zero, or greater than or equal to the
13133 ** number of columns in the table, SQLITE_RANGE is returned.
13134 **
13135 ** Otherwise, this function attempts to retrieve the text of column iCol of
13136 ** the current document. If successful, (*pz) is set to point to a buffer
13137 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
13138 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
13139 ** if an error occurs, an SQLite error code is returned and the final values
13140 ** of (*pz) and (*pn) are undefined.
13141 **
13142 ** xPhraseCount:
13143 ** Returns the number of phrases in the current query expression.
13144 **
13145 ** xPhraseSize:
13146 ** If parameter iCol is less than zero, or greater than or equal to the
13147 ** number of phrases in the current query, as returned by xPhraseCount,
13148 ** 0 is returned. Otherwise, this function returns the number of tokens in
13149 ** phrase iPhrase of the query. Phrases are numbered starting from zero.
13150 **
13151 ** xInstCount:
13152 ** Set *pnInst to the total number of occurrences of all phrases within
13153 ** the query within the current row. Return SQLITE_OK if successful, or
13154 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -13153,16 +13160,17 @@
13160 **
13161 ** xInst:
13162 ** Query for the details of phrase match iIdx within the current row.
13163 ** Phrase matches are numbered starting from zero, so the iIdx argument
13164 ** should be greater than or equal to zero and smaller than the value
13165 ** output by xInstCount(). If iIdx is less than zero or greater than
13166 ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
13167 **
13168 ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
13169 ** to the column in which it occurs and *piOff the token offset of the
13170 ** first token of the phrase. SQLITE_OK is returned if successful, or an
13171 ** error code (i.e. SQLITE_NOMEM) if an error occurs.
13172 **
13173 ** This API can be quite slow if used with an FTS5 table created with the
13174 ** "detail=none" or "detail=column" option.
13175 **
13176 ** xRowid:
@@ -13183,10 +13191,14 @@
13191 ** row visited, the callback function passed as the fourth argument
13192 ** is invoked. The context and API objects passed to the callback
13193 ** function may be used to access the properties of each matched row.
13194 ** Invoking Api.xUserData() returns a copy of the pointer passed as
13195 ** the third argument to pUserData.
13196 **
13197 ** If parameter iPhrase is less than zero, or greater than or equal to
13198 ** the number of phrases in the query, as returned by xPhraseCount(),
13199 ** this function returns SQLITE_RANGE.
13200 **
13201 ** If the callback function returns any value other than SQLITE_OK, the
13202 ** query is abandoned and the xQueryPhrase function returns immediately.
13203 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
13204 ** Otherwise, the error code is propagated upwards.
@@ -13304,22 +13316,30 @@
13316 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
13317 ** This is used to access token iToken of phrase iPhrase of the current
13318 ** query. Before returning, output parameter *ppToken is set to point
13319 ** to a buffer containing the requested token, and *pnToken to the
13320 ** size of this buffer in bytes.
13321 **
13322 ** If iPhrase or iToken are less than zero, or if iPhrase is greater than
13323 ** or equal to the number of phrases in the query as reported by
13324 ** xPhraseCount(), or if iToken is equal to or greater than the number of
13325 ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
13326 are both zeroed.
13327 **
13328 ** The output text is not a copy of the query text that specified the
13329 ** token. It is the output of the tokenizer module. For tokendata=1
13330 ** tables, this includes any embedded 0x00 and trailing data.
13331 **
13332 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13333 ** This is used to access token iToken of phrase hit iIdx within the
13334 ** current row. If iIdx is less than zero or greater than or equal to the
13335 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13336 ** output variable (*ppToken) is set to point to a buffer containing the
13337 ** matching document token, and (*pnToken) to the size of that buffer in
13338 ** bytes. This API is not available if the specified token matches a
13339 ** prefix query term. In that case both output variables are always set
13340 ** to 0.
13341 **
13342 ** The output text is not a copy of the document text that was tokenized.
13343 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13344 ** includes any embedded 0x00 and trailing data.
13345 **
@@ -13991,10 +14011,23 @@
14011 #if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH)
14012 # define SQLITE_USE_SEH 1
14013 #else
14014 # undef SQLITE_USE_SEH
14015 #endif
14016
14017 /*
14018 ** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly
14019 ** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0
14020 */
14021 #if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1
14022 /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */
14023 # undef SQLITE_DIRECT_OVERFLOW_READ
14024 #else
14025 /* In all other cases, enable */
14026 # define SQLITE_DIRECT_OVERFLOW_READ 1
14027 #endif
14028
14029
14030 /*
14031 ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
14032 ** 0 means mutexes are permanently disable and the library is never
14033 ** threadsafe. 1 means the library is serialized which is the highest
@@ -15874,11 +15907,11 @@
15907 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
15908 SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
15909 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
15910 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
15911 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
15912 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*);
15913 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
15914 SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
15915
15916 /* Functions used to truncate the database file. */
15917 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
@@ -18630,10 +18663,11 @@
18663 unsigned isResized:1; /* True if resizeIndexObject() has been called */
18664 unsigned isCovering:1; /* True if this is a covering index */
18665 unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
18666 unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
18667 unsigned bNoQuery:1; /* Do not use this index to optimize queries */
18668 unsigned bSlow:1; /* This index is not good for equality lookups */
18669 unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
18670 unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
18671 unsigned bHasExpr:1; /* Index contains an expression, either a literal
18672 ** expression, or a reference to a VIRTUAL column */
18673 #ifdef SQLITE_ENABLE_STAT4
@@ -24028,11 +24062,11 @@
24062 /* no break */ deliberate_fall_through
24063 case SQLITE_DBSTATUS_CACHE_HIT:
24064 case SQLITE_DBSTATUS_CACHE_MISS:
24065 case SQLITE_DBSTATUS_CACHE_WRITE:{
24066 int i;
24067 u64 nRet = 0;
24068 assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
24069 assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
24070
24071 for(i=0; i<db->nDb; i++){
24072 if( db->aDb[i].pBt ){
@@ -24041,11 +24075,11 @@
24075 }
24076 }
24077 *pHighwater = 0; /* IMP: R-42420-56072 */
24078 /* IMP: R-54100-20147 */
24079 /* IMP: R-29431-39229 */
24080 *pCurrent = (int)nRet & 0x7fffffff;
24081 break;
24082 }
24083
24084 /* Set *pCurrent to non-zero if there are unresolved deferred foreign
24085 ** key constraints. Set *pCurrent to zero if all foreign key constraints
@@ -34677,11 +34711,11 @@
34711 ** Load the sqlite3.iSysErrno field if that is an appropriate thing
34712 ** to do based on the SQLite error code in rc.
34713 */
34714 SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
34715 if( rc==SQLITE_IOERR_NOMEM ) return;
34716 #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
34717 if( rc==SQLITE_IOERR_IN_PAGE ){
34718 int ii;
34719 int iErr;
34720 sqlite3BtreeEnterAll(db);
34721 for(ii=0; ii<db->nDb; ii++){
@@ -42365,13 +42399,19 @@
42399 struct flock f; /* The posix advisory locking structure */
42400 int rc = SQLITE_OK; /* Result code form fcntl() */
42401
42402 pShmNode = pFile->pInode->pShmNode;
42403
42404 /* Assert that the parameters are within expected range and that the
42405 ** correct mutex or mutexes are held. */
42406 assert( pShmNode->nRef>=0 );
42407 assert( (ofst==UNIX_SHM_DMS && n==1)
42408 || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK))
42409 );
42410 if( ofst==UNIX_SHM_DMS ){
42411 assert( pShmNode->nRef>0 || unixMutexHeld() );
42412 assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
42413 }else{
42414 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42415 int ii;
42416 for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
42417 assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
@@ -57333,11 +57373,11 @@
57373 i64 journalSizeLimit; /* Size limit for persistent journal files */
57374 char *zFilename; /* Name of the database file */
57375 char *zJournal; /* Name of the journal file */
57376 int (*xBusyHandler)(void*); /* Function to call when busy */
57377 void *pBusyHandlerArg; /* Context argument for xBusyHandler */
57378 u32 aStat[4]; /* Total cache hits, misses, writes, spills */
57379 #ifdef SQLITE_TEST
57380 int nRead; /* Database pages read */
57381 #endif
57382 void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
57383 int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
@@ -63477,15 +63517,15 @@
63517 a[1] = sqlite3PcachePagecount(pPager->pPCache);
63518 a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
63519 a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
63520 a[4] = pPager->eState;
63521 a[5] = pPager->errCode;
63522 a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff;
63523 a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff;
63524 a[8] = 0; /* Used to be pPager->nOvfl */
63525 a[9] = pPager->nRead;
63526 a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff;
63527 return a;
63528 }
63529 #endif
63530
63531 /*
@@ -63497,11 +63537,11 @@
63537 ** Before returning, *pnVal is incremented by the
63538 ** current cache hit or miss count, according to the value of eStat. If the
63539 ** reset parameter is non-zero, the cache hit or miss count is zeroed before
63540 ** returning.
63541 */
63542 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){
63543
63544 assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
63545 || eStat==SQLITE_DBSTATUS_CACHE_MISS
63546 || eStat==SQLITE_DBSTATUS_CACHE_WRITE
63547 || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
@@ -64437,11 +64477,11 @@
64477 assert( pPager->eState>=PAGER_READER );
64478 return sqlite3WalFramesize(pPager->pWal);
64479 }
64480 #endif
64481
64482 #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
64483 SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){
64484 return sqlite3WalSystemErrno(pPager->pWal);
64485 }
64486 #endif
64487
@@ -106789,10 +106829,11 @@
106829 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
106830 }
106831 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
106832 pParse->checkSchema = 1;
106833 pTopNC->nNcErr++;
106834 eNewExprOp = TK_NULL;
106835 }
106836 assert( pFJMatch==0 );
106837
106838 /* Remove all substructure from pExpr */
106839 if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
@@ -110976,13 +111017,14 @@
111017 case TK_BLOB:
111018 return 0;
111019 case TK_COLUMN:
111020 assert( ExprUseYTab(p) );
111021 return ExprHasProperty(p, EP_CanBeNull) ||
111022 NEVER(p->y.pTab==0) || /* Reference to column of index on expr */
111023 (p->iColumn>=0
111024 && p->y.pTab->aCol!=0 /* Possible due to prior error */
111025 && ALWAYS(p->iColumn<p->y.pTab->nCol)
111026 && p->y.pTab->aCol[p->iColumn].notNull==0);
111027 default:
111028 return 1;
111029 }
111030 }
@@ -113560,12 +113602,14 @@
113602 assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
113603 if( pParse->pVdbe==0 ) return;
113604 inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
113605 if( inReg!=target ){
113606 u8 op;
113607 Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr);
113608 testcase( pX!=pExpr );
113609 if( ALWAYS(pX)
113610 && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER)
113611 ){
113612 op = OP_Copy;
113613 }else{
113614 op = OP_SCopy;
113615 }
@@ -117827,10 +117871,11 @@
117871 typedef struct StatAccum StatAccum;
117872 typedef struct StatSample StatSample;
117873 struct StatSample {
117874 tRowcnt *anEq; /* sqlite_stat4.nEq */
117875 tRowcnt *anDLt; /* sqlite_stat4.nDLt */
117876 tRowcnt *amxEq; /* Maximum length run of equal values */
117877 #ifdef SQLITE_ENABLE_STAT4
117878 tRowcnt *anLt; /* sqlite_stat4.nLt */
117879 union {
117880 i64 iRowid; /* Rowid in main table of the key */
117881 u8 *aRowid; /* Key for WITHOUT ROWID tables */
@@ -117986,10 +118031,11 @@
118031 assert( nKeyCol>0 );
118032
118033 /* Allocate the space required for the StatAccum object */
118034 n = sizeof(*p)
118035 + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
118036 + sizeof(tRowcnt)*nColUp /* StatAccum.amxEq */
118037 + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
118038 #ifdef SQLITE_ENABLE_STAT4
118039 if( mxSample ){
118040 n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
118041 + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
@@ -118008,11 +118054,12 @@
118054 p->nLimit = sqlite3_value_int64(argv[3]);
118055 p->nCol = nCol;
118056 p->nKeyCol = nKeyCol;
118057 p->nSkipAhead = 0;
118058 p->current.anDLt = (tRowcnt*)&p[1];
118059 p->current.amxEq = &p->current.anDLt[nColUp];
118060 p->current.anEq = &p->current.amxEq[nColUp];
118061
118062 #ifdef SQLITE_ENABLE_STAT4
118063 p->mxSample = p->nLimit==0 ? mxSample : 0;
118064 if( mxSample ){
118065 u8 *pSpace; /* Allocated space not yet assigned */
@@ -118277,11 +118324,14 @@
118324 assert( p->nCol>0 );
118325 assert( iChng<p->nCol );
118326
118327 if( p->nRow==0 ){
118328 /* This is the first call to this function. Do initialization. */
118329 for(i=0; i<p->nCol; i++){
118330 p->current.anEq[i] = 1;
118331 p->current.amxEq[i] = 1;
118332 }
118333 }else{
118334 /* Second and subsequent calls get processed here */
118335 #ifdef SQLITE_ENABLE_STAT4
118336 if( p->mxSample ) samplePushPrevious(p, iChng);
118337 #endif
@@ -118294,10 +118344,13 @@
118344 for(i=iChng; i<p->nCol; i++){
118345 p->current.anDLt[i]++;
118346 #ifdef SQLITE_ENABLE_STAT4
118347 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
118348 #endif
118349 if( p->current.amxEq[i]<p->current.anEq[i] ){
118350 p->current.amxEq[i] = p->current.anEq[i];
118351 }
118352 p->current.anEq[i] = 1;
118353 }
118354 }
118355
118356 p->nRow++;
@@ -118402,37 +118455,65 @@
118455 ** for each indexed column. This additional integer is an estimate of
118456 ** the number of rows matched by a equality query on the index using
118457 ** a key with the corresponding number of fields. In other words,
118458 ** if the index is on columns (a,b) and the sqlite_stat1 value is
118459 ** "100 10 2", then SQLite estimates that:
118460 ** | | |
118461 ** | | `-- "WHERE a=? AND b=?" matches approximately 2 rows
118462 ** | `---- "WHERE a=?" matches approximately 10 rows
118463 ** `-------- There are approximately 100 rows in the index total
118464 **
118465 ** If D is the count of distinct values and K is the total number of
118466 ** rows, then each estimate is usually computed as:
118467 **
118468 ** I = (K+D-1)/D
118469 **
118470 ** Adjustments to the I value are made in some cases. See comments
118471 ** in-line below.
 
 
118472 */
118473 sqlite3_str sStat; /* Text of the constructed "stat" line */
118474 int i; /* Loop counter */
118475 int iUneven = 1; /* max/avg */
118476 u64 nRow; /* Number of rows in the index */
118477
118478 sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100);
118479 nRow = p->nSkipAhead ? p->nEst : p->nRow;
118480 sqlite3_str_appendf(&sStat, "%llu", nRow);
118481 for(i=0; i<p->nKeyCol; i++){
118482 u64 nDistinct = p->current.anDLt[i] + 1;
118483 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
118484 u64 mx = p->current.amxEq[i];
118485 if( nDistinct==1 && p->nLimit>0 ){
118486 /* If we never saw more than a single value in a PRAGMA analysis_limit
118487 ** search, then set the estimated number of matching rows to the
118488 ** estimated number of rows in the index. */
118489 iVal = p->nEst;
118490 }else if( iVal<mx/10 ){
118491 /* Report uneven= if the maximum run of identical values ever
118492 ** reaches or exceeds 10 times the average run */
118493 int iRatio = mx/iVal;
118494 if( iUneven<iRatio ) iUneven = iRatio;
118495 }else if( iVal==2 && p->nRow*10 <= nDistinct*11 ){
118496 /* If the value is less than or equal to 1.1, round it down to 1.0 */
118497 iVal = 1;
118498 }
118499 sqlite3_str_appendf(&sStat, " %llu", iVal);
118500 assert( p->current.anEq[i] );
118501
118502 /* Add the "slow" argument if the peak number of rows obtained
118503 ** from a full equality match is so large that a full table scan
118504 ** seems likely to be faster.
118505 */
118506 if( i==p->nKeyCol-1
118507 && nRow > 1000
118508 && nRow <= iVal*iUneven + sqlite3LogEst(nRow*2/3)
118509 ){
118510 sqlite3_str_appendf(&sStat, " slow");
118511 }
118512 }
118513 if( iUneven>1 ){
118514 sqlite3_str_appendf(&sStat, " uneven=%d", iUneven);
118515 }
118516 sqlite3ResultStrAccum(context, &sStat);
118517 }
118518 #ifdef SQLITE_ENABLE_STAT4
118519 else if( eCall==STAT_GET_ROWID ){
@@ -119075,11 +119156,11 @@
119156 #ifdef SQLITE_ENABLE_STAT4
119157 if( z==0 ) z = "";
119158 #else
119159 assert( z!=0 );
119160 #endif
119161 for(i=0; i<nOut; i++){
119162 v = 0;
119163 while( (c=z[0])>='0' && c<='9' ){
119164 v = v*10 + c - '0';
119165 z++;
119166 }
@@ -119099,19 +119180,38 @@
119180 #else
119181 if( pIndex ){
119182 #endif
119183 pIndex->bUnordered = 0;
119184 pIndex->noSkipScan = 0;
119185 pIndex->bSlow = 0;
119186 while( z[0] ){
119187 if( sqlite3_strglob("unordered*", z)==0 ){
119188 pIndex->bUnordered = 1;
119189 }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
119190 int sz = sqlite3Atoi(z+3);
119191 if( sz<2 ) sz = 2;
119192 pIndex->szIdxRow = sqlite3LogEst(sz);
119193 }else if( sqlite3_strglob("noskipscan*", z)==0 ){
119194 pIndex->noSkipScan = 1;
119195 }else if( sqlite3_strglob("slow*", z)==0 ){
119196 pIndex->bSlow = 1;
119197 }else if( sqlite3_strglob("uneven=[0-9]*", z)==0 ){
119198 /* An argument of "uneven=NNN" means that the maximum length
119199 ** run of the same value is NNN times longer than the average.
119200 ** Go through the iaRowLogEst[] values for the index and increase
119201 ** them so that so that they are each no less than 1/8th the
119202 ** maximum value. */
119203 LogEst scale = sqlite3LogEst(sqlite3Atoi(z+7)) - 30;
119204 if( scale>0 ){
119205 LogEst mx = aLog[0];
119206 int jj;
119207 for(jj=1; jj<pIndex->nKeyCol; jj++){
119208 LogEst x = aLog[jj] + scale;
119209 if( x>mx ) x = mx;
119210 aLog[jj] = x;
119211 }
119212 }
119213 }
119214 #ifdef SQLITE_ENABLE_COSTMULT
119215 else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
119216 pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
119217 }
@@ -148743,11 +148843,11 @@
148843 pSub->pPrior = 0;
148844 pSub->pNext = 0;
148845 pSub->selFlags |= SF_Aggregate;
148846 pSub->selFlags &= ~SF_Compound;
148847 pSub->nSelectRow = 0;
148848 sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList);
148849 pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
148850 pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
148851 pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
148852 sqlite3PExprAddSelect(pParse, pTerm, pSub);
148853 if( pExpr==0 ){
@@ -154295,11 +154395,10 @@
154395 assert( sqlite3BtreeHoldsAllMutexes(db) );
154396 assert( sqlite3_mutex_held(db->mutex) );
154397
154398 if( p ){
154399 db->pDisconnect = 0;
 
154400 do {
154401 VTable *pNext = p->pNext;
154402 sqlite3VtabUnlock(p);
154403 p = pNext;
154404 }while( p );
@@ -155861,11 +155960,11 @@
155960 */
155961 SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
155962 #ifdef WHERETRACE_ENABLED
155963 SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
155964 SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm);
155965 SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC);
155966 #endif
155967 SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
155968 WhereClause *pWC, /* The WHERE clause to be searched */
155969 int iCur, /* Cursor number of LHS */
155970 int iColumn, /* Column number of LHS */
@@ -162890,21 +162989,38 @@
162989 #endif
162990
162991 #ifdef WHERETRACE_ENABLED
162992 /*
162993 ** Print a WhereLoop object for debugging purposes
162994 **
162995 ** Format example:
162996 **
162997 ** .--- Position in WHERE clause rSetup, rRun, nOut ---.
162998 ** | |
162999 ** | .--- selfMask nTerm ------. |
163000 ** | | | |
163001 ** | | .-- prereq Idx wsFlags----. | |
163002 ** | | | Name | | |
163003 ** | | | __|__ nEq ---. ___|__ | __|__
163004 ** | / \ / \ / \ | / \ / \ / \
163005 ** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
163006 */
163007 SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
163008 if( pWC ){
163009 WhereInfo *pWInfo = pWC->pWInfo;
163010 int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
163011 SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
163012 Table *pTab = pItem->pTab;
163013 Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
163014 sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
163015 p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
163016 sqlite3DebugPrintf(" %12s",
163017 pItem->zAlias ? pItem->zAlias : pTab->zName);
163018 }else{
163019 sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d",
163020 p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab);
163021 }
163022 if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
163023 const char *zName;
163024 if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
163025 if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
163026 int i = sqlite3Strlen30(zName) - 1;
@@ -162936,10 +163052,19 @@
163052 int i;
163053 for(i=0; i<p->nLTerm; i++){
163054 sqlite3WhereTermPrint(p->aLTerm[i], i);
163055 }
163056 }
163057 }
163058 SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){
163059 if( p ) sqlite3WhereLoopPrint(p, 0);
163060 }
163061 SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){
163062 while( p ){
163063 sqlite3ShowWhereLoop(p);
163064 p = p->pNextLoop;
163065 }
163066 }
163067 #endif
163068
163069 /*
163070 ** Convert bulk memory into a valid WhereLoop that can be passed
@@ -163049,50 +163174,64 @@
163174 }
163175 sqlite3DbNNFreeNN(db, pWInfo);
163176 }
163177
163178 /*
163179 ** Return TRUE if X is a proper subset of Y but is of equal or less cost.
163180 ** In other words, return true if all constraints of X are also part of Y
163181 ** and Y has additional constraints that might speed the search that X lacks
163182 ** but the cost of running X is not more than the cost of running Y.
163183 **
163184 ** In other words, return true if the cost relationwship between X and Y
163185 ** is inverted and needs to be adjusted.
163186 **
163187 ** Case 1:
163188 **
163189 ** (1a) X and Y use the same index.
163190 ** (1b) X has fewer == terms than Y
163191 ** (1c) Neither X nor Y use skip-scan
163192 ** (1d) X does not have a a greater cost than Y
163193 **
163194 ** Case 2:
163195 **
163196 ** (2a) X has the same or lower cost, or returns the same or fewer rows,
163197 ** than Y.
163198 ** (2b) X uses fewer WHERE clause terms than Y
163199 ** (2c) Every WHERE clause term used by X is also used by Y
163200 ** (2d) X skips at least as many columns as Y
163201 ** (2e) If X is a covering index, than Y is too
163202 */
163203 static int whereLoopCheaperProperSubset(
163204 const WhereLoop *pX, /* First WhereLoop to compare */
163205 const WhereLoop *pY /* Compare against this WhereLoop */
163206 ){
163207 int i, j;
163208 if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */
163209 assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 );
163210 assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 );
163211 if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */
163212 && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */
163213 && pX->nSkip==0 && pY->nSkip==0 /* (1c) */
163214 ){
163215 return 1; /* Case 1 is true */
163216 }
163217 if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
163218 return 0; /* (2b) */
163219 }
163220 if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */
 
163221 for(i=pX->nLTerm-1; i>=0; i--){
163222 if( pX->aLTerm[i]==0 ) continue;
163223 for(j=pY->nLTerm-1; j>=0; j--){
163224 if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
163225 }
163226 if( j<0 ) return 0; /* (2c) */
163227 }
163228 if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
163229 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
163230 return 0; /* (2e) */
163231 }
163232 return 1; /* Case 2 is true */
163233 }
163234
163235 /*
163236 ** Try to adjust the cost and number of output rows of WhereLoop pTemplate
163237 ** upwards or downwards so that:
@@ -163578,11 +163717,14 @@
163717 opMask = WO_LT|WO_LE;
163718 }else{
163719 assert( pNew->u.btree.nBtm==0 );
163720 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
163721 }
163722 if( pProbe->bUnordered || pProbe->bSlow ){
163723 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
163724 if( pProbe->bSlow ) opMask &= ~(WO_EQ|WO_IN|WO_IS);
163725 }
163726
163727 assert( pNew->u.btree.nEq<pProbe->nColumn );
163728 assert( pNew->u.btree.nEq<pProbe->nKeyCol
163729 || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
163730
@@ -166683,11 +166825,14 @@
166825 ** struct, the contents of WhereInfo.a[], the WhereClause structure
166826 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
166827 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
166828 ** some architectures. Hence the ROUND8() below.
166829 */
166830 nByteWInfo = ROUND8P(sizeof(WhereInfo));
166831 if( nTabList>1 ){
166832 nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel));
166833 }
166834 pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
166835 if( db->mallocFailed ){
166836 sqlite3DbFree(db, pWInfo);
166837 pWInfo = 0;
166838 goto whereBeginError;
@@ -167245,10 +167390,15 @@
167390 whereBeginError:
167391 if( pWInfo ){
167392 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
167393 whereInfoFree(db, pWInfo);
167394 }
167395 #ifdef WHERETRACE_ENABLED
167396 /* Prevent harmless compiler warnings about debugging routines
167397 ** being declared but never used */
167398 sqlite3ShowWhereLoopList(0);
167399 #endif /* WHERETRACE_ENABLED */
167400 return 0;
167401 }
167402
167403 /*
167404 ** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
@@ -203027,13 +203177,13 @@
203177 ** The original design stored all JSON as pure text, canonical RFC-8259.
203178 ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
203179 ** All generated JSON text still conforms strictly to RFC-8259, but text
203180 ** with JSON-5 extensions is accepted as input.
203181 **
203182 ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also
203183 ** accept BLOB values that have JSON encoded using a binary representation
203184 ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk
203185 ** format SQLite JSONB is completely different and incompatible with
203186 ** PostgreSQL JSONB.
203187 **
203188 ** Decoding and interpreting JSONB is still O(N) where N is the size of
203189 ** the input, the same as text JSON. However, the constant of proportionality
@@ -203120,10 +203270,13 @@
203270 ** code is between 0 and 12 and that the total size of the element
203271 ** (header plus payload) is the same as the size of the BLOB. If those
203272 ** checks are true, the BLOB is assumed to be JSONB and processing continues.
203273 ** Errors are only raised if some other miscoding is discovered during
203274 ** processing.
203275 **
203276 ** Additional information can be found in the doc/jsonb.md file of the
203277 ** canonical SQLite source tree.
203278 */
203279 #ifndef SQLITE_OMIT_JSON
203280 /* #include "sqliteInt.h" */
203281
203282 /* JSONB element types
@@ -203218,18 +203371,26 @@
203371 ** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
203372 */
203373 #define JSON_CACHE_ID (-429938) /* Cache entry */
203374 #define JSON_CACHE_SIZE 4 /* Max number of cache entries */
203375
203376 /*
203377 ** jsonUnescapeOneChar() returns this invalid code point if it encounters
203378 ** a syntax error.
203379 */
203380 #define JSON_INVALID_CHAR 0x99999
203381
203382 /* A cache mapping JSON text into JSONB blobs.
203383 **
203384 ** Each cache entry is a JsonParse object with the following restrictions:
203385 **
203386 ** * The bReadOnly flag must be set
203387 **
203388 ** * The aBlob[] array must be owned by the JsonParse object. In other
203389 ** words, nBlobAlloc must be non-zero.
203390 **
203391 ** * eEdit and delta must be zero.
203392 **
203393 ** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
203394 */
203395 struct JsonCache {
203396 sqlite3 *db; /* Database connection */
@@ -203286,27 +203447,27 @@
203447 **
203448 ** 3. Zero or more changes are made to aBlob[] (via json_remove() or
203449 ** json_replace() or json_patch() or similar).
203450 **
203451 ** 4. New JSON text is generated from the aBlob[] for output. This step
203452 ** is skipped if the function is one of the jsonb_* functions that
203453 ** returns JSONB instead of text JSON.
203454 */
203455 struct JsonParse {
203456 u8 *aBlob; /* JSONB representation of JSON value */
203457 u32 nBlob; /* Bytes of aBlob[] actually used */
203458 u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
203459 char *zJson; /* Json text used for parsing */
203460 int nJson; /* Length of the zJson string in bytes */
203461 u32 nJPRef; /* Number of references to this object */
203462 u32 iErr; /* Error location in zJson[] */
203463 u16 iDepth; /* Nesting depth */
203464 u8 nErr; /* Number of errors seen */
203465 u8 oom; /* Set to true if out of memory */
203466 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
203467 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
203468 u8 bReadOnly; /* Do not modify. */
 
 
203469 /* Search and edit information. See jsonLookupStep() */
203470 u8 eEdit; /* Edit operation to apply */
203471 int delta; /* Size change due to the edit */
203472 u32 nIns; /* Number of bytes to insert */
203473 u32 iLabel; /* Location of label if search landed on an object value */
@@ -203341,11 +203502,11 @@
203502 /**************************************************************************
203503 ** Forward references
203504 **************************************************************************/
203505 static void jsonReturnStringAsBlob(JsonString*);
203506 static int jsonFuncArgMightBeBinary(sqlite3_value *pJson);
203507 static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*);
203508 static void jsonReturnParse(sqlite3_context*,JsonParse*);
203509 static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
203510 static void jsonParseFree(JsonParse*);
203511 static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
203512 static u32 jsonUnescapeOneChar(const char*, u32, u32*);
@@ -203381,10 +203542,11 @@
203542 ){
203543 JsonCache *p;
203544
203545 assert( pParse->zJson!=0 );
203546 assert( pParse->bJsonIsRCStr );
203547 assert( pParse->delta==0 );
203548 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203549 if( p==0 ){
203550 sqlite3 *db = sqlite3_context_db_handle(ctx);
203551 p = sqlite3DbMallocZero(db, sizeof(*p));
203552 if( p==0 ) return SQLITE_NOMEM;
@@ -203453,10 +203615,11 @@
203615 JsonParse *tmp = p->a[i];
203616 memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
203617 p->a[p->nUsed-1] = tmp;
203618 i = p->nUsed - 1;
203619 }
203620 assert( p->a[i]->delta==0 );
203621 return p->a[i];
203622 }else{
203623 return 0;
203624 }
203625 }
@@ -203621,12 +203784,37 @@
203784 if( z==0 ) return;
203785 if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
203786 p->zBuf[p->nUsed++] = '"';
203787 while( 1 /*exit-by-break*/ ){
203788 k = 0;
203789 /* The following while() is the 4-way unwound equivalent of
203790 **
203791 ** while( k<N && jsonIsOk[z[k]] ){ k++; }
203792 */
203793 while( 1 /* Exit by break */ ){
203794 if( k+3>=N ){
203795 while( k<N && jsonIsOk[z[k]] ){ k++; }
203796 break;
203797 }
203798 if( !jsonIsOk[z[k]] ){
203799 break;
203800 }
203801 if( !jsonIsOk[z[k+1]] ){
203802 k += 1;
203803 break;
203804 }
203805 if( !jsonIsOk[z[k+2]] ){
203806 k += 2;
203807 break;
203808 }
203809 if( !jsonIsOk[z[k+3]] ){
203810 k += 3;
203811 break;
203812 }else{
203813 k += 4;
203814 }
203815 }
203816 if( k>=N ){
203817 if( k>0 ){
203818 memcpy(&p->zBuf[p->nUsed], z, k);
203819 p->nUsed += k;
203820 }
@@ -203714,11 +203902,11 @@
203902 if( jsonFuncArgMightBeBinary(pValue) ){
203903 JsonParse px;
203904 memset(&px, 0, sizeof(px));
203905 px.aBlob = (u8*)sqlite3_value_blob(pValue);
203906 px.nBlob = sqlite3_value_bytes(pValue);
203907 jsonTranslateBlobToText(&px, 0, p);
203908 }else if( p->eErr==0 ){
203909 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203910 p->eErr = JSTRING_ERR;
203911 jsonStringReset(p);
203912 }
@@ -204231,18 +204419,14 @@
204419 ** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
204420 ** any changes to *pOp and return false.
204421 */
204422 static int jsonIs4HexB(const char *z, int *pOp){
204423 if( z[0]!='u' ) return 0;
204424 if( !jsonIs4Hex(&z[1]) ) return 0;
 
 
 
204425 *pOp = JSONB_TEXTJ;
204426 return 1;
204427 }
 
204428
204429 /*
204430 ** Check a single element of the JSONB in pParse for validity.
204431 **
204432 ** The element to be checked starts at offset i and must end at on the
@@ -204384,11 +204568,11 @@
204568 }else if( x!=JSONB_TEXT5 ){
204569 return j+1;
204570 }else{
204571 u32 c = 0;
204572 u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
204573 if( c==JSON_INVALID_CHAR ) return j+1;
204574 j += szC - 1;
204575 }
204576 }
204577 j++;
204578 }
@@ -204456,11 +204640,11 @@
204640 ** -2 '}' seen \
204641 ** -3 ']' seen \___ For these returns, pParse->iErr is set to
204642 ** -4 ',' seen / the index in zJson[] of the seen character
204643 ** -5 ':' seen /
204644 */
204645 static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
204646 char c;
204647 u32 j;
204648 u32 iThis, iStart;
204649 int x;
204650 u8 t;
@@ -204476,11 +204660,11 @@
204660 return -1;
204661 }
204662 iStart = pParse->nBlob;
204663 for(j=i+1;;j++){
204664 u32 iBlob = pParse->nBlob;
204665 x = jsonTranslateTextToBlob(pParse, j);
204666 if( x<=0 ){
204667 int op;
204668 if( x==(-2) ){
204669 j = pParse->iErr;
204670 if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
@@ -204522,19 +204706,19 @@
204706 if( z[j]==':' ){
204707 j++;
204708 goto parse_object_value;
204709 }
204710 }
204711 x = jsonTranslateTextToBlob(pParse, j);
204712 if( x!=(-5) ){
204713 if( x!=(-1) ) pParse->iErr = j;
204714 return -1;
204715 }
204716 j = pParse->iErr+1;
204717 }
204718 parse_object_value:
204719 x = jsonTranslateTextToBlob(pParse, j);
204720 if( x<=0 ){
204721 if( x!=(-1) ) pParse->iErr = j;
204722 return -1;
204723 }
204724 j = x;
@@ -204549,11 +204733,11 @@
204733 continue;
204734 }else if( z[j]=='}' ){
204735 break;
204736 }
204737 }
204738 x = jsonTranslateTextToBlob(pParse, j);
204739 if( x==(-4) ){
204740 j = pParse->iErr;
204741 continue;
204742 }
204743 if( x==(-2) ){
@@ -204577,11 +204761,11 @@
204761 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204762 pParse->iErr = i;
204763 return -1;
204764 }
204765 for(j=i+1;;j++){
204766 x = jsonTranslateTextToBlob(pParse, j);
204767 if( x<=0 ){
204768 if( x==(-3) ){
204769 j = pParse->iErr;
204770 if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
204771 break;
@@ -204601,11 +204785,11 @@
204785 continue;
204786 }else if( z[j]==']' ){
204787 break;
204788 }
204789 }
204790 x = jsonTranslateTextToBlob(pParse, j);
204791 if( x==(-4) ){
204792 j = pParse->iErr;
204793 continue;
204794 }
204795 if( x==(-3) ){
@@ -204924,11 +205108,11 @@
205108 JsonParse *pParse, /* Initialize and fill this JsonParse object */
205109 sqlite3_context *pCtx /* Report errors here */
205110 ){
205111 int i;
205112 const char *zJson = pParse->zJson;
205113 i = jsonTranslateTextToBlob(pParse, 0);
205114 if( pParse->oom ) i = -1;
205115 if( i>0 ){
205116 #ifdef SQLITE_DEBUG
205117 assert( pParse->iDepth==0 );
205118 if( sqlite3Config.bJsonSelfcheck ){
@@ -204969,11 +205153,11 @@
205153 JsonParse px;
205154 memset(&px, 0, sizeof(px));
205155 jsonStringTerminate(pStr);
205156 px.zJson = pStr->zBuf;
205157 px.nJson = pStr->nUsed;
205158 (void)jsonTranslateTextToBlob(&px, 0);
205159 if( px.oom ){
205160 sqlite3_free(px.aBlob);
205161 sqlite3_result_error_nomem(pStr->pCtx);
205162 }else{
205163 assert( px.nBlobAlloc>0 );
@@ -205057,11 +205241,11 @@
205241 ** are detected. So a malformed JSONB input might either result
205242 ** in an error, or in incorrect JSON.
205243 **
205244 ** The pOut->eErr JSTRING_OOM flag is set on a OOM.
205245 */
205246 static u32 jsonTranslateBlobToText(
205247 const JsonParse *pParse, /* the complete parse of the JSON */
205248 u32 i, /* Start rendering at this index */
205249 JsonString *pOut /* Write JSON here */
205250 ){
205251 u32 sz, n, j, iEnd;
@@ -205228,11 +205412,11 @@
205412 case JSONB_ARRAY: {
205413 jsonAppendChar(pOut, '[');
205414 j = i+n;
205415 iEnd = j+sz;
205416 while( j<iEnd ){
205417 j = jsonTranslateBlobToText(pParse, j, pOut);
205418 jsonAppendChar(pOut, ',');
205419 }
205420 if( sz>0 ) pOut->nUsed--;
205421 jsonAppendChar(pOut, ']');
205422 break;
@@ -205241,11 +205425,11 @@
205425 int x = 0;
205426 jsonAppendChar(pOut, '{');
205427 j = i+n;
205428 iEnd = j+sz;
205429 while( j<iEnd ){
205430 j = jsonTranslateBlobToText(pParse, j, pOut);
205431 jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
205432 }
205433 if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
205434 if( sz>0 ) pOut->nUsed--;
205435 jsonAppendChar(pOut, '}');
@@ -205394,23 +205578,27 @@
205578
205579 /*
205580 ** Input z[0..n] defines JSON escape sequence including the leading '\\'.
205581 ** Decode that escape sequence into a single character. Write that
205582 ** character into *piOut. Return the number of bytes in the escape sequence.
205583 **
205584 ** If there is a syntax error of some kind (for example too few characters
205585 ** after the '\\' to complete the encoding) then *piOut is set to
205586 ** JSON_INVALID_CHAR.
205587 */
205588 static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
205589 assert( n>0 );
205590 assert( z[0]=='\\' );
205591 if( n<2 ){
205592 *piOut = JSON_INVALID_CHAR;
205593 return n;
205594 }
205595 switch( (u8)z[1] ){
205596 case 'u': {
205597 u32 v, vlo;
205598 if( n<6 ){
205599 *piOut = JSON_INVALID_CHAR;
205600 return n;
205601 }
205602 v = jsonHexToInt4(&z[2]);
205603 if( (v & 0xfc00)==0xd800
205604 && n>=12
@@ -205436,11 +205624,11 @@
205624 case '"':
205625 case '/':
205626 case '\\':{ *piOut = z[1]; return 2; }
205627 case 'x': {
205628 if( n<4 ){
205629 *piOut = JSON_INVALID_CHAR;
205630 return n;
205631 }
205632 *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
205633 return 4;
205634 }
@@ -205447,11 +205635,11 @@
205635 case 0xe2:
205636 case '\r':
205637 case '\n': {
205638 u32 nSkip = jsonBytesToBypass(z, n);
205639 if( nSkip==0 ){
205640 *piOut = JSON_INVALID_CHAR;
205641 return n;
205642 }else if( nSkip==n ){
205643 *piOut = 0;
205644 return n;
205645 }else if( z[nSkip]=='\\' ){
@@ -205460,11 +205648,11 @@
205648 int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
205649 return nSkip + sz;
205650 }
205651 }
205652 default: {
205653 *piOut = JSON_INVALID_CHAR;
205654 return 2;
205655 }
205656 }
205657 }
205658
@@ -205823,11 +206011,11 @@
206011 if( NEVER(aBlob==0) ) return;
206012 memset(&x, 0, sizeof(x));
206013 x.aBlob = (u8*)aBlob;
206014 x.nBlob = nBlob;
206015 jsonStringInit(&s, ctx);
206016 jsonTranslateBlobToText(&x, 0, &s);
206017 jsonReturnString(&s, 0, 0);
206018 }
206019
206020
206021 /*
@@ -205934,21 +206122,21 @@
206122 if( c=='\\' ){
206123 u32 v;
206124 u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
206125 if( v<=0x7f ){
206126 zOut[iOut++] = (char)v;
 
 
206127 }else if( v<=0x7ff ){
206128 assert( szEscape>=2 );
206129 zOut[iOut++] = (char)(0xc0 | (v>>6));
206130 zOut[iOut++] = 0x80 | (v&0x3f);
206131 }else if( v<0x10000 ){
206132 assert( szEscape>=3 );
206133 zOut[iOut++] = 0xe0 | (v>>12);
206134 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
206135 zOut[iOut++] = 0x80 | (v&0x3f);
206136 }else if( v==JSON_INVALID_CHAR ){
206137 /* Silently ignore illegal unicode */
206138 }else{
206139 assert( szEscape>=4 );
206140 zOut[iOut++] = 0xf0 | (v>>18);
206141 zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
206142 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
@@ -206046,17 +206234,33 @@
206234 }else{
206235 jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
206236 }
206237 break;
206238 }
206239 case SQLITE_FLOAT: {
206240 double r = sqlite3_value_double(pArg);
206241 if( NEVER(sqlite3IsNaN(r)) ){
206242 jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0);
206243 }else{
206244 int n = sqlite3_value_bytes(pArg);
206245 const char *z = (const char*)sqlite3_value_text(pArg);
206246 if( z==0 ) return 1;
206247 if( z[0]=='I' ){
206248 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
206249 }else if( z[0]=='-' && z[1]=='I' ){
206250 jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
206251 }else{
206252 jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z);
206253 }
206254 }
206255 break;
206256 }
206257 case SQLITE_INTEGER: {
206258 int n = sqlite3_value_bytes(pArg);
206259 const char *z = (const char*)sqlite3_value_text(pArg);
 
206260 if( z==0 ) return 1;
206261 jsonBlobAppendNode(pParse, JSONB_INT, n, z);
206262 break;
206263 }
206264 }
206265 if( pParse->oom ){
206266 sqlite3_result_error_nomem(ctx);
@@ -206153,15 +206357,10 @@
206357 }else{
206358 jsonBadPathError(ctx, zPath);
206359 }
206360 return;
206361 }
 
 
 
 
 
206362
206363 /*
206364 ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
206365 ** from the SQL function argument pArg. Return a pointer to the new
206366 ** JsonParse object.
@@ -206313,11 +206512,12 @@
206512 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
206513 }
206514 }else{
206515 JsonString s;
206516 jsonStringInit(&s, ctx);
206517 p->delta = 0;
206518 jsonTranslateBlobToText(p, 0, &s);
206519 jsonReturnString(&s, p, ctx);
206520 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206521 }
206522 }
206523
@@ -206333,29 +206533,32 @@
206533 */
206534 static void jsonDebugPrintBlob(
206535 JsonParse *pParse, /* JSON content */
206536 u32 iStart, /* Start rendering here */
206537 u32 iEnd, /* Do not render this byte or any byte after this one */
206538 int nIndent, /* Indent by this many spaces */
206539 sqlite3_str *pOut /* Generate output into this sqlite3_str object */
206540 ){
206541 while( iStart<iEnd ){
206542 u32 i, n, nn, sz = 0;
206543 int showContent = 1;
206544 u8 x = pParse->aBlob[iStart] & 0x0f;
206545 u32 savedNBlob = pParse->nBlob;
206546 sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, "");
206547 if( pParse->nBlobAlloc>pParse->nBlob ){
206548 pParse->nBlob = pParse->nBlobAlloc;
206549 }
206550 nn = n = jsonbPayloadSize(pParse, iStart, &sz);
206551 if( nn==0 ) nn = 1;
206552 if( sz>0 && x<JSONB_ARRAY ){
206553 nn += sz;
206554 }
206555 for(i=0; i<nn; i++){
206556 sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]);
206557 }
206558 if( n==0 ){
206559 sqlite3_str_appendf(pOut, " ERROR invalid node size\n");
206560 iStart = n==0 ? iStart+1 : iEnd;
206561 continue;
206562 }
206563 pParse->nBlob = savedNBlob;
206564 if( iStart+n+sz>iEnd ){
@@ -206366,59 +206569,61 @@
206569 }else{
206570 iEnd = pParse->nBlob;
206571 }
206572 }
206573 }
206574 sqlite3_str_appendall(pOut," <-- ");
206575 switch( x ){
206576 case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break;
206577 case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break;
206578 case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break;
206579 case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break;
206580 case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break;
206581 case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break;
206582 case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break;
206583 case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break;
206584 case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break;
206585 case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break;
206586 case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break;
206587 case JSONB_ARRAY: {
206588 sqlite3_str_appendf(pOut,"array, %u bytes\n", sz);
206589 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
206590 showContent = 0;
206591 break;
206592 }
206593 case JSONB_OBJECT: {
206594 sqlite3_str_appendf(pOut, "object, %u bytes\n", sz);
206595 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
206596 showContent = 0;
206597 break;
206598 }
206599 default: {
206600 sqlite3_str_appendall(pOut, "ERROR: unknown node type\n");
206601 showContent = 0;
206602 break;
206603 }
206604 }
206605 if( showContent ){
206606 if( sz==0 && x<=JSONB_FALSE ){
206607 sqlite3_str_append(pOut, "\n", 1);
206608 }else{
206609 u32 i;
206610 sqlite3_str_appendall(pOut, ": \"");
206611 for(i=iStart+n; i<iStart+n+sz; i++){
206612 u8 c = pParse->aBlob[i];
206613 if( c<0x20 || c>=0x7f ) c = '.';
206614 sqlite3_str_append(pOut, (char*)&c, 1);
206615 }
206616 sqlite3_str_append(pOut, "\"\n", 2);
206617 }
206618 }
206619 iStart += n + sz;
206620 }
206621 }
206622 static void jsonShowParse(JsonParse *pParse){
206623 sqlite3_str out;
206624 char zBuf[1000];
206625 if( pParse==0 ){
206626 printf("NULL pointer\n");
206627 return;
206628 }else{
206629 printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
@@ -206425,31 +206630,42 @@
206630 printf("nBlob = %u\n", pParse->nBlob);
206631 printf("delta = %d\n", pParse->delta);
206632 if( pParse->nBlob==0 ) return;
206633 printf("content (bytes 0..%u):\n", pParse->nBlob-1);
206634 }
206635 sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000);
206636 jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out);
206637 printf("%s", sqlite3_str_value(&out));
206638 sqlite3_str_reset(&out);
206639 }
206640 #endif /* SQLITE_DEBUG */
206641
206642 #ifdef SQLITE_DEBUG
206643 /*
206644 ** SQL function: json_parse(JSON)
206645 **
206646 ** Parse JSON using jsonParseFuncArg(). Return text that is a
206647 ** human-readable dump of the binary JSONB for the input parameter.
206648 */
206649 static void jsonParseFunc(
206650 sqlite3_context *ctx,
206651 int argc,
206652 sqlite3_value **argv
206653 ){
206654 JsonParse *p; /* The parse */
206655 sqlite3_str out;
206656
206657 assert( argc>=1 );
206658 sqlite3StrAccumInit(&out, 0, 0, 0, 1000000);
206659 p = jsonParseFuncArg(ctx, argv[0], 0);
206660 if( p==0 ) return;
206661 if( argc==1 ){
206662 jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out);
206663 sqlite3_result_text64(ctx, out.zText, out.nChar, sqlite3_free, SQLITE_UTF8);
206664 }else{
206665 jsonShowParse(p);
206666 }
206667 jsonParseFree(p);
206668 }
206669 #endif /* SQLITE_DEBUG */
206670
206671 /****************************************************************************
@@ -206641,11 +206857,11 @@
206857 }
206858 if( j<p->nBlob ){
206859 if( argc==2 ){
206860 if( flags & JSON_JSON ){
206861 jsonStringInit(&jx, ctx);
206862 jsonTranslateBlobToText(p, j, &jx);
206863 jsonReturnString(&jx, 0, 0);
206864 jsonStringReset(&jx);
206865 assert( (flags & JSON_BLOB)==0 );
206866 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206867 }else{
@@ -206656,11 +206872,11 @@
206872 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206873 }
206874 }
206875 }else{
206876 jsonAppendSeparator(&jx);
206877 jsonTranslateBlobToText(p, j, &jx);
206878 }
206879 }else if( j==JSON_LOOKUP_NOTFOUND ){
206880 if( argc==2 ){
206881 goto json_extract_error; /* Return NULL if not found */
206882 }else{
@@ -229267,23 +229483,28 @@
229483 **
229484 ** This function may be quite inefficient if used with an FTS5 table
229485 ** created with the "columnsize=0" option.
229486 **
229487 ** xColumnText:
229488 ** If parameter iCol is less than zero, or greater than or equal to the
229489 ** number of columns in the table, SQLITE_RANGE is returned.
229490 **
229491 ** Otherwise, this function attempts to retrieve the text of column iCol of
229492 ** the current document. If successful, (*pz) is set to point to a buffer
229493 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
229494 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
229495 ** if an error occurs, an SQLite error code is returned and the final values
229496 ** of (*pz) and (*pn) are undefined.
229497 **
229498 ** xPhraseCount:
229499 ** Returns the number of phrases in the current query expression.
229500 **
229501 ** xPhraseSize:
229502 ** If parameter iCol is less than zero, or greater than or equal to the
229503 ** number of phrases in the current query, as returned by xPhraseCount,
229504 ** 0 is returned. Otherwise, this function returns the number of tokens in
229505 ** phrase iPhrase of the query. Phrases are numbered starting from zero.
229506 **
229507 ** xInstCount:
229508 ** Set *pnInst to the total number of occurrences of all phrases within
229509 ** the query within the current row. Return SQLITE_OK if successful, or
229510 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -229295,16 +229516,17 @@
229516 **
229517 ** xInst:
229518 ** Query for the details of phrase match iIdx within the current row.
229519 ** Phrase matches are numbered starting from zero, so the iIdx argument
229520 ** should be greater than or equal to zero and smaller than the value
229521 ** output by xInstCount(). If iIdx is less than zero or greater than
229522 ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
229523 **
229524 ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
229525 ** to the column in which it occurs and *piOff the token offset of the
229526 ** first token of the phrase. SQLITE_OK is returned if successful, or an
229527 ** error code (i.e. SQLITE_NOMEM) if an error occurs.
229528 **
229529 ** This API can be quite slow if used with an FTS5 table created with the
229530 ** "detail=none" or "detail=column" option.
229531 **
229532 ** xRowid:
@@ -229325,10 +229547,14 @@
229547 ** row visited, the callback function passed as the fourth argument
229548 ** is invoked. The context and API objects passed to the callback
229549 ** function may be used to access the properties of each matched row.
229550 ** Invoking Api.xUserData() returns a copy of the pointer passed as
229551 ** the third argument to pUserData.
229552 **
229553 ** If parameter iPhrase is less than zero, or greater than or equal to
229554 ** the number of phrases in the query, as returned by xPhraseCount(),
229555 ** this function returns SQLITE_RANGE.
229556 **
229557 ** If the callback function returns any value other than SQLITE_OK, the
229558 ** query is abandoned and the xQueryPhrase function returns immediately.
229559 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
229560 ** Otherwise, the error code is propagated upwards.
@@ -229446,22 +229672,30 @@
229672 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
229673 ** This is used to access token iToken of phrase iPhrase of the current
229674 ** query. Before returning, output parameter *ppToken is set to point
229675 ** to a buffer containing the requested token, and *pnToken to the
229676 ** size of this buffer in bytes.
229677 **
229678 ** If iPhrase or iToken are less than zero, or if iPhrase is greater than
229679 ** or equal to the number of phrases in the query as reported by
229680 ** xPhraseCount(), or if iToken is equal to or greater than the number of
229681 ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
229682 are both zeroed.
229683 **
229684 ** The output text is not a copy of the query text that specified the
229685 ** token. It is the output of the tokenizer module. For tokendata=1
229686 ** tables, this includes any embedded 0x00 and trailing data.
229687 **
229688 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
229689 ** This is used to access token iToken of phrase hit iIdx within the
229690 ** current row. If iIdx is less than zero or greater than or equal to the
229691 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
229692 ** output variable (*ppToken) is set to point to a buffer containing the
229693 ** matching document token, and (*pnToken) to the size of that buffer in
229694 ** bytes. This API is not available if the specified token matches a
229695 ** prefix query term. In that case both output variables are always set
229696 ** to 0.
229697 **
229698 ** The output text is not a copy of the document text that was tokenized.
229699 ** It is the output of the tokenizer module. For tokendata=1 tables, this
229700 ** includes any embedded 0x00 and trailing data.
229701 **
@@ -232433,12 +232667,14 @@
232667 memset(&ctx, 0, sizeof(HighlightContext));
232668 ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
232669 ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
232670 ctx.iRangeEnd = -1;
232671 rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
232672 if( rc==SQLITE_RANGE ){
232673 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
232674 rc = SQLITE_OK;
232675 }else if( ctx.zIn ){
232676 if( rc==SQLITE_OK ){
232677 rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
232678 }
232679
232680 if( rc==SQLITE_OK ){
@@ -236273,15 +236509,19 @@
236509 Fts5Expr *pExpr,
236510 int iPhrase,
236511 Fts5Expr **ppNew
236512 ){
236513 int rc = SQLITE_OK; /* Return code */
236514 Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */
236515 Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
236516 TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
236517 if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
236518 rc = SQLITE_RANGE;
236519 }else{
236520 pOrig = pExpr->apExprPhrase[iPhrase];
236521 pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
236522 }
236523 if( rc==SQLITE_OK ){
236524 pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
236525 sizeof(Fts5ExprPhrase*));
236526 }
236527 if( rc==SQLITE_OK ){
@@ -236290,11 +236530,11 @@
236530 }
236531 if( rc==SQLITE_OK ){
236532 pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
236533 sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
236534 }
236535 if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){
236536 Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
236537 if( pColsetOrig ){
236538 sqlite3_int64 nByte;
236539 Fts5Colset *pColset;
236540 nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
@@ -236304,29 +236544,31 @@
236544 }
236545 pNew->pRoot->pNear->pColset = pColset;
236546 }
236547 }
236548
236549 if( rc==SQLITE_OK ){
236550 if( pOrig->nTerm ){
236551 int i; /* Used to iterate through phrase terms */
236552 sCtx.pConfig = pExpr->pConfig;
236553 for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
236554 int tflags = 0;
236555 Fts5ExprTerm *p;
236556 for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
236557 rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0);
236558 tflags = FTS5_TOKEN_COLOCATED;
236559 }
236560 if( rc==SQLITE_OK ){
236561 sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
236562 sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
236563 }
236564 }
236565 }else{
236566 /* This happens when parsing a token or quoted phrase that contains
236567 ** no token characters at all. (e.g ... MATCH '""'). */
236568 sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
236569 }
236570 }
236571
236572 if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
236573 /* All the allocations succeeded. Put the expression object together. */
236574 pNew->pIndex = pExpr->pIndex;
@@ -239776,13 +240018,13 @@
240018 for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
240019 if( pData->p[iOff] ) break;
240020 }
240021
240022 if( iOff<pData->nn ){
240023 u64 iVal;
240024 pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
240025 iOff += fts5GetVarint(&pData->p[iOff], &iVal);
240026 pLvl->iRowid += iVal;
240027 pLvl->iOff = iOff;
240028 }else{
240029 pLvl->bEof = 1;
240030 }
@@ -246173,20 +246415,20 @@
246415 fts5DataRelease(pLeaf);
246416 }
246417 }
246418
246419 static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
246420 i64 iTermOff = 0;
246421 int ii;
246422
246423 Fts5Buffer buf1 = {0,0,0};
246424 Fts5Buffer buf2 = {0,0,0};
246425
246426 ii = pLeaf->szLeaf;
246427 while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
246428 int res;
246429 i64 iOff;
246430 int nIncr;
246431
246432 ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
246433 iTermOff += nIncr;
246434 iOff = iTermOff;
@@ -249207,11 +249449,14 @@
249449 const char **pz,
249450 int *pn
249451 ){
249452 int rc = SQLITE_OK;
249453 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249454 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
249455 if( iCol<0 || iCol>=pTab->pConfig->nCol ){
249456 rc = SQLITE_RANGE;
249457 }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
249458 || pCsr->ePlan==FTS5_PLAN_SPECIAL
249459 ){
249460 *pz = 0;
249461 *pn = 0;
249462 }else{
@@ -249232,12 +249477,13 @@
249477 ){
249478 Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
249479 int rc = SQLITE_OK;
249480 int bLive = (pCsr->pSorter==0);
249481
249482 if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
249483 rc = SQLITE_RANGE;
249484 }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
249485 if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
249486 Fts5PoslistPopulator *aPopulator;
249487 int i;
249488 aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
249489 if( aPopulator==0 ) rc = SQLITE_NOMEM;
@@ -249257,18 +249503,24 @@
249503 }
249504 }
249505 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
249506 }
249507
249508 if( rc==SQLITE_OK ){
249509 if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
249510 Fts5Sorter *pSorter = pCsr->pSorter;
249511 int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
249512 *pn = pSorter->aIdx[iPhrase] - i1;
249513 *pa = &pSorter->aPoslist[i1];
249514 }else{
249515 *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
249516 }
249517 }else{
249518 *pa = 0;
249519 *pn = 0;
249520 }
249521
249522
249523 return rc;
249524 }
249525
249526 /*
@@ -250223,11 +250475,11 @@
250475 int nArg, /* Number of args */
250476 sqlite3_value **apUnused /* Function arguments */
250477 ){
250478 assert( nArg==0 );
250479 UNUSED_PARAM2(nArg, apUnused);
250480 sqlite3_result_text(pCtx, "fts5: 2023-12-29 19:03:01 4b70b94616ef37bac969051eee3ea6913a28f30520cdd4fc3a19e848f2cf12b7", -1, SQLITE_TRANSIENT);
250481 }
250482
250483 /*
250484 ** Return true if zName is the extension on one of the shadow tables used
250485 ** by this module.
250486
+37 -17
--- 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.45.0"
150150
#define SQLITE_VERSION_NUMBER 3045000
151
-#define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
151
+#define SQLITE_SOURCE_ID "2023-12-31 12:38:43 c216921b115169ebfd239267b4ab5ad0fc960ffadce09044b68812f49110d607"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -8037,13 +8037,15 @@
80378037
** can enter.)^ If the same thread tries to enter any mutex other
80388038
** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
80398039
**
80408040
** ^(Some systems (for example, Windows 95) do not support the operation
80418041
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8042
-** will always return SQLITE_BUSY. The SQLite core only ever uses
8043
-** sqlite3_mutex_try() as an optimization so this is acceptable
8044
-** behavior.)^
8042
+** will always return SQLITE_BUSY. In most cases the SQLite core only uses
8043
+** sqlite3_mutex_try() as an optimization, so this is acceptable
8044
+** behavior. The exceptions are unix builds that set the
8045
+** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
8046
+** sqlite3_mutex_try() is required.)^
80458047
**
80468048
** ^The sqlite3_mutex_leave() routine exits a mutex that was
80478049
** previously entered by the same thread. The behavior
80488050
** is undefined if the mutex is not currently entered by the
80498051
** calling thread or is not currently allocated.
@@ -12812,23 +12814,28 @@
1281212814
**
1281312815
** This function may be quite inefficient if used with an FTS5 table
1281412816
** created with the "columnsize=0" option.
1281512817
**
1281612818
** xColumnText:
12817
-** This function attempts to retrieve the text of column iCol of the
12818
-** current document. If successful, (*pz) is set to point to a buffer
12819
+** If parameter iCol is less than zero, or greater than or equal to the
12820
+** number of columns in the table, SQLITE_RANGE is returned.
12821
+**
12822
+** Otherwise, this function attempts to retrieve the text of column iCol of
12823
+** the current document. If successful, (*pz) is set to point to a buffer
1281912824
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
1282012825
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
1282112826
** if an error occurs, an SQLite error code is returned and the final values
1282212827
** of (*pz) and (*pn) are undefined.
1282312828
**
1282412829
** xPhraseCount:
1282512830
** Returns the number of phrases in the current query expression.
1282612831
**
1282712832
** xPhraseSize:
12828
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
12829
-** are numbered starting from zero.
12833
+** If parameter iCol is less than zero, or greater than or equal to the
12834
+** number of phrases in the current query, as returned by xPhraseCount,
12835
+** 0 is returned. Otherwise, this function returns the number of tokens in
12836
+** phrase iPhrase of the query. Phrases are numbered starting from zero.
1283012837
**
1283112838
** xInstCount:
1283212839
** Set *pnInst to the total number of occurrences of all phrases within
1283312840
** the query within the current row. Return SQLITE_OK if successful, or
1283412841
** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -12840,16 +12847,17 @@
1284012847
**
1284112848
** xInst:
1284212849
** Query for the details of phrase match iIdx within the current row.
1284312850
** Phrase matches are numbered starting from zero, so the iIdx argument
1284412851
** should be greater than or equal to zero and smaller than the value
12845
-** output by xInstCount().
12852
+** output by xInstCount(). If iIdx is less than zero or greater than
12853
+** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
1284612854
**
12847
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
12855
+** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
1284812856
** to the column in which it occurs and *piOff the token offset of the
12849
-** first token of the phrase. Returns SQLITE_OK if successful, or an error
12850
-** code (i.e. SQLITE_NOMEM) if an error occurs.
12857
+** first token of the phrase. SQLITE_OK is returned if successful, or an
12858
+** error code (i.e. SQLITE_NOMEM) if an error occurs.
1285112859
**
1285212860
** This API can be quite slow if used with an FTS5 table created with the
1285312861
** "detail=none" or "detail=column" option.
1285412862
**
1285512863
** xRowid:
@@ -12870,10 +12878,14 @@
1287012878
** row visited, the callback function passed as the fourth argument
1287112879
** is invoked. The context and API objects passed to the callback
1287212880
** function may be used to access the properties of each matched row.
1287312881
** Invoking Api.xUserData() returns a copy of the pointer passed as
1287412882
** the third argument to pUserData.
12883
+**
12884
+** If parameter iPhrase is less than zero, or greater than or equal to
12885
+** the number of phrases in the query, as returned by xPhraseCount(),
12886
+** this function returns SQLITE_RANGE.
1287512887
**
1287612888
** If the callback function returns any value other than SQLITE_OK, the
1287712889
** query is abandoned and the xQueryPhrase function returns immediately.
1287812890
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
1287912891
** Otherwise, the error code is propagated upwards.
@@ -12991,22 +13003,30 @@
1299113003
** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
1299213004
** This is used to access token iToken of phrase iPhrase of the current
1299313005
** query. Before returning, output parameter *ppToken is set to point
1299413006
** to a buffer containing the requested token, and *pnToken to the
1299513007
** size of this buffer in bytes.
13008
+**
13009
+** If iPhrase or iToken are less than zero, or if iPhrase is greater than
13010
+** or equal to the number of phrases in the query as reported by
13011
+** xPhraseCount(), or if iToken is equal to or greater than the number of
13012
+** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
13013
+ are both zeroed.
1299613014
**
1299713015
** The output text is not a copy of the query text that specified the
1299813016
** token. It is the output of the tokenizer module. For tokendata=1
1299913017
** tables, this includes any embedded 0x00 and trailing data.
1300013018
**
1300113019
** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
1300213020
** This is used to access token iToken of phrase hit iIdx within the
13003
-** current row. Output variable (*ppToken) is set to point to a buffer
13004
-** containing the matching document token, and (*pnToken) to the size
13005
-** of that buffer in bytes. This API is not available if the specified
13006
-** token matches a prefix query term. In that case both output variables
13007
-** are always set to 0.
13021
+** current row. If iIdx is less than zero or greater than or equal to the
13022
+** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13023
+** output variable (*ppToken) is set to point to a buffer containing the
13024
+** matching document token, and (*pnToken) to the size of that buffer in
13025
+** bytes. This API is not available if the specified token matches a
13026
+** prefix query term. In that case both output variables are always set
13027
+** to 0.
1300813028
**
1300913029
** The output text is not a copy of the document text that was tokenized.
1301013030
** It is the output of the tokenizer module. For tokendata=1 tables, this
1301113031
** includes any embedded 0x00 and trailing data.
1301213032
**
1301313033
--- 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.45.0"
150 #define SQLITE_VERSION_NUMBER 3045000
151 #define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -8037,13 +8037,15 @@
8037 ** can enter.)^ If the same thread tries to enter any mutex other
8038 ** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
8039 **
8040 ** ^(Some systems (for example, Windows 95) do not support the operation
8041 ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8042 ** will always return SQLITE_BUSY. The SQLite core only ever uses
8043 ** sqlite3_mutex_try() as an optimization so this is acceptable
8044 ** behavior.)^
 
 
8045 **
8046 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
8047 ** previously entered by the same thread. The behavior
8048 ** is undefined if the mutex is not currently entered by the
8049 ** calling thread or is not currently allocated.
@@ -12812,23 +12814,28 @@
12812 **
12813 ** This function may be quite inefficient if used with an FTS5 table
12814 ** created with the "columnsize=0" option.
12815 **
12816 ** xColumnText:
12817 ** This function attempts to retrieve the text of column iCol of the
12818 ** current document. If successful, (*pz) is set to point to a buffer
 
 
 
12819 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
12820 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
12821 ** if an error occurs, an SQLite error code is returned and the final values
12822 ** of (*pz) and (*pn) are undefined.
12823 **
12824 ** xPhraseCount:
12825 ** Returns the number of phrases in the current query expression.
12826 **
12827 ** xPhraseSize:
12828 ** Returns the number of tokens in phrase iPhrase of the query. Phrases
12829 ** are numbered starting from zero.
 
 
12830 **
12831 ** xInstCount:
12832 ** Set *pnInst to the total number of occurrences of all phrases within
12833 ** the query within the current row. Return SQLITE_OK if successful, or
12834 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -12840,16 +12847,17 @@
12840 **
12841 ** xInst:
12842 ** Query for the details of phrase match iIdx within the current row.
12843 ** Phrase matches are numbered starting from zero, so the iIdx argument
12844 ** should be greater than or equal to zero and smaller than the value
12845 ** output by xInstCount().
 
12846 **
12847 ** Usually, output parameter *piPhrase is set to the phrase number, *piCol
12848 ** to the column in which it occurs and *piOff the token offset of the
12849 ** first token of the phrase. Returns SQLITE_OK if successful, or an error
12850 ** code (i.e. SQLITE_NOMEM) if an error occurs.
12851 **
12852 ** This API can be quite slow if used with an FTS5 table created with the
12853 ** "detail=none" or "detail=column" option.
12854 **
12855 ** xRowid:
@@ -12870,10 +12878,14 @@
12870 ** row visited, the callback function passed as the fourth argument
12871 ** is invoked. The context and API objects passed to the callback
12872 ** function may be used to access the properties of each matched row.
12873 ** Invoking Api.xUserData() returns a copy of the pointer passed as
12874 ** the third argument to pUserData.
 
 
 
 
12875 **
12876 ** If the callback function returns any value other than SQLITE_OK, the
12877 ** query is abandoned and the xQueryPhrase function returns immediately.
12878 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
12879 ** Otherwise, the error code is propagated upwards.
@@ -12991,22 +13003,30 @@
12991 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
12992 ** This is used to access token iToken of phrase iPhrase of the current
12993 ** query. Before returning, output parameter *ppToken is set to point
12994 ** to a buffer containing the requested token, and *pnToken to the
12995 ** size of this buffer in bytes.
 
 
 
 
 
 
12996 **
12997 ** The output text is not a copy of the query text that specified the
12998 ** token. It is the output of the tokenizer module. For tokendata=1
12999 ** tables, this includes any embedded 0x00 and trailing data.
13000 **
13001 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13002 ** This is used to access token iToken of phrase hit iIdx within the
13003 ** current row. Output variable (*ppToken) is set to point to a buffer
13004 ** containing the matching document token, and (*pnToken) to the size
13005 ** of that buffer in bytes. This API is not available if the specified
13006 ** token matches a prefix query term. In that case both output variables
13007 ** are always set to 0.
 
 
13008 **
13009 ** The output text is not a copy of the document text that was tokenized.
13010 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13011 ** includes any embedded 0x00 and trailing data.
13012 **
13013
--- 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.45.0"
150 #define SQLITE_VERSION_NUMBER 3045000
151 #define SQLITE_SOURCE_ID "2023-12-31 12:38:43 c216921b115169ebfd239267b4ab5ad0fc960ffadce09044b68812f49110d607"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -8037,13 +8037,15 @@
8037 ** can enter.)^ If the same thread tries to enter any mutex other
8038 ** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
8039 **
8040 ** ^(Some systems (for example, Windows 95) do not support the operation
8041 ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
8042 ** will always return SQLITE_BUSY. In most cases the SQLite core only uses
8043 ** sqlite3_mutex_try() as an optimization, so this is acceptable
8044 ** behavior. The exceptions are unix builds that set the
8045 ** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
8046 ** sqlite3_mutex_try() is required.)^
8047 **
8048 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
8049 ** previously entered by the same thread. The behavior
8050 ** is undefined if the mutex is not currently entered by the
8051 ** calling thread or is not currently allocated.
@@ -12812,23 +12814,28 @@
12814 **
12815 ** This function may be quite inefficient if used with an FTS5 table
12816 ** created with the "columnsize=0" option.
12817 **
12818 ** xColumnText:
12819 ** If parameter iCol is less than zero, or greater than or equal to the
12820 ** number of columns in the table, SQLITE_RANGE is returned.
12821 **
12822 ** Otherwise, this function attempts to retrieve the text of column iCol of
12823 ** the current document. If successful, (*pz) is set to point to a buffer
12824 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
12825 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
12826 ** if an error occurs, an SQLite error code is returned and the final values
12827 ** of (*pz) and (*pn) are undefined.
12828 **
12829 ** xPhraseCount:
12830 ** Returns the number of phrases in the current query expression.
12831 **
12832 ** xPhraseSize:
12833 ** If parameter iCol is less than zero, or greater than or equal to the
12834 ** number of phrases in the current query, as returned by xPhraseCount,
12835 ** 0 is returned. Otherwise, this function returns the number of tokens in
12836 ** phrase iPhrase of the query. Phrases are numbered starting from zero.
12837 **
12838 ** xInstCount:
12839 ** Set *pnInst to the total number of occurrences of all phrases within
12840 ** the query within the current row. Return SQLITE_OK if successful, or
12841 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
@@ -12840,16 +12847,17 @@
12847 **
12848 ** xInst:
12849 ** Query for the details of phrase match iIdx within the current row.
12850 ** Phrase matches are numbered starting from zero, so the iIdx argument
12851 ** should be greater than or equal to zero and smaller than the value
12852 ** output by xInstCount(). If iIdx is less than zero or greater than
12853 ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
12854 **
12855 ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
12856 ** to the column in which it occurs and *piOff the token offset of the
12857 ** first token of the phrase. SQLITE_OK is returned if successful, or an
12858 ** error code (i.e. SQLITE_NOMEM) if an error occurs.
12859 **
12860 ** This API can be quite slow if used with an FTS5 table created with the
12861 ** "detail=none" or "detail=column" option.
12862 **
12863 ** xRowid:
@@ -12870,10 +12878,14 @@
12878 ** row visited, the callback function passed as the fourth argument
12879 ** is invoked. The context and API objects passed to the callback
12880 ** function may be used to access the properties of each matched row.
12881 ** Invoking Api.xUserData() returns a copy of the pointer passed as
12882 ** the third argument to pUserData.
12883 **
12884 ** If parameter iPhrase is less than zero, or greater than or equal to
12885 ** the number of phrases in the query, as returned by xPhraseCount(),
12886 ** this function returns SQLITE_RANGE.
12887 **
12888 ** If the callback function returns any value other than SQLITE_OK, the
12889 ** query is abandoned and the xQueryPhrase function returns immediately.
12890 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
12891 ** Otherwise, the error code is propagated upwards.
@@ -12991,22 +13003,30 @@
13003 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
13004 ** This is used to access token iToken of phrase iPhrase of the current
13005 ** query. Before returning, output parameter *ppToken is set to point
13006 ** to a buffer containing the requested token, and *pnToken to the
13007 ** size of this buffer in bytes.
13008 **
13009 ** If iPhrase or iToken are less than zero, or if iPhrase is greater than
13010 ** or equal to the number of phrases in the query as reported by
13011 ** xPhraseCount(), or if iToken is equal to or greater than the number of
13012 ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
13013 are both zeroed.
13014 **
13015 ** The output text is not a copy of the query text that specified the
13016 ** token. It is the output of the tokenizer module. For tokendata=1
13017 ** tables, this includes any embedded 0x00 and trailing data.
13018 **
13019 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13020 ** This is used to access token iToken of phrase hit iIdx within the
13021 ** current row. If iIdx is less than zero or greater than or equal to the
13022 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13023 ** output variable (*ppToken) is set to point to a buffer containing the
13024 ** matching document token, and (*pnToken) to the size of that buffer in
13025 ** bytes. This API is not available if the specified token matches a
13026 ** prefix query term. In that case both output variables are always set
13027 ** to 0.
13028 **
13029 ** The output text is not a copy of the document text that was tokenized.
13030 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13031 ** includes any embedded 0x00 and trailing data.
13032 **
13033

Keyboard Shortcuts

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