aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/where.c14
-rw-r--r--src/whereInt.h4
-rw-r--r--src/wherecode.c9
-rw-r--r--src/whereexpr.c1
4 files changed, 21 insertions, 7 deletions
diff --git a/src/where.c b/src/where.c
index 2afc012f6..ce6ae3070 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3463,10 +3463,9 @@ static int whereLoopAddBtree(
** Return true if pTerm is a virtual table LIMIT or OFFSET term.
*/
static int isLimitTerm(WhereTerm *pTerm){
- return pTerm->eOperator==WO_AUX && (
- pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT
- || pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
- );
+ assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
+ return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
+ && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
}
/*
@@ -3555,8 +3554,8 @@ static int whereLoopAddVirtualOne(
mxTerm = -1;
assert( pNew->nLSlot>=nConstraint );
- for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
- pNew->u.vtab.omitMask = 0;
+ memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
+ memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
for(i=0; i<nConstraint; i++, pIdxCons++){
int iTerm;
@@ -3590,6 +3589,9 @@ static int whereLoopAddVirtualOne(
}else{
testcase( i!=iTerm );
}
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
+ pNew->u.vtab.bOmitOffset = 1;
+ }
}
if( (pTerm->eOperator & WO_IN)!=0 ){
/* A virtual table that is constrained by an IN clause may not
diff --git a/src/whereInt.h b/src/whereInt.h
index cdddc1052..14c40fcb4 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -123,7 +123,8 @@ struct WhereLoop {
} btree;
struct { /* Information for virtual tables */
int idxNum; /* Index number */
- u8 needFree; /* True if sqlite3_free(idxStr) is needed */
+ u8 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
+ u8 bOmitOffset : 1; /* True to let virtual table handle offset */
i8 isOrdered; /* True if satisfies ORDER BY */
u16 omitMask; /* Terms that may be omitted */
char *idxStr; /* Index identifier string */
@@ -612,5 +613,6 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
+#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
#endif /* !defined(SQLITE_WHEREINT_H) */
diff --git a/src/wherecode.c b/src/wherecode.c
index 4990cda0c..2beb596e6 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1537,6 +1537,15 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}else{
Expr *pRight = pTerm->pExpr->pRight;
codeExprOrVector(pParse, pRight, iTarget, 1);
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
+ && pLoop->u.vtab.bOmitOffset
+ ){
+ assert( pTerm->eOperator==WO_AUX );
+ assert( pWInfo->pLimit!=0 );
+ assert( pWInfo->pLimit->iOffset>0 );
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
+ VdbeComment((v,"Zero OFFSET counter"));
+ }
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 183f22f59..8381994e2 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -1656,6 +1656,7 @@ void sqlite3WhereClauseClear(WhereClause *pWC){
}
#endif
while(1){
+ assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
if( a->wtFlags & TERM_DYNAMIC ){
sqlite3ExprDelete(db, a->pExpr);
}