aboutsummaryrefslogtreecommitdiff
path: root/src/where.c
diff options
context:
space:
mode:
authordrh <>2025-07-07 15:40:53 +0000
committerdrh <>2025-07-07 15:40:53 +0000
commit4fe1ac8fe1c3831588ae2ad1f8ea0841b11523ab (patch)
tree088d1cd122272ca4a858a8cbf914149d57c95c70 /src/where.c
parent4aacd1ef8eff53662b827e920d2c7d5d46833b9d (diff)
downloadsqlite-4fe1ac8fe1c3831588ae2ad1f8ea0841b11523ab.tar.gz
sqlite-4fe1ac8fe1c3831588ae2ad1f8ea0841b11523ab.zip
Simplifications to the row-value IN operator logic. Do not let the query
planner accept a WhereLoop for a row-value IN operator that uses the same index column more than once. FossilOrigin-Name: d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12
Diffstat (limited to 'src/where.c')
-rw-r--r--src/where.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/where.c b/src/where.c
index 6a195dd2d..5d80dd3d6 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3239,6 +3239,7 @@ static int whereLoopAddBtreeIndex(
if( ExprUseXSelect(pExpr) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
int i;
+ int bRedundant = 0;
nIn = 46; assert( 46==sqlite3LogEst(25) );
/* The expression may actually be of the form (x, y) IN (SELECT...).
@@ -3247,7 +3248,20 @@ static int whereLoopAddBtreeIndex(
** for each such term. The following loop checks that pTerm is the
** first such term in use, and sets nIn back to 0 if it is not. */
for(i=0; i<pNew->nLTerm-1; i++){
- if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
+ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){
+ nIn = 0;
+ if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){
+ /* Detect when two or more columns of an index match the same
+ ** column of a vector IN operater, and avoid adding the column
+ ** to the WhereLoop more than once. See tag-20250707-01
+ ** in test/rowvalue.test */
+ bRedundant = 1;
+ }
+ }
+ }
+ if( bRedundant ){
+ pNew->nLTerm--;
+ continue;
}
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
/* "x IN (value, value, ...)" */