aboutsummaryrefslogtreecommitdiff
path: root/src/wherecode.c
diff options
context:
space:
mode:
authordrh <>2021-05-18 19:10:10 +0000
committerdrh <>2021-05-18 19:10:10 +0000
commit93ffb50fcda87d7c937fcaeef1bcb61591227b9d (patch)
tree7fe22fcaf44363693eef400ad74e901df0b7049f /src/wherecode.c
parente74ca517b4910554a9d7d0454cf80c07b21764cd (diff)
downloadsqlite-93ffb50fcda87d7c937fcaeef1bcb61591227b9d.tar.gz
sqlite-93ffb50fcda87d7c937fcaeef1bcb61591227b9d.zip
In the MULTI-INDEX OR query plan, code for sub-expressions can sometimes be
generated twice. But for some subqueries, generating code off of the same tree twice causes problems. So now MULTI-INDEX OR makes a copy of the sub-expressions it uses to avoid code-generating them more than once. dbsqlfuzz 9ebd2140e7206ff724e665f172faea28af801635. FossilOrigin-Name: 4a55f72542c8bcc80253aa77043314cecb29d73cb4f51aa80f7811e86cc8ef68
Diffstat (limited to 'src/wherecode.c')
-rw-r--r--src/wherecode.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/wherecode.c b/src/wherecode.c
index 507148d31..4d0ba880d 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -2170,7 +2170,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* The extra 0x10000 bit on the opcode is masked off and does not
** become part of the new Expr.op. However, it does make the
** op==TK_AND comparison inside of sqlite3PExpr() false, and this
- ** prevents sqlite3PExpr() from implementing AND short-circuit
+ ** prevents sqlite3PExpr() from applying the AND short-circuit
** optimization, which we do not want here. */
pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
}
@@ -2186,10 +2186,16 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
+ Expr *pDelete; /* Local copy of OR clause term */
int jmp1 = 0; /* Address of jump operation */
testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
&& !ExprHasProperty(pOrExpr, EP_FromJoin)
); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
+ pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
+ if( db->mallocFailed ){
+ sqlite3ExprDelete(db, pDelete);
+ continue;
+ }
if( pAndExpr ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
@@ -2304,6 +2310,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3WhereEnd(pSubWInfo);
ExplainQueryPlanPop(pParse);
}
+ sqlite3ExprDelete(db, pDelete);
}
}
ExplainQueryPlanPop(pParse);