Fix some issues with vector range constraints and the column cache. Also vector range constraints and rowid columns.
FossilOrigin-Name: 42607366bfc2dceb1013797a973b3b8df75dcb4d
diff --git a/src/expr.c b/src/expr.c
index 3dcb73f..264f27d 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -411,6 +411,7 @@
Expr *pL, *pR;
int r1, r2;
+ if( i ) sqlite3ExprCachePush(pParse);
if( regLeft ){
pL = pLeft->x.pSelect->pEList->a[i].pExpr;
r1 = regLeft+i;
@@ -431,6 +432,7 @@
sqlite3VdbeAddOp3(v, opTest, dest, addr, p3);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
+ if( i ) sqlite3ExprCachePop(pParse);
}
}
diff --git a/src/wherecode.c b/src/wherecode.c
index 9db4a01..5eb520e 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -964,9 +964,6 @@
Vdbe *v = pParse->pVdbe;
int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
- p->op2 = p->op;
- p->op = TK_REGISTER;
- p->iTable = iSelect;
}
}else{
assert( nReg==1 );
@@ -1183,6 +1180,7 @@
if( pStart ){
Expr *pX; /* The expression that defines the start bound */
int r1, rTemp; /* Registers for holding the start boundary */
+ int op; /* Cursor seek operation */
/* The following constant maps TK_xx codes into corresponding
** seek opcodes. It depends on a particular ordering of TK_xx
@@ -1202,8 +1200,16 @@
pX = pStart->pExpr;
assert( pX!=0 );
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
- sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
+ if( pX->pRight->flags & EP_Vector ){
+ r1 = rTemp = sqlite3GetTempReg(pParse);
+ codeExprOrVector(pParse, pX->pRight, r1, 1);
+ op = aMoveOp[(pX->op - TK_GT) | 0x0001];
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+ disableTerm(pLevel, pStart);
+ op = aMoveOp[(pX->op - TK_GT)];
+ }
+ sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
@@ -1211,7 +1217,6 @@
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
- disableTerm(pLevel, pStart);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
VdbeCoverageIf(v, bRev==0);
@@ -1225,8 +1230,8 @@
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
- sqlite3ExprCode(pParse, pX->pRight, memEndValue);
- if( pX->op==TK_LT || pX->op==TK_GT ){
+ codeExprOrVector(pParse, pX->pRight, memEndValue, 1);
+ if( !(pX->pRight->flags&EP_Vector) && (pX->op==TK_LT || pX->op==TK_GT) ){
testOp = bRev ? OP_Le : OP_Ge;
}else{
testOp = bRev ? OP_Lt : OP_Gt;
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 4b96e2f..93908e6 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -1190,17 +1190,20 @@
&& ( (pExpr->pLeft->flags & EP_xIsSelect)==0
|| (pExpr->pRight->flags & EP_xIsSelect)==0
)){
- int i;
- for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
- int idxNew;
- Expr *pNew;
- Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i);
- Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i);
+ int nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
+ if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){
+ int i;
+ for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
+ int idxNew;
+ Expr *pNew;
+ Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i);
+ Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i);
- pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
- idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
- exprAnalyze(pSrc, pWC, idxNew);
- markTermAsChild(pWC, idxNew, idxTerm);
+ pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
+ idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+ exprAnalyze(pSrc, pWC, idxNew);
+ markTermAsChild(pWC, idxNew, idxTerm);
+ }
}
}