mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Code simplifications. New test cases.
FossilOrigin-Name: 57508518ef9d003d259ba98dcc32e5104aca26731a7161808741fe10bc0830d0
This commit is contained in:
47
src/expr.c
47
src/expr.c
@@ -1123,7 +1123,7 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
|
||||
assert( EXPR_FULLSIZE<=0xfff );
|
||||
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
|
||||
if( 0==flags || p->op==TK_SELECT_COLUMN || p->op==TK_TRUEFALSE ){
|
||||
if( 0==flags || p->op==TK_SELECT_COLUMN ){
|
||||
nSize = EXPR_FULLSIZE;
|
||||
}else{
|
||||
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
|
||||
@@ -1743,14 +1743,22 @@ int sqlite3ExprIdToTrueFalse(Expr *pExpr){
|
||||
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0
|
||||
){
|
||||
pExpr->op = TK_TRUEFALSE;
|
||||
pExpr->iTable = pExpr->u.zToken[4]==0;
|
||||
pExpr->pTab = 0;
|
||||
ExprSetProperty(pExpr, EP_NoReduce);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The argument is one of a TK_TRUEFALSE term. Return 1 if it is TRUE
|
||||
** and 0 if it is FALSE.
|
||||
*/
|
||||
int sqlite3ExprTruthOperand(const Expr *pExpr){
|
||||
assert( pExpr->op==TK_TRUEFALSE );
|
||||
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|
||||
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
|
||||
return pExpr->u.zToken[4]==0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
@@ -3570,7 +3578,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
return target;
|
||||
}
|
||||
case TK_TRUEFALSE: {
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pExpr->iTable, target);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthOperand(pExpr), target);
|
||||
return target;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
@@ -3729,13 +3737,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
break;
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
assert( pExpr->pRight->op==TK_TRUEFALSE );
|
||||
assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 );
|
||||
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
|
||||
int isTrue;
|
||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||
testcase( regFree1==0 );
|
||||
sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !pExpr->pRight->iTable,
|
||||
pExpr->pRight->iTable ^ (pExpr->op2==TK_IS));
|
||||
isTrue = sqlite3ExprTruthOperand(pExpr->pRight);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue,
|
||||
isTrue ^ (pExpr->op2==TK_IS));
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
@@ -4515,13 +4522,13 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
int isNot;
|
||||
int isTrue;
|
||||
testcase( jumpIfNull==0 );
|
||||
assert( pExpr->pRight->op==TK_TRUEFALSE );
|
||||
assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 );
|
||||
testcase( pExpr->pRight->iTable==0 );
|
||||
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
|
||||
isNot = pExpr->op2==TK_ISNOT;
|
||||
if( pExpr->pRight->iTable ^ isNot ){
|
||||
isTrue = sqlite3ExprTruthOperand(pExpr->pRight);
|
||||
testcase( isTrue && isNot );
|
||||
testcase( isTrue && !isNot );
|
||||
if( isTrue ^ isNot ){
|
||||
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
|
||||
isNot ? SQLITE_JUMPIFNULL : 0);
|
||||
}else{
|
||||
@@ -4685,15 +4692,15 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
break;
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
testcase( jumpIfNull==0 );
|
||||
int isNot;
|
||||
int isTrue;
|
||||
testcase( jumpIfNull==0 );
|
||||
assert( pExpr->pRight->op==TK_TRUEFALSE );
|
||||
assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 );
|
||||
testcase( pExpr->pRight->iTable==0 );
|
||||
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
|
||||
isNot = pExpr->op2==TK_ISNOT;
|
||||
if( pExpr->pRight->iTable ^ isNot ){
|
||||
isTrue = sqlite3ExprTruthOperand(pExpr->pRight);
|
||||
testcase( isTrue && isNot );
|
||||
testcase( isTrue && !isNot );
|
||||
if( isTrue ^ isNot ){
|
||||
/* IS TRUE and IS NOT FALSE */
|
||||
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
|
||||
isNot ? 0 : SQLITE_JUMPIFNULL);
|
||||
|
||||
@@ -314,7 +314,7 @@ ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
|
||||
ccons ::= DEFAULT scanpt id(X). {
|
||||
Expr *p = tokenExpr(pParse, TK_STRING, X);
|
||||
sqlite3ExprIdToTrueFalse(p);
|
||||
testcase( p->op==TK_TRUEFALSE && p->iTable==0 );
|
||||
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthOperand(p) );
|
||||
sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
|
||||
}
|
||||
|
||||
|
||||
@@ -799,7 +799,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
int rc = resolveExprStep(pWalker, pRight);
|
||||
if( rc==WRC_Abort ) return WRC_Abort;
|
||||
if( pRight->op==TK_TRUEFALSE ){
|
||||
assert( pRight->iTable==0 || pRight->iTable==1 );
|
||||
pExpr->op2 = pExpr->op;
|
||||
pExpr->op = TK_TRUTH;
|
||||
return WRC_Continue;
|
||||
|
||||
@@ -2387,8 +2387,7 @@ struct Expr {
|
||||
** TK_REGISTER: register number
|
||||
** TK_TRIGGER: 1 -> new, 0 -> old
|
||||
** EP_Unlikely: 134217728 times likelihood
|
||||
** TK_SELECT: 1st register of result vector
|
||||
** TK_TRUEFALSE: 1 for true, 0 for false */
|
||||
** TK_SELECT: 1st register of result vector */
|
||||
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
|
||||
** TK_VARIABLE: variable number (always >= 1).
|
||||
** TK_SELECT_COLUMN: column of the result vector */
|
||||
@@ -3841,6 +3840,7 @@ void sqlite3Savepoint(Parse*, int, Token*);
|
||||
void sqlite3CloseSavepoints(sqlite3 *);
|
||||
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
|
||||
int sqlite3ExprIdToTrueFalse(Expr*);
|
||||
int sqlite3ExprTruthOperand(const Expr*);
|
||||
int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
|
||||
@@ -293,7 +293,8 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
break;
|
||||
}
|
||||
case TK_TRUEFALSE: {
|
||||
sqlite3TreeViewLine(pView, pExpr->iTable ? "TRUE":"FALSE");
|
||||
sqlite3TreeViewLine(pView,
|
||||
sqlite3ExprTruthOperand(pExpr) ? "TRUE" : "FALSE");
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||
@@ -353,16 +354,15 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
|
||||
|
||||
case TK_TRUTH: {
|
||||
int x;
|
||||
const char *azOp[] = {
|
||||
"IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
|
||||
};
|
||||
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
|
||||
assert( pExpr->pRight );
|
||||
assert( pExpr->pRight->op==TK_TRUEFALSE );
|
||||
assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 );
|
||||
switch( (pExpr->op2==TK_ISNOT)*2 + pExpr->pRight->iTable ){
|
||||
case 0: zUniOp = "IS-FALSE"; break;
|
||||
case 1: zUniOp = "IS-TRUE"; break;
|
||||
case 2: zUniOp = "IS-NOT-FALSE"; break;
|
||||
case 3: zUniOp = "IS-NOT-TRUE"; break;
|
||||
}
|
||||
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthOperand(pExpr->pRight);
|
||||
zUniOp = azOp[x];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user