Fossil SCM
Cherry-pick SQLite changes intended for trunk.
Commit
92f2a04d3780cf24f63e93c0301297fefa4351ccdeeae6f36aa29788ebc3ddb2
Parent
72add409649d9c3…
2 files changed
+144
-17
+10
-4
+144
-17
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** a49296de0061931badaf3db6b965131a78b1. | |
| 21 | +** 7bf49e2c54c9f6f336416f01c0e76aaf70f1. | |
| 22 | 22 | */ |
| 23 | 23 | #define SQLITE_CORE 1 |
| 24 | 24 | #define SQLITE_AMALGAMATION 1 |
| 25 | 25 | #ifndef SQLITE_PRIVATE |
| 26 | 26 | # define SQLITE_PRIVATE static |
| @@ -459,11 +459,11 @@ | ||
| 459 | 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 460 | 460 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 461 | 461 | */ |
| 462 | 462 | #define SQLITE_VERSION "3.46.0" |
| 463 | 463 | #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" | |
| 465 | 465 | |
| 466 | 466 | /* |
| 467 | 467 | ** CAPI3REF: Run-Time Library Version Numbers |
| 468 | 468 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 469 | 469 | ** |
| @@ -7197,10 +7197,16 @@ | ||
| 7197 | 7197 | ** is not invoked when conflicting rows are deleted because of an |
| 7198 | 7198 | ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook |
| 7199 | 7199 | ** invoked when rows are deleted using the [truncate optimization]. |
| 7200 | 7200 | ** The exceptions defined in this paragraph might change in a future |
| 7201 | 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. | |
| 7202 | 7208 | ** |
| 7203 | 7209 | ** The update hook implementation must not do anything that will modify |
| 7204 | 7210 | ** the database connection that invoked the update hook. Any actions |
| 7205 | 7211 | ** to modify the database connection must be deferred until after the |
| 7206 | 7212 | ** completion of the [sqlite3_step()] call that triggered the update hook. |
| @@ -8668,11 +8674,11 @@ | ||
| 8668 | 8674 | ** by enclosing in double-quotes) so as not to confuse the parser. |
| 8669 | 8675 | ** |
| 8670 | 8676 | ** The sqlite3_keyword_count() interface returns the number of distinct |
| 8671 | 8677 | ** keywords understood by SQLite. |
| 8672 | 8678 | ** |
| 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 | |
| 8674 | 8680 | ** makes *Z point to that keyword expressed as UTF8 and writes the number |
| 8675 | 8681 | ** of bytes in the keyword into *L. The string that *Z points to is not |
| 8676 | 8682 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns |
| 8677 | 8683 | ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z |
| 8678 | 8684 | ** or L are NULL or invalid pointers then calls to |
| @@ -13113,12 +13119,12 @@ | ||
| 13113 | 13119 | |
| 13114 | 13120 | /* |
| 13115 | 13121 | ** EXTENSION API FUNCTIONS |
| 13116 | 13122 | ** |
| 13117 | 13123 | ** 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. | |
| 13120 | 13126 | ** |
| 13121 | 13127 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 13122 | 13128 | ** If parameter iCol is less than zero, set output variable *pnToken |
| 13123 | 13129 | ** to the total number of tokens in the FTS5 table. Or, if iCol is |
| 13124 | 13130 | ** non-negative but less than the number of columns in the table, return |
| @@ -15148,11 +15154,11 @@ | ||
| 15148 | 15154 | ** 0x00000008 WhereLoop inserts |
| 15149 | 15155 | ** |
| 15150 | 15156 | ** 0x00000010 Display sqlite3_index_info xBestIndex calls |
| 15151 | 15157 | ** 0x00000020 Range an equality scan metrics |
| 15152 | 15158 | ** 0x00000040 IN operator decisions |
| 15153 | -** 0x00000080 WhereLoop cost adjustements | |
| 15159 | +** 0x00000080 WhereLoop cost adjustments | |
| 15154 | 15160 | ** 0x00000100 |
| 15155 | 15161 | ** 0x00000200 Covering index decisions |
| 15156 | 15162 | ** 0x00000400 OR optimization |
| 15157 | 15163 | ** 0x00000800 Index scanner |
| 15158 | 15164 | ** 0x00001000 More details associated with code generation |
| @@ -165087,14 +165093,17 @@ | ||
| 165087 | 165093 | } |
| 165088 | 165094 | } |
| 165089 | 165095 | } |
| 165090 | 165096 | } |
| 165091 | 165097 | |
| 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 | + */ | |
| 165096 | 165105 | assert( pSrc->pTab->szTabRow>0 ); |
| 165097 | 165106 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ |
| 165098 | 165107 | /* The pProbe->szIdxRow is low for an IPK table since the interior |
| 165099 | 165108 | ** pages are small. Thus szIdxRow gives a good estimate of seek cost. |
| 165100 | 165109 | ** But the leaf pages are full-size, so pProbe->szIdxRow would badly |
| @@ -165101,11 +165110,19 @@ | ||
| 165101 | 165110 | ** under-estimate the scanning cost. */ |
| 165102 | 165111 | rCostIdx = pNew->nOut + 16; |
| 165103 | 165112 | }else{ |
| 165104 | 165113 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 165105 | 165114 | } |
| 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; | |
| 165107 | 165124 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ |
| 165108 | 165125 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 165109 | 165126 | } |
| 165110 | 165127 | ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); |
| 165111 | 165128 | |
| @@ -167354,17 +167371,93 @@ | ||
| 167354 | 167371 | pWInfo->revMask = revMask; |
| 167355 | 167372 | } |
| 167356 | 167373 | } |
| 167357 | 167374 | } |
| 167358 | 167375 | |
| 167359 | - | |
| 167360 | 167376 | pWInfo->nRowOut = pFrom->nRow; |
| 167361 | 167377 | |
| 167362 | 167378 | /* Free temporary memory and return success */ |
| 167363 | 167379 | sqlite3StackFreeNN(pParse->db, pSpace); |
| 167364 | 167380 | return SQLITE_OK; |
| 167365 | 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 | +} | |
| 167366 | 167459 | |
| 167367 | 167460 | /* |
| 167368 | 167461 | ** Most queries use only a single table (they are not joins) and have |
| 167369 | 167462 | ** simple == constraints against indexed fields. This routine attempts |
| 167370 | 167463 | ** to plan those simple cases using much less ceremony than the |
| @@ -168144,10 +168237,11 @@ | ||
| 168144 | 168237 | WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); |
| 168145 | 168238 | |
| 168146 | 168239 | wherePathSolver(pWInfo, 0); |
| 168147 | 168240 | if( db->mallocFailed ) goto whereBeginError; |
| 168148 | 168241 | if( pWInfo->pOrderBy ){ |
| 168242 | + whereInterstageHeuristic(pWInfo); | |
| 168149 | 168243 | wherePathSolver(pWInfo, pWInfo->nRowOut+1); |
| 168150 | 168244 | if( db->mallocFailed ) goto whereBeginError; |
| 168151 | 168245 | } |
| 168152 | 168246 | |
| 168153 | 168247 | /* TUNING: Assume that a DISTINCT clause on a subquery reduces |
| @@ -216631,11 +216725,11 @@ | ||
| 216631 | 216725 | const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ |
| 216632 | 216726 | const char *zName; /* SQL Collation sequence name (eg. "japanese") */ |
| 216633 | 216727 | UCollator *pUCollator; /* ICU library collation object */ |
| 216634 | 216728 | int rc; /* Return code from sqlite3_create_collation_x() */ |
| 216635 | 216729 | |
| 216636 | - assert(nArg==2); | |
| 216730 | + assert(nArg==2 || nArg==3); | |
| 216637 | 216731 | (void)nArg; /* Unused parameter */ |
| 216638 | 216732 | zLocale = (const char *)sqlite3_value_text(apArg[0]); |
| 216639 | 216733 | zName = (const char *)sqlite3_value_text(apArg[1]); |
| 216640 | 216734 | |
| 216641 | 216735 | if( !zLocale || !zName ){ |
| @@ -216646,11 +216740,43 @@ | ||
| 216646 | 216740 | if( !U_SUCCESS(status) ){ |
| 216647 | 216741 | icuFunctionError(p, "ucol_open", status); |
| 216648 | 216742 | return; |
| 216649 | 216743 | } |
| 216650 | 216744 | 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 | + } | |
| 216652 | 216778 | rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, |
| 216653 | 216779 | icuCollationColl, icuCollationDel |
| 216654 | 216780 | ); |
| 216655 | 216781 | if( rc!=SQLITE_OK ){ |
| 216656 | 216782 | ucol_close(pUCollator); |
| @@ -216669,10 +216795,11 @@ | ||
| 216669 | 216795 | unsigned int enc; /* Optimal text encoding */ |
| 216670 | 216796 | unsigned char iContext; /* sqlite3_user_data() context */ |
| 216671 | 216797 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
| 216672 | 216798 | } scalars[] = { |
| 216673 | 216799 | {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, |
| 216800 | + {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, | |
| 216674 | 216801 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) |
| 216675 | 216802 | {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, |
| 216676 | 216803 | {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, |
| 216677 | 216804 | {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, |
| 216678 | 216805 | {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, |
| @@ -230915,12 +231042,12 @@ | ||
| 230915 | 231042 | |
| 230916 | 231043 | /* |
| 230917 | 231044 | ** EXTENSION API FUNCTIONS |
| 230918 | 231045 | ** |
| 230919 | 231046 | ** 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. | |
| 230922 | 231049 | ** |
| 230923 | 231050 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 230924 | 231051 | ** If parameter iCol is less than zero, set output variable *pnToken |
| 230925 | 231052 | ** to the total number of tokens in the FTS5 table. Or, if iCol is |
| 230926 | 231053 | ** non-negative but less than the number of columns in the table, return |
| @@ -251969,11 +252096,11 @@ | ||
| 251969 | 252096 | int nArg, /* Number of args */ |
| 251970 | 252097 | sqlite3_value **apUnused /* Function arguments */ |
| 251971 | 252098 | ){ |
| 251972 | 252099 | assert( nArg==0 ); |
| 251973 | 252100 | 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); | |
| 251975 | 252102 | } |
| 251976 | 252103 | |
| 251977 | 252104 | /* |
| 251978 | 252105 | ** Return true if zName is the extension on one of the shadow tables used |
| 251979 | 252106 | ** by this module. |
| 251980 | 252107 |
| --- 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 @@ | ||
| 146 | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | 148 | */ |
| 149 | 149 | #define SQLITE_VERSION "3.46.0" |
| 150 | 150 | #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" | |
| 152 | 152 | |
| 153 | 153 | /* |
| 154 | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | 156 | ** |
| @@ -6884,10 +6884,16 @@ | ||
| 6884 | 6884 | ** is not invoked when conflicting rows are deleted because of an |
| 6885 | 6885 | ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook |
| 6886 | 6886 | ** invoked when rows are deleted using the [truncate optimization]. |
| 6887 | 6887 | ** The exceptions defined in this paragraph might change in a future |
| 6888 | 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. | |
| 6889 | 6895 | ** |
| 6890 | 6896 | ** The update hook implementation must not do anything that will modify |
| 6891 | 6897 | ** the database connection that invoked the update hook. Any actions |
| 6892 | 6898 | ** to modify the database connection must be deferred until after the |
| 6893 | 6899 | ** completion of the [sqlite3_step()] call that triggered the update hook. |
| @@ -8355,11 +8361,11 @@ | ||
| 8355 | 8361 | ** by enclosing in double-quotes) so as not to confuse the parser. |
| 8356 | 8362 | ** |
| 8357 | 8363 | ** The sqlite3_keyword_count() interface returns the number of distinct |
| 8358 | 8364 | ** keywords understood by SQLite. |
| 8359 | 8365 | ** |
| 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 | |
| 8361 | 8367 | ** makes *Z point to that keyword expressed as UTF8 and writes the number |
| 8362 | 8368 | ** of bytes in the keyword into *L. The string that *Z points to is not |
| 8363 | 8369 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns |
| 8364 | 8370 | ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z |
| 8365 | 8371 | ** or L are NULL or invalid pointers then calls to |
| @@ -12800,12 +12806,12 @@ | ||
| 12800 | 12806 | |
| 12801 | 12807 | /* |
| 12802 | 12808 | ** EXTENSION API FUNCTIONS |
| 12803 | 12809 | ** |
| 12804 | 12810 | ** 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. | |
| 12807 | 12813 | ** |
| 12808 | 12814 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 12809 | 12815 | ** If parameter iCol is less than zero, set output variable *pnToken |
| 12810 | 12816 | ** to the total number of tokens in the FTS5 table. Or, if iCol is |
| 12811 | 12817 | ** non-negative but less than the number of columns in the table, return |
| 12812 | 12818 |
| --- 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 |