| | @@ -456,11 +456,11 @@ |
| 456 | 456 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 457 | 457 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 458 | 458 | */ |
| 459 | 459 | #define SQLITE_VERSION "3.42.0" |
| 460 | 460 | #define SQLITE_VERSION_NUMBER 3042000 |
| 461 | | -#define SQLITE_SOURCE_ID "2023-05-12 10:52:12 469718f106e1cfa7f8f4714a9e743108c361af81e0258061c2b76880a7c352ae" |
| 461 | +#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0" |
| 462 | 462 | |
| 463 | 463 | /* |
| 464 | 464 | ** CAPI3REF: Run-Time Library Version Numbers |
| 465 | 465 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 466 | 466 | ** |
| | @@ -8197,13 +8197,13 @@ |
| 8197 | 8197 | ** ^The sqlite3_mutex_leave() routine exits a mutex that was |
| 8198 | 8198 | ** previously entered by the same thread. The behavior |
| 8199 | 8199 | ** is undefined if the mutex is not currently entered by the |
| 8200 | 8200 | ** calling thread or is not currently allocated. |
| 8201 | 8201 | ** |
| 8202 | | -** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or |
| 8203 | | -** sqlite3_mutex_leave() is a NULL pointer, then all three routines |
| 8204 | | -** behave as no-ops. |
| 8202 | +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), |
| 8203 | +** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, |
| 8204 | +** then any of the four routines behaves as a no-op. |
| 8205 | 8205 | ** |
| 8206 | 8206 | ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. |
| 8207 | 8207 | */ |
| 8208 | 8208 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); |
| 8209 | 8209 | SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); |
| | @@ -20506,11 +20506,11 @@ |
| 20506 | 20506 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); |
| 20507 | 20507 | SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); |
| 20508 | 20508 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); |
| 20509 | 20509 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); |
| 20510 | 20510 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); |
| 20511 | | -SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcItem*); |
| 20511 | +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); |
| 20512 | 20512 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 20513 | 20513 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 20514 | 20514 | #endif |
| 20515 | 20515 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); |
| 20516 | 20516 | SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); |
| | @@ -68240,11 +68240,11 @@ |
| 68240 | 68240 | ** Legal values for BtCursor.curFlags |
| 68241 | 68241 | */ |
| 68242 | 68242 | #define BTCF_WriteFlag 0x01 /* True if a write cursor */ |
| 68243 | 68243 | #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ |
| 68244 | 68244 | #define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ |
| 68245 | | -#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ |
| 68245 | +#define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ |
| 68246 | 68246 | #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ |
| 68247 | 68247 | #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ |
| 68248 | 68248 | #define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ |
| 68249 | 68249 | |
| 68250 | 68250 | /* |
| | @@ -108615,14 +108615,15 @@ |
| 108615 | 108615 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ |
| 108616 | 108616 | return exprIsConst(p, 3, iCur); |
| 108617 | 108617 | } |
| 108618 | 108618 | |
| 108619 | 108619 | /* |
| 108620 | | -** Check pExpr to see if it is an constraint on the single data source pSrc. |
| 108621 | | -** In other words, check to see if pExpr constrains pSrc but does not depend |
| 108622 | | -** on any other tables or data sources anywhere else in the query. Return |
| 108623 | | -** true (non-zero) if pExpr is a constraint on pSrc only. |
| 108620 | +** Check pExpr to see if it is an constraint on the single data source |
| 108621 | +** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr |
| 108622 | +** constrains pSrc but does not depend on any other tables or data |
| 108623 | +** sources anywhere else in the query. Return true (non-zero) if pExpr |
| 108624 | +** is a constraint on pSrc only. |
| 108624 | 108625 | ** |
| 108625 | 108626 | ** This is an optimization. False negatives will perhaps cause slower |
| 108626 | 108627 | ** queries, but false positives will yield incorrect answers. So when in |
| 108627 | 108628 | ** doubt, return 0. |
| 108628 | 108629 | ** |
| | @@ -108635,25 +108636,56 @@ |
| 108635 | 108636 | ** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. |
| 108636 | 108637 | ** (Is there some way to relax this constraint?) |
| 108637 | 108638 | ** |
| 108638 | 108639 | ** (4) If pSrc is the right operand of a LEFT JOIN, then... |
| 108639 | 108640 | ** (4a) pExpr must come from an ON clause.. |
| 108640 | | - (4b) and specifically the ON clause associated with the LEFT JOIN. |
| 108641 | +** (4b) and specifically the ON clause associated with the LEFT JOIN. |
| 108641 | 108642 | ** |
| 108642 | 108643 | ** (5) If pSrc is not the right operand of a LEFT JOIN or the left |
| 108643 | 108644 | ** operand of a RIGHT JOIN, then pExpr must be from the WHERE |
| 108644 | 108645 | ** clause, not an ON clause. |
| 108646 | +** |
| 108647 | +** (6) Either: |
| 108648 | +** |
| 108649 | +** (6a) pExpr does not originate in an ON or USING clause, or |
| 108650 | +** |
| 108651 | +** (6b) The ON or USING clause from which pExpr is derived is |
| 108652 | +** not to the left of a RIGHT JOIN (or FULL JOIN). |
| 108653 | +** |
| 108654 | +** Without this restriction, accepting pExpr as a single-table |
| 108655 | +** constraint might move the the ON/USING filter expression |
| 108656 | +** from the left side of a RIGHT JOIN over to the right side, |
| 108657 | +** which leads to incorrect answers. See also restriction (9) |
| 108658 | +** on push-down. |
| 108645 | 108659 | */ |
| 108646 | | -SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr *pExpr, const SrcItem *pSrc){ |
| 108660 | +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( |
| 108661 | + Expr *pExpr, /* The constraint */ |
| 108662 | + const SrcList *pSrcList, /* Complete FROM clause */ |
| 108663 | + int iSrc /* Which element of pSrcList to use */ |
| 108664 | +){ |
| 108665 | + const SrcItem *pSrc = &pSrcList->a[iSrc]; |
| 108647 | 108666 | if( pSrc->fg.jointype & JT_LTORJ ){ |
| 108648 | 108667 | return 0; /* rule (3) */ |
| 108649 | 108668 | } |
| 108650 | 108669 | if( pSrc->fg.jointype & JT_LEFT ){ |
| 108651 | 108670 | if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */ |
| 108652 | 108671 | if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ |
| 108653 | 108672 | }else{ |
| 108654 | 108673 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ |
| 108674 | + } |
| 108675 | + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) /* (6a) */ |
| 108676 | + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (6b) */ |
| 108677 | + ){ |
| 108678 | + int jj; |
| 108679 | + for(jj=0; jj<iSrc; jj++){ |
| 108680 | + if( pExpr->w.iJoin==pSrcList->a[jj].iCursor ){ |
| 108681 | + if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){ |
| 108682 | + return 0; /* restriction (6) */ |
| 108683 | + } |
| 108684 | + break; |
| 108685 | + } |
| 108686 | + } |
| 108655 | 108687 | } |
| 108656 | 108688 | return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ |
| 108657 | 108689 | } |
| 108658 | 108690 | |
| 108659 | 108691 | |
| | @@ -144080,11 +144112,12 @@ |
| 144080 | 144112 | ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING |
| 144081 | 144113 | ** clause and the subquery. |
| 144082 | 144114 | ** |
| 144083 | 144115 | ** Without this restriction, the push-down optimization might move |
| 144084 | 144116 | ** the ON/USING filter expression from the left side of a RIGHT JOIN |
| 144085 | | -** over to the right side, which leads to incorrect answers. |
| 144117 | +** over to the right side, which leads to incorrect answers. See |
| 144118 | +** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). |
| 144086 | 144119 | ** |
| 144087 | 144120 | ** (10) The inner query is not the right-hand table of a RIGHT JOIN. |
| 144088 | 144121 | ** |
| 144089 | 144122 | ** (11) The subquery is not a VALUES clause |
| 144090 | 144123 | ** |
| | @@ -144165,10 +144198,11 @@ |
| 144165 | 144198 | while( pWhere->op==TK_AND ){ |
| 144166 | 144199 | nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); |
| 144167 | 144200 | pWhere = pWhere->pLeft; |
| 144168 | 144201 | } |
| 144169 | 144202 | |
| 144203 | +#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ |
| 144170 | 144204 | if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ |
| 144171 | 144205 | && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ |
| 144172 | 144206 | ){ |
| 144173 | 144207 | int jj; |
| 144174 | 144208 | for(jj=0; jj<iSrc; jj++){ |
| | @@ -144182,12 +144216,10 @@ |
| 144182 | 144216 | } |
| 144183 | 144217 | } |
| 144184 | 144218 | } |
| 144185 | 144219 | } |
| 144186 | 144220 | } |
| 144187 | | - |
| 144188 | | -#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ |
| 144189 | 144221 | if( isLeftJoin |
| 144190 | 144222 | && (ExprHasProperty(pWhere,EP_OuterON)==0 |
| 144191 | 144223 | || pWhere->w.iJoin!=iCursor) |
| 144192 | 144224 | ){ |
| 144193 | 144225 | return 0; /* restriction (4) */ |
| | @@ -144197,11 +144229,11 @@ |
| 144197 | 144229 | ){ |
| 144198 | 144230 | return 0; /* restriction (5) */ |
| 144199 | 144231 | } |
| 144200 | 144232 | #endif |
| 144201 | 144233 | |
| 144202 | | - if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrc) ){ |
| 144234 | + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ |
| 144203 | 144235 | nChng++; |
| 144204 | 144236 | pSubq->selFlags |= SF_PushDown; |
| 144205 | 144237 | while( pSubq ){ |
| 144206 | 144238 | SubstContext x; |
| 144207 | 144239 | pNew = sqlite3ExprDup(pParse->db, pWhere, 0); |
| | @@ -158617,12 +158649,11 @@ |
| 158617 | 158649 | ** and to set up the WhereLevel object pLevel so that the code generator |
| 158618 | 158650 | ** makes use of the automatic index. |
| 158619 | 158651 | */ |
| 158620 | 158652 | static SQLITE_NOINLINE void constructAutomaticIndex( |
| 158621 | 158653 | Parse *pParse, /* The parsing context */ |
| 158622 | | - const WhereClause *pWC, /* The WHERE clause */ |
| 158623 | | - const SrcItem *pSrc, /* The FROM clause term to get the next index */ |
| 158654 | + WhereClause *pWC, /* The WHERE clause */ |
| 158624 | 158655 | const Bitmask notReady, /* Mask of cursors that are not available */ |
| 158625 | 158656 | WhereLevel *pLevel /* Write new index here */ |
| 158626 | 158657 | ){ |
| 158627 | 158658 | int nKeyCol; /* Number of columns in the constructed index */ |
| 158628 | 158659 | WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| | @@ -158643,11 +158674,12 @@ |
| 158643 | 158674 | Bitmask extraCols; /* Bitmap of additional columns */ |
| 158644 | 158675 | u8 sentWarning = 0; /* True if a warning has been issued */ |
| 158645 | 158676 | u8 useBloomFilter = 0; /* True to also add a Bloom filter */ |
| 158646 | 158677 | Expr *pPartial = 0; /* Partial Index Expression */ |
| 158647 | 158678 | int iContinue = 0; /* Jump here to skip excluded rows */ |
| 158648 | | - SrcItem *pTabItem; /* FROM clause term being indexed */ |
| 158679 | + SrcList *pTabList; /* The complete FROM clause */ |
| 158680 | + SrcItem *pSrc; /* The FROM clause term to get the next index */ |
| 158649 | 158681 | int addrCounter = 0; /* Address where integer counter is initialized */ |
| 158650 | 158682 | int regBase; /* Array of registers where record is assembled */ |
| 158651 | 158683 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 158652 | 158684 | int addrExp = 0; /* Address of OP_Explain */ |
| 158653 | 158685 | #endif |
| | @@ -158659,10 +158691,12 @@ |
| 158659 | 158691 | addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 158660 | 158692 | |
| 158661 | 158693 | /* Count the number of columns that will be added to the index |
| 158662 | 158694 | ** and used to match WHERE clause constraints */ |
| 158663 | 158695 | nKeyCol = 0; |
| 158696 | + pTabList = pWC->pWInfo->pTabList; |
| 158697 | + pSrc = &pTabList->a[pLevel->iFrom]; |
| 158664 | 158698 | pTable = pSrc->pTab; |
| 158665 | 158699 | pWCEnd = &pWC->a[pWC->nTerm]; |
| 158666 | 158700 | pLoop = pLevel->pWLoop; |
| 158667 | 158701 | idxCols = 0; |
| 158668 | 158702 | for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ |
| | @@ -158669,11 +158703,11 @@ |
| 158669 | 158703 | Expr *pExpr = pTerm->pExpr; |
| 158670 | 158704 | /* Make the automatic index a partial index if there are terms in the |
| 158671 | 158705 | ** WHERE clause (or the ON clause of a LEFT join) that constrain which |
| 158672 | 158706 | ** rows of the target table (pSrc) that can be used. */ |
| 158673 | 158707 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 158674 | | - && sqlite3ExprIsSingleTableConstraint(pExpr, pSrc) |
| 158708 | + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) |
| 158675 | 158709 | ){ |
| 158676 | 158710 | pPartial = sqlite3ExprAnd(pParse, pPartial, |
| 158677 | 158711 | sqlite3ExprDup(pParse->db, pExpr, 0)); |
| 158678 | 158712 | } |
| 158679 | 158713 | if( termCanDriveIndex(pTerm, pSrc, notReady) ){ |
| | @@ -158799,18 +158833,18 @@ |
| 158799 | 158833 | pLevel->regFilter = ++pParse->nMem; |
| 158800 | 158834 | sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); |
| 158801 | 158835 | } |
| 158802 | 158836 | |
| 158803 | 158837 | /* Fill the automatic index with content */ |
| 158804 | | - pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; |
| 158805 | | - if( pTabItem->fg.viaCoroutine ){ |
| 158806 | | - int regYield = pTabItem->regReturn; |
| 158838 | + assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); |
| 158839 | + if( pSrc->fg.viaCoroutine ){ |
| 158840 | + int regYield = pSrc->regReturn; |
| 158807 | 158841 | addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); |
| 158808 | | - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); |
| 158842 | + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); |
| 158809 | 158843 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); |
| 158810 | 158844 | VdbeCoverage(v); |
| 158811 | | - VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); |
| 158845 | + VdbeComment((v, "next row of %s", pSrc->pTab->zName)); |
| 158812 | 158846 | }else{ |
| 158813 | 158847 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); |
| 158814 | 158848 | } |
| 158815 | 158849 | if( pPartial ){ |
| 158816 | 158850 | iContinue = sqlite3VdbeMakeLabel(pParse); |
| | @@ -158827,18 +158861,18 @@ |
| 158827 | 158861 | } |
| 158828 | 158862 | sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); |
| 158829 | 158863 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); |
| 158830 | 158864 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 158831 | 158865 | if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); |
| 158832 | | - if( pTabItem->fg.viaCoroutine ){ |
| 158866 | + if( pSrc->fg.viaCoroutine ){ |
| 158833 | 158867 | sqlite3VdbeChangeP2(v, addrCounter, regBase+n); |
| 158834 | 158868 | testcase( pParse->db->mallocFailed ); |
| 158835 | 158869 | assert( pLevel->iIdxCur>0 ); |
| 158836 | 158870 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, |
| 158837 | | - pTabItem->regResult, pLevel->iIdxCur); |
| 158871 | + pSrc->regResult, pLevel->iIdxCur); |
| 158838 | 158872 | sqlite3VdbeGoto(v, addrTop); |
| 158839 | | - pTabItem->fg.viaCoroutine = 0; |
| 158873 | + pSrc->fg.viaCoroutine = 0; |
| 158840 | 158874 | }else{ |
| 158841 | 158875 | sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); |
| 158842 | 158876 | sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); |
| 158843 | 158877 | } |
| 158844 | 158878 | sqlite3VdbeJumpHere(v, addrTop); |
| | @@ -158897,13 +158931,15 @@ |
| 158897 | 158931 | assert( v!=0 ); |
| 158898 | 158932 | assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); |
| 158899 | 158933 | |
| 158900 | 158934 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 158901 | 158935 | do{ |
| 158936 | + const SrcList *pTabList; |
| 158902 | 158937 | const SrcItem *pItem; |
| 158903 | 158938 | const Table *pTab; |
| 158904 | 158939 | u64 sz; |
| 158940 | + int iSrc; |
| 158905 | 158941 | sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); |
| 158906 | 158942 | addrCont = sqlite3VdbeMakeLabel(pParse); |
| 158907 | 158943 | iCur = pLevel->iTabCur; |
| 158908 | 158944 | pLevel->regFilter = ++pParse->nMem; |
| 158909 | 158945 | |
| | @@ -158913,11 +158949,13 @@ |
| 158913 | 158949 | ** measure the size of the table at run-time using OP_Count with |
| 158914 | 158950 | ** P3==1 and use that value to initialize the blob. But that makes |
| 158915 | 158951 | ** testing complicated. By basing the blob size on the value in the |
| 158916 | 158952 | ** sqlite_stat1 table, testing is much easier. |
| 158917 | 158953 | */ |
| 158918 | | - pItem = &pWInfo->pTabList->a[pLevel->iFrom]; |
| 158954 | + pTabList = pWInfo->pTabList; |
| 158955 | + iSrc = pLevel->iFrom; |
| 158956 | + pItem = &pTabList->a[iSrc]; |
| 158919 | 158957 | assert( pItem!=0 ); |
| 158920 | 158958 | pTab = pItem->pTab; |
| 158921 | 158959 | assert( pTab!=0 ); |
| 158922 | 158960 | sz = sqlite3LogEstToInt(pTab->nRowLogEst); |
| 158923 | 158961 | if( sz<10000 ){ |
| | @@ -158930,11 +158968,11 @@ |
| 158930 | 158968 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); |
| 158931 | 158969 | pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm]; |
| 158932 | 158970 | for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ |
| 158933 | 158971 | Expr *pExpr = pTerm->pExpr; |
| 158934 | 158972 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 158935 | | - && sqlite3ExprIsSingleTableConstraint(pExpr, pItem) |
| 158973 | + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) |
| 158936 | 158974 | ){ |
| 158937 | 158975 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); |
| 158938 | 158976 | } |
| 158939 | 158977 | } |
| 158940 | 158978 | if( pLoop->wsFlags & WHERE_IPK ){ |
| | @@ -164162,15 +164200,15 @@ |
| 164162 | 164200 | int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 164163 | 164201 | sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); |
| 164164 | 164202 | sqlite3VdbeJumpHere(v, iOnce); |
| 164165 | 164203 | } |
| 164166 | 164204 | } |
| 164205 | + assert( pTabList == pWInfo->pTabList ); |
| 164167 | 164206 | if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ |
| 164168 | 164207 | if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 164169 | 164208 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 164170 | | - constructAutomaticIndex(pParse, &pWInfo->sWC, |
| 164171 | | - &pTabList->a[pLevel->iFrom], notReady, pLevel); |
| 164209 | + constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); |
| 164172 | 164210 | #endif |
| 164173 | 164211 | }else{ |
| 164174 | 164212 | sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); |
| 164175 | 164213 | } |
| 164176 | 164214 | if( db->mallocFailed ) goto whereBeginError; |
| | @@ -228819,10 +228857,14 @@ |
| 228819 | 228857 | |
| 228820 | 228858 | |
| 228821 | 228859 | /* #include "fts5Int.h" */ |
| 228822 | 228860 | /* #include "fts5parse.h" */ |
| 228823 | 228861 | |
| 228862 | +#ifndef SQLITE_FTS5_MAX_EXPR_DEPTH |
| 228863 | +# define SQLITE_FTS5_MAX_EXPR_DEPTH 256 |
| 228864 | +#endif |
| 228865 | + |
| 228824 | 228866 | /* |
| 228825 | 228867 | ** All token types in the generated fts5parse.h file are greater than 0. |
| 228826 | 228868 | */ |
| 228827 | 228869 | #define FTS5_EOF 0 |
| 228828 | 228870 | |
| | @@ -228859,15 +228901,21 @@ |
| 228859 | 228901 | ** FTS5_AND (nChild, apChild valid) |
| 228860 | 228902 | ** FTS5_OR (nChild, apChild valid) |
| 228861 | 228903 | ** FTS5_NOT (nChild, apChild valid) |
| 228862 | 228904 | ** FTS5_STRING (pNear valid) |
| 228863 | 228905 | ** FTS5_TERM (pNear valid) |
| 228906 | +** |
| 228907 | +** iHeight: |
| 228908 | +** Distance from this node to furthest leaf. This is always 0 for nodes |
| 228909 | +** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one |
| 228910 | +** greater than the largest child value. |
| 228864 | 228911 | */ |
| 228865 | 228912 | struct Fts5ExprNode { |
| 228866 | 228913 | int eType; /* Node type */ |
| 228867 | 228914 | int bEof; /* True at EOF */ |
| 228868 | 228915 | int bNomatch; /* True if entry is not a match */ |
| 228916 | + int iHeight; /* Distance to tree leaf nodes */ |
| 228869 | 228917 | |
| 228870 | 228918 | /* Next method for this node. */ |
| 228871 | 228919 | int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); |
| 228872 | 228920 | |
| 228873 | 228921 | i64 iRowid; /* Current rowid */ |
| | @@ -228933,10 +228981,35 @@ |
| 228933 | 228981 | Fts5ExprPhrase **apPhrase; /* Array of all phrases */ |
| 228934 | 228982 | Fts5ExprNode *pExpr; /* Result of a successful parse */ |
| 228935 | 228983 | int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ |
| 228936 | 228984 | }; |
| 228937 | 228985 | |
| 228986 | +/* |
| 228987 | +** Check that the Fts5ExprNode.iHeight variables are set correctly in |
| 228988 | +** the expression tree passed as the only argument. |
| 228989 | +*/ |
| 228990 | +#ifndef NDEBUG |
| 228991 | +static void assert_expr_depth_ok(int rc, Fts5ExprNode *p){ |
| 228992 | + if( rc==SQLITE_OK ){ |
| 228993 | + if( p->eType==FTS5_TERM || p->eType==FTS5_STRING || p->eType==0 ){ |
| 228994 | + assert( p->iHeight==0 ); |
| 228995 | + }else{ |
| 228996 | + int ii; |
| 228997 | + int iMaxChild = 0; |
| 228998 | + for(ii=0; ii<p->nChild; ii++){ |
| 228999 | + Fts5ExprNode *pChild = p->apChild[ii]; |
| 229000 | + iMaxChild = MAX(iMaxChild, pChild->iHeight); |
| 229001 | + assert_expr_depth_ok(SQLITE_OK, pChild); |
| 229002 | + } |
| 229003 | + assert( p->iHeight==iMaxChild+1 ); |
| 229004 | + } |
| 229005 | + } |
| 229006 | +} |
| 229007 | +#else |
| 229008 | +# define assert_expr_depth_ok(rc, p) |
| 229009 | +#endif |
| 229010 | + |
| 228938 | 229011 | static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ |
| 228939 | 229012 | va_list ap; |
| 228940 | 229013 | va_start(ap, zFmt); |
| 228941 | 229014 | if( pParse->rc==SQLITE_OK ){ |
| 228942 | 229015 | assert( pParse->zErr==0 ); |
| | @@ -229046,10 +229119,12 @@ |
| 229046 | 229119 | do { |
| 229047 | 229120 | t = fts5ExprGetToken(&sParse, &z, &token); |
| 229048 | 229121 | sqlite3Fts5Parser(pEngine, t, token, &sParse); |
| 229049 | 229122 | }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); |
| 229050 | 229123 | sqlite3Fts5ParserFree(pEngine, fts5ParseFree); |
| 229124 | + |
| 229125 | + assert_expr_depth_ok(sParse.rc, sParse.pExpr); |
| 229051 | 229126 | |
| 229052 | 229127 | /* If the LHS of the MATCH expression was a user column, apply the |
| 229053 | 229128 | ** implicit column-filter. */ |
| 229054 | 229129 | if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ |
| 229055 | 229130 | int n = sizeof(Fts5Colset); |
| | @@ -231008,18 +231083,22 @@ |
| 231008 | 231083 | }; |
| 231009 | 231084 | } |
| 231010 | 231085 | } |
| 231011 | 231086 | |
| 231012 | 231087 | static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ |
| 231088 | + int ii = p->nChild; |
| 231013 | 231089 | if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ |
| 231014 | 231090 | int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; |
| 231015 | 231091 | memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); |
| 231016 | 231092 | p->nChild += pSub->nChild; |
| 231017 | 231093 | sqlite3_free(pSub); |
| 231018 | 231094 | }else{ |
| 231019 | 231095 | p->apChild[p->nChild++] = pSub; |
| 231020 | 231096 | } |
| 231097 | + for( ; ii<p->nChild; ii++){ |
| 231098 | + p->iHeight = MAX(p->iHeight, p->apChild[ii]->iHeight + 1); |
| 231099 | + } |
| 231021 | 231100 | } |
| 231022 | 231101 | |
| 231023 | 231102 | /* |
| 231024 | 231103 | ** This function is used when parsing LIKE or GLOB patterns against |
| 231025 | 231104 | ** trigram indexes that specify either detail=column or detail=none. |
| | @@ -231046,10 +231125,11 @@ |
| 231046 | 231125 | nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); |
| 231047 | 231126 | pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); |
| 231048 | 231127 | if( pRet ){ |
| 231049 | 231128 | pRet->eType = FTS5_AND; |
| 231050 | 231129 | pRet->nChild = nTerm; |
| 231130 | + pRet->iHeight = 1; |
| 231051 | 231131 | fts5ExprAssignXNext(pRet); |
| 231052 | 231132 | pParse->nPhrase--; |
| 231053 | 231133 | for(ii=0; ii<nTerm; ii++){ |
| 231054 | 231134 | Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero( |
| 231055 | 231135 | &pParse->rc, sizeof(Fts5ExprPhrase) |
| | @@ -231151,10 +231231,18 @@ |
| 231151 | 231231 | } |
| 231152 | 231232 | } |
| 231153 | 231233 | }else{ |
| 231154 | 231234 | fts5ExprAddChildren(pRet, pLeft); |
| 231155 | 231235 | fts5ExprAddChildren(pRet, pRight); |
| 231236 | + if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ |
| 231237 | + sqlite3Fts5ParseError(pParse, |
| 231238 | + "fts5 expression tree is too large (maximum depth %d)", |
| 231239 | + SQLITE_FTS5_MAX_EXPR_DEPTH |
| 231240 | + ); |
| 231241 | + sqlite3_free(pRet); |
| 231242 | + pRet = 0; |
| 231243 | + } |
| 231156 | 231244 | } |
| 231157 | 231245 | } |
| 231158 | 231246 | } |
| 231159 | 231247 | } |
| 231160 | 231248 | |
| | @@ -242545,11 +242633,11 @@ |
| 242545 | 242633 | int nArg, /* Number of args */ |
| 242546 | 242634 | sqlite3_value **apUnused /* Function arguments */ |
| 242547 | 242635 | ){ |
| 242548 | 242636 | assert( nArg==0 ); |
| 242549 | 242637 | UNUSED_PARAM2(nArg, apUnused); |
| 242550 | | - sqlite3_result_text(pCtx, "fts5: 2023-05-11 21:15:55 3e9c9bbdb59b9d500ff218db538c047c83da7ac18ebb95c3ee7629ab15e0b43a", -1, SQLITE_TRANSIENT); |
| 242638 | + sqlite3_result_text(pCtx, "fts5: 2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0", -1, SQLITE_TRANSIENT); |
| 242551 | 242639 | } |
| 242552 | 242640 | |
| 242553 | 242641 | /* |
| 242554 | 242642 | ** Return true if zName is the extension on one of the shadow tables used |
| 242555 | 242643 | ** by this module. |
| 242556 | 242644 | |