diff options
author | drh <drh@noemail.net> | 2016-02-10 16:52:24 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-02-10 16:52:24 +0000 |
commit | 2a0b527b37a16bc8f70287dc93dcac0b66f8d930 (patch) | |
tree | 3a8b9bdeb7f04901688994fa49342f3f18a85b5d /src/insert.c | |
parent | bdb00225abc20bfc9bee34db4bc85daadaa0a003 (diff) | |
download | sqlite-2a0b527b37a16bc8f70287dc93dcac0b66f8d930.tar.gz sqlite-2a0b527b37a16bc8f70287dc93dcac0b66f8d930.zip |
Omit unnecessary CHECK constraints in UPDATE statements, when none of the
columns referenced in the CHECK constraint are modified.
FossilOrigin-Name: 02fbdbc782dd98f080bf4482d820f36c0ef3d519
Diffstat (limited to 'src/insert.c')
-rw-r--r-- | src/insert.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/insert.c b/src/insert.c index 95321cd94..a77d3e97d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1077,6 +1077,38 @@ insert_cleanup: #undef tmask #endif +/* This is the Walker callback from checkConstraintUnchanged(). Set +** pWalker->eCode to 0 if this expression node references any of the +** columns that are being modifed by an UPDATE statement. +*/ +static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + && pExpr->iColumn>=0 + && pWalker->u.aiCol[pExpr->iColumn]>=0 + ){ + pWalker->eCode = 0; + } + return WRC_Continue; +} + +/* +** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The +** only columns that are modified by the UPDATE are those for which +** aiChng[i]>=0. Return true if CHECK constraint pExpr does not use +** any of the changing columns. In other words, return true if this +** CHECK constraint can be skipped when validating the new row in +** the UPDATE statement. +*/ +static int checkConstraintUnchanged(Expr *pExpr, int *aiChng){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 1; + w.xExprCallback = checkConstraintExprNode; + w.u.aiCol = aiChng; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -1275,7 +1307,9 @@ void sqlite3GenerateConstraintChecks( onError = overrideError!=OE_Default ? overrideError : OE_Abort; for(i=0; i<pCheck->nExpr; i++){ int allOk = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); + Expr *pExpr = pCheck->a[i].pExpr; + if( aiChng && checkConstraintUnchanged(pExpr, aiChng) ) continue; + sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ sqlite3VdbeGoto(v, ignoreDest); }else{ |