aboutsummaryrefslogtreecommitdiff
path: root/src/wherecode.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-03-01 18:07:05 +0000
committerdrh <drh@noemail.net>2019-03-01 18:07:05 +0000
commitb531aa8fd9ca317c1ce586d1156c6c084a734264 (patch)
tree3d13092589d53d762685b3d1aead4d09cc9d7505 /src/wherecode.c
parent9cb02640419614ae3771ebbffce076474380029b (diff)
downloadsqlite-b531aa8fd9ca317c1ce586d1156c6c084a734264.tar.gz
sqlite-b531aa8fd9ca317c1ce586d1156c6c084a734264.zip
In a query that uses a partial index, the expression that is the WHERE clause
of the partial index must always be true. Use this fact to avoid evaluating identical terms in the WHERE clause of the query. FossilOrigin-Name: 9b2879629c34fc0a8e99d94648903eb93aabbc7a3682c80cb7382f9a9ca5ffb7
Diffstat (limited to 'src/wherecode.c')
-rw-r--r--src/wherecode.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/wherecode.c b/src/wherecode.c
index 79189386b..758d6b5ee 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1160,6 +1160,34 @@ static void whereIndexExprTrans(
}
/*
+** The pTruth expression is always tree because it is the WHERE clause
+** a partial index that is driving a query loop. Look through all of the
+** WHERE clause terms on the query, and if any of those terms must be
+** true because pTruth is true, then mark those WHERE clause terms as
+** coded.
+*/
+static void whereApplyPartialIndexConstraints(
+ Expr *pTruth,
+ int iTabCur,
+ WhereClause *pWC
+){
+ int i;
+ WhereTerm *pTerm;
+ while( pTruth->op==TK_AND ){
+ whereApplyPartialIndexConstraints(pTruth->pLeft, iTabCur, pWC);
+ pTruth = pTruth->pRight;
+ }
+ for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+ Expr *pExpr;
+ if( pTerm->wtFlags & TERM_CODED ) continue;
+ pExpr = pTerm->pExpr;
+ if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+}
+
+/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
@@ -1768,6 +1796,14 @@ Bitmask sqlite3WhereCodeOneLoopStart(
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);
+ }
+
/* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;