diff options
author | drh <drh@noemail.net> | 2019-11-03 00:07:41 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-11-03 00:07:41 +0000 |
commit | db535390dbe2506858a781e8250e3e51a3270f10 (patch) | |
tree | 3b98f4366a0ed2d7aed6ebc6c7ef8074a0896c2b /src | |
parent | 03836614148488e8ea5539743b796d557451d630 (diff) | |
download | sqlite-db535390dbe2506858a781e8250e3e51a3270f10.tar.gz sqlite-db535390dbe2506858a781e8250e3e51a3270f10.zip |
The optimization of check-in [9b2879629c34fc0a] is incorrectly reasoned.
The WHERE clause of the partial index might not be true if the table of
the partial index is the right table of a left join. So disable the
optimization in that case. Ticket [623eff57e76d45f6]
FossilOrigin-Name: 3be19e1151af1850b65991edb82420f9412a7798dd756c86eaa9ffdde573263a
Diffstat (limited to 'src')
-rw-r--r-- | src/wherecode.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/src/wherecode.c b/src/wherecode.c index 351af766e..7447fafb5 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1870,35 +1870,43 @@ Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } - /* If pIdx is an index on one or more expressions, then look through - ** all the expressions in pWInfo and try to transform matching expressions - ** into reference to index columns. Also attempt to translate references - ** to virtual columns in the table into references to (stored) columns - ** of the index. - ** - ** Do not do this for the RHS of a LEFT JOIN. This is because the - ** expression may be evaluated after OP_NullRow has been executed on - ** the cursor. In this case it is important to do the full evaluation, - ** as the result of the expression may not be NULL, even if all table - ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a - ** - ** Also, do not do this when processing one index an a multi-index - ** OR clause, since the transformation will become invalid once we - ** move forward to the next index. - ** https://sqlite.org/src/info/4e8e4857d32d401f - */ - if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ - whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); - } - - /* If a partial index is driving the loop, try to eliminate WHERE clause - ** terms from the query that must be true due to the WHERE clause of - ** the partial index - */ - if( pIdx->pPartIdxWhere ){ - whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); + if( pLevel->iLeftJoin==0 ){ + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. Also attempt to translate references + ** to virtual columns in the table into references to (stored) columns + ** of the index. + ** + ** Do not do this for the RHS of a LEFT JOIN. This is because the + ** expression may be evaluated after OP_NullRow has been executed on + ** the cursor. In this case it is important to do the full evaluation, + ** as the result of the expression may not be NULL, even if all table + ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a + ** + ** Also, do not do this when processing one index an a multi-index + ** OR clause, since the transformation will become invalid once we + ** move forward to the next index. + ** https://sqlite.org/src/info/4e8e4857d32d401f + */ + if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + } + + /* If a partial index is driving the loop, try to eliminate WHERE clause + ** terms from the query that must be true due to the WHERE clause of + ** the partial index. + ** + ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work + ** for a LEFT JOIN. + */ + if( pIdx->pPartIdxWhere ){ + whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); + } + }else{ + testcase( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ); + testcase( pIdx->pPartIdxWhere ); } - + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; |