diff options
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c index 2bc5eae20..77b5e0ad6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2660,7 +2660,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** all members of the RHS set, skipping duplicates. ** ** A cursor is opened on the b-tree object that is the RHS of the IN operator -** and pX->iTable is set to the index of that cursor. +** and the *piTab parameter is set to the index of that cursor. ** ** The returned value of this function indicates the b-tree type, as follows: ** @@ -2680,7 +2680,10 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephemeral table instead of an -** existing table. +** existing table. In this case, the creation and initialization of the +** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag +** will be set on pX and the pX->y.sub fields will be set to show where +** the subroutine is coded. ** ** The inFlags parameter must contain, at a minimum, one of the bits ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains @@ -2741,12 +2744,17 @@ int sqlite3FindInIndex( ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ - int iTab = pParse->nTab++; /* Cursor of the RHS table */ + int iTab; /* Cursor of the RHS table */ int mustBeUnique; /* True if RHS must be unique */ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){ + iTab = pX->iTable; + }else{ + iTab = pParse->nTab++; + } /* If the RHS of this IN(...) operator is a SELECT, and if it matters ** whether or not the SELECT result contains NULL values, check whether @@ -2912,6 +2920,8 @@ int sqlite3FindInIndex( && ExprUseXList(pX) && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) ){ + pParse->nTab--; /* Back out the allocation of the unused cursor */ + iTab = -1; /* Cursor is not allocated */ eType = IN_INDEX_NOOP; } @@ -3078,7 +3088,9 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); - sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + if( iTab!=pExpr->iTable ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + } sqlite3VdbeJumpHere(v, addrOnce); return; } |