mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
For the MULTI-INDEX-OR optimization, when pushing down WHERE clause terms from
the main query into the various OR-term subqueries, do not push down slices of a vector comparison, since the right-hand operand of the comparison might have only been initialized in a different OR branch that was not taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. FossilOrigin-Name: 9f67ad00cd38b7c5ec6d14b379e1a611777bbdf6901d843a80712ba7d94d6d33
This commit is contained in:
@@ -285,6 +285,7 @@ struct WhereTerm {
|
||||
#else
|
||||
# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
|
||||
#endif
|
||||
#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
|
||||
|
||||
/*
|
||||
** An instance of the WhereScan object is used as an iterator for locating
|
||||
|
||||
@@ -2317,7 +2317,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
|
||||
|
||||
/* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
|
||||
** Then for every term xN, evaluate as the subexpression: xN AND z
|
||||
** Then for every term xN, evaluate as the subexpression: xN AND y
|
||||
** That way, terms in y that are factored into the disjunction will
|
||||
** be picked up by the recursive calls to sqlite3WhereBegin() below.
|
||||
**
|
||||
@@ -2329,6 +2329,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** This optimization also only applies if the (x1 OR x2 OR ...) term
|
||||
** is not contained in the ON clause of a LEFT JOIN.
|
||||
** See ticket http://www.sqlite.org/src/info/f2369304e4
|
||||
**
|
||||
** 2022-02-04: Do not push down slices of a row-value comparison.
|
||||
** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
|
||||
** the initialization of the right-hand operand of the vector comparison
|
||||
** might not occur, or might occur only in an OR branch that is not
|
||||
** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
|
||||
*/
|
||||
if( pWC->nTerm>1 ){
|
||||
int iTerm;
|
||||
@@ -2337,7 +2343,10 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( &pWC->a[iTerm] == pTerm ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
|
||||
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
|
||||
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
|
||||
continue;
|
||||
}
|
||||
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
|
||||
@@ -1399,7 +1399,7 @@ static void exprAnalyze(
|
||||
|
||||
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
|
||||
transferJoinMarkings(pNew, pExpr);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
}
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
|
||||
Reference in New Issue
Block a user