diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/where.c | 14 | ||||
-rw-r--r-- | src/whereInt.h | 4 | ||||
-rw-r--r-- | src/wherecode.c | 9 | ||||
-rw-r--r-- | src/whereexpr.c | 1 |
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); } |