diff options
author | drh <> | 2022-05-02 14:32:56 +0000 |
---|---|---|
committer | drh <> | 2022-05-02 14:32:56 +0000 |
commit | 3a45d30ea5eff2c17c5ee1561e12f0865ad75b3e (patch) | |
tree | 518e637f398b934091815aa9ddccf26b9a39cb3b /src | |
parent | b94182bdc6235ce520322890d4b1567e6404d04f (diff) | |
download | sqlite-3a45d30ea5eff2c17c5ee1561e12f0865ad75b3e.tar.gz sqlite-3a45d30ea5eff2c17c5ee1561e12f0865ad75b3e.zip |
Improvement on check-in [a193749730d6cfba] so that the subroutine call to
the IN operator right-hand side generator from the RIGHT JOIN no-match logic
does not generate unreachable byte code.
FossilOrigin-Name: cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 11 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/wherecode.c | 9 |
3 files changed, 12 insertions, 9 deletions
diff --git a/src/expr.c b/src/expr.c index f8ee68dc2..8e47578cc 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2743,12 +2743,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 @@ -3082,7 +3087,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; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e526a775c..e9f0af544 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5315,6 +5315,7 @@ const char *sqlite3JournalModename(int); #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ +#define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */ int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); diff --git a/src/wherecode.c b/src/wherecode.c index 333295a48..d4470ac4d 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -612,7 +612,7 @@ static int codeEqualityTerm( eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ @@ -622,14 +622,9 @@ static int codeEqualityTerm( } sqlite3ExprDelete(db, pX); }else{ - int j1; - sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - j1 = sqlite3VdbeAddOp0(v, OP_Goto); aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab); iTab = pExpr->iTable; - sqlite3VdbeJumpHere(v, j1); } pX = pExpr; } |