mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-15 11:41:13 +03:00
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
This commit is contained in:
11
src/expr.c
11
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user