diff options
author | drh <drh@noemail.net> | 2009-09-23 02:29:36 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2009-09-23 02:29:36 +0000 |
commit | 6a2fe09387572e67602e84517d9a68063040209e (patch) | |
tree | 677b41cd38277f580dc81cd790ce7b8cebdc12d2 /src/expr.c | |
parent | 7ba5bc5bf20bbcd3720230106955800da59418b7 (diff) | |
download | sqlite-6a2fe09387572e67602e84517d9a68063040209e.tar.gz sqlite-6a2fe09387572e67602e84517d9a68063040209e.zip |
Generalize the IS and IS NOT operators so that their right-hand side can be
an arbitrary expression and not simple the constant NULL. They work like
= and <> except that NULL values compare equal to one another an unequal to
everything else.
FossilOrigin-Name: 98853f6104076c50ea92175e17a3254bfbbd4619
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/expr.c b/src/expr.c index 50b24de41..998bf41a8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -152,7 +152,7 @@ static char comparisonAffinity(Expr *pExpr){ char aff; assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || - pExpr->op==TK_NE ); + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); assert( pExpr->pLeft ); aff = sqlite3ExprAffinity(pExpr->pLeft); if( pExpr->pRight ){ @@ -2244,6 +2244,19 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_AND: case TK_OR: case TK_PLUS: @@ -3018,6 +3031,19 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); @@ -3167,6 +3193,19 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_ISNULL: case TK_NOTNULL: { testcase( op==TK_ISNULL ); |