diff options
author | drh <drh@noemail.net> | 2013-08-01 13:04:46 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-08-01 13:04:46 +0000 |
commit | 619a1305e77cc6382013fb1e9c406d8fb88ca600 (patch) | |
tree | dab4997708035a1e0c99a3749f6ef8cc70f56cfa /src | |
parent | cf0fd4a5fd0cbb5f87a2dea65893b76e59d5c413 (diff) | |
download | sqlite-619a1305e77cc6382013fb1e9c406d8fb88ca600.tar.gz sqlite-619a1305e77cc6382013fb1e9c406d8fb88ca600.zip |
Fill out an initial implementation of the sqlite3ExprImpliesExpr() function.
FossilOrigin-Name: 8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 54 | ||||
-rw-r--r-- | src/insert.c | 4 | ||||
-rw-r--r-- | src/resolve.c | 4 | ||||
-rw-r--r-- | src/select.c | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 |
5 files changed, 48 insertions, 22 deletions
diff --git a/src/expr.c b/src/expr.c index 96c05dc3a..6fa34443a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3798,6 +3798,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** by a COLLATE operator at the top level. Return 2 if there are differences ** other than the top-level COLLATE operator. ** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** ** Sometimes this routine will return 2 even if the two expressions ** really are equivalent. If we cannot prove that the expressions are ** identical, we return 2 just to be safe. So if this routine @@ -3808,7 +3811,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. */ -int sqlite3ExprCompare(Expr *pA, Expr *pB){ +int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( pA==0||pB==0 ){ return pB==pA ? 0 : 2; } @@ -3819,18 +3822,19 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( pA->op!=pB->op ){ - if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ return 1; } - if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){ + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){ return 1; } return 2; } - if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; - if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; - if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; @@ -3848,6 +3852,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ ** Compare two ExprList objects. Return 0 if they are identical and ** non-zero if they differ in any way. ** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** ** This routine might return non-zero for equivalent ExprLists. The ** only consequence will be disabled optimizations. But this routine ** must never return 0 if the two ExprList objects are different, or @@ -3856,7 +3863,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ ** Two NULL pointers are considered to be the same. But a NULL pointer ** always differs from a non-NULL pointer. */ -int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ +int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ int i; if( pA==0 && pB==0 ) return 0; if( pA==0 || pB==0 ) return 1; @@ -3865,7 +3872,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; - if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1; } return 0; } @@ -3875,9 +3882,13 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x>0 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -3887,7 +3898,22 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ ** it will always give the correct answer and is hence always safe. */ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ - return 0; /* FIXME: this needs to be worked out */ + if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){ + return 1; + } + if( pE2->op==TK_OR + && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) ) + ){ + return 1; + } + if( pE2->op==TK_NOTNULL + && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0 + && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS) + ){ + return 1; + } + return 0; } /* @@ -4070,7 +4096,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; i<pAggInfo->nFunc; i++, pItem++){ - if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){ + if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){ break; } } diff --git a/src/insert.c b/src/insert.c index 54821f18b..1c2cabb93 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1648,7 +1648,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ return 0; /* Different collating sequences */ } } - if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere) ){ + if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ return 0; /* Different WHERE clauses */ } @@ -1806,7 +1806,7 @@ static int xferOptimization( } } #ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){ + if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif diff --git a/src/resolve.c b/src/resolve.c index 239e0eb2a..f288ed930 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -825,7 +825,7 @@ static int resolveOrderByTermToExprList( ** result-set entry. */ for(i=0; i<pEList->nExpr; i++){ - if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){ + if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){ return i+1; } } @@ -1053,7 +1053,7 @@ static int resolveOrderGroupBy( return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ - if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){ + if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ pItem->iOrderByCol = j+1; } } diff --git a/src/select.c b/src/select.c index fa35f4587..014feca8f 100644 --- a/src/select.c +++ b/src/select.c @@ -4177,7 +4177,7 @@ int sqlite3Select( ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER ** to disable this optimization for testing purposes. */ - if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 + if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ pOrderBy = 0; } @@ -4198,7 +4198,7 @@ int sqlite3Select( ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && sqlite3ExprListCompare(pOrderBy, p->pEList)==0 + && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0 ){ p->selFlags &= ~SF_Distinct; p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 21e32ff7b..291957db9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2834,8 +2834,8 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(sqlite3*, Token*); -int sqlite3ExprCompare(Expr*, Expr*); -int sqlite3ExprListCompare(ExprList*, ExprList*); +int sqlite3ExprCompare(Expr*, Expr*, int); +int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Expr*, Expr*, int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); |