mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
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
This commit is contained in:
@@ -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( 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 );
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
/* Record the instruction used to terminate the loop. */
|
||||
if( pLoop->wsFlags & WHERE_ONEROW ){
|
||||
pLevel->op = OP_Noop;
|
||||
|
||||
Reference in New Issue
Block a user