aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2016-07-29 20:58:19 +0000
committerdan <dan@noemail.net>2016-07-29 20:58:19 +0000
commit19ff12dd76b7b57cd9feed6298a399fc5d8f9cec (patch)
tree7b27213eb24b785ebf985193d90a07a3fbdf0fd0 /src
parent145b4ea519b7826e7905628c479549994e405b0b (diff)
downloadsqlite-19ff12dd76b7b57cd9feed6298a399fc5d8f9cec.tar.gz
sqlite-19ff12dd76b7b57cd9feed6298a399fc5d8f9cec.zip
Fix some issues with vector range constraints and the column cache. Also vector range constraints and rowid columns.
FossilOrigin-Name: 42607366bfc2dceb1013797a973b3b8df75dcb4d
Diffstat (limited to 'src')
-rw-r--r--src/expr.c2
-rw-r--r--src/wherecode.c21
-rw-r--r--src/whereexpr.c23
3 files changed, 28 insertions, 18 deletions
diff --git a/src/expr.c b/src/expr.c
index 3dcb73ff1..264f27dbf 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -411,6 +411,7 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){
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 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){
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 9db4a0146..5eb520eb3 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -964,9 +964,6 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
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 @@ Bitmask sqlite3WhereCodeOneLoopStart(
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 @@ Bitmask sqlite3WhereCodeOneLoopStart(
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 @@ Bitmask sqlite3WhereCodeOneLoopStart(
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 @@ Bitmask sqlite3WhereCodeOneLoopStart(
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 4b96e2faa..93908e6d3 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -1190,17 +1190,20 @@ static void exprAnalyze(
&& ( (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);
+ }
}
}