aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-08-10 10:05:22 +0000
committerdrh <>2024-08-10 10:05:22 +0000
commitfe4ed96006fe32ba7fcdb0fdc8bb34e7083a7ebe (patch)
tree7b7a36258304ae0a53d6fa0d1941e09b449145ea /src
parent4098aa5d198e891e10a7de57abdf3c34c22633d2 (diff)
parentc5900bfd593e352668c885cc6fd187ae336895c6 (diff)
downloadsqlite-fe4ed96006fe32ba7fcdb0fdc8bb34e7083a7ebe.tar.gz
sqlite-fe4ed96006fe32ba7fcdb0fdc8bb34e7083a7ebe.zip
Enhancements to covering-index prediction. In particular, avoid the
false-positive prediction described by [forum:/forumpost/e60e4c295d22f8ce|forum post e60e4c295d22f8ce]. Add early detection of over-prediction of covering-indexes so that sqlite3_prepare() will return an error rather than just generate bad bytecode. FossilOrigin-Name: f0b671183f44d0ae294956e7651a1653f47bd6219f9636872d15993f30f28dfb
Diffstat (limited to 'src')
-rw-r--r--src/where.c58
1 files changed, 18 insertions, 40 deletions
diff --git a/src/where.c b/src/where.c
index c850121c3..15f5fe7d9 100644
--- a/src/where.c
+++ b/src/where.c
@@ -4047,7 +4047,9 @@ static int whereLoopAddBtree(
" according to whereIsCoveringIndex()\n", pProbe->zName));
}
}
- }else if( m==0 ){
+ }else if( m==0
+ && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
+ ){
WHERETRACE(0x200,
("-> %s a covering index according to bitmasks\n",
pProbe->zName, m==0 ? "is" : "is not"));
@@ -7078,26 +7080,6 @@ whereBeginError:
}
#endif
-#ifdef SQLITE_DEBUG
-/*
-** Return true if cursor iCur is opened by instruction k of the
-** bytecode. Used inside of assert() only.
-*/
-static int cursorIsOpen(Vdbe *v, int iCur, int k){
- while( k>=0 ){
- VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
- if( pOp->p1!=iCur ) continue;
- if( pOp->opcode==OP_Close ) return 0;
- if( pOp->opcode==OP_OpenRead ) return 1;
- if( pOp->opcode==OP_OpenWrite ) return 1;
- if( pOp->opcode==OP_OpenDup ) return 1;
- if( pOp->opcode==OP_OpenAutoindex ) return 1;
- if( pOp->opcode==OP_OpenEphemeral ) return 1;
- }
- return 0;
-}
-#endif /* SQLITE_DEBUG */
-
/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
@@ -7376,18 +7358,20 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
assert( pIdx->pTable==pTab );
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
if( pOp->opcode==OP_Offset ){
- /* Do not need to translate the column number */
+ x = 0;
}else
#endif
- if( !HasRowid(pTab) ){
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- x = pPk->aiColumn[x];
- assert( x>=0 );
- }else{
- testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
- x = sqlite3StorageColumnToTable(pTab,x);
+ {
+ if( !HasRowid(pTab) ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ x = pPk->aiColumn[x];
+ assert( x>=0 );
+ }else{
+ testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
+ x = sqlite3StorageColumnToTable(pTab,x);
+ }
+ x = sqlite3TableColumnToIndex(pIdx, x);
}
- x = sqlite3TableColumnToIndex(pIdx, x);
if( x>=0 ){
pOp->p2 = x;
pOp->p1 = pLevel->iIdxCur;
@@ -7397,16 +7381,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
** reference. Verify that this is harmless - that the
** table being referenced really is open.
*/
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- || pOp->opcode==OP_Offset
- );
-#else
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- );
-#endif
+ if( pLoop->wsFlags & WHERE_IDX_ONLY ){
+ sqlite3ErrorMsg(pParse, "internal query planner error");
+ pParse->rc = SQLITE_INTERNAL;
+ }
}
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;