| | @@ -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 | | -** 4733d351ec2376291f093ba8d2ba71d82c6f with changes in files: |
| 21 | +** c476d956d0bd3065cf894de6f9d393b999ff with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -467,14 +467,14 @@ |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.52.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3052000 |
| 472 | | -#define SQLITE_SOURCE_ID "2026-01-26 10:53:24 4733d351ec2376291f093ba8d2ba71d82c6f100c68dc860eee0532986c154e71" |
| 472 | +#define SQLITE_SOURCE_ID "2026-02-04 20:51:27 c476d956d0bd3065cf894de6f9d393b999ff7d2268a35f01a6d88804789ab58f" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-01-26T10:53:24.426Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-02-04T20:51:27.822Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -11571,23 +11571,45 @@ |
| 11571 | 11571 | #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ |
| 11572 | 11572 | |
| 11573 | 11573 | /* |
| 11574 | 11574 | ** CAPI3REF: Bind array values to the CARRAY table-valued function |
| 11575 | 11575 | ** |
| 11576 | | -** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to |
| 11577 | | -** one of the first argument of the [carray() table-valued function]. The |
| 11578 | | -** S parameter is a pointer to the [prepared statement] that uses the carray() |
| 11579 | | -** functions. I is the parameter index to be bound. P is a pointer to the |
| 11580 | | -** array to be bound, and N is the number of eements in the array. The |
| 11581 | | -** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], |
| 11582 | | -** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to |
| 11583 | | -** indicate the datatype of the array being bound. The X argument is not a |
| 11584 | | -** NULL pointer, then SQLite will invoke the function X on the P parameter |
| 11585 | | -** after it has finished using P, even if the call to |
| 11586 | | -** sqlite3_carray_bind() fails. The special-case finalizer |
| 11587 | | -** SQLITE_TRANSIENT has no effect here. |
| 11576 | +** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to |
| 11577 | +** parameter that is the first argument of the [carray() table-valued function]. |
| 11578 | +** The S parameter is a pointer to the [prepared statement] that uses the carray() |
| 11579 | +** functions. I is the parameter index to be bound. I must be the index of the |
| 11580 | +** parameter that is the first argument to the carray() table-valued function. |
| 11581 | +** P is a pointer to the array to be bound, and N is the number of elements in |
| 11582 | +** the array. The F argument is one of constants [SQLITE_CARRAY_INT32], |
| 11583 | +** [SQLITE_CARRAY_INT64], [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], |
| 11584 | +** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. |
| 11585 | +** |
| 11586 | +** If the X argument is not a NULL pointer or one of the special |
| 11587 | +** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke |
| 11588 | +** the function X with argument D when it is finished using the data in P. |
| 11589 | +** The call to X(D) is a destructor for the array P. The destructor X(D) |
| 11590 | +** is invoked even if the call to sqlite3_carray_bind() fails. If the X |
| 11591 | +** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes |
| 11592 | +** that the data static and the destructor is never invoked. If the X |
| 11593 | +** parameter is the special-case value [SQLITE_TRANSIENT], then |
| 11594 | +** sqlite3_carray_bind_v2() makes its own private copy of the data prior |
| 11595 | +** to returning and never invokes the destructor X. |
| 11596 | +** |
| 11597 | +** The sqlite3_carray_bind() function works the same as sqlite_carray_bind_v2() |
| 11598 | +** with a D parameter set to P. In other words, |
| 11599 | +** sqlite3_carray_bind(S,I,P,N,F,X) is same as |
| 11600 | +** sqlite3_carray_bind(S,I,P,N,F,X,P). |
| 11588 | 11601 | */ |
| 11602 | +SQLITE_API int sqlite3_carray_bind_v2( |
| 11603 | + sqlite3_stmt *pStmt, /* Statement to be bound */ |
| 11604 | + int i, /* Parameter index */ |
| 11605 | + void *aData, /* Pointer to array data */ |
| 11606 | + int nData, /* Number of data elements */ |
| 11607 | + int mFlags, /* CARRAY flags */ |
| 11608 | + void (*xDel)(void*), /* Destructor for aData */ |
| 11609 | + void *pDel /* Optional argument to xDel() */ |
| 11610 | +); |
| 11589 | 11611 | SQLITE_API int sqlite3_carray_bind( |
| 11590 | 11612 | sqlite3_stmt *pStmt, /* Statement to be bound */ |
| 11591 | 11613 | int i, /* Parameter index */ |
| 11592 | 11614 | void *aData, /* Pointer to array data */ |
| 11593 | 11615 | int nData, /* Number of data elements */ |
| | @@ -21094,10 +21116,11 @@ |
| 21094 | 21116 | u16 mWFlags; /* Use-dependent flags */ |
| 21095 | 21117 | union { /* Extra data for callback */ |
| 21096 | 21118 | NameContext *pNC; /* Naming context */ |
| 21097 | 21119 | int n; /* A counter */ |
| 21098 | 21120 | int iCur; /* A cursor number */ |
| 21121 | + int sz; /* String literal length */ |
| 21099 | 21122 | SrcList *pSrcList; /* FROM clause */ |
| 21100 | 21123 | struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ |
| 21101 | 21124 | struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ |
| 21102 | 21125 | int *aiCol; /* array of column indexes */ |
| 21103 | 21126 | struct IdxCover *pIdxCover; /* Check for index coverage */ |
| | @@ -21877,10 +21900,11 @@ |
| 21877 | 21900 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 21878 | 21901 | #endif |
| 21879 | 21902 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); |
| 21880 | 21903 | SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); |
| 21881 | 21904 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 21905 | +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr*); |
| 21882 | 21906 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| 21883 | 21907 | SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); |
| 21884 | 21908 | SQLITE_PRIVATE void sqlite3GenerateRowDelete( |
| 21885 | 21909 | Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); |
| 21886 | 21910 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); |
| | @@ -86688,10 +86712,15 @@ |
| 86688 | 86712 | ** the column value into *ppVal. If *ppVal is initially NULL then a new |
| 86689 | 86713 | ** sqlite3_value object is allocated. |
| 86690 | 86714 | ** |
| 86691 | 86715 | ** If *ppVal is initially NULL then the caller is responsible for |
| 86692 | 86716 | ** ensuring that the value written into *ppVal is eventually freed. |
| 86717 | +** |
| 86718 | +** If the buffer does not contain a well-formed record, this routine may |
| 86719 | +** read several bytes past the end of the buffer. Callers must therefore |
| 86720 | +** ensure that any buffer which may contain a corrupt record is padded |
| 86721 | +** with at least 8 bytes of addressable memory. |
| 86693 | 86722 | */ |
| 86694 | 86723 | SQLITE_PRIVATE int sqlite3Stat4Column( |
| 86695 | 86724 | sqlite3 *db, /* Database handle */ |
| 86696 | 86725 | const void *pRec, /* Pointer to buffer containing record */ |
| 86697 | 86726 | int nRec, /* Size of buffer pRec in bytes */ |
| | @@ -118827,11 +118856,14 @@ |
| 118827 | 118856 | if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; |
| 118828 | 118857 | } |
| 118829 | 118858 | if( pIEpr==0 ) break; |
| 118830 | 118859 | if( NEVER(!ExprUseYTab(pExpr)) ) break; |
| 118831 | 118860 | for(i=0; i<pSrcList->nSrc; i++){ |
| 118832 | | - if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; |
| 118861 | + if( pSrcList->a[i].iCursor==pIEpr->iDataCur ){ |
| 118862 | + testcase( i>0 ); |
| 118863 | + break; |
| 118864 | + } |
| 118833 | 118865 | } |
| 118834 | 118866 | if( i>=pSrcList->nSrc ) break; |
| 118835 | 118867 | if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ |
| 118836 | 118868 | if( pParse->nErr ){ return WRC_Abort; } |
| 118837 | 118869 | |
| | @@ -141374,10 +141406,11 @@ |
| 141374 | 141406 | int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); |
| 141375 | 141407 | /* Version 3.52.0 and later */ |
| 141376 | 141408 | void (*str_truncate)(sqlite3_str*,int); |
| 141377 | 141409 | void (*str_free)(sqlite3_str*); |
| 141378 | 141410 | int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); |
| 141411 | + int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); |
| 141379 | 141412 | }; |
| 141380 | 141413 | |
| 141381 | 141414 | /* |
| 141382 | 141415 | ** This is the function signature used for all extension entry points. It |
| 141383 | 141416 | ** is also defined in the file "loadext.c". |
| | @@ -141716,10 +141749,11 @@ |
| 141716 | 141749 | #define sqlite3_db_status64 sqlite3_api->db_status64 |
| 141717 | 141750 | /* Version 3.52.0 and later */ |
| 141718 | 141751 | #define sqlite3_str_truncate sqlite3_api->str_truncate |
| 141719 | 141752 | #define sqlite3_str_free sqlite3_api->str_free |
| 141720 | 141753 | #define sqlite3_carray_bind sqlite3_api->carray_bind |
| 141754 | +#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 |
| 141721 | 141755 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 141722 | 141756 | |
| 141723 | 141757 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 141724 | 141758 | /* This case when the file really is being compiled as a loadable |
| 141725 | 141759 | ** extension */ |
| | @@ -142247,12 +142281,14 @@ |
| 142247 | 142281 | sqlite3_db_status64, |
| 142248 | 142282 | /* Version 3.52.0 and later */ |
| 142249 | 142283 | sqlite3_str_truncate, |
| 142250 | 142284 | sqlite3_str_free, |
| 142251 | 142285 | #ifdef SQLITE_ENABLE_CARRAY |
| 142252 | | - sqlite3_carray_bind |
| 142286 | + sqlite3_carray_bind, |
| 142287 | + sqlite3_carray_bind_v2 |
| 142253 | 142288 | #else |
| 142289 | + 0, |
| 142254 | 142290 | 0 |
| 142255 | 142291 | #endif |
| 142256 | 142292 | }; |
| 142257 | 142293 | |
| 142258 | 142294 | /* True if x is the directory separator character |
| | @@ -150108,11 +150144,11 @@ |
| 150108 | 150144 | ** function is responsible for ensuring that this structure is eventually |
| 150109 | 150145 | ** freed. |
| 150110 | 150146 | */ |
| 150111 | 150147 | static KeyInfo *multiSelectByMergeKeyInfo(Parse *pParse, Select *p, int nExtra){ |
| 150112 | 150148 | ExprList *pOrderBy = p->pOrderBy; |
| 150113 | | - int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; |
| 150149 | + int nOrderBy = (pOrderBy!=0) ? pOrderBy->nExpr : 0; |
| 150114 | 150150 | sqlite3 *db = pParse->db; |
| 150115 | 150151 | KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); |
| 150116 | 150152 | if( pRet ){ |
| 150117 | 150153 | int i; |
| 150118 | 150154 | for(i=0; i<nOrderBy; i++){ |
| | @@ -150911,14 +150947,12 @@ |
| 150911 | 150947 | ** EofB: ... |
| 150912 | 150948 | ** AltB: ... |
| 150913 | 150949 | ** AeqB: ... |
| 150914 | 150950 | ** AgtB: ... |
| 150915 | 150951 | ** Init: initialize coroutine registers |
| 150916 | | -** yield coA |
| 150917 | | -** if eof(A) goto EofA |
| 150918 | | -** yield coB |
| 150919 | | -** if eof(B) goto EofB |
| 150952 | +** yield coA, on eof goto EofA |
| 150953 | +** yield coB, on eof goto EofB |
| 150920 | 150954 | ** Cmpr: Compare A, B |
| 150921 | 150955 | ** Jump AltB, AeqB, AgtB |
| 150922 | 150956 | ** End: ... |
| 150923 | 150957 | ** |
| 150924 | 150958 | ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not |
| | @@ -151006,30 +151040,33 @@ |
| 151006 | 151040 | } |
| 151007 | 151041 | } |
| 151008 | 151042 | } |
| 151009 | 151043 | |
| 151010 | 151044 | /* Compute the comparison permutation and keyinfo that is used with |
| 151011 | | - ** the permutation used to determine if the next |
| 151012 | | - ** row of results comes from selectA or selectB. Also add explicit |
| 151013 | | - ** collations to the ORDER BY clause terms so that when the subqueries |
| 151014 | | - ** to the right and the left are evaluated, they use the correct |
| 151015 | | - ** collation. |
| 151045 | + ** the permutation to determine if the next row of results comes |
| 151046 | + ** from selectA or selectB. Also add literal collations to the |
| 151047 | + ** ORDER BY clause terms so that when selectA and selectB are |
| 151048 | + ** evaluated, they use the correct collation. |
| 151016 | 151049 | */ |
| 151017 | 151050 | aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); |
| 151018 | 151051 | if( aPermute ){ |
| 151019 | 151052 | struct ExprList_item *pItem; |
| 151053 | + int bKeep = 0; |
| 151020 | 151054 | aPermute[0] = nOrderBy; |
| 151021 | 151055 | for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ |
| 151022 | 151056 | assert( pItem!=0 ); |
| 151023 | 151057 | assert( pItem->u.x.iOrderByCol>0 ); |
| 151024 | 151058 | assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); |
| 151025 | 151059 | aPermute[i] = pItem->u.x.iOrderByCol - 1; |
| 151060 | + if( aPermute[i]!=(u32)i-1 ) bKeep = 1; |
| 151026 | 151061 | } |
| 151027 | | - pKeyMerge = multiSelectByMergeKeyInfo(pParse, p, 1); |
| 151028 | | - }else{ |
| 151029 | | - pKeyMerge = 0; |
| 151062 | + if( bKeep==0 ){ |
| 151063 | + sqlite3DbFreeNN(db, aPermute); |
| 151064 | + aPermute = 0; |
| 151065 | + } |
| 151030 | 151066 | } |
| 151067 | + pKeyMerge = multiSelectByMergeKeyInfo(pParse, p, 1); |
| 151031 | 151068 | |
| 151032 | 151069 | /* Allocate a range of temporary registers and the KeyInfo needed |
| 151033 | 151070 | ** for the logic that removes duplicate result rows when the |
| 151034 | 151071 | ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). |
| 151035 | 151072 | */ |
| | @@ -151104,11 +151141,11 @@ |
| 151104 | 151141 | /* Generate a coroutine to evaluate the SELECT statement to the |
| 151105 | 151142 | ** left of the compound operator - the "A" select. |
| 151106 | 151143 | */ |
| 151107 | 151144 | addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; |
| 151108 | 151145 | addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); |
| 151109 | | - VdbeComment((v, "left SELECT")); |
| 151146 | + VdbeComment((v, "SUBR: next-A")); |
| 151110 | 151147 | pPrior->iLimit = regLimitA; |
| 151111 | 151148 | ExplainQueryPlan((pParse, 1, "LEFT")); |
| 151112 | 151149 | sqlite3Select(pParse, pPrior, &destA); |
| 151113 | 151150 | sqlite3VdbeEndCoroutine(v, regAddrA); |
| 151114 | 151151 | sqlite3VdbeJumpHere(v, addr1); |
| | @@ -151116,11 +151153,11 @@ |
| 151116 | 151153 | /* Generate a coroutine to evaluate the SELECT statement on |
| 151117 | 151154 | ** the right - the "B" select |
| 151118 | 151155 | */ |
| 151119 | 151156 | addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; |
| 151120 | 151157 | addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); |
| 151121 | | - VdbeComment((v, "right SELECT")); |
| 151158 | + VdbeComment((v, "SUBR: next-B")); |
| 151122 | 151159 | savedLimit = p->iLimit; |
| 151123 | 151160 | savedOffset = p->iOffset; |
| 151124 | 151161 | p->iLimit = regLimitB; |
| 151125 | 151162 | p->iOffset = 0; |
| 151126 | 151163 | ExplainQueryPlan((pParse, 1, "RIGHT")); |
| | @@ -151130,20 +151167,20 @@ |
| 151130 | 151167 | sqlite3VdbeEndCoroutine(v, regAddrB); |
| 151131 | 151168 | |
| 151132 | 151169 | /* Generate a subroutine that outputs the current row of the A |
| 151133 | 151170 | ** select as the next output row of the compound select. |
| 151134 | 151171 | */ |
| 151135 | | - VdbeNoopComment((v, "Output routine for A")); |
| 151172 | + VdbeNoopComment((v, "SUBR: out-A")); |
| 151136 | 151173 | addrOutA = generateOutputSubroutine(pParse, |
| 151137 | 151174 | p, &destA, pDest, regOutA, |
| 151138 | 151175 | regPrev, pKeyDup, labelEnd); |
| 151139 | 151176 | |
| 151140 | 151177 | /* Generate a subroutine that outputs the current row of the B |
| 151141 | 151178 | ** select as the next output row of the compound select. |
| 151142 | 151179 | */ |
| 151143 | 151180 | if( op==TK_ALL || op==TK_UNION ){ |
| 151144 | | - VdbeNoopComment((v, "Output routine for B")); |
| 151181 | + VdbeNoopComment((v, "SUBR: out-B")); |
| 151145 | 151182 | addrOutB = generateOutputSubroutine(pParse, |
| 151146 | 151183 | p, &destB, pDest, regOutB, |
| 151147 | 151184 | regPrev, pKeyDup, labelEnd); |
| 151148 | 151185 | } |
| 151149 | 151186 | sqlite3KeyInfoUnref(pKeyDup); |
| | @@ -151152,14 +151189,16 @@ |
| 151152 | 151189 | ** are exhausted and only data in select B remains. |
| 151153 | 151190 | */ |
| 151154 | 151191 | if( op==TK_EXCEPT || op==TK_INTERSECT ){ |
| 151155 | 151192 | addrEofA_noB = addrEofA = labelEnd; |
| 151156 | 151193 | }else{ |
| 151157 | | - VdbeNoopComment((v, "eof-A subroutine")); |
| 151194 | + VdbeNoopComment((v, "SUBR: eof-A")); |
| 151158 | 151195 | addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); |
| 151196 | + VdbeComment((v, "out-B")); |
| 151159 | 151197 | addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); |
| 151160 | 151198 | VdbeCoverage(v); |
| 151199 | + VdbeComment((v, "next-B")); |
| 151161 | 151200 | sqlite3VdbeGoto(v, addrEofA); |
| 151162 | 151201 | p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); |
| 151163 | 151202 | } |
| 151164 | 151203 | |
| 151165 | 151204 | /* Generate a subroutine to run when the results from select B |
| | @@ -151167,21 +151206,24 @@ |
| 151167 | 151206 | */ |
| 151168 | 151207 | if( op==TK_INTERSECT ){ |
| 151169 | 151208 | addrEofB = addrEofA; |
| 151170 | 151209 | if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; |
| 151171 | 151210 | }else{ |
| 151172 | | - VdbeNoopComment((v, "eof-B subroutine")); |
| 151211 | + VdbeNoopComment((v, "SUBR: eof-B")); |
| 151173 | 151212 | addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); |
| 151213 | + VdbeComment((v, "out-A")); |
| 151174 | 151214 | sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); |
| 151215 | + VdbeComment((v, "next-A")); |
| 151175 | 151216 | sqlite3VdbeGoto(v, addrEofB); |
| 151176 | 151217 | } |
| 151177 | 151218 | |
| 151178 | 151219 | /* Generate code to handle the case of A<B |
| 151179 | 151220 | */ |
| 151180 | | - VdbeNoopComment((v, "A-lt-B subroutine")); |
| 151181 | 151221 | addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); |
| 151222 | + VdbeComment((v, "out-A")); |
| 151182 | 151223 | sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v); |
| 151224 | + VdbeComment((v, "next-A")); |
| 151183 | 151225 | sqlite3VdbeGoto(v, labelCmpr); |
| 151184 | 151226 | |
| 151185 | 151227 | /* Generate code to handle the case of A==B |
| 151186 | 151228 | */ |
| 151187 | 151229 | if( op==TK_ALL ){ |
| | @@ -151188,40 +151230,52 @@ |
| 151188 | 151230 | addrAeqB = addrAltB; |
| 151189 | 151231 | }else if( op==TK_INTERSECT ){ |
| 151190 | 151232 | addrAeqB = addrAltB; |
| 151191 | 151233 | addrAltB++; |
| 151192 | 151234 | }else{ |
| 151193 | | - VdbeNoopComment((v, "A-eq-B subroutine")); |
| 151194 | | - addrAeqB = |
| 151195 | | - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v); |
| 151196 | | - sqlite3VdbeGoto(v, labelCmpr); |
| 151235 | + addrAeqB = addrAltB + 1; |
| 151197 | 151236 | } |
| 151198 | 151237 | |
| 151199 | 151238 | /* Generate code to handle the case of A>B |
| 151200 | 151239 | */ |
| 151201 | | - VdbeNoopComment((v, "A-gt-B subroutine")); |
| 151202 | 151240 | addrAgtB = sqlite3VdbeCurrentAddr(v); |
| 151203 | 151241 | if( op==TK_ALL || op==TK_UNION ){ |
| 151204 | 151242 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); |
| 151243 | + VdbeComment((v, "out-B")); |
| 151244 | + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); |
| 151245 | + VdbeComment((v, "next-B")); |
| 151246 | + sqlite3VdbeGoto(v, labelCmpr); |
| 151247 | + }else{ |
| 151248 | + addrAgtB++; /* Just do next-B. Might as well use the next-B call |
| 151249 | + ** in the next code block */ |
| 151205 | 151250 | } |
| 151206 | | - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); |
| 151207 | | - sqlite3VdbeGoto(v, labelCmpr); |
| 151208 | 151251 | |
| 151209 | 151252 | /* This code runs once to initialize everything. |
| 151210 | 151253 | */ |
| 151211 | 151254 | sqlite3VdbeJumpHere(v, addr1); |
| 151212 | 151255 | sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); |
| 151256 | + VdbeComment((v, "next-A")); |
| 151257 | + /* v--- Also the A>B case for EXCEPT and INTERSECT */ |
| 151213 | 151258 | sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); |
| 151259 | + VdbeComment((v, "next-B")); |
| 151214 | 151260 | |
| 151215 | 151261 | /* Implement the main merge loop |
| 151216 | 151262 | */ |
| 151263 | + if( aPermute!=0 ){ |
| 151264 | + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); |
| 151265 | + } |
| 151217 | 151266 | sqlite3VdbeResolveLabel(v, labelCmpr); |
| 151218 | | - sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); |
| 151219 | 151267 | sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, |
| 151220 | 151268 | (char*)pKeyMerge, P4_KEYINFO); |
| 151221 | | - sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); |
| 151222 | | - sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); |
| 151269 | + if( aPermute!=0 ){ |
| 151270 | + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); |
| 151271 | + } |
| 151272 | + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); |
| 151273 | + VdbeCoverageIf(v, op==TK_ALL); |
| 151274 | + VdbeCoverageIf(v, op==TK_UNION); |
| 151275 | + VdbeCoverageIf(v, op==TK_EXCEPT); |
| 151276 | + VdbeCoverageIf(v, op==TK_INTERSECT); |
| 151223 | 151277 | |
| 151224 | 151278 | /* Jump to the this point in order to terminate the query. |
| 151225 | 151279 | */ |
| 151226 | 151280 | sqlite3VdbeResolveLabel(v, labelEnd); |
| 151227 | 151281 | |
| | @@ -165697,10 +165751,38 @@ |
| 165697 | 165751 | sqlite3ValueFree(pVal); |
| 165698 | 165752 | return rc; |
| 165699 | 165753 | } |
| 165700 | 165754 | #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ |
| 165701 | 165755 | |
| 165756 | +/* |
| 165757 | +** If pExpr is one of "like", "glob", "match", or "regexp", then |
| 165758 | +** return the corresponding SQLITE_INDEX_CONSTRAINT_xxxx value. |
| 165759 | +** If not, return 0. |
| 165760 | +** |
| 165761 | +** pExpr is guaranteed to be a TK_FUNCTION. |
| 165762 | +*/ |
| 165763 | +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr *pExpr){ |
| 165764 | + static const struct { |
| 165765 | + const char *zOp; |
| 165766 | + unsigned char eOp; |
| 165767 | + } aOp[] = { |
| 165768 | + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, |
| 165769 | + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, |
| 165770 | + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, |
| 165771 | + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } |
| 165772 | + }; |
| 165773 | + int i; |
| 165774 | + assert( pExpr->op==TK_FUNCTION ); |
| 165775 | + assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 165776 | + for(i=0; i<ArraySize(aOp); i++){ |
| 165777 | + if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ |
| 165778 | + return aOp[i].eOp; |
| 165779 | + } |
| 165780 | + } |
| 165781 | + return 0; |
| 165782 | +} |
| 165783 | + |
| 165702 | 165784 | |
| 165703 | 165785 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 165704 | 165786 | /* |
| 165705 | 165787 | ** Check to see if the pExpr expression is a form that needs to be passed |
| 165706 | 165788 | ** to the xBestIndex method of virtual tables. Forms of interest include: |
| | @@ -165733,19 +165815,10 @@ |
| 165733 | 165815 | unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ |
| 165734 | 165816 | Expr **ppLeft, /* Column expression to left of MATCH/op2 */ |
| 165735 | 165817 | Expr **ppRight /* Expression to left of MATCH/op2 */ |
| 165736 | 165818 | ){ |
| 165737 | 165819 | if( pExpr->op==TK_FUNCTION ){ |
| 165738 | | - static const struct Op2 { |
| 165739 | | - const char *zOp; |
| 165740 | | - unsigned char eOp2; |
| 165741 | | - } aOp[] = { |
| 165742 | | - { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, |
| 165743 | | - { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, |
| 165744 | | - { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, |
| 165745 | | - { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } |
| 165746 | | - }; |
| 165747 | 165820 | ExprList *pList; |
| 165748 | 165821 | Expr *pCol; /* Column reference */ |
| 165749 | 165822 | int i; |
| 165750 | 165823 | |
| 165751 | 165824 | assert( ExprUseXList(pExpr) ); |
| | @@ -165761,20 +165834,15 @@ |
| 165761 | 165834 | ** vtab_column MATCH expression |
| 165762 | 165835 | ** MATCH(expression,vtab_column) |
| 165763 | 165836 | */ |
| 165764 | 165837 | pCol = pList->a[1].pExpr; |
| 165765 | 165838 | assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); |
| 165766 | | - if( ExprIsVtab(pCol) ){ |
| 165767 | | - for(i=0; i<ArraySize(aOp); i++){ |
| 165768 | | - assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 165769 | | - if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ |
| 165770 | | - *peOp2 = aOp[i].eOp2; |
| 165771 | | - *ppRight = pList->a[0].pExpr; |
| 165772 | | - *ppLeft = pCol; |
| 165773 | | - return 1; |
| 165774 | | - } |
| 165775 | | - } |
| 165839 | + if( ExprIsVtab(pCol) && (i = sqlite3ExprIsLikeOperator(pExpr))!=0 ){ |
| 165840 | + *peOp2 = i; |
| 165841 | + *ppRight = pList->a[0].pExpr; |
| 165842 | + *ppLeft = pCol; |
| 165843 | + return 1; |
| 165776 | 165844 | } |
| 165777 | 165845 | |
| 165778 | 165846 | /* We can also match against the first column of overloaded |
| 165779 | 165847 | ** functions where xFindFunction returns a value of at least |
| 165780 | 165848 | ** SQLITE_INDEX_CONSTRAINT_FUNCTION. |
| | @@ -170218,10 +170286,71 @@ |
| 170218 | 170286 | p->u.btree.pIndex = 0; |
| 170219 | 170287 | } |
| 170220 | 170288 | } |
| 170221 | 170289 | return rc; |
| 170222 | 170290 | } |
| 170291 | + |
| 170292 | +/* |
| 170293 | +** Callback for estLikePatternLength(). |
| 170294 | +** |
| 170295 | +** If this node is a string literal that is longer pWalker->sz, then set |
| 170296 | +** pWalker->sz to the byte length of that string literal. |
| 170297 | +** |
| 170298 | +** pWalker->eCode indicates how to count characters: |
| 170299 | +** |
| 170300 | +** eCode==0 Count as a GLOB pattern |
| 170301 | +** eCode==1 Count as a LIKE pattern |
| 170302 | +*/ |
| 170303 | +static int exprNodePatternLengthEst(Walker *pWalker, Expr *pExpr){ |
| 170304 | + if( pExpr->op==TK_STRING ){ |
| 170305 | + int sz = 0; /* Pattern size in bytes */ |
| 170306 | + u8 *z = (u8*)pExpr->u.zToken; /* The pattern */ |
| 170307 | + u8 c; /* Next character of the pattern */ |
| 170308 | + u8 c1, c2, c3; /* Wildcards */ |
| 170309 | + if( pWalker->eCode ){ |
| 170310 | + c1 = '%'; |
| 170311 | + c2 = '_'; |
| 170312 | + c3 = 0; |
| 170313 | + }else{ |
| 170314 | + c1 = '*'; |
| 170315 | + c2 = '?'; |
| 170316 | + c3 = '['; |
| 170317 | + } |
| 170318 | + while( (c = *(z++))!=0 ){ |
| 170319 | + if( c==c3 ){ |
| 170320 | + if( *z ) z++; |
| 170321 | + while( *z && *z!=']' ) z++; |
| 170322 | + }else if( c!=c1 && c!=c2 ){ |
| 170323 | + sz++; |
| 170324 | + } |
| 170325 | + } |
| 170326 | + if( sz>pWalker->u.sz ) pWalker->u.sz = sz; |
| 170327 | + } |
| 170328 | + return WRC_Continue; |
| 170329 | +} |
| 170330 | + |
| 170331 | +/* |
| 170332 | +** Return the length of the longest string literal in the given |
| 170333 | +** expression. |
| 170334 | +** |
| 170335 | +** eCode indicates how to count characters: |
| 170336 | +** |
| 170337 | +** eCode==0 Count as a GLOB pattern |
| 170338 | +** eCode==1 Count as a LIKE pattern |
| 170339 | +*/ |
| 170340 | +static int estLikePatternLength(Expr *p, u16 eCode){ |
| 170341 | + Walker w; |
| 170342 | + w.u.sz = 0; |
| 170343 | + w.eCode = eCode; |
| 170344 | + w.xExprCallback = exprNodePatternLengthEst; |
| 170345 | + w.xSelectCallback = sqlite3SelectWalkFail; |
| 170346 | +#ifdef SQLITE_DEBUG |
| 170347 | + w.xSelectCallback2 = sqlite3SelectWalkAssert2; |
| 170348 | +#endif |
| 170349 | + sqlite3WalkExpr(&w, p); |
| 170350 | + return w.u.sz; |
| 170351 | +} |
| 170223 | 170352 | |
| 170224 | 170353 | /* |
| 170225 | 170354 | ** Adjust the WhereLoop.nOut value downward to account for terms of the |
| 170226 | 170355 | ** WHERE clause that reference the loop but which are not used by an |
| 170227 | 170356 | ** index. |
| | @@ -170247,10 +170376,17 @@ |
| 170247 | 170376 | ** of rows in the table. In other words, assume that x==EXPR will filter |
| 170248 | 170377 | ** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the |
| 170249 | 170378 | ** "x" column is boolean or else -1 or 0 or 1 is a common default value |
| 170250 | 170379 | ** on the "x" column and so in that case only cap the output row estimate |
| 170251 | 170380 | ** at 1/2 instead of 1/4. |
| 170381 | +** |
| 170382 | +** Heuristic 3: If there is a LIKE or GLOB (or REGEXP or MATCH) operator |
| 170383 | +** with a large constant pattern, then reduce the size of the search |
| 170384 | +** space according to the length of the pattern, under the theory that |
| 170385 | +** longer patterns are less likely to match. This heuristic was added |
| 170386 | +** to give better output-row count estimates when preparing queries for |
| 170387 | +** the Join-Order Benchmarks. See forum thread 2026-01-30T09:57:54z |
| 170252 | 170388 | */ |
| 170253 | 170389 | static void whereLoopOutputAdjust( |
| 170254 | 170390 | WhereClause *pWC, /* The WHERE clause */ |
| 170255 | 170391 | WhereLoop *pLoop, /* The loop to adjust downward */ |
| 170256 | 170392 | LogEst nRow /* Number of rows in the entire table */ |
| | @@ -170296,25 +170432,43 @@ |
| 170296 | 170432 | ** then use the probability provided by the application. */ |
| 170297 | 170433 | pLoop->nOut += pTerm->truthProb; |
| 170298 | 170434 | }else{ |
| 170299 | 170435 | /* In the absence of explicit truth probabilities, use heuristics to |
| 170300 | 170436 | ** guess a reasonable truth probability. */ |
| 170437 | + Expr *pOpExpr = pTerm->pExpr; |
| 170301 | 170438 | pLoop->nOut--; |
| 170302 | 170439 | if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 |
| 170303 | 170440 | && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ |
| 170304 | 170441 | ){ |
| 170305 | | - Expr *pRight = pTerm->pExpr->pRight; |
| 170442 | + Expr *pRight = pOpExpr->pRight; |
| 170306 | 170443 | int k = 0; |
| 170307 | | - testcase( pTerm->pExpr->op==TK_IS ); |
| 170444 | + testcase( pOpExpr->op==TK_IS ); |
| 170308 | 170445 | if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ |
| 170309 | 170446 | k = 10; |
| 170310 | 170447 | }else{ |
| 170311 | 170448 | k = 20; |
| 170312 | 170449 | } |
| 170313 | 170450 | if( iReduce<k ){ |
| 170314 | 170451 | pTerm->wtFlags |= TERM_HEURTRUTH; |
| 170315 | 170452 | iReduce = k; |
| 170453 | + } |
| 170454 | + }else |
| 170455 | + if( ExprHasProperty(pOpExpr, EP_InfixFunc) |
| 170456 | + && pOpExpr->op==TK_FUNCTION |
| 170457 | + ){ |
| 170458 | + int eOp; |
| 170459 | + assert( ExprUseXList(pOpExpr) ); |
| 170460 | + assert( pOpExpr->x.pList->nExpr>=2 ); |
| 170461 | + eOp = sqlite3ExprIsLikeOperator(pOpExpr); |
| 170462 | + if( ALWAYS(eOp>0) ){ |
| 170463 | + int szPattern; |
| 170464 | + Expr *pRHS = pOpExpr->x.pList->a[0].pExpr; |
| 170465 | + eOp = eOp==SQLITE_INDEX_CONSTRAINT_LIKE; |
| 170466 | + szPattern = estLikePatternLength(pRHS, eOp); |
| 170467 | + if( szPattern>0 ){ |
| 170468 | + pLoop->nOut -= szPattern*2; |
| 170469 | + } |
| 170316 | 170470 | } |
| 170317 | 170471 | } |
| 170318 | 170472 | } |
| 170319 | 170473 | } |
| 170320 | 170474 | } |
| | @@ -172136,11 +172290,11 @@ |
| 172136 | 172290 | SrcItem *pItem; |
| 172137 | 172291 | SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; |
| 172138 | 172292 | sqlite3 *db = pWInfo->pParse->db; |
| 172139 | 172293 | int rc = SQLITE_OK; |
| 172140 | 172294 | int bFirstPastRJ = 0; |
| 172141 | | - int hasRightJoin = 0; |
| 172295 | + int hasRightCrossJoin = 0; |
| 172142 | 172296 | WhereLoop *pNew; |
| 172143 | 172297 | |
| 172144 | 172298 | |
| 172145 | 172299 | /* Loop over the tables in the join, from left to right */ |
| 172146 | 172300 | pNew = pBuilder->pNew; |
| | @@ -172163,16 +172317,24 @@ |
| 172163 | 172317 | /* Add prerequisites to prevent reordering of FROM clause terms |
| 172164 | 172318 | ** across CROSS joins and outer joins. The bFirstPastRJ boolean |
| 172165 | 172319 | ** prevents the right operand of a RIGHT JOIN from being swapped with |
| 172166 | 172320 | ** other elements even further to the right. |
| 172167 | 172321 | ** |
| 172168 | | - ** The JT_LTORJ case and the hasRightJoin flag work together to |
| 172169 | | - ** prevent FROM-clause terms from moving from the right side of |
| 172170 | | - ** a LEFT JOIN over to the left side of that join if the LEFT JOIN |
| 172171 | | - ** is itself on the left side of a RIGHT JOIN. |
| 172322 | + ** The hasRightCrossJoin flag prevent FROM-clause terms from moving |
| 172323 | + ** from the right side of a LEFT JOIN or CROSS JOIN over to the |
| 172324 | + ** left side of that same join. This is a required restriction in |
| 172325 | + ** the case of LEFT JOIN - an incorrect answer may results if it is |
| 172326 | + ** not enforced. This restriction is not required for CROSS JOIN. |
| 172327 | + ** It is provided merely as a means of controlling join order, under |
| 172328 | + ** the theory that no real-world queries that care about performance |
| 172329 | + ** actually use the CROSS JOIN syntax. |
| 172172 | 172330 | */ |
| 172173 | | - if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; |
| 172331 | + if( pItem->fg.jointype & (JT_LTORJ|JT_CROSS) ){ |
| 172332 | + testcase( pItem->fg.jointype & JT_LTORJ ); |
| 172333 | + testcase( pItem->fg.jointype & JT_CROSS ); |
| 172334 | + hasRightCrossJoin = 1; |
| 172335 | + } |
| 172174 | 172336 | mPrereq |= mPrior; |
| 172175 | 172337 | bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; |
| 172176 | 172338 | }else if( pItem->fg.fromExists ){ |
| 172177 | 172339 | /* joins that result from the EXISTS-to-JOIN optimization should not |
| 172178 | 172340 | ** be moved to the left of any of their dependencies */ |
| | @@ -172182,11 +172344,11 @@ |
| 172182 | 172344 | for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ |
| 172183 | 172345 | if( (pNew->maskSelf & pTerm->prereqAll)!=0 ){ |
| 172184 | 172346 | mPrereq |= (pTerm->prereqAll & (pNew->maskSelf-1)); |
| 172185 | 172347 | } |
| 172186 | 172348 | } |
| 172187 | | - }else if( !hasRightJoin ){ |
| 172349 | + }else if( !hasRightCrossJoin ){ |
| 172188 | 172350 | mPrereq = 0; |
| 172189 | 172351 | } |
| 172190 | 172352 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 172191 | 172353 | if( IsVirtual(pItem->pSTab) ){ |
| 172192 | 172354 | SrcItem *p; |
| | @@ -214034,32 +214196,36 @@ |
| 214034 | 214196 | jsonParseReset(&v); |
| 214035 | 214197 | jsonParseReset(&ix); |
| 214036 | 214198 | return rc; |
| 214037 | 214199 | } |
| 214038 | 214200 | }else if( zPath[0]=='[' ){ |
| 214201 | + u64 kk = 0; |
| 214039 | 214202 | x = pParse->aBlob[iRoot] & 0x0f; |
| 214040 | 214203 | if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; |
| 214041 | 214204 | n = jsonbPayloadSize(pParse, iRoot, &sz); |
| 214042 | | - k = 0; |
| 214043 | 214205 | i = 1; |
| 214044 | 214206 | while( sqlite3Isdigit(zPath[i]) ){ |
| 214045 | | - k = k*10 + zPath[i] - '0'; |
| 214207 | + if( kk<0xffffffff ) kk = kk*10 + zPath[i] - '0'; |
| 214208 | + /* ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that |
| 214209 | + ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */ |
| 214046 | 214210 | i++; |
| 214047 | 214211 | } |
| 214048 | 214212 | if( i<2 || zPath[i]!=']' ){ |
| 214049 | 214213 | if( zPath[1]=='#' ){ |
| 214050 | | - k = jsonbArrayCount(pParse, iRoot); |
| 214214 | + kk = jsonbArrayCount(pParse, iRoot); |
| 214051 | 214215 | i = 2; |
| 214052 | 214216 | if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ |
| 214053 | | - unsigned int nn = 0; |
| 214217 | + u64 nn = 0; |
| 214054 | 214218 | i = 3; |
| 214055 | 214219 | do{ |
| 214056 | | - nn = nn*10 + zPath[i] - '0'; |
| 214220 | + if( nn<0xffffffff ) nn = nn*10 + zPath[i] - '0'; |
| 214221 | + /* ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to |
| 214222 | + ** get NOTFOUND instead of PATHERROR, without overflowing nn. */ |
| 214057 | 214223 | i++; |
| 214058 | 214224 | }while( sqlite3Isdigit(zPath[i]) ); |
| 214059 | | - if( nn>k ) return JSON_LOOKUP_NOTFOUND; |
| 214060 | | - k -= nn; |
| 214225 | + if( nn>kk ) return JSON_LOOKUP_NOTFOUND; |
| 214226 | + kk -= nn; |
| 214061 | 214227 | } |
| 214062 | 214228 | if( zPath[i]!=']' ){ |
| 214063 | 214229 | return JSON_LOOKUP_PATHERROR; |
| 214064 | 214230 | } |
| 214065 | 214231 | }else{ |
| | @@ -214067,22 +214233,22 @@ |
| 214067 | 214233 | } |
| 214068 | 214234 | } |
| 214069 | 214235 | j = iRoot+n; |
| 214070 | 214236 | iEnd = j+sz; |
| 214071 | 214237 | while( j<iEnd ){ |
| 214072 | | - if( k==0 ){ |
| 214238 | + if( kk==0 ){ |
| 214073 | 214239 | rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); |
| 214074 | 214240 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); |
| 214075 | 214241 | return rc; |
| 214076 | 214242 | } |
| 214077 | | - k--; |
| 214243 | + kk--; |
| 214078 | 214244 | n = jsonbPayloadSize(pParse, j, &sz); |
| 214079 | 214245 | if( n==0 ) return JSON_LOOKUP_ERROR; |
| 214080 | 214246 | j += n+sz; |
| 214081 | 214247 | } |
| 214082 | 214248 | if( j>iEnd ) return JSON_LOOKUP_ERROR; |
| 214083 | | - if( k>0 ) return JSON_LOOKUP_NOTFOUND; |
| 214249 | + if( kk>0 ) return JSON_LOOKUP_NOTFOUND; |
| 214084 | 214250 | if( pParse->eEdit>=JEDIT_INS ){ |
| 214085 | 214251 | JsonParse v; |
| 214086 | 214252 | testcase( pParse->eEdit==JEDIT_INS ); |
| 214087 | 214253 | testcase( pParse->eEdit==JEDIT_AINS ); |
| 214088 | 214254 | testcase( pParse->eEdit==JEDIT_SET ); |
| | @@ -231358,10 +231524,11 @@ |
| 231358 | 231524 | struct carray_bind { |
| 231359 | 231525 | void *aData; /* The data */ |
| 231360 | 231526 | int nData; /* Number of elements */ |
| 231361 | 231527 | int mFlags; /* Control flags */ |
| 231362 | 231528 | void (*xDel)(void*); /* Destructor for aData */ |
| 231529 | + void *pDel; /* Alternative argument to xDel() */ |
| 231363 | 231530 | }; |
| 231364 | 231531 | |
| 231365 | 231532 | |
| 231366 | 231533 | /* carray_cursor is a subclass of sqlite3_vtab_cursor which will |
| 231367 | 231534 | ** serve as the underlying representation of a cursor that scans |
| | @@ -231690,26 +231857,38 @@ |
| 231690 | 231857 | ** Destructor for the carray_bind object |
| 231691 | 231858 | */ |
| 231692 | 231859 | static void carrayBindDel(void *pPtr){ |
| 231693 | 231860 | carray_bind *p = (carray_bind*)pPtr; |
| 231694 | 231861 | if( p->xDel!=SQLITE_STATIC ){ |
| 231695 | | - p->xDel(p->aData); |
| 231862 | + p->xDel(p->pDel); |
| 231696 | 231863 | } |
| 231697 | 231864 | sqlite3_free(p); |
| 231698 | 231865 | } |
| 231699 | 231866 | |
| 231700 | 231867 | /* |
| 231701 | 231868 | ** Invoke this interface in order to bind to the single-argument |
| 231702 | 231869 | ** version of CARRAY(). |
| 231870 | +** |
| 231871 | +** pStmt The prepared statement to which to bind |
| 231872 | +** idx The index of the parameter of pStmt to which to bind |
| 231873 | +** aData The data to be bound |
| 231874 | +** nData The number of elements in aData |
| 231875 | +** mFlags One of SQLITE_CARRAY_xxxx indicating datatype of aData |
| 231876 | +** xDestroy Destructor for pDestroy or aData if pDestroy==NULL. |
| 231877 | +** pDestroy Invoke xDestroy on this pointer if not NULL |
| 231878 | +** |
| 231879 | +** The destructor is called pDestroy if pDestroy!=NULL, or against |
| 231880 | +** aData if pDestroy==NULL. |
| 231703 | 231881 | */ |
| 231704 | | -SQLITE_API int sqlite3_carray_bind( |
| 231882 | +SQLITE_API int sqlite3_carray_bind_v2( |
| 231705 | 231883 | sqlite3_stmt *pStmt, |
| 231706 | 231884 | int idx, |
| 231707 | 231885 | void *aData, |
| 231708 | 231886 | int nData, |
| 231709 | 231887 | int mFlags, |
| 231710 | | - void (*xDestroy)(void*) |
| 231888 | + void (*xDestroy)(void*), |
| 231889 | + void *pDestroy |
| 231711 | 231890 | ){ |
| 231712 | 231891 | carray_bind *pNew = 0; |
| 231713 | 231892 | int i; |
| 231714 | 231893 | int rc = SQLITE_OK; |
| 231715 | 231894 | |
| | @@ -231782,23 +231961,41 @@ |
| 231782 | 231961 | } |
| 231783 | 231962 | }else{ |
| 231784 | 231963 | memcpy(pNew->aData, aData, sz); |
| 231785 | 231964 | } |
| 231786 | 231965 | pNew->xDel = sqlite3_free; |
| 231966 | + pNew->pDel = pNew->aData; |
| 231787 | 231967 | }else{ |
| 231788 | 231968 | pNew->aData = aData; |
| 231789 | 231969 | pNew->xDel = xDestroy; |
| 231970 | + pNew->pDel = pDestroy; |
| 231790 | 231971 | } |
| 231791 | 231972 | return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel); |
| 231792 | 231973 | |
| 231793 | 231974 | carray_bind_error: |
| 231794 | 231975 | if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){ |
| 231795 | | - xDestroy(aData); |
| 231976 | + xDestroy(pDestroy); |
| 231796 | 231977 | } |
| 231797 | 231978 | sqlite3_free(pNew); |
| 231798 | 231979 | return rc; |
| 231799 | 231980 | } |
| 231981 | + |
| 231982 | +/* |
| 231983 | +** Invoke this interface in order to bind to the single-argument |
| 231984 | +** version of CARRAY(). Same as sqlite3_carray_bind_v2() with the |
| 231985 | +** pDestroy parameter set to NULL. |
| 231986 | +*/ |
| 231987 | +SQLITE_API int sqlite3_carray_bind( |
| 231988 | + sqlite3_stmt *pStmt, |
| 231989 | + int idx, |
| 231990 | + void *aData, |
| 231991 | + int nData, |
| 231992 | + int mFlags, |
| 231993 | + void (*xDestroy)(void*) |
| 231994 | +){ |
| 231995 | + return sqlite3_carray_bind_v2(pStmt,idx,aData,nData,mFlags,xDestroy,aData); |
| 231996 | +} |
| 231800 | 231997 | |
| 231801 | 231998 | /* |
| 231802 | 231999 | ** Invoke this routine to register the carray() function. |
| 231803 | 232000 | */ |
| 231804 | 232001 | SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3 *db){ |
| | @@ -232157,10 +232354,24 @@ |
| 232157 | 232354 | ** bytes read. |
| 232158 | 232355 | */ |
| 232159 | 232356 | static int sessionVarintGet(const u8 *aBuf, int *piVal){ |
| 232160 | 232357 | return getVarint32(aBuf, *piVal); |
| 232161 | 232358 | } |
| 232359 | + |
| 232360 | +/* |
| 232361 | +** Read a varint value from buffer aBuf[], size nBuf bytes, into *piVal. |
| 232362 | +** Return the number of bytes read. |
| 232363 | +*/ |
| 232364 | +static int sessionVarintGetSafe(const u8 *aBuf, int nBuf, int *piVal){ |
| 232365 | + u8 aCopy[5]; |
| 232366 | + const u8 *aRead = aBuf; |
| 232367 | + if( nBuf<5 ){ |
| 232368 | + memcpy(aCopy, aBuf, nBuf); |
| 232369 | + aRead = aCopy; |
| 232370 | + } |
| 232371 | + return getVarint32(aRead, *piVal); |
| 232372 | +} |
| 232162 | 232373 | |
| 232163 | 232374 | /* Load an unaligned and unsigned 32-bit integer */ |
| 232164 | 232375 | #define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) |
| 232165 | 232376 | |
| 232166 | 232377 | /* |
| | @@ -235370,11 +235581,12 @@ |
| 235370 | 235581 | |
| 235371 | 235582 | if( rc==SQLITE_OK ){ |
| 235372 | 235583 | u8 *aVal = &pIn->aData[pIn->iNext]; |
| 235373 | 235584 | if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ |
| 235374 | 235585 | int nByte; |
| 235375 | | - pIn->iNext += sessionVarintGet(aVal, &nByte); |
| 235586 | + int nRem = pIn->nData - pIn->iNext; |
| 235587 | + pIn->iNext += sessionVarintGetSafe(aVal, nRem, &nByte); |
| 235376 | 235588 | rc = sessionInputBuffer(pIn, nByte); |
| 235377 | 235589 | if( rc==SQLITE_OK ){ |
| 235378 | 235590 | if( nByte<0 || nByte>pIn->nData-pIn->iNext ){ |
| 235379 | 235591 | rc = SQLITE_CORRUPT_BKPT; |
| 235380 | 235592 | }else{ |
| | @@ -235423,11 +235635,12 @@ |
| 235423 | 235635 | int nCol = 0; |
| 235424 | 235636 | int nRead = 0; |
| 235425 | 235637 | |
| 235426 | 235638 | rc = sessionInputBuffer(pIn, 9); |
| 235427 | 235639 | if( rc==SQLITE_OK ){ |
| 235428 | | - nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); |
| 235640 | + int nBuf = pIn->nData - pIn->iNext; |
| 235641 | + nRead += sessionVarintGetSafe(&pIn->aData[pIn->iNext], nBuf, &nCol); |
| 235429 | 235642 | /* The hard upper limit for the number of columns in an SQLite |
| 235430 | 235643 | ** database table is, according to sqliteLimit.h, 32676. So |
| 235431 | 235644 | ** consider any table-header that purports to have more than 65536 |
| 235432 | 235645 | ** columns to be corrupt. This is convenient because otherwise, |
| 235433 | 235646 | ** if the (nCol>65536) condition below were omitted, a sufficiently |
| | @@ -235583,14 +235796,14 @@ |
| 235583 | 235796 | sqlite3ValueFree(p->apValue[i]); |
| 235584 | 235797 | } |
| 235585 | 235798 | memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); |
| 235586 | 235799 | } |
| 235587 | 235800 | |
| 235588 | | - /* Make sure the buffer contains at least 10 bytes of input data, or all |
| 235589 | | - ** remaining data if there are less than 10 bytes available. This is |
| 235590 | | - ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 235591 | | - ** it, or for the two single byte values otherwise. */ |
| 235801 | + /* Make sure the buffer contains at least 2 bytes of input data, or all |
| 235802 | + ** remaining data if there are less than 2 bytes available. This is |
| 235803 | + ** sufficient either for the 'T' or 'P' byte that begins a new table, |
| 235804 | + ** or for the "op" and "bIndirect" single bytes otherwise. */ |
| 235592 | 235805 | p->rc = sessionInputBuffer(&p->in, 2); |
| 235593 | 235806 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 235594 | 235807 | |
| 235595 | 235808 | p->in.iCurrent = p->in.iNext; |
| 235596 | 235809 | sessionDiscardData(&p->in); |
| | @@ -235616,15 +235829,17 @@ |
| 235616 | 235829 | ** corrupt changeset. */ |
| 235617 | 235830 | assert( p->in.iNext==1 || p->zTab ); |
| 235618 | 235831 | return (p->rc = SQLITE_CORRUPT_BKPT); |
| 235619 | 235832 | } |
| 235620 | 235833 | |
| 235621 | | - p->op = op; |
| 235622 | | - p->bIndirect = p->in.aData[p->in.iNext++]; |
| 235623 | | - if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ |
| 235834 | + if( (op!=SQLITE_UPDATE && op!=SQLITE_DELETE && op!=SQLITE_INSERT) |
| 235835 | + || (p->in.iNext>=p->in.nData) |
| 235836 | + ){ |
| 235624 | 235837 | return (p->rc = SQLITE_CORRUPT_BKPT); |
| 235625 | 235838 | } |
| 235839 | + p->op = op; |
| 235840 | + p->bIndirect = p->in.aData[p->in.iNext++]; |
| 235626 | 235841 | |
| 235627 | 235842 | if( paRec ){ |
| 235628 | 235843 | int nVal; /* Number of values to buffer */ |
| 235629 | 235844 | if( p->bPatchset==0 && op==SQLITE_UPDATE ){ |
| 235630 | 235845 | nVal = p->nCol * 2; |
| | @@ -261258,11 +261473,11 @@ |
| 261258 | 261473 | int nArg, /* Number of args */ |
| 261259 | 261474 | sqlite3_value **apUnused /* Function arguments */ |
| 261260 | 261475 | ){ |
| 261261 | 261476 | assert( nArg==0 ); |
| 261262 | 261477 | UNUSED_PARAM2(nArg, apUnused); |
| 261263 | | - sqlite3_result_text(pCtx, "fts5: 2026-01-26 10:53:24 4733d351ec2376291f093ba8d2ba71d82c6f100c68dc860eee0532986c154e71", -1, SQLITE_TRANSIENT); |
| 261478 | + sqlite3_result_text(pCtx, "fts5: 2026-02-04 18:10:49 e6902937ecdbeb449986469859b46631272fb0a9e7e1c31adea14cff072b6d67", -1, SQLITE_TRANSIENT); |
| 261264 | 261479 | } |
| 261265 | 261480 | |
| 261266 | 261481 | /* |
| 261267 | 261482 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 261268 | 261483 | ** |
| 261269 | 261484 | |