1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-18 10:21:03 +03:00

Attempt to optimize "x IS NULL" and "x IS NOT NULL" expressions when x is a column with a NOT NULL constraint.

FossilOrigin-Name: 5ecd842555009ce27ee6390325ac5c2504143474b12b730933f0833b3dad788a
This commit is contained in:
dan
2021-02-26 20:14:32 +00:00
parent 4b17455ab2
commit 8ddf686267
6 changed files with 150 additions and 9 deletions

View File

@@ -785,6 +785,44 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
break;
}
/* An "<expr> IS NOT NULL" or "<expr> IS NULL". After resolving the
** LHS, check if there is a NOT NULL constraint in the schema that
** means the value of the expression can be determined immediately.
** If that is the case, replace the current expression node with
** a TK_TRUEFALSE node.
**
** If the node is replaced with a TK_TRUEFALSE node, then also restore
** the NameContext ref-counts to the state they where in before the
** LHS expression was resolved. This prevents the current select
** from being erroneously marked as correlated in some cases.
*/
case TK_NOTNULL:
case TK_ISNULL: {
int anRef[8];
NameContext *p;
int i;
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
anRef[i] = p->nRef;
}
sqlite3WalkExpr(pWalker, pExpr->pLeft);
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) ){
if( pExpr->op==TK_NOTNULL ){
pExpr->u.zToken = "true";
ExprSetProperty(pExpr, EP_IsTrue);
}else{
pExpr->u.zToken = "false";
ExprSetProperty(pExpr, EP_IsFalse);
}
pExpr->op = TK_TRUEFALSE;
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
p->nRef = anRef[i];
}
sqlite3ExprDelete(pParse->db, pExpr->pLeft);
pExpr->pLeft = 0;
}
return WRC_Prune;
}
/* A column name: ID
** Or table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID

View File

@@ -407,6 +407,9 @@ static void unsetJoinExpr(Expr *p, int iTable){
&& (iTable<0 || p->iRightJoinTable==iTable) ){
ExprClearProperty(p, EP_FromJoin);
}
if( p->op==TK_COLUMN && p->iTable==iTable ){
ExprClearProperty(p, EP_CanBeNull);
}
if( p->op==TK_FUNCTION && p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){

View File

@@ -1407,6 +1407,11 @@ static void exprAnalyze(
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
}else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){
pExpr->op = TK_TRUEFALSE;
ExprSetProperty(pExpr, EP_IsFalse);
pTerm->prereqAll = 0;
pTerm->eOperator = 0;
}
}