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:
41
src/expr.c
41
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 );
|
||||
|
||||
Reference in New Issue
Block a user