mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Omit the SQLITE_STOREP2 and SQLITE_KEEPNULL options from the comparison
opcodes, allowing them to run faster. This required refactoring the vector comparison logic, which in turn required changing OP_ElseNotEq into OP_ElseEq. FossilOrigin-Name: 380b46054b6a9b67e57357815e8e94057253fa3cce838ae76e5d5031c6bd26b2
This commit is contained in:
38
src/expr.c
38
src/expr.c
@@ -611,6 +611,7 @@ static void codeVectorCompare(
|
||||
int regLeft = 0;
|
||||
int regRight = 0;
|
||||
u8 opx = op;
|
||||
int addrCmp = 0;
|
||||
int addrDone = sqlite3VdbeMakeLabel(pParse);
|
||||
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
|
||||
|
||||
@@ -630,21 +631,24 @@ static void codeVectorCompare(
|
||||
assert( p5==0 || pExpr->op!=op );
|
||||
assert( p5==SQLITE_NULLEQ || pExpr->op==op );
|
||||
|
||||
p5 |= SQLITE_STOREP2;
|
||||
if( opx==TK_LE ) opx = TK_LT;
|
||||
if( opx==TK_GE ) opx = TK_GT;
|
||||
if( op==TK_LE ) opx = TK_LT;
|
||||
if( op==TK_GE ) opx = TK_GT;
|
||||
if( op==TK_NE ) opx = TK_EQ;
|
||||
|
||||
regLeft = exprCodeSubselect(pParse, pLeft);
|
||||
regRight = exprCodeSubselect(pParse, pRight);
|
||||
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, dest);
|
||||
for(i=0; 1 /*Loop exits by "break"*/; i++){
|
||||
int regFree1 = 0, regFree2 = 0;
|
||||
Expr *pL, *pR;
|
||||
int r1, r2;
|
||||
assert( i>=0 && i<nLeft );
|
||||
if( addrCmp ) sqlite3VdbeJumpHere(v, addrCmp);
|
||||
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1);
|
||||
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
|
||||
codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5, isCommuted);
|
||||
addrCmp = sqlite3VdbeCurrentAddr(v);
|
||||
codeCompare(pParse, pL, pR, opx, r1, r2, addrDone, p5, isCommuted);
|
||||
testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
|
||||
testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
|
||||
testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
|
||||
@@ -653,26 +657,32 @@ static void codeVectorCompare(
|
||||
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
|
||||
sqlite3ReleaseTempReg(pParse, regFree1);
|
||||
sqlite3ReleaseTempReg(pParse, regFree2);
|
||||
if( (opx==TK_LT || opx==TK_GT) && i<nLeft-1 ){
|
||||
addrCmp = sqlite3VdbeAddOp0(v, OP_ElseEq);
|
||||
testcase(opx==TK_LT); VdbeCoverageIf(v,opx==TK_LT);
|
||||
testcase(opx==TK_GT); VdbeCoverageIf(v,opx==TK_GT);
|
||||
}
|
||||
if( p5==SQLITE_NULLEQ ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, dest, r2);
|
||||
}
|
||||
if( i==nLeft-1 ){
|
||||
break;
|
||||
}
|
||||
if( opx==TK_EQ ){
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
}else if( opx==TK_NE ){
|
||||
sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, dest, addrDone); VdbeCoverage(v);
|
||||
}else{
|
||||
assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
|
||||
sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone);
|
||||
VdbeCoverageIf(v, op==TK_LT);
|
||||
VdbeCoverageIf(v, op==TK_GT);
|
||||
VdbeCoverageIf(v, op==TK_LE);
|
||||
VdbeCoverageIf(v, op==TK_GE);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone);
|
||||
if( i==nLeft-2 ) opx = op;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, addrCmp);
|
||||
sqlite3VdbeResolveLabel(v, addrDone);
|
||||
if( op==TK_NE ){
|
||||
sqlite3VdbeAddOp2(v, OP_Not, dest, dest);
|
||||
}
|
||||
}
|
||||
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
|
||||
Reference in New Issue
Block a user