1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Catch vector size mismatch problems during name resolution to avoid later

problems.

FossilOrigin-Name: 56562a0346170cf7b72445976864b058437a8ac3
This commit is contained in:
drh
2016-09-05 12:02:34 +00:00
parent 80aa545337
commit b29e60c448
8 changed files with 141 additions and 92 deletions

View File

@@ -522,75 +522,68 @@ static void codeVectorCompare(
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
int nLeft = sqlite3ExprVectorSize(pLeft);
int nRight = sqlite3ExprVectorSize(pRight);
int i;
int regLeft = 0;
int regRight = 0;
u8 opx = op;
int addrDone = sqlite3VdbeMakeLabel(v);
/* Check that both sides of the comparison are vectors, and that
** both are the same length. */
if( nLeft!=nRight ){
sqlite3ErrorMsg(pParse, "row value misused");
}else{
int i;
int regLeft = 0;
int regRight = 0;
u8 opx = op;
int addrDone = sqlite3VdbeMakeLabel(v);
assert( nLeft==sqlite3ExprVectorSize(pRight) );
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|| pExpr->op==TK_LE || pExpr->op==TK_GE
);
assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
|| (pExpr->op==TK_ISNOT && op==TK_NE) );
assert( p5==0 || pExpr->op!=op );
assert( p5==SQLITE_NULLEQ || pExpr->op==op );
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|| pExpr->op==TK_LE || pExpr->op==TK_GE
);
assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
|| (pExpr->op==TK_ISNOT && op==TK_NE) );
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;
p5 |= SQLITE_STOREP2;
if( opx==TK_LE ) opx = TK_LT;
if( opx==TK_GE ) opx = TK_GT;
regLeft = exprCodeSubselect(pParse, pLeft);
regRight = exprCodeSubselect(pParse, pRight);
regLeft = exprCodeSubselect(pParse, pLeft);
regRight = exprCodeSubselect(pParse, pRight);
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( i>0 ) sqlite3ExprCachePush(pParse);
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);
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);
testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
if( i>0 ) sqlite3ExprCachePop(pParse);
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;
}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);
if( i==nLeft-2 ) opx = op;
}
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( i>0 ) sqlite3ExprCachePush(pParse);
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);
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);
testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
if( i>0 ) sqlite3ExprCachePop(pParse);
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;
}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);
if( i==nLeft-2 ) opx = op;
}
sqlite3VdbeResolveLabel(v, addrDone);
}
sqlite3VdbeResolveLabel(v, addrDone);
}
#if SQLITE_MAX_EXPR_DEPTH>0