aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2009-11-18 01:25:26 +0000
committerdrh <drh@noemail.net>2009-11-18 01:25:26 +0000
commit2f2855b63872e7a573b76c95909cf96827963b5a (patch)
treea75f3f4ae0154bdb59cc23631c702c539a90e137 /src/expr.c
parent3c65721a5ba2c1457fdc28bc15e76f945c031c0a (diff)
downloadsqlite-2f2855b63872e7a573b76c95909cf96827963b5a.tar.gz
sqlite-2f2855b63872e7a573b76c95909cf96827963b5a.zip
Suppress more instances of unnecessary OP_IsNull and OP_Affinity opcodes.
FossilOrigin-Name: bf6c0bd1c5568c6292ea0a64c8a5071e1bd3079a
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c
index db74e8759..99d88f940 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1289,6 +1289,24 @@ int sqlite3ExprCanBeNull(const Expr *p){
}
/*
+** Generate an OP_IsNull instruction that tests register iReg and jumps
+** to location iDest if the value in iReg is NULL. The value in iReg
+** was computed by pExpr. If we can look at pExpr at compile-time and
+** determine that it can never generate a NULL, then the OP_IsNull operation
+** can be omitted.
+*/
+void sqlite3ExprCodeIsNullJump(
+ Vdbe *v, /* The VDBE under construction */
+ const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */
+ int iReg, /* Test the value in this register for NULL */
+ int iDest /* Jump here if the value is null */
+){
+ if( sqlite3ExprCanBeNull(pExpr) ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest);
+ }
+}
+
+/*
** Return TRUE if the given expression is a constant which would be
** unchanged by OP_Affinity with the affinity given in the second
** argument.
@@ -1317,6 +1335,10 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
case TK_BLOB: {
return 1;
}
+ case TK_COLUMN: {
+ return p->iTable>=0 && p->iColumn<0
+ && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
+ }
default: {
return 0;
}