mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Fill out an initial implementation of the sqlite3ExprImpliesExpr() function.
FossilOrigin-Name: 8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1
This commit is contained in:
54
src/expr.c
54
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user