More refactoring in where.c. (CVS 2552)
FossilOrigin-Name: a35bd50af8961133adc66e40c38402e81a02bb56
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Refactoring\sof\sthe\squery\soptimizer\sin\sadvance\sof\sadding\sbetter\soptimization.\s(CVS\s2551)
|
||||
D 2005-07-19T17:38:23
|
||||
C More\srefactoring\sin\swhere.c.\s(CVS\s2552)
|
||||
D 2005-07-19T22:22:13
|
||||
F Makefile.in 22ea9c0fe748f591712d8fe3c6d972c6c173a165
|
||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@@ -85,7 +85,7 @@ F src/vdbeapi.c 7f392f0792d1258c958083d7de9eae7c3530c9a6
|
||||
F src/vdbeaux.c 3732a86566a6be4da4c606e9334baf3fd98667af
|
||||
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
|
||||
F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
|
||||
F src/where.c 1da2268f5e37257276dff46ebbc1cc596a9efaa1
|
||||
F src/where.c 5a84161299ff90aeb67c885f6bf89c29c3efbb27
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
||||
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
|
||||
@@ -286,7 +286,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
|
||||
P ca69f36832d57775e73ac5cdbe0a32d7b759432b
|
||||
R 9a4258be8ecf1889fef260cdd1d2d34b
|
||||
P 57c6bd3760163c174be4a2ece58f414e82b55938
|
||||
R 3cdcdb6928aa7a2c42a275a913941b5a
|
||||
U drh
|
||||
Z a631f1b7791a9c3a4f6bac427d47518f
|
||||
Z b929286800f2e064fa91faa90163e11f
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
57c6bd3760163c174be4a2ece58f414e82b55938
|
||||
a35bd50af8961133adc66e40c38402e81a02bb56
|
||||
+55
-63
@@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.146 2005/07/19 17:38:23 drh Exp $
|
||||
** $Id: where.c,v 1.147 2005/07/19 22:22:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -551,6 +551,35 @@ static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){
|
||||
sqlite3IndexAffinityStr(v, pIdx);
|
||||
}
|
||||
|
||||
/*
|
||||
** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
|
||||
** where X is a reference to the iColumn of table iCur and <op> is either
|
||||
** op1 or op2. Return a pointer to the term.
|
||||
*/
|
||||
static WhereTerm *findTerm(
|
||||
WhereClause *pWC, /* The WHERE clause to be searched */
|
||||
int iCur, /* Cursor number of LHS */
|
||||
int iColumn, /* Column number of LHS */
|
||||
Bitmask loopMask, /* RHS must not overlap with this mask */
|
||||
u8 op1, u8 op2 /* Expression must use either of these opcodes */
|
||||
){
|
||||
WhereTerm *pTerm;
|
||||
int k;
|
||||
for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
|
||||
u8 op = pTerm->pExpr->op;
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& (pTerm->prereqRight & loopMask)==0
|
||||
&& pTerm->leftColumn==iColumn
|
||||
&& (op==op1 || op==op2)
|
||||
){
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( k>0 ); /* The search is always successful */
|
||||
return pTerm;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Generate code for an equality term of the WHERE clause. An equality
|
||||
** term can be either X=expr or X IN (...). pTerm is the X.
|
||||
@@ -1139,22 +1168,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** constraints that column. If the WHERE clause term is X=expr, then
|
||||
** generate code to evaluate expr and leave the result on the stack */
|
||||
for(j=0; j<nColumn; j++){
|
||||
for(pTerm=wc.a, k=0; k<wc.nTerm; k++, pTerm++){
|
||||
Expr *pX = pTerm->pExpr;
|
||||
assert( pX );
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& (pTerm->prereqRight & loopMask)==0
|
||||
&& pTerm->leftColumn==pIdx->aiColumn[j]
|
||||
&& (pX->op==TK_EQ || pX->op==TK_IN)
|
||||
){
|
||||
char idxaff = pIdx->pTable->aCol[pTerm->leftColumn].affinity;
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
if( sqlite3IndexAffinityOk(pX, idxaff) ){
|
||||
codeEqualityTerm(pParse, pTerm, brk, pLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_EQ, TK_IN);
|
||||
assert( pTerm!=0 );
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
codeEqualityTerm(pParse, pTerm, brk, pLevel);
|
||||
}
|
||||
pLevel->iMem = pParse->nMem++;
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
@@ -1287,21 +1304,11 @@ WhereInfo *sqlite3WhereBegin(
|
||||
/* Evaluate the equality constraints
|
||||
*/
|
||||
for(j=0; j<nEqColumn; j++){
|
||||
int iIdxCol = pIdx->aiColumn[j];
|
||||
for(pTerm=wc.a, k=0; k<wc.nTerm; k++, pTerm++){
|
||||
Expr *pX;
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& pTerm->leftColumn==iIdxCol
|
||||
&& (pX = pTerm->pExpr)->op==TK_EQ
|
||||
&& (pTerm->prereqRight & loopMask)==0
|
||||
){
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
disableTerm(pLevel, pTerm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( k<wc.nTerm );
|
||||
pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_EQ, TK_EQ);
|
||||
assert( pTerm!=0 );
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pTerm->pExpr->pRight);
|
||||
disableTerm(pLevel, pTerm);
|
||||
}
|
||||
|
||||
/* Duplicate the equality term values because they will all be
|
||||
@@ -1325,22 +1332,14 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** key computed here really ends up being the start key.
|
||||
*/
|
||||
if( (score & 4)!=0 ){
|
||||
for(pTerm=wc.a, k=0; k<wc.nTerm; k++, pTerm++){
|
||||
Expr *pX = pTerm->pExpr;
|
||||
assert( pX );
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& (pX->op==TK_LT || pX->op==TK_LE)
|
||||
&& (pTerm->prereqRight & loopMask)==0
|
||||
&& pTerm->leftColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
leFlag = pX->op==TK_LE;
|
||||
disableTerm(pLevel, pTerm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( k<wc.nTerm );
|
||||
Expr *pX;
|
||||
pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_LT, TK_LE);
|
||||
assert( pTerm!=0 );
|
||||
pX = pTerm->pExpr;
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
leFlag = pX->op==TK_LE;
|
||||
disableTerm(pLevel, pTerm);
|
||||
testOp = OP_IdxGE;
|
||||
}else{
|
||||
testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
|
||||
@@ -1370,21 +1369,14 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** "start" key really ends up being used as the termination key.
|
||||
*/
|
||||
if( (score & 8)!=0 ){
|
||||
for(pTerm=wc.a, k=0; k<wc.nTerm; k++, pTerm++){
|
||||
Expr *pX = pTerm->pExpr;
|
||||
assert( pX );
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& (pX->op==TK_GT || pX->op==TK_GE)
|
||||
&& (pTerm->prereqRight & loopMask)==0
|
||||
&& pTerm->leftColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
geFlag = pX->op==TK_GE;
|
||||
disableTerm(pLevel, pTerm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Expr *pX;
|
||||
pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_GT, TK_GE);
|
||||
assert( pTerm!=0 );
|
||||
pX = pTerm->pExpr;
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
geFlag = pX->op==TK_GE;
|
||||
disableTerm(pLevel, pTerm);
|
||||
}else{
|
||||
geFlag = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user