diff options
author | dan <Dan Kennedy> | 2024-05-01 19:48:24 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2024-05-01 19:48:24 +0000 |
commit | f3ea92cceb577524c1d329aed2400127d7fd716a (patch) | |
tree | 50b6d0d585f266b29ce41ac5190d78e2b740f9bd /src | |
parent | 8d5fe073d25b8bfd632d10d4875461316806481d (diff) | |
download | sqlite-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')
-rw-r--r-- | src/wherecode.c | 25 |
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; |