| | @@ -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 | | -** 3778b2a9ca1cc12a88ef6c32a1ee7c58a0a8. |
| 21 | +** 7a0cdc7edb704a88a77b748cd28f6e00c498. |
| 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 |
| | @@ -462,11 +462,11 @@ |
| 462 | 462 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 463 | 463 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 464 | 464 | */ |
| 465 | 465 | #define SQLITE_VERSION "3.47.0" |
| 466 | 466 | #define SQLITE_VERSION_NUMBER 3047000 |
| 467 | | -#define SQLITE_SOURCE_ID "2024-08-10 15:46:57 3778b2a9ca1cc12a88ef6c32a1ee7c58a0a829ed9715a3d32a225d377d7527ef" |
| 467 | +#define SQLITE_SOURCE_ID "2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9" |
| 468 | 468 | |
| 469 | 469 | /* |
| 470 | 470 | ** CAPI3REF: Run-Time Library Version Numbers |
| 471 | 471 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 472 | 472 | ** |
| | @@ -17915,10 +17915,11 @@ |
| 17915 | 17915 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ |
| 17916 | 17916 | #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ |
| 17917 | 17917 | #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ |
| 17918 | 17918 | #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ |
| 17919 | 17919 | #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ |
| 17920 | +#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ |
| 17920 | 17921 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17921 | 17922 | |
| 17922 | 17923 | /* |
| 17923 | 17924 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 17924 | 17925 | */ |
| | @@ -120471,16 +120472,17 @@ |
| 120471 | 120472 | if( rc ) return rc; |
| 120472 | 120473 | |
| 120473 | 120474 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 120474 | 120475 | int nIdxCol = 1; /* Number of columns in stat4 records */ |
| 120475 | 120476 | |
| 120476 | | - char *zIndex; /* Index name */ |
| 120477 | | - Index *pIdx; /* Pointer to the index object */ |
| 120478 | | - int nSample; /* Number of samples */ |
| 120479 | | - int nByte; /* Bytes of space required */ |
| 120480 | | - int i; /* Bytes of space required */ |
| 120481 | | - tRowcnt *pSpace; |
| 120477 | + char *zIndex; /* Index name */ |
| 120478 | + Index *pIdx; /* Pointer to the index object */ |
| 120479 | + int nSample; /* Number of samples */ |
| 120480 | + int nByte; /* Bytes of space required */ |
| 120481 | + int i; /* Bytes of space required */ |
| 120482 | + tRowcnt *pSpace; /* Available allocated memory space */ |
| 120483 | + u8 *pPtr; /* Available memory as a u8 for easier manipulation */ |
| 120482 | 120484 | |
| 120483 | 120485 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 120484 | 120486 | if( zIndex==0 ) continue; |
| 120485 | 120487 | nSample = sqlite3_column_int(pStmt, 1); |
| 120486 | 120488 | pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); |
| | @@ -120496,20 +120498,22 @@ |
| 120496 | 120498 | }else{ |
| 120497 | 120499 | nIdxCol = pIdx->nColumn; |
| 120498 | 120500 | } |
| 120499 | 120501 | pIdx->nSampleCol = nIdxCol; |
| 120500 | 120502 | pIdx->mxSample = nSample; |
| 120501 | | - nByte = sizeof(IndexSample) * nSample; |
| 120503 | + nByte = ROUND8(sizeof(IndexSample) * nSample); |
| 120502 | 120504 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 120503 | 120505 | nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 120504 | 120506 | |
| 120505 | 120507 | pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
| 120506 | 120508 | if( pIdx->aSample==0 ){ |
| 120507 | 120509 | sqlite3_finalize(pStmt); |
| 120508 | 120510 | return SQLITE_NOMEM_BKPT; |
| 120509 | 120511 | } |
| 120510 | | - pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
| 120512 | + pPtr = (u8*)pIdx->aSample; |
| 120513 | + pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); |
| 120514 | + pSpace = (tRowcnt*)pPtr; |
| 120511 | 120515 | assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); |
| 120512 | 120516 | pIdx->aAvgEq = pSpace; pSpace += nIdxCol; |
| 120513 | 120517 | pIdx->pTable->tabFlags |= TF_HasStat4; |
| 120514 | 120518 | for(i=0; i<nSample; i++){ |
| 120515 | 120519 | pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; |
| | @@ -157188,10 +157192,11 @@ |
| 157188 | 157192 | u16 nEq; /* Number of equality constraints */ |
| 157189 | 157193 | u16 nBtm; /* Size of BTM vector */ |
| 157190 | 157194 | u16 nTop; /* Size of TOP vector */ |
| 157191 | 157195 | u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ |
| 157192 | 157196 | Index *pIndex; /* Index used, or NULL */ |
| 157197 | + ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ |
| 157193 | 157198 | } btree; |
| 157194 | 157199 | struct { /* Information for virtual tables */ |
| 157195 | 157200 | int idxNum; /* Index number */ |
| 157196 | 157201 | u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ |
| 157197 | 157202 | u32 bOmitOffset : 1; /* True to let virtual table handle offset */ |
| | @@ -157681,11 +157686,12 @@ |
| 157681 | 157686 | #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ |
| 157682 | 157687 | #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ |
| 157683 | 157688 | #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ |
| 157684 | 157689 | #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ |
| 157685 | 157690 | #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ |
| 157686 | | - /* 0x02000000 -- available for reuse */ |
| 157691 | +#define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. |
| 157692 | + ** NB: False-negatives are possible */ |
| 157687 | 157693 | #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ |
| 157688 | 157694 | |
| 157689 | 157695 | #endif /* !defined(SQLITE_WHEREINT_H) */ |
| 157690 | 157696 | |
| 157691 | 157697 | /************** End of whereInt.h ********************************************/ |
| | @@ -166458,10 +166464,14 @@ |
| 166458 | 166464 | #else |
| 166459 | 166465 | pNew->rRun = rSize + 16; |
| 166460 | 166466 | #endif |
| 166461 | 166467 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 166462 | 166468 | whereLoopOutputAdjust(pWC, pNew, rSize); |
| 166469 | + if( pSrc->pSelect ){ |
| 166470 | + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; |
| 166471 | + pNew->u.btree.pOrderBy = pSrc->pSelect->pOrderBy; |
| 166472 | + } |
| 166463 | 166473 | rc = whereLoopInsert(pBuilder, pNew); |
| 166464 | 166474 | pNew->nOut = rSize; |
| 166465 | 166475 | if( rc ) break; |
| 166466 | 166476 | }else{ |
| 166467 | 166477 | Bitmask m; |
| | @@ -167290,10 +167300,101 @@ |
| 167290 | 167300 | } |
| 167291 | 167301 | |
| 167292 | 167302 | whereLoopClear(db, pNew); |
| 167293 | 167303 | return rc; |
| 167294 | 167304 | } |
| 167305 | + |
| 167306 | +/* Implementation of the order-by-subquery optimization: |
| 167307 | +** |
| 167308 | +** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really |
| 167309 | +** a subquery or CTE that has an ORDER BY clause. See if any of the terms |
| 167310 | +** in the subquery ORDER BY clause will satisfy pOrderBy from the outer |
| 167311 | +** query. Mark off all satisfied terms (by setting bits in *pOBSat) and |
| 167312 | +** return TRUE if they do. If not, return false. |
| 167313 | +** |
| 167314 | +** Example: |
| 167315 | +** |
| 167316 | +** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); |
| 167317 | +** CREATE TABLE t2(x,y); |
| 167318 | +** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) |
| 167319 | +** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; |
| 167320 | +** |
| 167321 | +** The CTE named "t3" comes out in the natural order of "p", so the first |
| 167322 | +** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" |
| 167323 | +** and sorting only needs to occur on the second term "b". |
| 167324 | +** |
| 167325 | +** Limitations: |
| 167326 | +** |
| 167327 | +** (1) The optimization is not applied if the outer ORDER BY contains |
| 167328 | +** a COLLATE clause. The optimization might be applied if the |
| 167329 | +** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as |
| 167330 | +** long as the subquery ORDER BY does the same. But if the |
| 167331 | +** outer ORDER BY uses COLLATE, even a redundant COLLATE, the |
| 167332 | +** optimization is bypassed. |
| 167333 | +** |
| 167334 | +** (2) The subquery ORDER BY terms must exactly match subquery result |
| 167335 | +** columns, including any COLLATE annotations. This routine relies |
| 167336 | +** on iOrderByCol to do matching between order by terms and result |
| 167337 | +** columns, and iOrderByCol will not be set if the result column |
| 167338 | +** and ORDER BY collations differ. |
| 167339 | +** |
| 167340 | +** (3) The subquery and outer ORDER BY can be in opposite directions as |
| 167341 | +** long as the subquery is materialized. If the subquery is |
| 167342 | +** implemented as a co-routine, the sort orders must be in the same |
| 167343 | +** direction because there is no way to run a co-routine backwards. |
| 167344 | +*/ |
| 167345 | +static SQLITE_NOINLINE int wherePathMatchSubqueryOB( |
| 167346 | + WhereInfo *pWInfo, /* The WHERE clause */ |
| 167347 | + WhereLoop *pLoop, /* The nested loop term that is a subquery */ |
| 167348 | + int iLoop, /* Which level of the nested loop. 0==outermost */ |
| 167349 | + int iCur, /* Cursor used by the this loop */ |
| 167350 | + ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ |
| 167351 | + Bitmask *pRevMask, /* When loops need to go in reverse order */ |
| 167352 | + Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ |
| 167353 | +){ |
| 167354 | + int iOB; /* Index into pOrderBy->a[] */ |
| 167355 | + int jSub; /* Index into pSubOB->a[] */ |
| 167356 | + u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ |
| 167357 | + u8 revIdx = 0; /* Sort direction for jSub */ |
| 167358 | + Expr *pOBExpr; /* Current term of outer ORDER BY */ |
| 167359 | + ExprList *pSubOB; /* Complete ORDER BY on the subquery */ |
| 167360 | + |
| 167361 | + pSubOB = pLoop->u.btree.pOrderBy; |
| 167362 | + assert( pSubOB!=0 ); |
| 167363 | + for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} |
| 167364 | + for(jSub=0; jSub<pSubOB->nExpr && iOB<pOrderBy->nExpr; jSub++, iOB++){ |
| 167365 | + if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; |
| 167366 | + pOBExpr = pOrderBy->a[iOB].pExpr; |
| 167367 | + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; |
| 167368 | + if( pOBExpr->iTable!=iCur ) break; |
| 167369 | + if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; |
| 167370 | + if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 167371 | + u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ |
| 167372 | + u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ |
| 167373 | + if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ |
| 167374 | + break; |
| 167375 | + } |
| 167376 | + revIdx = sfSub & KEYINFO_ORDER_DESC; |
| 167377 | + if( jSub>0 ){ |
| 167378 | + if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ |
| 167379 | + break; |
| 167380 | + } |
| 167381 | + }else{ |
| 167382 | + rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); |
| 167383 | + if( rev ){ |
| 167384 | + if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ |
| 167385 | + /* Cannot run a co-routine in reverse order */ |
| 167386 | + break; |
| 167387 | + } |
| 167388 | + *pRevMask |= MASKBIT(iLoop); |
| 167389 | + } |
| 167390 | + } |
| 167391 | + } |
| 167392 | + *pOBSat |= MASKBIT(iOB); |
| 167393 | + } |
| 167394 | + return jSub>0; |
| 167395 | +} |
| 167295 | 167396 | |
| 167296 | 167397 | /* |
| 167297 | 167398 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th |
| 167298 | 167399 | ** parameters) to see if it outputs rows in the requested ORDER BY |
| 167299 | 167400 | ** (or GROUP BY) without requiring a separate sort operation. Return N: |
| | @@ -167436,13 +167537,22 @@ |
| 167436 | 167537 | obSat |= MASKBIT(i); |
| 167437 | 167538 | } |
| 167438 | 167539 | |
| 167439 | 167540 | if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ |
| 167440 | 167541 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 167542 | + if( pLoop->u.btree.pOrderBy |
| 167543 | + && OptimizationEnabled(db, SQLITE_OrderBySubq) |
| 167544 | + && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, |
| 167545 | + pOrderBy,pRevMask, &obSat) |
| 167546 | + ){ |
| 167547 | + nColumn = 0; |
| 167548 | + isOrderDistinct = 0; |
| 167549 | + }else{ |
| 167550 | + nColumn = 1; |
| 167551 | + } |
| 167441 | 167552 | pIndex = 0; |
| 167442 | 167553 | nKeyCol = 0; |
| 167443 | | - nColumn = 1; |
| 167444 | 167554 | }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ |
| 167445 | 167555 | return 0; |
| 167446 | 167556 | }else{ |
| 167447 | 167557 | nKeyCol = pIndex->nKeyCol; |
| 167448 | 167558 | nColumn = pIndex->nColumn; |
| | @@ -167533,11 +167643,11 @@ |
| 167533 | 167643 | isOrderDistinct = 0; |
| 167534 | 167644 | } |
| 167535 | 167645 | } |
| 167536 | 167646 | |
| 167537 | 167647 | /* Find the ORDER BY term that corresponds to the j-th column |
| 167538 | | - ** of the index and mark that ORDER BY term off |
| 167648 | + ** of the index and mark that ORDER BY term having been satisfied. |
| 167539 | 167649 | */ |
| 167540 | 167650 | isMatch = 0; |
| 167541 | 167651 | for(i=0; bOnce && i<nOrderBy; i++){ |
| 167542 | 167652 | if( MASKBIT(i) & obSat ) continue; |
| 167543 | 167653 | pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); |
| | @@ -237272,17 +237382,21 @@ |
| 237272 | 237382 | Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */ |
| 237273 | 237383 | }; |
| 237274 | 237384 | |
| 237275 | 237385 | /* |
| 237276 | 237386 | ** eType: |
| 237277 | | -** Expression node type. Always one of: |
| 237387 | +** Expression node type. Usually one of: |
| 237278 | 237388 | ** |
| 237279 | 237389 | ** FTS5_AND (nChild, apChild valid) |
| 237280 | 237390 | ** FTS5_OR (nChild, apChild valid) |
| 237281 | 237391 | ** FTS5_NOT (nChild, apChild valid) |
| 237282 | 237392 | ** FTS5_STRING (pNear valid) |
| 237283 | 237393 | ** FTS5_TERM (pNear valid) |
| 237394 | +** |
| 237395 | +** An expression node with eType==0 may also exist. It always matches zero |
| 237396 | +** rows. This is created when a phrase containing no tokens is parsed. |
| 237397 | +** e.g. "". |
| 237284 | 237398 | ** |
| 237285 | 237399 | ** iHeight: |
| 237286 | 237400 | ** Distance from this node to furthest leaf. This is always 0 for nodes |
| 237287 | 237401 | ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one |
| 237288 | 237402 | ** greater than the largest child value. |
| | @@ -240330,10 +240444,11 @@ |
| 240330 | 240444 | |
| 240331 | 240445 | static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ |
| 240332 | 240446 | pNode->iRowid = iRowid; |
| 240333 | 240447 | pNode->bEof = 0; |
| 240334 | 240448 | switch( pNode->eType ){ |
| 240449 | + case 0: |
| 240335 | 240450 | case FTS5_TERM: |
| 240336 | 240451 | case FTS5_STRING: |
| 240337 | 240452 | return (pNode->pNear->apPhrase[0]->poslist.n>0); |
| 240338 | 240453 | |
| 240339 | 240454 | case FTS5_AND: { |
| | @@ -252389,24 +252504,27 @@ |
| 252389 | 252504 | |
| 252390 | 252505 | return pRet; |
| 252391 | 252506 | } |
| 252392 | 252507 | |
| 252393 | 252508 | static void fts5ApiPhraseNext( |
| 252394 | | - Fts5Context *pUnused, |
| 252509 | + Fts5Context *pCtx, |
| 252395 | 252510 | Fts5PhraseIter *pIter, |
| 252396 | 252511 | int *piCol, int *piOff |
| 252397 | 252512 | ){ |
| 252398 | | - UNUSED_PARAM(pUnused); |
| 252399 | 252513 | if( pIter->a>=pIter->b ){ |
| 252400 | 252514 | *piCol = -1; |
| 252401 | 252515 | *piOff = -1; |
| 252402 | 252516 | }else{ |
| 252403 | 252517 | int iVal; |
| 252404 | 252518 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 252405 | 252519 | if( iVal==1 ){ |
| 252520 | + /* Avoid returning a (*piCol) value that is too large for the table, |
| 252521 | + ** even if the position-list is corrupt. The caller might not be |
| 252522 | + ** expecting it. */ |
| 252523 | + int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; |
| 252406 | 252524 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 252407 | | - *piCol = iVal; |
| 252525 | + *piCol = (iVal>=nCol ? nCol-1 : iVal); |
| 252408 | 252526 | *piOff = 0; |
| 252409 | 252527 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 252410 | 252528 | } |
| 252411 | 252529 | *piOff += (iVal-2); |
| 252412 | 252530 | } |
| | @@ -253117,11 +253235,11 @@ |
| 253117 | 253235 | int nArg, /* Number of args */ |
| 253118 | 253236 | sqlite3_value **apUnused /* Function arguments */ |
| 253119 | 253237 | ){ |
| 253120 | 253238 | assert( nArg==0 ); |
| 253121 | 253239 | UNUSED_PARAM2(nArg, apUnused); |
| 253122 | | - sqlite3_result_text(pCtx, "fts5: 2024-08-10 15:46:57 3778b2a9ca1cc12a88ef6c32a1ee7c58a0a829ed9715a3d32a225d377d7527ef", -1, SQLITE_TRANSIENT); |
| 253240 | + sqlite3_result_text(pCtx, "fts5: 2024-08-16 18:51:46 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9", -1, SQLITE_TRANSIENT); |
| 253123 | 253241 | } |
| 253124 | 253242 | |
| 253125 | 253243 | /* |
| 253126 | 253244 | ** Return true if zName is the extension on one of the shadow tables used |
| 253127 | 253245 | ** by this module. |
| 253128 | 253246 | |