aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/where.c28
-rw-r--r--src/whereInt.h5
2 files changed, 16 insertions, 17 deletions
diff --git a/src/where.c b/src/where.c
index 021cab187..c2824862e 100644
--- a/src/where.c
+++ b/src/where.c
@@ -2504,11 +2504,11 @@ static int codeAllEqualityTerms(
if( nSkip ){
int iIdxCur = pLevel->iIdxCur;
- sqlite3VdbeAddOp2(v, (bRev?OP_Last:OP_Rewind), iIdxCur, pLevel->addrNxt);
- pLevel->addrSkip = sqlite3VdbeCurrentAddr(v);
- pLevel->opSkip = bRev ? OP_SeekLt : OP_SeekGt;
- pLevel->p3Skip = regBase;
- pLevel->p4Skip = nSkip;
+ sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
+ j = sqlite3VdbeAddOp0(v, OP_Goto);
+ pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt),
+ iIdxCur, 0, regBase, nSkip);
+ sqlite3VdbeJumpHere(v, j);
for(j=0; j<nSkip; j++){
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
assert( pIdx->aiColumn[j]>=0 );
@@ -3928,11 +3928,13 @@ static int whereLoopAddBtreeIndex(
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowEst[saved_nEq+1]>50
){
+ LogEst nIter;
pNew->u.btree.nEq++;
pNew->u.btree.nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
- pNew->wsFlags |= WHERE_SKIP_SCAN;
- whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul);
+ pNew->wsFlags |= WHERE_SKIPSCAN;
+ nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
+ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
}
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0;
@@ -3969,8 +3971,10 @@ static int whereLoopAddBtreeIndex(
pNew->u.btree.nEq++;
pNew->nOut = nRowEst + nInMul + nIn;
}else if( pTerm->eOperator & (WO_EQ) ){
- assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0
- || nInMul==0 );
+ assert(
+ (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0
+ || nInMul==0
+ );
pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0
|| (pProbe->onError!=OE_None && nInMul==0
@@ -5784,11 +5788,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
- addr = sqlite3VdbeAddOp4Int(v, pLevel->opSkip, pLevel->iIdxCur, 0,
- pLevel->p3Skip, pLevel->p4Skip);
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
- sqlite3VdbeJumpHere(v, pLevel->addrSkip-1);
- sqlite3VdbeJumpHere(v, addr);
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip);
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
if( pLevel->iLeftJoin ){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
diff --git a/src/whereInt.h b/src/whereInt.h
index 62c93471e..56646c55e 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -71,10 +71,7 @@ struct WhereLevel {
int addrBody; /* Beginning of the body of this loop */
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
- u8 opSkip; /* Opcode to terminate the skip-scan */
int p1, p2; /* Operands of the opcode used to ends the loop */
- int p3Skip; /* P3 operand for the skip-scan terminator */
- u16 p4Skip; /* P4 operand for the skip-scan terminator */
union { /* Information that depends on pWLoop->wsFlags */
struct {
int nIn; /* Number of entries in aInLoop[] */
@@ -459,4 +456,4 @@ struct WhereInfo {
#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
-#define WHERE_SKIP_SCAN 0x00008000 /* Uses the skip-scan algorithm */
+#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */