diff --git a/src/where.c b/src/where.c index 2a32d54edd..b04522309a 100644 --- a/src/where.c +++ b/src/where.c @@ -2790,12 +2790,17 @@ static int indexMightHelpWithOrderBy( /* Check to see if a partial index with pPartIndexWhere can be used ** in the current query. Return true if it can be and false if not. */ -static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ +static int whereUsablePartialIndex( + int iTab, /* The table for which we want an index */ + int isLeft, /* True if iTab is the right table of a LEFT JOIN */ + WhereClause *pWC, /* The WHERE clause of the query */ + Expr *pWhere /* The WHERE clause from the partial index */ +){ int i; WhereTerm *pTerm; Parse *pParse = pWC->pWInfo->pParse; while( pWhere->op==TK_AND ){ - if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0; + if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; @@ -2803,6 +2808,7 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ Expr *pExpr; pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) ){ return 1; @@ -2965,8 +2971,11 @@ static int whereLoopAddBtree( for(; rc==SQLITE_OK && pProbe; pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ ){ + int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 - && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ + && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC, + pProbe->pPartIdxWhere) + ){ testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ continue; /* Partial index inappropriate for this query */ } diff --git a/test/join.test b/test/join.test index 0edfe0d84b..19a061d46e 100644 --- a/test/join.test +++ b/test/join.test @@ -953,4 +953,26 @@ do_execsql_test join-20.2 { SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1); } {} +# 2019-11-30 ticket 7f39060a24b47353 +# Do not allow a WHERE clause term to qualify a partial index on the +# right table of a LEFT JOIN. +# +do_execsql_test join-21.10 { + DROP TABLE t0; + DROP TABLE t1; + CREATE TABLE t0(aa); + CREATE TABLE t1(bb); + INSERT INTO t0(aa) VALUES (1); + INSERT INTO t1(bb) VALUES (1); + SELECT 11, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL; + SELECT 12, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL; + SELECT 13, * FROM t1 LEFT JOIN t0 ON aa ISNULL; + SELECT 14, * FROM t1 LEFT JOIN t0 ON +aa ISNULL; + CREATE INDEX i0 ON t0(aa) WHERE aa ISNULL; + SELECT 21, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL; + SELECT 22, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL; + SELECT 23, * FROM t1 LEFT JOIN t0 ON aa ISNULL; + SELECT 24, * FROM t1 LEFT JOIN t0 ON +aa ISNULL; +} {13 1 {} 14 1 {} 23 1 {} 24 1 {}} + finish_test