diff options
author | drh <> | 2022-02-02 19:51:44 +0000 |
---|---|---|
committer | drh <> | 2022-02-02 19:51:44 +0000 |
commit | 044a017abc5a2322f7ca27350b18a5575e8be631 (patch) | |
tree | ba262fa2c55dfdd13d3c27aa8c9b4a31bca1e850 /src/wherecode.c | |
parent | 9ede896ac15ef680f107aa77df6ab3e7163b0093 (diff) | |
parent | cc0db61364b9eec3d91c069e280a258a555aa65d (diff) | |
download | sqlite-044a017abc5a2322f7ca27350b18a5575e8be631.tar.gz sqlite-044a017abc5a2322f7ca27350b18a5575e8be631.zip |
Add the sqlite3_vtab_in() interface that allows virtual tables to process
IN constraints all at once, rather than one value at a time.
FossilOrigin-Name: 52559af093809b572082b5ebaacf97b727ee1860ae118530761b62e937545163
Diffstat (limited to 'src/wherecode.c')
-rw-r--r-- | src/wherecode.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/wherecode.c b/src/wherecode.c index 2beb596e6..8d7163ce0 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1532,8 +1532,15 @@ Bitmask sqlite3WhereCodeOneLoopStart( pTerm = pLoop->aLTerm[j]; if( NEVER(pTerm==0) ) continue; if( pTerm->eOperator & WO_IN ){ - codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); - addrNotFound = pLevel->addrNxt; + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + } }else{ Expr *pRight = pTerm->pExpr->pRight; codeExprOrVector(pParse, pRight, iTarget, 1); @@ -1568,13 +1575,19 @@ Bitmask sqlite3WhereCodeOneLoopStart( iIn = 0; } for(j=nConstraint-1; j>=0; j--){ + int bIn; /* True to generate byte code to loop over RHS IN values */ pTerm = pLoop->aLTerm[j]; - if( (pTerm->eOperator & WO_IN)!=0 ) iIn--; + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + ){ + bIn = 1; + }else{ + bIn = 0; + } + if( bIn ) iIn--; if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); - }else if( (pTerm->eOperator & WO_IN)!=0 - && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 - ){ + }else if( bIn && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ |