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

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
This commit is contained in:
drh
2009-09-23 02:29:36 +00:00
parent 7ba5bc5bf2
commit 6a2fe09387
7 changed files with 134 additions and 47 deletions

View File

@@ -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, &regFree1,
pExpr->pRight, &r2, &regFree2);
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, &regFree1,
pExpr->pRight, &r2, &regFree2);
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, &regFree1,
pExpr->pRight, &r2, &regFree2);
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 );