aboutsummaryrefslogtreecommitdiff
path: root/src/wherecode.c
diff options
context:
space:
mode:
authordan <Dan Kennedy>2024-05-01 19:48:24 +0000
committerdan <Dan Kennedy>2024-05-01 19:48:24 +0000
commitf3ea92cceb577524c1d329aed2400127d7fd716a (patch)
tree50b6d0d585f266b29ce41ac5190d78e2b740f9bd /src/wherecode.c
parent8d5fe073d25b8bfd632d10d4875461316806481d (diff)
downloadsqlite-f3ea92cceb577524c1d329aed2400127d7fd716a.tar.gz
sqlite-f3ea92cceb577524c1d329aed2400127d7fd716a.zip
Avoid an OP_Next in cases where an IN(...) query against a UNIQUE index may return at most 1 row.
FossilOrigin-Name: 560f64157d2fe40e107582eebb6526185c9c43305e364f4132e182dbec5b210a
Diffstat (limited to 'src/wherecode.c')
-rw-r--r--src/wherecode.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/wherecode.c b/src/wherecode.c
index d95eae279..a895d3935 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1338,6 +1338,27 @@ static SQLITE_NOINLINE void filterPullDown(
}
/*
+** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...)
+** operator. Return true if level pLoop is guaranteed to visit only one
+** row for each key generated for the index.
+*/
+static int whereLoopIsOneRow(WhereLoop *pLoop){
+ if( pLoop->u.btree.pIndex->onError
+ && pLoop->nSkip==0
+ && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol
+ ){
+ int ii;
+ for(ii=0; ii<pLoop->u.btree.nEq; ii++){
+ if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){
+ return 0;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
@@ -2084,7 +2105,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Record the instruction used to terminate the loop. */
- if( pLoop->wsFlags & WHERE_ONEROW ){
+ if( (pLoop->wsFlags & WHERE_ONEROW)
+ || (pLevel->u.in.nIn && whereLoopIsOneRow(pLoop))
+ ){
pLevel->op = OP_Noop;
}else if( bRev ){
pLevel->op = OP_Prev;