1
0
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:
drh
2021-03-29 18:53:47 +00:00
parent 871e7ff43d
commit 4bc20452b5
6 changed files with 57 additions and 97 deletions

View File

@@ -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, &regFree1);
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
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