diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 22 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/where.c | 8 |
3 files changed, 26 insertions, 5 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; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 64c7c356f..293c2446b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2675,6 +2675,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); +void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); diff --git a/src/where.c b/src/where.c index 7abf7d582..c39504047 100644 --- a/src/where.c +++ b/src/where.c @@ -2789,9 +2789,7 @@ static int codeAllEqualityTerms( testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ Expr *pRight = pTerm->pExpr->pRight; - if( sqlite3ExprCanBeNull(pRight) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); - } + sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){ zAff[j] = SQLITE_AFF_NONE; @@ -3124,7 +3122,7 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions @@ -3162,7 +3160,7 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq); sqlite3ExprCode(pParse, pRight, regBase+nEq); - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions |