After opening a non-covering index cursor, pass the corresponding table cursor to the implementation via sqlite3BtreeCursorHint().

FossilOrigin-Name: d48c6d2dcd50128f35bba8931371e708d24b63f2ea7a5988af8864d18ef5d14e
This commit is contained in:
dan committed 2026-06-16 18:06:46 +00:00
1 parent 9fb225190c
commit 544b208113
10 files changed
+83 -30

No files matched your search

+16 -13
View File
@@ -1,5 +1,5 @@
C Limit\sVIEW\srecursion\sdepth\sto\sSQLITE_LIMIT_EXPR_DEPTH\sto\sprevent\s\nstatic\soverflow\sin\smalicious\sschemas\swith\stens\sof\sthousands\sof\nlevels\sof\srecursive\sviews.\n[bugs:/info/2026-06-16T04:21:51Z|Bug\s2026-06-16T04:21:51Z]
D 2026-06-16T13:43:08.110
C After\sopening\sa\snon-covering\sindex\scursor,\spass\sthe\scorresponding\stable\scursor\sto\sthe\simplementation\svia\ssqlite3BtreeCursorHint().
D 2026-06-16T18:06:46.153
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -677,9 +677,9 @@ F src/auth.c b5ece4e1edccad082c0332fa0087df225473bae0feea9269f824312201377185
F src/backup.c 6ebe22ccbedfcb92423833992130e8d65824be4e6599c3a03f540ab38fc7d13c
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
F src/btree.c c9b13797b0b68e0c057ec796976b1ab1e8b4e766d1a7c7f919b2d8a1d2193a80
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
F src/btree.c 515cf62220ceb483ba9a31ebb3d7565ea9d63ffc3d61bb974b2815fef393df0e
F src/btree.h 2886ff5e136ed6472edc77515896892e3f9105436f191d95320a15d967ac4889
F src/btreeInt.h 4f512ad31083216b6789762d4c345b73367985d3b39421c9ba7c0902d09fb38b
F src/build.c 866e584cdf40fbc83f530af9fd4d0991582a6fdbd8a9911b7cdbbea5f26a4a9e
F src/callback.c 3605bbf02bd7ed46c79cd48346db4a32fc51d67624400539c0532f4eead804ad
F src/carray.c 3efe3982d5fb323334c29328a4e189ccaef6b95612a6084ad5fa124fd5db1179
@@ -804,7 +804,7 @@ F src/upsert.c dd9f0fcccbfb4f20e1026a21a7254ba3f2c08e9cfa92affaff5b5ec3b00ea549
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
F src/util.c 98cf12c8ba65623a76c1eb6e6afa98ff40107c9919bf79af42f4bfc70e654232
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
F src/vdbe.c 39658ee12b9d6bf5fc546e1ede20b307d86d9e988ae709c9b461249a8312513d
F src/vdbe.c 6397694fa506aa1841dc8bb6a17c514aa602a4ad2515024fcd5880558c1ef57f
F src/vdbe.h 70e862ac8a11b590f8c1eaac17a0078429d42bc4ea3f757a9af0f451dd966a71
F src/vdbeInt.h c31ba4dc8d280c2b1dc89c6fcee68f2555e3813ab34279552c20b964c0e338b1
F src/vdbeapi.c 6cdcbe5c7afa754c998e73d2d5d2805556268362914b952811bdfb9c78a37cf1
@@ -819,7 +819,7 @@ F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
F src/wal.c abfd99239725a258af4f733681b24dd7a9ee298babe389a36d29c197e2443ebf
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 33e4a6558ee69f33d6a4e7069e3a40a55959d14e5653a9a83926e70305d471f3
F src/where.c e76636ee3a58a3fc84e6a0362c69dd61234c24a77cfc9219b8db8cc2278ae5b7
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
F src/wherecode.c bc39ccbe3648f01157038b16cc55bdbff128590972b7185521b5526dc2815765
F src/whereexpr.c a1e22cf9f6cb59770d9652c757dcf1924078ad2d48a9da89e254be9327677465
@@ -1031,8 +1031,8 @@ F test/createtab.test 85cdfdae5c3de331cd888d6c66e1aba575b47c2e3c3cc4a1d6f5414069
F test/cse.test 00b3aea44b16828833c94fbe92475fd6977583fcb064ae0bc590986812b38d0c
F test/csv01.test 96bc1634961682363a7b4ad5c0e38450e6e9743b38ac626422e1b56cbdc06cd8
F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c4773
F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/cursorhint.test d8b93ac48dfdb2cf4284142710d63e860b6497afff2e9c525daf752a229e5b97
F test/cursorhint2.test a10f29c0c52d4d73c19cf639f3c33cccbf5024bcf950fa48f2a8cdc14628b985
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 328ed63091d34c8a6e8dcec4f999a031ce310f24395b8f0f67f07eaf36cbfd1f
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
@@ -2208,8 +2208,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P 0b72246732fecd7909add28f2d95f1727e1c4dc6c8f3b8e6e3482f6d17c92d34
R 0aa2d61f35a87c7a58d6909964314503
U drh
Z 423360f46549491b114d6ada047fd081
P 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06
R 237ea409b5f47403026e3eec6a17c3ca
T *branch * cursor-hint-tblcsr
T *sym-cursor-hint-tblcsr *
T -sym-trunk *
U dan
Z 8b75c7202ab01c7d8eacb5d6b04a0202
# Remove this line to create a well-formed Fossil manifest.
+2 -2
View File
@@ -1,2 +1,2 @@
branch trunk
tag trunk
branch cursor-hint-tblcsr
tag cursor-hint-tblcsr
+1 -1
View File
@@ -1 +1 @@
3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06
d48c6d2dcd50128f35bba8931371e708d24b63f2ea7a5988af8864d18ef5d14e
+21 -4
View File
@@ -1005,24 +1005,41 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
/* Used only by system that substitute their own storage engine */
#ifdef SQLITE_DEBUG
if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){
va_list ap;
va_list ap;
va_start(ap, eHintType);
if( eHintType==BTREE_HINT_RANGE ){
Expr *pExpr;
Walker w;
memset(&w, 0, sizeof(w));
w.xExprCallback = sqlite3CursorRangeHintExprCheck;
va_start(ap, eHintType);
pExpr = va_arg(ap, Expr*);
w.u.aMem = va_arg(ap, Mem*);
va_end(ap);
assert( pExpr!=0 );
assert( w.u.aMem!=0 );
sqlite3WalkExpr(&w, pExpr);
}else if( ALWAYS(eHintType==BTREE_HINT_TABLECURSOR) ){
BtCursor *pCsr = va_arg(ap, BtCursor*);
assert( pCur->pCursorHintTableCursor==0
|| pCur->pCursorHintTableCursor==pCsr
);
assert( pCsr->pKeyInfo==0 || CORRUPT_DB );
pCur->pCursorHintTableCursor = pCsr;
}
va_end(ap);
#endif /* SQLITE_DEBUG */
}
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
/*
** Return the pointer configured via the BTREE_HINT_TABLECURSOR hint on
** cursor pCsr. This is used from OP_DeferredSeek to assert() that the
** index cursor has been correctly configured with the table cursor.
*/
BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor *pCsr){
return pCsr->pCursorHintTableCursor;
}
#endif
/*
** Provide flag hints to the cursor.
+4
View File
@@ -188,6 +188,7 @@ int sqlite3BtreeNewDb(Btree *p);
** engine.
*/
#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
#define BTREE_HINT_TABLECURSOR 1 /* Table csr associated with this index csr */
/*
** Values that may be OR'd together to form the argument to the
@@ -247,6 +248,9 @@ void sqlite3BtreeCursorZero(BtCursor*);
void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
void sqlite3BtreeCursorHint(BtCursor*, int, ...);
#ifdef SQLITE_DEBUG
BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor*);
#endif
#endif
int sqlite3BtreeCloseCursor(BtCursor*);
+3
View File
@@ -538,6 +538,9 @@ struct BtCursor {
Btree *pBtree; /* The Btree to which this cursor belongs */
Pgno *aOverflow; /* Cache of overflow page locations */
void *pKey; /* Saved key that was cursor last known position */
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
BtCursor *pCursorHintTableCursor;
#endif
/* All fields above are zeroed when the cursor is allocated. See
** sqlite3BtreeCursorZero(). Fields that follow must be manually
** initialized. */
+27 -8
View File
@@ -6789,6 +6789,11 @@ case OP_IdxRowid: { /* out2, ncycle */
assert( pTabCur->eCurType==CURTYPE_BTREE );
assert( pTabCur->uc.pCursor!=0 );
assert( pTabCur->isTable );
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
assert(
sqlite3BtreeCursorHintTblCsr(pC->uc.pCursor)==pTabCur->uc.pCursor
);
#endif
pTabCur->nullRow = 0;
pTabCur->movetoTarget = rowid;
pTabCur->deferredMoveto = 1;
@@ -9171,23 +9176,37 @@ case OP_Init: { /* jump0 */
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/* Opcode: CursorHint P1 * * P4 *
/* Opcode: CursorHint P1 * P3 P4 *
**
** Provide a hint to cursor P1 that it only needs to return rows that
** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer
** to values currently held in registers. TK_COLUMN terms in the P4
** Provide a hint to cursor P1.
**
** If P4 is of type P4_EXPR, then the hint is that the cursor need only return
** rows that satisfy the Expr in P4. TK_REGISTER terms in the P4 expression
** refer to values currently held in registers. TK_COLUMN terms in the P4
** expression refer to columns in the b-tree to which cursor P1 is pointing.
** P3 is ignore in this case.
**
** Or, if P4 is P4_NOTUSED, then the hint is that cursor P1 is an index cursor
** used to drive table cursor P3. In other words, that this VM may execute
** OP_DeferredSeek instructions to lazily position P3 based on current
** position of P1.
*/
case OP_CursorHint: {
VdbeCursor *pC;
pC = p->apCsr[pOp->p1];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p4type==P4_EXPR );
pC = p->apCsr[pOp->p1];
if( pC ){
assert( pC->eCurType==CURTYPE_BTREE );
sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
pOp->p4.pExpr, aMem);
if( pOp->p4type==P4_EXPR ){
sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
pOp->p4.pExpr, aMem);
}else if( p->apCsr[pOp->p3] ){
sqlite3BtreeCursorHint(
pC->uc.pCursor, BTREE_HINT_TABLECURSOR, p->apCsr[pOp->p3]->uc.pCursor
);
}
}
break;
}
+5
View File
@@ -7388,6 +7388,11 @@ WhereInfo *sqlite3WhereBegin(
(u8*)&colUsed, P4_INT64);
}
#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
#ifdef SQLITE_ENABLE_CURSOR_HINTS
if( HasRowid(pTab) ){
sqlite3VdbeAddOp3(v, OP_CursorHint, iIndexCur, 0, pTabItem->iCursor);
}
#endif
}
}
if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
+1 -1
View File
@@ -38,7 +38,7 @@ do_execsql_test 1.0 {
proc p4_of_opcode {db opcode sql} {
set res {}
$db eval "EXPLAIN $sql" x {
if {$x(opcode)==$opcode} {lappend res $x(p4)}
if {$x(opcode)==$opcode && $x(p4)!=""} {lappend res $x(p4)}
}
return $res
}
+3 -1
View File
@@ -36,7 +36,9 @@ proc extract_hints {sql} {
set csr($a(p1)) $lookup($a(p2))
}
CursorHint {
lappend ret $csr($a(p1)) $a(p4)
if {$a(p4)!=""} {
lappend ret $csr($a(p1)) $a(p4)
}
}
}
}