]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More refactoring in where.c. (CVS 2552)
authordrh <drh@noemail.net>
Tue, 19 Jul 2005 22:22:12 +0000 (22:22 +0000)
committerdrh <drh@noemail.net>
Tue, 19 Jul 2005 22:22:12 +0000 (22:22 +0000)
FossilOrigin-Name: a35bd50af8961133adc66e40c38402e81a02bb56

manifest
manifest.uuid
src/where.c

index 388983af7bd78ba81ff0c28ce58c3f0be232fae1..f63464223e524b496f943584364154d9b0f9c35a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 872d65ac524a73e74ed06a26493a36275c7fb6b6..20ef12eab7190a84753d12f6b6f5a8116a255c42 100644 (file)
@@ -1 +1 @@
-57c6bd3760163c174be4a2ece58f414e82b55938
\ No newline at end of file
+a35bd50af8961133adc66e40c38402e81a02bb56
\ No newline at end of file
index d9cf7c07635bbcd88c28de6a30847b3cbe901a28..1e5dc61612680dee7078720596ae4aa3c959d43c 100644 (file)
@@ -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;
       }