mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
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
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user