Fossil SCM
Update the built-in SQLite to the latest 3.39.0 alpha which includes the latest bug fixes, and especially the fix for the infinite loop when the Bloom filter pull-down optimization encounters a NULL key.
Commit
b2cb7bdb5a361c5d6138d4f774925f4272697aeefab0dfedad9c7bd97b14f6db
Parent
f905bd0d8d5b70f…
2 files changed
+131
-20
+1
-1
+131
-20
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -452,11 +452,11 @@ | ||
| 452 | 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | 454 | */ |
| 455 | 455 | #define SQLITE_VERSION "3.39.0" |
| 456 | 456 | #define SQLITE_VERSION_NUMBER 3039000 |
| 457 | -#define SQLITE_SOURCE_ID "2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb" | |
| 457 | +#define SQLITE_SOURCE_ID "2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb" | |
| 458 | 458 | |
| 459 | 459 | /* |
| 460 | 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | 462 | ** |
| @@ -17054,10 +17054,11 @@ | ||
| 17054 | 17054 | #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ |
| 17055 | 17055 | #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ |
| 17056 | 17056 | #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ |
| 17057 | 17057 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ |
| 17058 | 17058 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ |
| 17059 | + /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ | |
| 17059 | 17060 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17060 | 17061 | |
| 17061 | 17062 | /* |
| 17062 | 17063 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 17063 | 17064 | */ |
| @@ -19732,10 +19733,11 @@ | ||
| 19732 | 19733 | SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); |
| 19733 | 19734 | SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); |
| 19734 | 19735 | SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); |
| 19735 | 19736 | SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); |
| 19736 | 19737 | SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); |
| 19738 | +SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); | |
| 19737 | 19739 | SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); |
| 19738 | 19740 | SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); |
| 19739 | 19741 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); |
| 19740 | 19742 | SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); |
| 19741 | 19743 | SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, |
| @@ -20587,10 +20589,11 @@ | ||
| 20587 | 20589 | ** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). |
| 20588 | 20590 | */ |
| 20589 | 20591 | #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ |
| 20590 | 20592 | #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ |
| 20591 | 20593 | #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ |
| 20594 | +#define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */ | |
| 20592 | 20595 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); |
| 20593 | 20596 | |
| 20594 | 20597 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 20595 | 20598 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 20596 | 20599 | #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ |
| @@ -31057,10 +31060,57 @@ | ||
| 31057 | 31060 | */ |
| 31058 | 31061 | static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ |
| 31059 | 31062 | sqlite3TreeViewPush(&p, moreFollows); |
| 31060 | 31063 | sqlite3TreeViewLine(p, "%s", zLabel); |
| 31061 | 31064 | } |
| 31065 | + | |
| 31066 | +/* | |
| 31067 | +** Show a list of Column objects in tree format. | |
| 31068 | +*/ | |
| 31069 | +SQLITE_PRIVATE void sqlite3TreeViewColumnList( | |
| 31070 | + TreeView *pView, | |
| 31071 | + const Column *aCol, | |
| 31072 | + int nCol, | |
| 31073 | + u8 moreToFollow | |
| 31074 | +){ | |
| 31075 | + int i; | |
| 31076 | + sqlite3TreeViewPush(&pView, moreToFollow); | |
| 31077 | + sqlite3TreeViewLine(pView, "COLUMNS"); | |
| 31078 | + for(i=0; i<nCol; i++){ | |
| 31079 | + u16 flg = aCol[i].colFlags; | |
| 31080 | + int moreToFollow = i<(nCol - 1); | |
| 31081 | + sqlite3TreeViewPush(&pView, moreToFollow); | |
| 31082 | + sqlite3TreeViewLine(pView, 0); | |
| 31083 | + printf(" %s", aCol[i].zCnName); | |
| 31084 | + switch( aCol[i].eCType ){ | |
| 31085 | + case COLTYPE_ANY: printf(" ANY"); break; | |
| 31086 | + case COLTYPE_BLOB: printf(" BLOB"); break; | |
| 31087 | + case COLTYPE_INT: printf(" INT"); break; | |
| 31088 | + case COLTYPE_INTEGER: printf(" INTEGER"); break; | |
| 31089 | + case COLTYPE_REAL: printf(" REAL"); break; | |
| 31090 | + case COLTYPE_TEXT: printf(" TEXT"); break; | |
| 31091 | + case COLTYPE_CUSTOM: { | |
| 31092 | + if( flg & COLFLAG_HASTYPE ){ | |
| 31093 | + const char *z = aCol[i].zCnName; | |
| 31094 | + z += strlen(z)+1; | |
| 31095 | + printf(" X-%s", z); | |
| 31096 | + break; | |
| 31097 | + } | |
| 31098 | + } | |
| 31099 | + } | |
| 31100 | + if( flg & COLFLAG_PRIMKEY ) printf(" PRIMARY KEY"); | |
| 31101 | + if( flg & COLFLAG_HIDDEN ) printf(" HIDDEN"); | |
| 31102 | +#ifdef COLFLAG_NOEXPAND | |
| 31103 | + if( flg & COLFLAG_NOEXPAND ) printf(" NO-EXPAND"); | |
| 31104 | +#endif | |
| 31105 | + if( flg ) printf(" flags=%04x", flg); | |
| 31106 | + printf("\n"); | |
| 31107 | + fflush(stdout); | |
| 31108 | + sqlite3TreeViewPop(&pView); | |
| 31109 | + } | |
| 31110 | + sqlite3TreeViewPop(&pView); | |
| 31111 | +} | |
| 31062 | 31112 | |
| 31063 | 31113 | /* |
| 31064 | 31114 | ** Generate a human-readable description of a WITH clause. |
| 31065 | 31115 | */ |
| 31066 | 31116 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ |
| @@ -31113,10 +31163,11 @@ | ||
| 31113 | 31163 | int i; |
| 31114 | 31164 | if( pSrc==0 ) return; |
| 31115 | 31165 | for(i=0; i<pSrc->nSrc; i++){ |
| 31116 | 31166 | const SrcItem *pItem = &pSrc->a[i]; |
| 31117 | 31167 | StrAccum x; |
| 31168 | + int n = 0; | |
| 31118 | 31169 | char zLine[100]; |
| 31119 | 31170 | sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); |
| 31120 | 31171 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; |
| 31121 | 31172 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); |
| 31122 | 31173 | if( pItem->pTab ){ |
| @@ -31141,13 +31192,24 @@ | ||
| 31141 | 31192 | if( pItem->fg.isCte ){ |
| 31142 | 31193 | sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); |
| 31143 | 31194 | } |
| 31144 | 31195 | sqlite3StrAccumFinish(&x); |
| 31145 | 31196 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 31197 | + n = 0; | |
| 31198 | + if( pItem->pSelect ) n++; | |
| 31199 | + if( pItem->fg.isTabFunc ) n++; | |
| 31200 | + if( pItem->fg.isUsing ) n++; | |
| 31201 | + if( pItem->fg.isUsing ){ | |
| 31202 | + sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); | |
| 31203 | + } | |
| 31146 | 31204 | if( pItem->pSelect ){ |
| 31205 | + if( pItem->pTab ){ | |
| 31206 | + Table *pTab = pItem->pTab; | |
| 31207 | + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); | |
| 31208 | + } | |
| 31147 | 31209 | assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 31148 | - sqlite3TreeViewSelect(pView, pItem->pSelect, 0); | |
| 31210 | + sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); | |
| 31149 | 31211 | } |
| 31150 | 31212 | if( pItem->fg.isTabFunc ){ |
| 31151 | 31213 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| 31152 | 31214 | } |
| 31153 | 31215 | sqlite3TreeViewPop(&pView); |
| @@ -31310,10 +31372,11 @@ | ||
| 31310 | 31372 | /* |
| 31311 | 31373 | ** Generate a human-readable explanation for a Window object |
| 31312 | 31374 | */ |
| 31313 | 31375 | SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ |
| 31314 | 31376 | int nElement = 0; |
| 31377 | + if( pWin==0 ) return; | |
| 31315 | 31378 | if( pWin->pFilter ){ |
| 31316 | 31379 | sqlite3TreeViewItem(pView, "FILTER", 1); |
| 31317 | 31380 | sqlite3TreeViewExpr(pView, pWin->pFilter, 0); |
| 31318 | 31381 | sqlite3TreeViewPop(&pView); |
| 31319 | 31382 | } |
| @@ -31374,10 +31437,11 @@ | ||
| 31374 | 31437 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 31375 | 31438 | /* |
| 31376 | 31439 | ** Generate a human-readable explanation for a Window Function object |
| 31377 | 31440 | */ |
| 31378 | 31441 | SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ |
| 31442 | + if( pWin==0 ) return; | |
| 31379 | 31443 | sqlite3TreeViewPush(&pView, more); |
| 31380 | 31444 | sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", |
| 31381 | 31445 | pWin->pWFunc->zName, pWin->pWFunc->nArg); |
| 31382 | 31446 | sqlite3TreeViewWindow(pView, pWin, 0); |
| 31383 | 31447 | sqlite3TreeViewPop(&pView); |
| @@ -31625,11 +31689,21 @@ | ||
| 31625 | 31689 | sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); |
| 31626 | 31690 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31627 | 31691 | break; |
| 31628 | 31692 | } |
| 31629 | 31693 | case TK_IN: { |
| 31630 | - sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); | |
| 31694 | + sqlite3_str *pStr = sqlite3_str_new(0); | |
| 31695 | + char *z; | |
| 31696 | + sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); | |
| 31697 | + if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); | |
| 31698 | + if( ExprHasProperty(pExpr, EP_Subrtn) ){ | |
| 31699 | + sqlite3_str_appendf(pStr, " subrtn(%d,%d)", | |
| 31700 | + pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); | |
| 31701 | + } | |
| 31702 | + z = sqlite3_str_finish(pStr); | |
| 31703 | + sqlite3TreeViewLine(pView, z); | |
| 31704 | + sqlite3_free(z); | |
| 31631 | 31705 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); |
| 31632 | 31706 | if( ExprUseXSelect(pExpr) ){ |
| 31633 | 31707 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31634 | 31708 | }else{ |
| 31635 | 31709 | sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); |
| @@ -89252,10 +89326,12 @@ | ||
| 89252 | 89326 | if( pOp->p2==0 ) break; |
| 89253 | 89327 | |
| 89254 | 89328 | /* Most jump operations do a goto to this spot in order to update |
| 89255 | 89329 | ** the pOp pointer. */ |
| 89256 | 89330 | jump_to_p2: |
| 89331 | + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ | |
| 89332 | + assert( pOp->p2<p->nOp ); /* Jumps must be in range */ | |
| 89257 | 89333 | pOp = &aOp[pOp->p2 - 1]; |
| 89258 | 89334 | break; |
| 89259 | 89335 | } |
| 89260 | 89336 | |
| 89261 | 89337 | /* Opcode: EndCoroutine P1 * * * * |
| @@ -105782,11 +105858,11 @@ | ||
| 105782 | 105858 | |
| 105783 | 105859 | /* |
| 105784 | 105860 | ** Check pExpr to see if it is an invariant constraint on data source pSrc. |
| 105785 | 105861 | ** This is an optimization. False negatives will perhaps cause slower |
| 105786 | 105862 | ** queries, but false positives will yield incorrect answers. So when in |
| 105787 | -** double, return 0. | |
| 105863 | +** doubt, return 0. | |
| 105788 | 105864 | ** |
| 105789 | 105865 | ** To be an invariant constraint, the following must be true: |
| 105790 | 105866 | ** |
| 105791 | 105867 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. |
| 105792 | 105868 | ** |
| @@ -106141,11 +106217,11 @@ | ||
| 106141 | 106217 | ** The job of this routine is to find or create a b-tree object that can |
| 106142 | 106218 | ** be used either to test for membership in the RHS set or to iterate through |
| 106143 | 106219 | ** all members of the RHS set, skipping duplicates. |
| 106144 | 106220 | ** |
| 106145 | 106221 | ** A cursor is opened on the b-tree object that is the RHS of the IN operator |
| 106146 | -** and pX->iTable is set to the index of that cursor. | |
| 106222 | +** and the *piTab parameter is set to the index of that cursor. | |
| 106147 | 106223 | ** |
| 106148 | 106224 | ** The returned value of this function indicates the b-tree type, as follows: |
| 106149 | 106225 | ** |
| 106150 | 106226 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 106151 | 106227 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| @@ -106161,11 +106237,14 @@ | ||
| 106161 | 106237 | ** SELECT <column1>, <column2>... FROM <table> |
| 106162 | 106238 | ** |
| 106163 | 106239 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 106164 | 106240 | ** an ephemeral table might need to be generated from the RHS and then |
| 106165 | 106241 | ** pX->iTable made to point to the ephemeral table instead of an |
| 106166 | -** existing table. | |
| 106242 | +** existing table. In this case, the creation and initialization of the | |
| 106243 | +** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag | |
| 106244 | +** will be set on pX and the pX->y.sub fields will be set to show where | |
| 106245 | +** the subroutine is coded. | |
| 106167 | 106246 | ** |
| 106168 | 106247 | ** The inFlags parameter must contain, at a minimum, one of the bits |
| 106169 | 106248 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains |
| 106170 | 106249 | ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast |
| 106171 | 106250 | ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will |
| @@ -106222,16 +106301,21 @@ | ||
| 106222 | 106301 | int *aiMap, /* Mapping from Index fields to RHS fields */ |
| 106223 | 106302 | int *piTab /* OUT: index to use */ |
| 106224 | 106303 | ){ |
| 106225 | 106304 | Select *p; /* SELECT to the right of IN operator */ |
| 106226 | 106305 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 106227 | - int iTab = pParse->nTab++; /* Cursor of the RHS table */ | |
| 106306 | + int iTab; /* Cursor of the RHS table */ | |
| 106228 | 106307 | int mustBeUnique; /* True if RHS must be unique */ |
| 106229 | 106308 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 106230 | 106309 | |
| 106231 | 106310 | assert( pX->op==TK_IN ); |
| 106232 | 106311 | mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; |
| 106312 | + if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){ | |
| 106313 | + iTab = pX->iTable; | |
| 106314 | + }else{ | |
| 106315 | + iTab = pParse->nTab++; | |
| 106316 | + } | |
| 106233 | 106317 | |
| 106234 | 106318 | /* If the RHS of this IN(...) operator is a SELECT, and if it matters |
| 106235 | 106319 | ** whether or not the SELECT result contains NULL values, check whether |
| 106236 | 106320 | ** or not NULL is actually possible (it may not be, for example, due |
| 106237 | 106321 | ** to NOT NULL constraints in the schema). If no NULL values are possible, |
| @@ -106393,10 +106477,12 @@ | ||
| 106393 | 106477 | if( eType==0 |
| 106394 | 106478 | && (inFlags & IN_INDEX_NOOP_OK) |
| 106395 | 106479 | && ExprUseXList(pX) |
| 106396 | 106480 | && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) |
| 106397 | 106481 | ){ |
| 106482 | + pParse->nTab--; /* Back out the allocation of the unused cursor */ | |
| 106483 | + iTab = -1; /* Cursor is not allocated */ | |
| 106398 | 106484 | eType = IN_INDEX_NOOP; |
| 106399 | 106485 | } |
| 106400 | 106486 | |
| 106401 | 106487 | if( eType==0 ){ |
| 106402 | 106488 | /* Could not find an existing table or index to use as the RHS b-tree. |
| @@ -106559,11 +106645,13 @@ | ||
| 106559 | 106645 | pExpr->x.pSelect->selId)); |
| 106560 | 106646 | } |
| 106561 | 106647 | assert( ExprUseYSub(pExpr) ); |
| 106562 | 106648 | sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, |
| 106563 | 106649 | pExpr->y.sub.iAddr); |
| 106564 | - sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); | |
| 106650 | + if( iTab!=pExpr->iTable ){ | |
| 106651 | + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); | |
| 106652 | + } | |
| 106565 | 106653 | sqlite3VdbeJumpHere(v, addrOnce); |
| 106566 | 106654 | return; |
| 106567 | 106655 | } |
| 106568 | 106656 | |
| 106569 | 106657 | /* Begin coding the subroutine */ |
| @@ -113002,13 +113090,18 @@ | ||
| 113002 | 113090 | ** * the index contains 100 rows, |
| 113003 | 113091 | ** * "WHERE a=?" matches 10 rows, and |
| 113004 | 113092 | ** * "WHERE a=? AND b=?" matches 2 rows. |
| 113005 | 113093 | ** |
| 113006 | 113094 | ** If D is the count of distinct values and K is the total number of |
| 113007 | - ** rows, then each estimate is computed as: | |
| 113095 | + ** rows, then each estimate is usually computed as: | |
| 113008 | 113096 | ** |
| 113009 | 113097 | ** I = (K+D-1)/D |
| 113098 | + ** | |
| 113099 | + ** In other words, I is K/D rounded up to the next whole integer. | |
| 113100 | + ** However, if I is between 1.0 and 1.1 (in other words if I is | |
| 113101 | + ** close to 1.0 but just a little larger) then do not round up but | |
| 113102 | + ** instead keep the I value at 1.0. | |
| 113010 | 113103 | */ |
| 113011 | 113104 | sqlite3_str sStat; /* Text of the constructed "stat" line */ |
| 113012 | 113105 | int i; /* Loop counter */ |
| 113013 | 113106 | |
| 113014 | 113107 | sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); |
| @@ -113015,10 +113108,11 @@ | ||
| 113015 | 113108 | sqlite3_str_appendf(&sStat, "%llu", |
| 113016 | 113109 | p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); |
| 113017 | 113110 | for(i=0; i<p->nKeyCol; i++){ |
| 113018 | 113111 | u64 nDistinct = p->current.anDLt[i] + 1; |
| 113019 | 113112 | u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 113113 | + if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; | |
| 113020 | 113114 | sqlite3_str_appendf(&sStat, " %llu", iVal); |
| 113021 | 113115 | assert( p->current.anEq[i] ); |
| 113022 | 113116 | } |
| 113023 | 113117 | sqlite3ResultStrAccum(context, &sStat); |
| 113024 | 113118 | } |
| @@ -130512,15 +130606,23 @@ | ||
| 130512 | 130606 | sqlite3_total_changes64, |
| 130513 | 130607 | /* Version 3.37.0 and later */ |
| 130514 | 130608 | sqlite3_autovacuum_pages, |
| 130515 | 130609 | /* Version 3.38.0 and later */ |
| 130516 | 130610 | sqlite3_error_offset, |
| 130611 | +#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 130517 | 130612 | sqlite3_vtab_rhs_value, |
| 130518 | 130613 | sqlite3_vtab_distinct, |
| 130519 | 130614 | sqlite3_vtab_in, |
| 130520 | 130615 | sqlite3_vtab_in_first, |
| 130521 | 130616 | sqlite3_vtab_in_next, |
| 130617 | +#else | |
| 130618 | + 0, | |
| 130619 | + 0, | |
| 130620 | + 0, | |
| 130621 | + 0, | |
| 130622 | + 0, | |
| 130623 | +#endif | |
| 130522 | 130624 | /* Version 3.39.0 and later */ |
| 130523 | 130625 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 130524 | 130626 | sqlite3_deserialize, |
| 130525 | 130627 | sqlite3_serialize |
| 130526 | 130628 | #else |
| @@ -149443,20 +149545,26 @@ | ||
| 149443 | 149545 | |
| 149444 | 149546 | iTab = 0; |
| 149445 | 149547 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ |
| 149446 | 149548 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); |
| 149447 | 149549 | }else{ |
| 149448 | - sqlite3 *db = pParse->db; | |
| 149449 | - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); | |
| 149450 | - | |
| 149451 | - if( !db->mallocFailed ){ | |
| 149550 | + Expr *pExpr = pTerm->pExpr; | |
| 149551 | + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ | |
| 149552 | + sqlite3 *db = pParse->db; | |
| 149553 | + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); | |
| 149554 | + if( !db->mallocFailed ){ | |
| 149555 | + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); | |
| 149556 | + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); | |
| 149557 | + pExpr->iTable = iTab; | |
| 149558 | + } | |
| 149559 | + sqlite3ExprDelete(db, pX); | |
| 149560 | + }else{ | |
| 149452 | 149561 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); |
| 149453 | - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); | |
| 149454 | - pTerm->pExpr->iTable = iTab; | |
| 149562 | + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab); | |
| 149563 | + iTab = pExpr->iTable; | |
| 149455 | 149564 | } |
| 149456 | - sqlite3ExprDelete(db, pX); | |
| 149457 | - pX = pTerm->pExpr; | |
| 149565 | + pX = pExpr; | |
| 149458 | 149566 | } |
| 149459 | 149567 | |
| 149460 | 149568 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 149461 | 149569 | testcase( bRev ); |
| 149462 | 149570 | bRev = !bRev; |
| @@ -150079,16 +150187,16 @@ | ||
| 150079 | 150187 | ** that contains the value of pExpr. |
| 150080 | 150188 | */ |
| 150081 | 150189 | static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ |
| 150082 | 150190 | IdxExprTrans *pX = p->u.pIdxTrans; |
| 150083 | 150191 | if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ |
| 150192 | + pExpr = sqlite3ExprSkipCollate(pExpr); | |
| 150084 | 150193 | preserveExpr(pX, pExpr); |
| 150085 | 150194 | pExpr->affExpr = sqlite3ExprAffinity(pExpr); |
| 150086 | 150195 | pExpr->op = TK_COLUMN; |
| 150087 | 150196 | pExpr->iTable = pX->iIdxCur; |
| 150088 | 150197 | pExpr->iColumn = pX->iIdxCol; |
| 150089 | - testcase( ExprHasProperty(pExpr, EP_Skip) ); | |
| 150090 | 150198 | testcase( ExprHasProperty(pExpr, EP_Unlikely) ); |
| 150091 | 150199 | ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); |
| 150092 | 150200 | pExpr->y.pTab = 0; |
| 150093 | 150201 | return WRC_Prune; |
| 150094 | 150202 | }else{ |
| @@ -150238,10 +150346,12 @@ | ||
| 150238 | 150346 | if( pLevel->regFilter==0 ) continue; |
| 150239 | 150347 | if( pLevel->pWLoop->nSkip ) continue; |
| 150240 | 150348 | /* ,--- Because sqlite3ConstructBloomFilter() has will not have set |
| 150241 | 150349 | ** vvvvv--' pLevel->regFilter if this were true. */ |
| 150242 | 150350 | if( NEVER(pLoop->prereq & notReady) ) continue; |
| 150351 | + assert( pLevel->addrBrk==0 ); | |
| 150352 | + pLevel->addrBrk = addrNxt; | |
| 150243 | 150353 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 150244 | 150354 | WhereTerm *pTerm = pLoop->aLTerm[0]; |
| 150245 | 150355 | int regRowid; |
| 150246 | 150356 | assert( pTerm!=0 ); |
| 150247 | 150357 | assert( pTerm->pExpr!=0 ); |
| @@ -150264,10 +150374,11 @@ | ||
| 150264 | 150374 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, |
| 150265 | 150375 | addrNxt, r1, nEq); |
| 150266 | 150376 | VdbeCoverage(pParse->pVdbe); |
| 150267 | 150377 | } |
| 150268 | 150378 | pLevel->regFilter = 0; |
| 150379 | + pLevel->addrBrk = 0; | |
| 150269 | 150380 | } |
| 150270 | 150381 | } |
| 150271 | 150382 | |
| 150272 | 150383 | /* |
| 150273 | 150384 | ** Generate code for the start of the iLevel-th loop in the WHERE clause |
| @@ -226807,11 +226918,11 @@ | ||
| 226807 | 226918 | /* State used by the fts5DataXXX() functions. */ |
| 226808 | 226919 | sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ |
| 226809 | 226920 | sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ |
| 226810 | 226921 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 226811 | 226922 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 226812 | - sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ | |
| 226923 | + sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ | |
| 226813 | 226924 | sqlite3_stmt *pIdxSelect; |
| 226814 | 226925 | int nRead; /* Total number of blocks read */ |
| 226815 | 226926 | |
| 226816 | 226927 | sqlite3_stmt *pDataVersion; |
| 226817 | 226928 | i64 iStructVersion; /* data_version when pStruct read */ |
| @@ -236124,11 +236235,11 @@ | ||
| 236124 | 236235 | int nArg, /* Number of args */ |
| 236125 | 236236 | sqlite3_value **apUnused /* Function arguments */ |
| 236126 | 236237 | ){ |
| 236127 | 236238 | assert( nArg==0 ); |
| 236128 | 236239 | UNUSED_PARAM2(nArg, apUnused); |
| 236129 | - sqlite3_result_text(pCtx, "fts5: 2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb", -1, SQLITE_TRANSIENT); | |
| 236240 | + sqlite3_result_text(pCtx, "fts5: 2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb", -1, SQLITE_TRANSIENT); | |
| 236130 | 236241 | } |
| 236131 | 236242 | |
| 236132 | 236243 | /* |
| 236133 | 236244 | ** Return true if zName is the extension on one of the shadow tables used |
| 236134 | 236245 | ** by this module. |
| 236135 | 236246 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -452,11 +452,11 @@ | |
| 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | */ |
| 455 | #define SQLITE_VERSION "3.39.0" |
| 456 | #define SQLITE_VERSION_NUMBER 3039000 |
| 457 | #define SQLITE_SOURCE_ID "2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb" |
| 458 | |
| 459 | /* |
| 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | ** |
| @@ -17054,10 +17054,11 @@ | |
| 17054 | #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ |
| 17055 | #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ |
| 17056 | #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ |
| 17057 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ |
| 17058 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ |
| 17059 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17060 | |
| 17061 | /* |
| 17062 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 17063 | */ |
| @@ -19732,10 +19733,11 @@ | |
| 19732 | SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); |
| 19733 | SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); |
| 19734 | SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); |
| 19735 | SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); |
| 19736 | SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); |
| 19737 | SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); |
| 19738 | SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); |
| 19739 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); |
| 19740 | SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); |
| 19741 | SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, |
| @@ -20587,10 +20589,11 @@ | |
| 20587 | ** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). |
| 20588 | */ |
| 20589 | #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ |
| 20590 | #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ |
| 20591 | #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ |
| 20592 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); |
| 20593 | |
| 20594 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 20595 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 20596 | #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ |
| @@ -31057,10 +31060,57 @@ | |
| 31057 | */ |
| 31058 | static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ |
| 31059 | sqlite3TreeViewPush(&p, moreFollows); |
| 31060 | sqlite3TreeViewLine(p, "%s", zLabel); |
| 31061 | } |
| 31062 | |
| 31063 | /* |
| 31064 | ** Generate a human-readable description of a WITH clause. |
| 31065 | */ |
| 31066 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ |
| @@ -31113,10 +31163,11 @@ | |
| 31113 | int i; |
| 31114 | if( pSrc==0 ) return; |
| 31115 | for(i=0; i<pSrc->nSrc; i++){ |
| 31116 | const SrcItem *pItem = &pSrc->a[i]; |
| 31117 | StrAccum x; |
| 31118 | char zLine[100]; |
| 31119 | sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); |
| 31120 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; |
| 31121 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); |
| 31122 | if( pItem->pTab ){ |
| @@ -31141,13 +31192,24 @@ | |
| 31141 | if( pItem->fg.isCte ){ |
| 31142 | sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); |
| 31143 | } |
| 31144 | sqlite3StrAccumFinish(&x); |
| 31145 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 31146 | if( pItem->pSelect ){ |
| 31147 | assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 31148 | sqlite3TreeViewSelect(pView, pItem->pSelect, 0); |
| 31149 | } |
| 31150 | if( pItem->fg.isTabFunc ){ |
| 31151 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| 31152 | } |
| 31153 | sqlite3TreeViewPop(&pView); |
| @@ -31310,10 +31372,11 @@ | |
| 31310 | /* |
| 31311 | ** Generate a human-readable explanation for a Window object |
| 31312 | */ |
| 31313 | SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ |
| 31314 | int nElement = 0; |
| 31315 | if( pWin->pFilter ){ |
| 31316 | sqlite3TreeViewItem(pView, "FILTER", 1); |
| 31317 | sqlite3TreeViewExpr(pView, pWin->pFilter, 0); |
| 31318 | sqlite3TreeViewPop(&pView); |
| 31319 | } |
| @@ -31374,10 +31437,11 @@ | |
| 31374 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 31375 | /* |
| 31376 | ** Generate a human-readable explanation for a Window Function object |
| 31377 | */ |
| 31378 | SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ |
| 31379 | sqlite3TreeViewPush(&pView, more); |
| 31380 | sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", |
| 31381 | pWin->pWFunc->zName, pWin->pWFunc->nArg); |
| 31382 | sqlite3TreeViewWindow(pView, pWin, 0); |
| 31383 | sqlite3TreeViewPop(&pView); |
| @@ -31625,11 +31689,21 @@ | |
| 31625 | sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); |
| 31626 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31627 | break; |
| 31628 | } |
| 31629 | case TK_IN: { |
| 31630 | sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); |
| 31631 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); |
| 31632 | if( ExprUseXSelect(pExpr) ){ |
| 31633 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31634 | }else{ |
| 31635 | sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); |
| @@ -89252,10 +89326,12 @@ | |
| 89252 | if( pOp->p2==0 ) break; |
| 89253 | |
| 89254 | /* Most jump operations do a goto to this spot in order to update |
| 89255 | ** the pOp pointer. */ |
| 89256 | jump_to_p2: |
| 89257 | pOp = &aOp[pOp->p2 - 1]; |
| 89258 | break; |
| 89259 | } |
| 89260 | |
| 89261 | /* Opcode: EndCoroutine P1 * * * * |
| @@ -105782,11 +105858,11 @@ | |
| 105782 | |
| 105783 | /* |
| 105784 | ** Check pExpr to see if it is an invariant constraint on data source pSrc. |
| 105785 | ** This is an optimization. False negatives will perhaps cause slower |
| 105786 | ** queries, but false positives will yield incorrect answers. So when in |
| 105787 | ** double, return 0. |
| 105788 | ** |
| 105789 | ** To be an invariant constraint, the following must be true: |
| 105790 | ** |
| 105791 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. |
| 105792 | ** |
| @@ -106141,11 +106217,11 @@ | |
| 106141 | ** The job of this routine is to find or create a b-tree object that can |
| 106142 | ** be used either to test for membership in the RHS set or to iterate through |
| 106143 | ** all members of the RHS set, skipping duplicates. |
| 106144 | ** |
| 106145 | ** A cursor is opened on the b-tree object that is the RHS of the IN operator |
| 106146 | ** and pX->iTable is set to the index of that cursor. |
| 106147 | ** |
| 106148 | ** The returned value of this function indicates the b-tree type, as follows: |
| 106149 | ** |
| 106150 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 106151 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| @@ -106161,11 +106237,14 @@ | |
| 106161 | ** SELECT <column1>, <column2>... FROM <table> |
| 106162 | ** |
| 106163 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 106164 | ** an ephemeral table might need to be generated from the RHS and then |
| 106165 | ** pX->iTable made to point to the ephemeral table instead of an |
| 106166 | ** existing table. |
| 106167 | ** |
| 106168 | ** The inFlags parameter must contain, at a minimum, one of the bits |
| 106169 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains |
| 106170 | ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast |
| 106171 | ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will |
| @@ -106222,16 +106301,21 @@ | |
| 106222 | int *aiMap, /* Mapping from Index fields to RHS fields */ |
| 106223 | int *piTab /* OUT: index to use */ |
| 106224 | ){ |
| 106225 | Select *p; /* SELECT to the right of IN operator */ |
| 106226 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 106227 | int iTab = pParse->nTab++; /* Cursor of the RHS table */ |
| 106228 | int mustBeUnique; /* True if RHS must be unique */ |
| 106229 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 106230 | |
| 106231 | assert( pX->op==TK_IN ); |
| 106232 | mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; |
| 106233 | |
| 106234 | /* If the RHS of this IN(...) operator is a SELECT, and if it matters |
| 106235 | ** whether or not the SELECT result contains NULL values, check whether |
| 106236 | ** or not NULL is actually possible (it may not be, for example, due |
| 106237 | ** to NOT NULL constraints in the schema). If no NULL values are possible, |
| @@ -106393,10 +106477,12 @@ | |
| 106393 | if( eType==0 |
| 106394 | && (inFlags & IN_INDEX_NOOP_OK) |
| 106395 | && ExprUseXList(pX) |
| 106396 | && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) |
| 106397 | ){ |
| 106398 | eType = IN_INDEX_NOOP; |
| 106399 | } |
| 106400 | |
| 106401 | if( eType==0 ){ |
| 106402 | /* Could not find an existing table or index to use as the RHS b-tree. |
| @@ -106559,11 +106645,13 @@ | |
| 106559 | pExpr->x.pSelect->selId)); |
| 106560 | } |
| 106561 | assert( ExprUseYSub(pExpr) ); |
| 106562 | sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, |
| 106563 | pExpr->y.sub.iAddr); |
| 106564 | sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); |
| 106565 | sqlite3VdbeJumpHere(v, addrOnce); |
| 106566 | return; |
| 106567 | } |
| 106568 | |
| 106569 | /* Begin coding the subroutine */ |
| @@ -113002,13 +113090,18 @@ | |
| 113002 | ** * the index contains 100 rows, |
| 113003 | ** * "WHERE a=?" matches 10 rows, and |
| 113004 | ** * "WHERE a=? AND b=?" matches 2 rows. |
| 113005 | ** |
| 113006 | ** If D is the count of distinct values and K is the total number of |
| 113007 | ** rows, then each estimate is computed as: |
| 113008 | ** |
| 113009 | ** I = (K+D-1)/D |
| 113010 | */ |
| 113011 | sqlite3_str sStat; /* Text of the constructed "stat" line */ |
| 113012 | int i; /* Loop counter */ |
| 113013 | |
| 113014 | sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); |
| @@ -113015,10 +113108,11 @@ | |
| 113015 | sqlite3_str_appendf(&sStat, "%llu", |
| 113016 | p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); |
| 113017 | for(i=0; i<p->nKeyCol; i++){ |
| 113018 | u64 nDistinct = p->current.anDLt[i] + 1; |
| 113019 | u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 113020 | sqlite3_str_appendf(&sStat, " %llu", iVal); |
| 113021 | assert( p->current.anEq[i] ); |
| 113022 | } |
| 113023 | sqlite3ResultStrAccum(context, &sStat); |
| 113024 | } |
| @@ -130512,15 +130606,23 @@ | |
| 130512 | sqlite3_total_changes64, |
| 130513 | /* Version 3.37.0 and later */ |
| 130514 | sqlite3_autovacuum_pages, |
| 130515 | /* Version 3.38.0 and later */ |
| 130516 | sqlite3_error_offset, |
| 130517 | sqlite3_vtab_rhs_value, |
| 130518 | sqlite3_vtab_distinct, |
| 130519 | sqlite3_vtab_in, |
| 130520 | sqlite3_vtab_in_first, |
| 130521 | sqlite3_vtab_in_next, |
| 130522 | /* Version 3.39.0 and later */ |
| 130523 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 130524 | sqlite3_deserialize, |
| 130525 | sqlite3_serialize |
| 130526 | #else |
| @@ -149443,20 +149545,26 @@ | |
| 149443 | |
| 149444 | iTab = 0; |
| 149445 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ |
| 149446 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); |
| 149447 | }else{ |
| 149448 | sqlite3 *db = pParse->db; |
| 149449 | pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); |
| 149450 | |
| 149451 | if( !db->mallocFailed ){ |
| 149452 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); |
| 149453 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); |
| 149454 | pTerm->pExpr->iTable = iTab; |
| 149455 | } |
| 149456 | sqlite3ExprDelete(db, pX); |
| 149457 | pX = pTerm->pExpr; |
| 149458 | } |
| 149459 | |
| 149460 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 149461 | testcase( bRev ); |
| 149462 | bRev = !bRev; |
| @@ -150079,16 +150187,16 @@ | |
| 150079 | ** that contains the value of pExpr. |
| 150080 | */ |
| 150081 | static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ |
| 150082 | IdxExprTrans *pX = p->u.pIdxTrans; |
| 150083 | if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ |
| 150084 | preserveExpr(pX, pExpr); |
| 150085 | pExpr->affExpr = sqlite3ExprAffinity(pExpr); |
| 150086 | pExpr->op = TK_COLUMN; |
| 150087 | pExpr->iTable = pX->iIdxCur; |
| 150088 | pExpr->iColumn = pX->iIdxCol; |
| 150089 | testcase( ExprHasProperty(pExpr, EP_Skip) ); |
| 150090 | testcase( ExprHasProperty(pExpr, EP_Unlikely) ); |
| 150091 | ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); |
| 150092 | pExpr->y.pTab = 0; |
| 150093 | return WRC_Prune; |
| 150094 | }else{ |
| @@ -150238,10 +150346,12 @@ | |
| 150238 | if( pLevel->regFilter==0 ) continue; |
| 150239 | if( pLevel->pWLoop->nSkip ) continue; |
| 150240 | /* ,--- Because sqlite3ConstructBloomFilter() has will not have set |
| 150241 | ** vvvvv--' pLevel->regFilter if this were true. */ |
| 150242 | if( NEVER(pLoop->prereq & notReady) ) continue; |
| 150243 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 150244 | WhereTerm *pTerm = pLoop->aLTerm[0]; |
| 150245 | int regRowid; |
| 150246 | assert( pTerm!=0 ); |
| 150247 | assert( pTerm->pExpr!=0 ); |
| @@ -150264,10 +150374,11 @@ | |
| 150264 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, |
| 150265 | addrNxt, r1, nEq); |
| 150266 | VdbeCoverage(pParse->pVdbe); |
| 150267 | } |
| 150268 | pLevel->regFilter = 0; |
| 150269 | } |
| 150270 | } |
| 150271 | |
| 150272 | /* |
| 150273 | ** Generate code for the start of the iLevel-th loop in the WHERE clause |
| @@ -226807,11 +226918,11 @@ | |
| 226807 | /* State used by the fts5DataXXX() functions. */ |
| 226808 | sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ |
| 226809 | sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ |
| 226810 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 226811 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 226812 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ |
| 226813 | sqlite3_stmt *pIdxSelect; |
| 226814 | int nRead; /* Total number of blocks read */ |
| 226815 | |
| 226816 | sqlite3_stmt *pDataVersion; |
| 226817 | i64 iStructVersion; /* data_version when pStruct read */ |
| @@ -236124,11 +236235,11 @@ | |
| 236124 | int nArg, /* Number of args */ |
| 236125 | sqlite3_value **apUnused /* Function arguments */ |
| 236126 | ){ |
| 236127 | assert( nArg==0 ); |
| 236128 | UNUSED_PARAM2(nArg, apUnused); |
| 236129 | sqlite3_result_text(pCtx, "fts5: 2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb", -1, SQLITE_TRANSIENT); |
| 236130 | } |
| 236131 | |
| 236132 | /* |
| 236133 | ** Return true if zName is the extension on one of the shadow tables used |
| 236134 | ** by this module. |
| 236135 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -452,11 +452,11 @@ | |
| 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | */ |
| 455 | #define SQLITE_VERSION "3.39.0" |
| 456 | #define SQLITE_VERSION_NUMBER 3039000 |
| 457 | #define SQLITE_SOURCE_ID "2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb" |
| 458 | |
| 459 | /* |
| 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | ** |
| @@ -17054,10 +17054,11 @@ | |
| 17054 | #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ |
| 17055 | #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ |
| 17056 | #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ |
| 17057 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ |
| 17058 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ |
| 17059 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ |
| 17060 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17061 | |
| 17062 | /* |
| 17063 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 17064 | */ |
| @@ -19732,10 +19733,11 @@ | |
| 19733 | SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); |
| 19734 | SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); |
| 19735 | SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); |
| 19736 | SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); |
| 19737 | SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); |
| 19738 | SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); |
| 19739 | SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); |
| 19740 | SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); |
| 19741 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); |
| 19742 | SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); |
| 19743 | SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, |
| @@ -20587,10 +20589,11 @@ | |
| 20589 | ** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). |
| 20590 | */ |
| 20591 | #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ |
| 20592 | #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ |
| 20593 | #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ |
| 20594 | #define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */ |
| 20595 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); |
| 20596 | |
| 20597 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 20598 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 20599 | #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ |
| @@ -31057,10 +31060,57 @@ | |
| 31060 | */ |
| 31061 | static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ |
| 31062 | sqlite3TreeViewPush(&p, moreFollows); |
| 31063 | sqlite3TreeViewLine(p, "%s", zLabel); |
| 31064 | } |
| 31065 | |
| 31066 | /* |
| 31067 | ** Show a list of Column objects in tree format. |
| 31068 | */ |
| 31069 | SQLITE_PRIVATE void sqlite3TreeViewColumnList( |
| 31070 | TreeView *pView, |
| 31071 | const Column *aCol, |
| 31072 | int nCol, |
| 31073 | u8 moreToFollow |
| 31074 | ){ |
| 31075 | int i; |
| 31076 | sqlite3TreeViewPush(&pView, moreToFollow); |
| 31077 | sqlite3TreeViewLine(pView, "COLUMNS"); |
| 31078 | for(i=0; i<nCol; i++){ |
| 31079 | u16 flg = aCol[i].colFlags; |
| 31080 | int moreToFollow = i<(nCol - 1); |
| 31081 | sqlite3TreeViewPush(&pView, moreToFollow); |
| 31082 | sqlite3TreeViewLine(pView, 0); |
| 31083 | printf(" %s", aCol[i].zCnName); |
| 31084 | switch( aCol[i].eCType ){ |
| 31085 | case COLTYPE_ANY: printf(" ANY"); break; |
| 31086 | case COLTYPE_BLOB: printf(" BLOB"); break; |
| 31087 | case COLTYPE_INT: printf(" INT"); break; |
| 31088 | case COLTYPE_INTEGER: printf(" INTEGER"); break; |
| 31089 | case COLTYPE_REAL: printf(" REAL"); break; |
| 31090 | case COLTYPE_TEXT: printf(" TEXT"); break; |
| 31091 | case COLTYPE_CUSTOM: { |
| 31092 | if( flg & COLFLAG_HASTYPE ){ |
| 31093 | const char *z = aCol[i].zCnName; |
| 31094 | z += strlen(z)+1; |
| 31095 | printf(" X-%s", z); |
| 31096 | break; |
| 31097 | } |
| 31098 | } |
| 31099 | } |
| 31100 | if( flg & COLFLAG_PRIMKEY ) printf(" PRIMARY KEY"); |
| 31101 | if( flg & COLFLAG_HIDDEN ) printf(" HIDDEN"); |
| 31102 | #ifdef COLFLAG_NOEXPAND |
| 31103 | if( flg & COLFLAG_NOEXPAND ) printf(" NO-EXPAND"); |
| 31104 | #endif |
| 31105 | if( flg ) printf(" flags=%04x", flg); |
| 31106 | printf("\n"); |
| 31107 | fflush(stdout); |
| 31108 | sqlite3TreeViewPop(&pView); |
| 31109 | } |
| 31110 | sqlite3TreeViewPop(&pView); |
| 31111 | } |
| 31112 | |
| 31113 | /* |
| 31114 | ** Generate a human-readable description of a WITH clause. |
| 31115 | */ |
| 31116 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ |
| @@ -31113,10 +31163,11 @@ | |
| 31163 | int i; |
| 31164 | if( pSrc==0 ) return; |
| 31165 | for(i=0; i<pSrc->nSrc; i++){ |
| 31166 | const SrcItem *pItem = &pSrc->a[i]; |
| 31167 | StrAccum x; |
| 31168 | int n = 0; |
| 31169 | char zLine[100]; |
| 31170 | sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); |
| 31171 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; |
| 31172 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); |
| 31173 | if( pItem->pTab ){ |
| @@ -31141,13 +31192,24 @@ | |
| 31192 | if( pItem->fg.isCte ){ |
| 31193 | sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); |
| 31194 | } |
| 31195 | sqlite3StrAccumFinish(&x); |
| 31196 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 31197 | n = 0; |
| 31198 | if( pItem->pSelect ) n++; |
| 31199 | if( pItem->fg.isTabFunc ) n++; |
| 31200 | if( pItem->fg.isUsing ) n++; |
| 31201 | if( pItem->fg.isUsing ){ |
| 31202 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); |
| 31203 | } |
| 31204 | if( pItem->pSelect ){ |
| 31205 | if( pItem->pTab ){ |
| 31206 | Table *pTab = pItem->pTab; |
| 31207 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); |
| 31208 | } |
| 31209 | assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 31210 | sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); |
| 31211 | } |
| 31212 | if( pItem->fg.isTabFunc ){ |
| 31213 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| 31214 | } |
| 31215 | sqlite3TreeViewPop(&pView); |
| @@ -31310,10 +31372,11 @@ | |
| 31372 | /* |
| 31373 | ** Generate a human-readable explanation for a Window object |
| 31374 | */ |
| 31375 | SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ |
| 31376 | int nElement = 0; |
| 31377 | if( pWin==0 ) return; |
| 31378 | if( pWin->pFilter ){ |
| 31379 | sqlite3TreeViewItem(pView, "FILTER", 1); |
| 31380 | sqlite3TreeViewExpr(pView, pWin->pFilter, 0); |
| 31381 | sqlite3TreeViewPop(&pView); |
| 31382 | } |
| @@ -31374,10 +31437,11 @@ | |
| 31437 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 31438 | /* |
| 31439 | ** Generate a human-readable explanation for a Window Function object |
| 31440 | */ |
| 31441 | SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ |
| 31442 | if( pWin==0 ) return; |
| 31443 | sqlite3TreeViewPush(&pView, more); |
| 31444 | sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", |
| 31445 | pWin->pWFunc->zName, pWin->pWFunc->nArg); |
| 31446 | sqlite3TreeViewWindow(pView, pWin, 0); |
| 31447 | sqlite3TreeViewPop(&pView); |
| @@ -31625,11 +31689,21 @@ | |
| 31689 | sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); |
| 31690 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31691 | break; |
| 31692 | } |
| 31693 | case TK_IN: { |
| 31694 | sqlite3_str *pStr = sqlite3_str_new(0); |
| 31695 | char *z; |
| 31696 | sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); |
| 31697 | if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); |
| 31698 | if( ExprHasProperty(pExpr, EP_Subrtn) ){ |
| 31699 | sqlite3_str_appendf(pStr, " subrtn(%d,%d)", |
| 31700 | pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); |
| 31701 | } |
| 31702 | z = sqlite3_str_finish(pStr); |
| 31703 | sqlite3TreeViewLine(pView, z); |
| 31704 | sqlite3_free(z); |
| 31705 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); |
| 31706 | if( ExprUseXSelect(pExpr) ){ |
| 31707 | sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); |
| 31708 | }else{ |
| 31709 | sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); |
| @@ -89252,10 +89326,12 @@ | |
| 89326 | if( pOp->p2==0 ) break; |
| 89327 | |
| 89328 | /* Most jump operations do a goto to this spot in order to update |
| 89329 | ** the pOp pointer. */ |
| 89330 | jump_to_p2: |
| 89331 | assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ |
| 89332 | assert( pOp->p2<p->nOp ); /* Jumps must be in range */ |
| 89333 | pOp = &aOp[pOp->p2 - 1]; |
| 89334 | break; |
| 89335 | } |
| 89336 | |
| 89337 | /* Opcode: EndCoroutine P1 * * * * |
| @@ -105782,11 +105858,11 @@ | |
| 105858 | |
| 105859 | /* |
| 105860 | ** Check pExpr to see if it is an invariant constraint on data source pSrc. |
| 105861 | ** This is an optimization. False negatives will perhaps cause slower |
| 105862 | ** queries, but false positives will yield incorrect answers. So when in |
| 105863 | ** doubt, return 0. |
| 105864 | ** |
| 105865 | ** To be an invariant constraint, the following must be true: |
| 105866 | ** |
| 105867 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. |
| 105868 | ** |
| @@ -106141,11 +106217,11 @@ | |
| 106217 | ** The job of this routine is to find or create a b-tree object that can |
| 106218 | ** be used either to test for membership in the RHS set or to iterate through |
| 106219 | ** all members of the RHS set, skipping duplicates. |
| 106220 | ** |
| 106221 | ** A cursor is opened on the b-tree object that is the RHS of the IN operator |
| 106222 | ** and the *piTab parameter is set to the index of that cursor. |
| 106223 | ** |
| 106224 | ** The returned value of this function indicates the b-tree type, as follows: |
| 106225 | ** |
| 106226 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 106227 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| @@ -106161,11 +106237,14 @@ | |
| 106237 | ** SELECT <column1>, <column2>... FROM <table> |
| 106238 | ** |
| 106239 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 106240 | ** an ephemeral table might need to be generated from the RHS and then |
| 106241 | ** pX->iTable made to point to the ephemeral table instead of an |
| 106242 | ** existing table. In this case, the creation and initialization of the |
| 106243 | ** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag |
| 106244 | ** will be set on pX and the pX->y.sub fields will be set to show where |
| 106245 | ** the subroutine is coded. |
| 106246 | ** |
| 106247 | ** The inFlags parameter must contain, at a minimum, one of the bits |
| 106248 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains |
| 106249 | ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast |
| 106250 | ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will |
| @@ -106222,16 +106301,21 @@ | |
| 106301 | int *aiMap, /* Mapping from Index fields to RHS fields */ |
| 106302 | int *piTab /* OUT: index to use */ |
| 106303 | ){ |
| 106304 | Select *p; /* SELECT to the right of IN operator */ |
| 106305 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 106306 | int iTab; /* Cursor of the RHS table */ |
| 106307 | int mustBeUnique; /* True if RHS must be unique */ |
| 106308 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 106309 | |
| 106310 | assert( pX->op==TK_IN ); |
| 106311 | mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; |
| 106312 | if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){ |
| 106313 | iTab = pX->iTable; |
| 106314 | }else{ |
| 106315 | iTab = pParse->nTab++; |
| 106316 | } |
| 106317 | |
| 106318 | /* If the RHS of this IN(...) operator is a SELECT, and if it matters |
| 106319 | ** whether or not the SELECT result contains NULL values, check whether |
| 106320 | ** or not NULL is actually possible (it may not be, for example, due |
| 106321 | ** to NOT NULL constraints in the schema). If no NULL values are possible, |
| @@ -106393,10 +106477,12 @@ | |
| 106477 | if( eType==0 |
| 106478 | && (inFlags & IN_INDEX_NOOP_OK) |
| 106479 | && ExprUseXList(pX) |
| 106480 | && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) |
| 106481 | ){ |
| 106482 | pParse->nTab--; /* Back out the allocation of the unused cursor */ |
| 106483 | iTab = -1; /* Cursor is not allocated */ |
| 106484 | eType = IN_INDEX_NOOP; |
| 106485 | } |
| 106486 | |
| 106487 | if( eType==0 ){ |
| 106488 | /* Could not find an existing table or index to use as the RHS b-tree. |
| @@ -106559,11 +106645,13 @@ | |
| 106645 | pExpr->x.pSelect->selId)); |
| 106646 | } |
| 106647 | assert( ExprUseYSub(pExpr) ); |
| 106648 | sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, |
| 106649 | pExpr->y.sub.iAddr); |
| 106650 | if( iTab!=pExpr->iTable ){ |
| 106651 | sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); |
| 106652 | } |
| 106653 | sqlite3VdbeJumpHere(v, addrOnce); |
| 106654 | return; |
| 106655 | } |
| 106656 | |
| 106657 | /* Begin coding the subroutine */ |
| @@ -113002,13 +113090,18 @@ | |
| 113090 | ** * the index contains 100 rows, |
| 113091 | ** * "WHERE a=?" matches 10 rows, and |
| 113092 | ** * "WHERE a=? AND b=?" matches 2 rows. |
| 113093 | ** |
| 113094 | ** If D is the count of distinct values and K is the total number of |
| 113095 | ** rows, then each estimate is usually computed as: |
| 113096 | ** |
| 113097 | ** I = (K+D-1)/D |
| 113098 | ** |
| 113099 | ** In other words, I is K/D rounded up to the next whole integer. |
| 113100 | ** However, if I is between 1.0 and 1.1 (in other words if I is |
| 113101 | ** close to 1.0 but just a little larger) then do not round up but |
| 113102 | ** instead keep the I value at 1.0. |
| 113103 | */ |
| 113104 | sqlite3_str sStat; /* Text of the constructed "stat" line */ |
| 113105 | int i; /* Loop counter */ |
| 113106 | |
| 113107 | sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); |
| @@ -113015,10 +113108,11 @@ | |
| 113108 | sqlite3_str_appendf(&sStat, "%llu", |
| 113109 | p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); |
| 113110 | for(i=0; i<p->nKeyCol; i++){ |
| 113111 | u64 nDistinct = p->current.anDLt[i] + 1; |
| 113112 | u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 113113 | if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; |
| 113114 | sqlite3_str_appendf(&sStat, " %llu", iVal); |
| 113115 | assert( p->current.anEq[i] ); |
| 113116 | } |
| 113117 | sqlite3ResultStrAccum(context, &sStat); |
| 113118 | } |
| @@ -130512,15 +130606,23 @@ | |
| 130606 | sqlite3_total_changes64, |
| 130607 | /* Version 3.37.0 and later */ |
| 130608 | sqlite3_autovacuum_pages, |
| 130609 | /* Version 3.38.0 and later */ |
| 130610 | sqlite3_error_offset, |
| 130611 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 130612 | sqlite3_vtab_rhs_value, |
| 130613 | sqlite3_vtab_distinct, |
| 130614 | sqlite3_vtab_in, |
| 130615 | sqlite3_vtab_in_first, |
| 130616 | sqlite3_vtab_in_next, |
| 130617 | #else |
| 130618 | 0, |
| 130619 | 0, |
| 130620 | 0, |
| 130621 | 0, |
| 130622 | 0, |
| 130623 | #endif |
| 130624 | /* Version 3.39.0 and later */ |
| 130625 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 130626 | sqlite3_deserialize, |
| 130627 | sqlite3_serialize |
| 130628 | #else |
| @@ -149443,20 +149545,26 @@ | |
| 149545 | |
| 149546 | iTab = 0; |
| 149547 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ |
| 149548 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); |
| 149549 | }else{ |
| 149550 | Expr *pExpr = pTerm->pExpr; |
| 149551 | if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ |
| 149552 | sqlite3 *db = pParse->db; |
| 149553 | pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); |
| 149554 | if( !db->mallocFailed ){ |
| 149555 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); |
| 149556 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); |
| 149557 | pExpr->iTable = iTab; |
| 149558 | } |
| 149559 | sqlite3ExprDelete(db, pX); |
| 149560 | }else{ |
| 149561 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); |
| 149562 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab); |
| 149563 | iTab = pExpr->iTable; |
| 149564 | } |
| 149565 | pX = pExpr; |
| 149566 | } |
| 149567 | |
| 149568 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 149569 | testcase( bRev ); |
| 149570 | bRev = !bRev; |
| @@ -150079,16 +150187,16 @@ | |
| 150187 | ** that contains the value of pExpr. |
| 150188 | */ |
| 150189 | static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ |
| 150190 | IdxExprTrans *pX = p->u.pIdxTrans; |
| 150191 | if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ |
| 150192 | pExpr = sqlite3ExprSkipCollate(pExpr); |
| 150193 | preserveExpr(pX, pExpr); |
| 150194 | pExpr->affExpr = sqlite3ExprAffinity(pExpr); |
| 150195 | pExpr->op = TK_COLUMN; |
| 150196 | pExpr->iTable = pX->iIdxCur; |
| 150197 | pExpr->iColumn = pX->iIdxCol; |
| 150198 | testcase( ExprHasProperty(pExpr, EP_Unlikely) ); |
| 150199 | ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); |
| 150200 | pExpr->y.pTab = 0; |
| 150201 | return WRC_Prune; |
| 150202 | }else{ |
| @@ -150238,10 +150346,12 @@ | |
| 150346 | if( pLevel->regFilter==0 ) continue; |
| 150347 | if( pLevel->pWLoop->nSkip ) continue; |
| 150348 | /* ,--- Because sqlite3ConstructBloomFilter() has will not have set |
| 150349 | ** vvvvv--' pLevel->regFilter if this were true. */ |
| 150350 | if( NEVER(pLoop->prereq & notReady) ) continue; |
| 150351 | assert( pLevel->addrBrk==0 ); |
| 150352 | pLevel->addrBrk = addrNxt; |
| 150353 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 150354 | WhereTerm *pTerm = pLoop->aLTerm[0]; |
| 150355 | int regRowid; |
| 150356 | assert( pTerm!=0 ); |
| 150357 | assert( pTerm->pExpr!=0 ); |
| @@ -150264,10 +150374,11 @@ | |
| 150374 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, |
| 150375 | addrNxt, r1, nEq); |
| 150376 | VdbeCoverage(pParse->pVdbe); |
| 150377 | } |
| 150378 | pLevel->regFilter = 0; |
| 150379 | pLevel->addrBrk = 0; |
| 150380 | } |
| 150381 | } |
| 150382 | |
| 150383 | /* |
| 150384 | ** Generate code for the start of the iLevel-th loop in the WHERE clause |
| @@ -226807,11 +226918,11 @@ | |
| 226918 | /* State used by the fts5DataXXX() functions. */ |
| 226919 | sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ |
| 226920 | sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ |
| 226921 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 226922 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 226923 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ |
| 226924 | sqlite3_stmt *pIdxSelect; |
| 226925 | int nRead; /* Total number of blocks read */ |
| 226926 | |
| 226927 | sqlite3_stmt *pDataVersion; |
| 226928 | i64 iStructVersion; /* data_version when pStruct read */ |
| @@ -236124,11 +236235,11 @@ | |
| 236235 | int nArg, /* Number of args */ |
| 236236 | sqlite3_value **apUnused /* Function arguments */ |
| 236237 | ){ |
| 236238 | assert( nArg==0 ); |
| 236239 | UNUSED_PARAM2(nArg, apUnused); |
| 236240 | sqlite3_result_text(pCtx, "fts5: 2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb", -1, SQLITE_TRANSIENT); |
| 236241 | } |
| 236242 | |
| 236243 | /* |
| 236244 | ** Return true if zName is the extension on one of the shadow tables used |
| 236245 | ** by this module. |
| 236246 |
+1
-1
| --- extsrc/sqlite3.h | ||
| +++ extsrc/sqlite3.h | ||
| @@ -146,11 +146,11 @@ | ||
| 146 | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | 148 | */ |
| 149 | 149 | #define SQLITE_VERSION "3.39.0" |
| 150 | 150 | #define SQLITE_VERSION_NUMBER 3039000 |
| 151 | -#define SQLITE_SOURCE_ID "2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb" | |
| 151 | +#define SQLITE_SOURCE_ID "2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb" | |
| 152 | 152 | |
| 153 | 153 | /* |
| 154 | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | 156 | ** |
| 157 | 157 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -146,11 +146,11 @@ | |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.39.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3039000 |
| 151 | #define SQLITE_SOURCE_ID "2022-04-26 19:16:11 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| 157 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -146,11 +146,11 @@ | |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.39.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3039000 |
| 151 | #define SQLITE_SOURCE_ID "2022-05-03 14:01:48 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| 157 |