Fossil SCM

Cherry-pick SQLite changes intended for trunk.

danield 2024-04-04 21:07 trunk
Commit 92f2a04d3780cf24f63e93c0301297fefa4351ccdeeae6f36aa29788ebc3ddb2
2 files changed +144 -17 +10 -4
+144 -17
--- 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
-** a49296de0061931badaf3db6b965131a78b1.
21
+** 7bf49e2c54c9f6f336416f01c0e76aaf70f1.
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.46.0"
463463
#define SQLITE_VERSION_NUMBER 3046000
464
-#define SQLITE_SOURCE_ID "2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3"
464
+#define SQLITE_SOURCE_ID "2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900"
465465
466466
/*
467467
** CAPI3REF: Run-Time Library Version Numbers
468468
** KEYWORDS: sqlite3_version sqlite3_sourceid
469469
**
@@ -7197,10 +7197,16 @@
71977197
** is not invoked when conflicting rows are deleted because of an
71987198
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
71997199
** invoked when rows are deleted using the [truncate optimization].
72007200
** The exceptions defined in this paragraph might change in a future
72017201
** release of SQLite.
7202
+**
7203
+** Whether the update hook is invoked before or after the
7204
+** corresponding change is currently unspecified and may differ
7205
+** depending on the type of change. Do not rely on the order of the
7206
+** hook call with regards to the final result of the operation which
7207
+** triggers the hook.
72027208
**
72037209
** The update hook implementation must not do anything that will modify
72047210
** the database connection that invoked the update hook. Any actions
72057211
** to modify the database connection must be deferred until after the
72067212
** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8668,11 +8674,11 @@
86688674
** by enclosing in double-quotes) so as not to confuse the parser.
86698675
**
86708676
** The sqlite3_keyword_count() interface returns the number of distinct
86718677
** keywords understood by SQLite.
86728678
**
8673
-** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
8679
+** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
86748680
** makes *Z point to that keyword expressed as UTF8 and writes the number
86758681
** of bytes in the keyword into *L. The string that *Z points to is not
86768682
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
86778683
** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
86788684
** or L are NULL or invalid pointers then calls to
@@ -13113,12 +13119,12 @@
1311313119
1311413120
/*
1311513121
** EXTENSION API FUNCTIONS
1311613122
**
1311713123
** xUserData(pFts):
13118
-** Return a copy of the context pointer the extension function was
13119
-** registered with.
13124
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
13125
+** API when the extension function was registered.
1312013126
**
1312113127
** xColumnTotalSize(pFts, iCol, pnToken):
1312213128
** If parameter iCol is less than zero, set output variable *pnToken
1312313129
** to the total number of tokens in the FTS5 table. Or, if iCol is
1312413130
** non-negative but less than the number of columns in the table, return
@@ -15148,11 +15154,11 @@
1514815154
** 0x00000008 WhereLoop inserts
1514915155
**
1515015156
** 0x00000010 Display sqlite3_index_info xBestIndex calls
1515115157
** 0x00000020 Range an equality scan metrics
1515215158
** 0x00000040 IN operator decisions
15153
-** 0x00000080 WhereLoop cost adjustements
15159
+** 0x00000080 WhereLoop cost adjustments
1515415160
** 0x00000100
1515515161
** 0x00000200 Covering index decisions
1515615162
** 0x00000400 OR optimization
1515715163
** 0x00000800 Index scanner
1515815164
** 0x00001000 More details associated with code generation
@@ -165087,14 +165093,17 @@
165087165093
}
165088165094
}
165089165095
}
165090165096
}
165091165097
165092
- /* Set rCostIdx to the cost of visiting selected rows in index. Add
165093
- ** it to pNew->rRun, which is currently set to the cost of the index
165094
- ** seek only. Then, if this is a non-covering index, add the cost of
165095
- ** visiting the rows in the main table. */
165098
+ /* Set rCostIdx to the estimated cost of visiting selected rows in the
165099
+ ** index. The estimate is the sum of two values:
165100
+ ** 1. The cost of doing one search-by-key to find the first matching
165101
+ ** entry
165102
+ ** 2. Stepping forward in the index pNew->nOut times to find all
165103
+ ** additional matching entries.
165104
+ */
165096165105
assert( pSrc->pTab->szTabRow>0 );
165097165106
if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
165098165107
/* The pProbe->szIdxRow is low for an IPK table since the interior
165099165108
** pages are small. Thus szIdxRow gives a good estimate of seek cost.
165100165109
** But the leaf pages are full-size, so pProbe->szIdxRow would badly
@@ -165101,11 +165110,19 @@
165101165110
** under-estimate the scanning cost. */
165102165111
rCostIdx = pNew->nOut + 16;
165103165112
}else{
165104165113
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
165105165114
}
165106
- pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
165115
+ rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
165116
+
165117
+ /* Estimate the cost of running the loop. If all data is coming
165118
+ ** from the index, then this is just the cost of doing the index
165119
+ ** lookup and scan. But if some data is coming out of the main table,
165120
+ ** we also have to add in the cost of doing pNew->nOut searches to
165121
+ ** locate the row in the main table that corresponds to the index entry.
165122
+ */
165123
+ pNew->rRun = rCostIdx;
165107165124
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
165108165125
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
165109165126
}
165110165127
ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
165111165128
@@ -167354,17 +167371,93 @@
167354167371
pWInfo->revMask = revMask;
167355167372
}
167356167373
}
167357167374
}
167358167375
167359
-
167360167376
pWInfo->nRowOut = pFrom->nRow;
167361167377
167362167378
/* Free temporary memory and return success */
167363167379
sqlite3StackFreeNN(pParse->db, pSpace);
167364167380
return SQLITE_OK;
167365167381
}
167382
+
167383
+/*
167384
+** This routine implements a heuristic designed to improve query planning.
167385
+** This routine is called in between the first and second call to
167386
+** wherePathSolver(). Hence the name "Interstage" "Heuristic".
167387
+**
167388
+** The first call to wherePathSolver() (hereafter just "solver()") computes
167389
+** the best path without regard to the order of the outputs. The second call
167390
+** to the solver() builds upon the first call to try to find an alternative
167391
+** path that satisfies the ORDER BY clause.
167392
+**
167393
+** This routine looks at the results of the first solver() run, and for
167394
+** every FROM clause term in the resulting query plan that uses an equality
167395
+** constraint against an index, disable other WhereLoops for that same
167396
+** FROM clause term that would try to do a full-table scan. This prevents
167397
+** an index search from being converted into a full-table scan in order to
167398
+** satisfy an ORDER BY clause, since even though we might get slightly better
167399
+** performance using the full-scan without sorting if the output size
167400
+** estimates are very precise, we might also get severe performance
167401
+** degradation using the full-scan if the output size estimate is too large.
167402
+** It is better to err on the side of caution.
167403
+**
167404
+** Except, if the first solver() call generated a full-table scan in an outer
167405
+** loop then stop this analysis at the first full-scan, since the second
167406
+** solver() run might try to swap that full-scan for another in order to
167407
+** get the output into the correct order. In other words, we allow a
167408
+** rewrite like this:
167409
+**
167410
+** First Solver() Second Solver()
167411
+** |-- SCAN t1 |-- SCAN t2
167412
+** |-- SEARCH t2 `-- SEARCH t1
167413
+** `-- SORT USING B-TREE
167414
+**
167415
+** The purpose of this routine is to disallow rewrites such as:
167416
+**
167417
+** First Solver() Second Solver()
167418
+** |-- SEARCH t1 |-- SCAN t2 <--- bad!
167419
+** |-- SEARCH t2 `-- SEARCH t1
167420
+** `-- SORT USING B-TREE
167421
+**
167422
+** See test cases in test/whereN.test for the real-world query that
167423
+** originally provoked this heuristic.
167424
+*/
167425
+static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){
167426
+ int i;
167427
+#ifdef WHERETRACE_ENABLED
167428
+ int once = 0;
167429
+#endif
167430
+ for(i=0; i<pWInfo->nLevel; i++){
167431
+ WhereLoop *p = pWInfo->a[i].pWLoop;
167432
+ if( p==0 ) break;
167433
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue;
167434
+ if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
167435
+ u8 iTab = p->iTab;
167436
+ WhereLoop *pLoop;
167437
+ for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
167438
+ if( pLoop->iTab!=iTab ) continue;
167439
+ if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){
167440
+ /* Auto-index and index-constrained loops allowed to remain */
167441
+ continue;
167442
+ }
167443
+#ifdef WHERETRACE_ENABLED
167444
+ if( sqlite3WhereTrace & 0x80 ){
167445
+ if( once==0 ){
167446
+ sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n");
167447
+ once = 1;
167448
+ }
167449
+ sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC);
167450
+ }
167451
+#endif /* WHERETRACE_ENABLED */
167452
+ pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */
167453
+ }
167454
+ }else{
167455
+ break;
167456
+ }
167457
+ }
167458
+}
167366167459
167367167460
/*
167368167461
** Most queries use only a single table (they are not joins) and have
167369167462
** simple == constraints against indexed fields. This routine attempts
167370167463
** to plan those simple cases using much less ceremony than the
@@ -168144,10 +168237,11 @@
168144168237
WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
168145168238
168146168239
wherePathSolver(pWInfo, 0);
168147168240
if( db->mallocFailed ) goto whereBeginError;
168148168241
if( pWInfo->pOrderBy ){
168242
+ whereInterstageHeuristic(pWInfo);
168149168243
wherePathSolver(pWInfo, pWInfo->nRowOut+1);
168150168244
if( db->mallocFailed ) goto whereBeginError;
168151168245
}
168152168246
168153168247
/* TUNING: Assume that a DISTINCT clause on a subquery reduces
@@ -216631,11 +216725,11 @@
216631216725
const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
216632216726
const char *zName; /* SQL Collation sequence name (eg. "japanese") */
216633216727
UCollator *pUCollator; /* ICU library collation object */
216634216728
int rc; /* Return code from sqlite3_create_collation_x() */
216635216729
216636
- assert(nArg==2);
216730
+ assert(nArg==2 || nArg==3);
216637216731
(void)nArg; /* Unused parameter */
216638216732
zLocale = (const char *)sqlite3_value_text(apArg[0]);
216639216733
zName = (const char *)sqlite3_value_text(apArg[1]);
216640216734
216641216735
if( !zLocale || !zName ){
@@ -216646,11 +216740,43 @@
216646216740
if( !U_SUCCESS(status) ){
216647216741
icuFunctionError(p, "ucol_open", status);
216648216742
return;
216649216743
}
216650216744
assert(p);
216651
-
216745
+ if(nArg==3){
216746
+ const char *zOption = (const char*)sqlite3_value_text(apArg[2]);
216747
+ static const struct {
216748
+ const char *zName;
216749
+ UColAttributeValue val;
216750
+ } aStrength[] = {
216751
+ { "PRIMARY", UCOL_PRIMARY },
216752
+ { "SECONDARY", UCOL_SECONDARY },
216753
+ { "TERTIARY", UCOL_TERTIARY },
216754
+ { "DEFAULT", UCOL_DEFAULT_STRENGTH },
216755
+ { "QUARTERNARY", UCOL_QUATERNARY },
216756
+ { "IDENTICAL", UCOL_IDENTICAL },
216757
+ };
216758
+ int i;
216759
+ for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
216760
+ if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){
216761
+ ucol_setStrength(pUCollator, aStrength[i].val);
216762
+ break;
216763
+ }
216764
+ }
216765
+ if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){
216766
+ sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p));
216767
+ sqlite3_str_appendf(pStr,
216768
+ "unknown collation strength \"%s\" - should be one of:",
216769
+ zOption);
216770
+ for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
216771
+ sqlite3_str_appendf(pStr, " %s", aStrength[i].zName);
216772
+ }
216773
+ sqlite3_result_error(p, sqlite3_str_value(pStr), -1);
216774
+ sqlite3_free(sqlite3_str_finish(pStr));
216775
+ return;
216776
+ }
216777
+ }
216652216778
rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
216653216779
icuCollationColl, icuCollationDel
216654216780
);
216655216781
if( rc!=SQLITE_OK ){
216656216782
ucol_close(pUCollator);
@@ -216669,10 +216795,11 @@
216669216795
unsigned int enc; /* Optimal text encoding */
216670216796
unsigned char iContext; /* sqlite3_user_data() context */
216671216797
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
216672216798
} scalars[] = {
216673216799
{"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
216800
+ {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
216674216801
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
216675216802
{"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc},
216676216803
{"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216677216804
{"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216678216805
{"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
@@ -230915,12 +231042,12 @@
230915231042
230916231043
/*
230917231044
** EXTENSION API FUNCTIONS
230918231045
**
230919231046
** xUserData(pFts):
230920
-** Return a copy of the context pointer the extension function was
230921
-** registered with.
231047
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
231048
+** API when the extension function was registered.
230922231049
**
230923231050
** xColumnTotalSize(pFts, iCol, pnToken):
230924231051
** If parameter iCol is less than zero, set output variable *pnToken
230925231052
** to the total number of tokens in the FTS5 table. Or, if iCol is
230926231053
** non-negative but less than the number of columns in the table, return
@@ -251969,11 +252096,11 @@
251969252096
int nArg, /* Number of args */
251970252097
sqlite3_value **apUnused /* Function arguments */
251971252098
){
251972252099
assert( nArg==0 );
251973252100
UNUSED_PARAM2(nArg, apUnused);
251974
- sqlite3_result_text(pCtx, "fts5: 2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3", -1, SQLITE_TRANSIENT);
252101
+ sqlite3_result_text(pCtx, "fts5: 2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900", -1, SQLITE_TRANSIENT);
251975252102
}
251976252103
251977252104
/*
251978252105
** Return true if zName is the extension on one of the shadow tables used
251979252106
** by this module.
251980252107
--- 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 ** a49296de0061931badaf3db6b965131a78b1.
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.46.0"
463 #define SQLITE_VERSION_NUMBER 3046000
464 #define SQLITE_SOURCE_ID "2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -7197,10 +7197,16 @@
7197 ** is not invoked when conflicting rows are deleted because of an
7198 ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
7199 ** invoked when rows are deleted using the [truncate optimization].
7200 ** The exceptions defined in this paragraph might change in a future
7201 ** release of SQLite.
 
 
 
 
 
 
7202 **
7203 ** The update hook implementation must not do anything that will modify
7204 ** the database connection that invoked the update hook. Any actions
7205 ** to modify the database connection must be deferred until after the
7206 ** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8668,11 +8674,11 @@
8668 ** by enclosing in double-quotes) so as not to confuse the parser.
8669 **
8670 ** The sqlite3_keyword_count() interface returns the number of distinct
8671 ** keywords understood by SQLite.
8672 **
8673 ** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
8674 ** makes *Z point to that keyword expressed as UTF8 and writes the number
8675 ** of bytes in the keyword into *L. The string that *Z points to is not
8676 ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
8677 ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
8678 ** or L are NULL or invalid pointers then calls to
@@ -13113,12 +13119,12 @@
13113
13114 /*
13115 ** EXTENSION API FUNCTIONS
13116 **
13117 ** xUserData(pFts):
13118 ** Return a copy of the context pointer the extension function was
13119 ** registered with.
13120 **
13121 ** xColumnTotalSize(pFts, iCol, pnToken):
13122 ** If parameter iCol is less than zero, set output variable *pnToken
13123 ** to the total number of tokens in the FTS5 table. Or, if iCol is
13124 ** non-negative but less than the number of columns in the table, return
@@ -15148,11 +15154,11 @@
15148 ** 0x00000008 WhereLoop inserts
15149 **
15150 ** 0x00000010 Display sqlite3_index_info xBestIndex calls
15151 ** 0x00000020 Range an equality scan metrics
15152 ** 0x00000040 IN operator decisions
15153 ** 0x00000080 WhereLoop cost adjustements
15154 ** 0x00000100
15155 ** 0x00000200 Covering index decisions
15156 ** 0x00000400 OR optimization
15157 ** 0x00000800 Index scanner
15158 ** 0x00001000 More details associated with code generation
@@ -165087,14 +165093,17 @@
165087 }
165088 }
165089 }
165090 }
165091
165092 /* Set rCostIdx to the cost of visiting selected rows in index. Add
165093 ** it to pNew->rRun, which is currently set to the cost of the index
165094 ** seek only. Then, if this is a non-covering index, add the cost of
165095 ** visiting the rows in the main table. */
 
 
 
165096 assert( pSrc->pTab->szTabRow>0 );
165097 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
165098 /* The pProbe->szIdxRow is low for an IPK table since the interior
165099 ** pages are small. Thus szIdxRow gives a good estimate of seek cost.
165100 ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
@@ -165101,11 +165110,19 @@
165101 ** under-estimate the scanning cost. */
165102 rCostIdx = pNew->nOut + 16;
165103 }else{
165104 rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
165105 }
165106 pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
 
 
 
 
 
 
 
 
165107 if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
165108 pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
165109 }
165110 ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
165111
@@ -167354,17 +167371,93 @@
167354 pWInfo->revMask = revMask;
167355 }
167356 }
167357 }
167358
167359
167360 pWInfo->nRowOut = pFrom->nRow;
167361
167362 /* Free temporary memory and return success */
167363 sqlite3StackFreeNN(pParse->db, pSpace);
167364 return SQLITE_OK;
167365 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167366
167367 /*
167368 ** Most queries use only a single table (they are not joins) and have
167369 ** simple == constraints against indexed fields. This routine attempts
167370 ** to plan those simple cases using much less ceremony than the
@@ -168144,10 +168237,11 @@
168144 WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
168145
168146 wherePathSolver(pWInfo, 0);
168147 if( db->mallocFailed ) goto whereBeginError;
168148 if( pWInfo->pOrderBy ){
 
168149 wherePathSolver(pWInfo, pWInfo->nRowOut+1);
168150 if( db->mallocFailed ) goto whereBeginError;
168151 }
168152
168153 /* TUNING: Assume that a DISTINCT clause on a subquery reduces
@@ -216631,11 +216725,11 @@
216631 const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
216632 const char *zName; /* SQL Collation sequence name (eg. "japanese") */
216633 UCollator *pUCollator; /* ICU library collation object */
216634 int rc; /* Return code from sqlite3_create_collation_x() */
216635
216636 assert(nArg==2);
216637 (void)nArg; /* Unused parameter */
216638 zLocale = (const char *)sqlite3_value_text(apArg[0]);
216639 zName = (const char *)sqlite3_value_text(apArg[1]);
216640
216641 if( !zLocale || !zName ){
@@ -216646,11 +216740,43 @@
216646 if( !U_SUCCESS(status) ){
216647 icuFunctionError(p, "ucol_open", status);
216648 return;
216649 }
216650 assert(p);
216651
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216652 rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
216653 icuCollationColl, icuCollationDel
216654 );
216655 if( rc!=SQLITE_OK ){
216656 ucol_close(pUCollator);
@@ -216669,10 +216795,11 @@
216669 unsigned int enc; /* Optimal text encoding */
216670 unsigned char iContext; /* sqlite3_user_data() context */
216671 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
216672 } scalars[] = {
216673 {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
 
216674 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
216675 {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc},
216676 {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216677 {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216678 {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
@@ -230915,12 +231042,12 @@
230915
230916 /*
230917 ** EXTENSION API FUNCTIONS
230918 **
230919 ** xUserData(pFts):
230920 ** Return a copy of the context pointer the extension function was
230921 ** registered with.
230922 **
230923 ** xColumnTotalSize(pFts, iCol, pnToken):
230924 ** If parameter iCol is less than zero, set output variable *pnToken
230925 ** to the total number of tokens in the FTS5 table. Or, if iCol is
230926 ** non-negative but less than the number of columns in the table, return
@@ -251969,11 +252096,11 @@
251969 int nArg, /* Number of args */
251970 sqlite3_value **apUnused /* Function arguments */
251971 ){
251972 assert( nArg==0 );
251973 UNUSED_PARAM2(nArg, apUnused);
251974 sqlite3_result_text(pCtx, "fts5: 2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3", -1, SQLITE_TRANSIENT);
251975 }
251976
251977 /*
251978 ** Return true if zName is the extension on one of the shadow tables used
251979 ** by this module.
251980
--- 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 ** 7bf49e2c54c9f6f336416f01c0e76aaf70f1.
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.46.0"
463 #define SQLITE_VERSION_NUMBER 3046000
464 #define SQLITE_SOURCE_ID "2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -7197,10 +7197,16 @@
7197 ** is not invoked when conflicting rows are deleted because of an
7198 ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
7199 ** invoked when rows are deleted using the [truncate optimization].
7200 ** The exceptions defined in this paragraph might change in a future
7201 ** release of SQLite.
7202 **
7203 ** Whether the update hook is invoked before or after the
7204 ** corresponding change is currently unspecified and may differ
7205 ** depending on the type of change. Do not rely on the order of the
7206 ** hook call with regards to the final result of the operation which
7207 ** triggers the hook.
7208 **
7209 ** The update hook implementation must not do anything that will modify
7210 ** the database connection that invoked the update hook. Any actions
7211 ** to modify the database connection must be deferred until after the
7212 ** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8668,11 +8674,11 @@
8674 ** by enclosing in double-quotes) so as not to confuse the parser.
8675 **
8676 ** The sqlite3_keyword_count() interface returns the number of distinct
8677 ** keywords understood by SQLite.
8678 **
8679 ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
8680 ** makes *Z point to that keyword expressed as UTF8 and writes the number
8681 ** of bytes in the keyword into *L. The string that *Z points to is not
8682 ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
8683 ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
8684 ** or L are NULL or invalid pointers then calls to
@@ -13113,12 +13119,12 @@
13119
13120 /*
13121 ** EXTENSION API FUNCTIONS
13122 **
13123 ** xUserData(pFts):
13124 ** Return a copy of the pUserData pointer passed to the xCreateFunction()
13125 ** API when the extension function was registered.
13126 **
13127 ** xColumnTotalSize(pFts, iCol, pnToken):
13128 ** If parameter iCol is less than zero, set output variable *pnToken
13129 ** to the total number of tokens in the FTS5 table. Or, if iCol is
13130 ** non-negative but less than the number of columns in the table, return
@@ -15148,11 +15154,11 @@
15154 ** 0x00000008 WhereLoop inserts
15155 **
15156 ** 0x00000010 Display sqlite3_index_info xBestIndex calls
15157 ** 0x00000020 Range an equality scan metrics
15158 ** 0x00000040 IN operator decisions
15159 ** 0x00000080 WhereLoop cost adjustments
15160 ** 0x00000100
15161 ** 0x00000200 Covering index decisions
15162 ** 0x00000400 OR optimization
15163 ** 0x00000800 Index scanner
15164 ** 0x00001000 More details associated with code generation
@@ -165087,14 +165093,17 @@
165093 }
165094 }
165095 }
165096 }
165097
165098 /* Set rCostIdx to the estimated cost of visiting selected rows in the
165099 ** index. The estimate is the sum of two values:
165100 ** 1. The cost of doing one search-by-key to find the first matching
165101 ** entry
165102 ** 2. Stepping forward in the index pNew->nOut times to find all
165103 ** additional matching entries.
165104 */
165105 assert( pSrc->pTab->szTabRow>0 );
165106 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
165107 /* The pProbe->szIdxRow is low for an IPK table since the interior
165108 ** pages are small. Thus szIdxRow gives a good estimate of seek cost.
165109 ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
@@ -165101,11 +165110,19 @@
165110 ** under-estimate the scanning cost. */
165111 rCostIdx = pNew->nOut + 16;
165112 }else{
165113 rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
165114 }
165115 rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
165116
165117 /* Estimate the cost of running the loop. If all data is coming
165118 ** from the index, then this is just the cost of doing the index
165119 ** lookup and scan. But if some data is coming out of the main table,
165120 ** we also have to add in the cost of doing pNew->nOut searches to
165121 ** locate the row in the main table that corresponds to the index entry.
165122 */
165123 pNew->rRun = rCostIdx;
165124 if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
165125 pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
165126 }
165127 ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
165128
@@ -167354,17 +167371,93 @@
167371 pWInfo->revMask = revMask;
167372 }
167373 }
167374 }
167375
 
