diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/where.c | 28 | ||||
-rw-r--r-- | src/whereInt.h | 5 |
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 */ |