aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-11-03 00:07:41 +0000
committerdrh <drh@noemail.net>2019-11-03 00:07:41 +0000
commitdb535390dbe2506858a781e8250e3e51a3270f10 (patch)
tree3b98f4366a0ed2d7aed6ebc6c7ef8074a0896c2b /src
parent03836614148488e8ea5539743b796d557451d630 (diff)
downloadsqlite-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.c64
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;