167376 pWInfo->nRowOut = pFrom->nRow;
167377
167378 /* Free temporary memory and return success */
167379 sqlite3StackFreeNN(pParse->db, pSpace);
167380 return SQLITE_OK;
167381 }
167382
167383 /*
167384 ** This routine implements a heuristic designed to improve query planning.
167385 ** This routine is called in between the first and second call to
167386 ** wherePathSolver(). Hence the name "Interstage" "Heuristic".
167387 **
167388 ** The first call to wherePathSolver() (hereafter just "solver()") computes
167389 ** the best path without regard to the order of the outputs. The second call
167390 ** to the solver() builds upon the first call to try to find an alternative
167391 ** path that satisfies the ORDER BY clause.
167392 **
167393 ** This routine looks at the results of the first solver() run, and for
167394 ** every FROM clause term in the resulting query plan that uses an equality
167395 ** constraint against an index, disable other WhereLoops for that same
167396 ** FROM clause term that would try to do a full-table scan. This prevents
167397 ** an index search from being converted into a full-table scan in order to
167398 ** satisfy an ORDER BY clause, since even though we might get slightly better
167399 ** performance using the full-scan without sorting if the output size
167400 ** estimates are very precise, we might also get severe performance
167401 ** degradation using the full-scan if the output size estimate is too large.
167402 ** It is better to err on the side of caution.
167403 **
167404 ** Except, if the first solver() call generated a full-table scan in an outer
167405 ** loop then stop this analysis at the first full-scan, since the second
167406 ** solver() run might try to swap that full-scan for another in order to
167407 ** get the output into the correct order. In other words, we allow a
167408 ** rewrite like this:
167409 **
167410 ** First Solver() Second Solver()
167411 ** |-- SCAN t1 |-- SCAN t2
167412 ** |-- SEARCH t2 `-- SEARCH t1
167413 ** `-- SORT USING B-TREE
167414 **
167415 ** The purpose of this routine is to disallow rewrites such as:
167416 **
167417 ** First Solver() Second Solver()
167418 ** |-- SEARCH t1 |-- SCAN t2 <--- bad!
167419 ** |-- SEARCH t2 `-- SEARCH t1
167420 ** `-- SORT USING B-TREE
167421 **
167422 ** See test cases in test/whereN.test for the real-world query that
167423 ** originally provoked this heuristic.
167424 */
167425 static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){
167426 int i;
167427 #ifdef WHERETRACE_ENABLED
167428 int once = 0;
167429 #endif
167430 for(i=0; i<pWInfo->nLevel; i++){
167431 WhereLoop *p = pWInfo->a[i].pWLoop;
167432 if( p==0 ) break;
167433 if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue;
167434 if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
167435 u8 iTab = p->iTab;
167436 WhereLoop *pLoop;
167437 for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
167438 if( pLoop->iTab!=iTab ) continue;
167439 if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){
167440 /* Auto-index and index-constrained loops allowed to remain */
167441 continue;
167442 }
167443 #ifdef WHERETRACE_ENABLED
167444 if( sqlite3WhereTrace & 0x80 ){
167445 if( once==0 ){
167446 sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n");
167447 once = 1;
167448 }
167449 sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC);
167450 }
167451 #endif /* WHERETRACE_ENABLED */
167452 pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */
167453 }
167454 }else{
167455 break;
167456 }
167457 }
167458 }
167459
167460 /*
167461 ** Most queries use only a single table (they are not joins) and have
167462 ** simple == constraints against indexed fields. This routine attempts
167463 ** to plan those simple cases using much less ceremony than the
@@ -168144,10 +168237,11 @@
168237 WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
168238
168239 wherePathSolver(pWInfo, 0);
168240 if( db->mallocFailed ) goto whereBeginError;
168241 if( pWInfo->pOrderBy ){
168242 whereInterstageHeuristic(pWInfo);
168243 wherePathSolver(pWInfo, pWInfo->nRowOut+1);
168244 if( db->mallocFailed ) goto whereBeginError;
168245 }
168246
168247 /* TUNING: Assume that a DISTINCT clause on a subquery reduces
@@ -216631,11 +216725,11 @@
216725 const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
216726 const char *zName; /* SQL Collation sequence name (eg. "japanese") */
216727 UCollator *pUCollator; /* ICU library collation object */
216728 int rc; /* Return code from sqlite3_create_collation_x() */
216729
216730 assert(nArg==2 || nArg==3);
216731 (void)nArg; /* Unused parameter */
216732 zLocale = (const char *)sqlite3_value_text(apArg[0]);
216733 zName = (const char *)sqlite3_value_text(apArg[1]);
216734
216735 if( !zLocale || !zName ){
@@ -216646,11 +216740,43 @@
216740 if( !U_SUCCESS(status) ){
216741 icuFunctionError(p, "ucol_open", status);
216742 return;
216743 }
216744 assert(p);
216745 if(nArg==3){
216746 const char *zOption = (const char*)sqlite3_value_text(apArg[2]);
216747 static const struct {
216748 const char *zName;
216749 UColAttributeValue val;
216750 } aStrength[] = {
216751 { "PRIMARY", UCOL_PRIMARY },
216752 { "SECONDARY", UCOL_SECONDARY },
216753 { "TERTIARY", UCOL_TERTIARY },
216754 { "DEFAULT", UCOL_DEFAULT_STRENGTH },
216755 { "QUARTERNARY", UCOL_QUATERNARY },
216756 { "IDENTICAL", UCOL_IDENTICAL },
216757 };
216758 int i;
216759 for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
216760 if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){
216761 ucol_setStrength(pUCollator, aStrength[i].val);
216762 break;
216763 }
216764 }
216765 if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){
216766 sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p));
216767 sqlite3_str_appendf(pStr,
216768 "unknown collation strength \"%s\" - should be one of:",
216769 zOption);
216770 for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
216771 sqlite3_str_appendf(pStr, " %s", aStrength[i].zName);
216772 }
216773 sqlite3_result_error(p, sqlite3_str_value(pStr), -1);
216774 sqlite3_free(sqlite3_str_finish(pStr));
216775 return;
216776 }
216777 }
216778 rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
216779 icuCollationColl, icuCollationDel
216780 );
216781 if( rc!=SQLITE_OK ){
216782 ucol_close(pUCollator);
@@ -216669,10 +216795,11 @@
216795 unsigned int enc; /* Optimal text encoding */
216796 unsigned char iContext; /* sqlite3_user_data() context */
216797 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
216798 } scalars[] = {
216799 {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
216800 {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
216801 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
216802 {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc},
216803 {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216804 {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
216805 {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
@@ -230915,12 +231042,12 @@
231042
231043 /*
231044 ** EXTENSION API FUNCTIONS
231045 **
231046 ** xUserData(pFts):
231047 ** Return a copy of the pUserData pointer passed to the xCreateFunction()
231048 ** API when the extension function was registered.
231049 **
231050 ** xColumnTotalSize(pFts, iCol, pnToken):
231051 ** If parameter iCol is less than zero, set output variable *pnToken
231052 ** to the total number of tokens in the FTS5 table. Or, if iCol is
231053 ** non-negative but less than the number of columns in the table, return
@@ -251969,11 +252096,11 @@
252096 int nArg, /* Number of args */
252097 sqlite3_value **apUnused /* Function arguments */
252098 ){
252099 assert( nArg==0 );
252100 UNUSED_PARAM2(nArg, apUnused);
252101 sqlite3_result_text(pCtx, "fts5: 2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900", -1, SQLITE_TRANSIENT);
252102 }
252103
252104 /*
252105 ** Return true if zName is the extension on one of the shadow tables used
252106 ** by this module.
252107
+10 -4
--- 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.46.0"
150150
#define SQLITE_VERSION_NUMBER 3046000
151
-#define SQLITE_SOURCE_ID "2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3"
151
+#define SQLITE_SOURCE_ID "2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -6884,10 +6884,16 @@
68846884
** is not invoked when conflicting rows are deleted because of an
68856885
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
68866886
** invoked when rows are deleted using the [truncate optimization].
68876887
** The exceptions defined in this paragraph might change in a future
68886888
** release of SQLite.
6889
+**
6890
+** Whether the update hook is invoked before or after the
6891
+** corresponding change is currently unspecified and may differ
6892
+** depending on the type of change. Do not rely on the order of the
6893
+** hook call with regards to the final result of the operation which
6894
+** triggers the hook.
68896895
**
68906896
** The update hook implementation must not do anything that will modify
68916897
** the database connection that invoked the update hook. Any actions
68926898
** to modify the database connection must be deferred until after the
68936899
** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8355,11 +8361,11 @@
83558361
** by enclosing in double-quotes) so as not to confuse the parser.
83568362
**
83578363
** The sqlite3_keyword_count() interface returns the number of distinct
83588364
** keywords understood by SQLite.
83598365
**
8360
-** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
8366
+** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
83618367
** makes *Z point to that keyword expressed as UTF8 and writes the number
83628368
** of bytes in the keyword into *L. The string that *Z points to is not
83638369
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
83648370
** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
83658371
** or L are NULL or invalid pointers then calls to
@@ -12800,12 +12806,12 @@
1280012806
1280112807
/*
1280212808
** EXTENSION API FUNCTIONS
1280312809
**
1280412810
** xUserData(pFts):
12805
-** Return a copy of the context pointer the extension function was
12806
-** registered with.
12811
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
12812
+** API when the extension function was registered.
1280712813
**
1280812814
** xColumnTotalSize(pFts, iCol, pnToken):
1280912815
** If parameter iCol is less than zero, set output variable *pnToken
1281012816
** to the total number of tokens in the FTS5 table. Or, if iCol is
1281112817
** non-negative but less than the number of columns in the table, return
1281212818
--- 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.46.0"
150 #define SQLITE_VERSION_NUMBER 3046000
151 #define SQLITE_SOURCE_ID "2024-03-26 11:14:52 a49296de0061931badaf3db6b965131a78b1c6c21b1eeb62815ea7adf767d0b3"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -6884,10 +6884,16 @@
6884 ** is not invoked when conflicting rows are deleted because of an
6885 ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
6886 ** invoked when rows are deleted using the [truncate optimization].
6887 ** The exceptions defined in this paragraph might change in a future
6888 ** release of SQLite.
 
 
 
 
 
 
6889 **
6890 ** The update hook implementation must not do anything that will modify
6891 ** the database connection that invoked the update hook. Any actions
6892 ** to modify the database connection must be deferred until after the
6893 ** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8355,11 +8361,11 @@
8355 ** by enclosing in double-quotes) so as not to confuse the parser.
8356 **
8357 ** The sqlite3_keyword_count() interface returns the number of distinct
8358 ** keywords understood by SQLite.
8359 **
8360 ** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
8361 ** makes *Z point to that keyword expressed as UTF8 and writes the number
8362 ** of bytes in the keyword into *L. The string that *Z points to is not
8363 ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
8364 ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
8365 ** or L are NULL or invalid pointers then calls to
@@ -12800,12 +12806,12 @@
12800
12801 /*
12802 ** EXTENSION API FUNCTIONS
12803 **
12804 ** xUserData(pFts):
12805 ** Return a copy of the context pointer the extension function was
12806 ** registered with.
12807 **
12808 ** xColumnTotalSize(pFts, iCol, pnToken):
12809 ** If parameter iCol is less than zero, set output variable *pnToken
12810 ** to the total number of tokens in the FTS5 table. Or, if iCol is
12811 ** non-negative but less than the number of columns in the table, return
12812
--- 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.46.0"
150 #define SQLITE_VERSION_NUMBER 3046000
151 #define SQLITE_SOURCE_ID "2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -6884,10 +6884,16 @@
6884 ** is not invoked when conflicting rows are deleted because of an
6885 ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
6886 ** invoked when rows are deleted using the [truncate optimization].
6887 ** The exceptions defined in this paragraph might change in a future
6888 ** release of SQLite.
6889 **
6890 ** Whether the update hook is invoked before or after the
6891 ** corresponding change is currently unspecified and may differ
6892 ** depending on the type of change. Do not rely on the order of the
6893 ** hook call with regards to the final result of the operation which
6894 ** triggers the hook.
6895 **
6896 ** The update hook implementation must not do anything that will modify
6897 ** the database connection that invoked the update hook. Any actions
6898 ** to modify the database connection must be deferred until after the
6899 ** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -8355,11 +8361,11 @@
8361 ** by enclosing in double-quotes) so as not to confuse the parser.
8362 **
8363 ** The sqlite3_keyword_count() interface returns the number of distinct
8364 ** keywords understood by SQLite.
8365 **
8366 ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
8367 ** makes *Z point to that keyword expressed as UTF8 and writes the number
8368 ** of bytes in the keyword into *L. The string that *Z points to is not
8369 ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
8370 ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
8371 ** or L are NULL or invalid pointers then calls to
@@ -12800,12 +12806,12 @@
12806
12807 /*
12808 ** EXTENSION API FUNCTIONS
12809 **
12810 ** xUserData(pFts):
12811 ** Return a copy of the pUserData pointer passed to the xCreateFunction()
12812 ** API when the extension function was registered.
12813 **
12814 ** xColumnTotalSize(pFts, iCol, pnToken):
12815 ** If parameter iCol is less than zero, set output variable *pnToken
12816 ** to the total number of tokens in the FTS5 table. Or, if iCol is
12817 ** non-negative but less than the number of columns in the table, return
12818

Keyboard Shortcuts

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