]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Comment and variable-name cleanup in where.c. Add testcase() macros to
authordrh <drh@noemail.net>
Sat, 19 Apr 2008 14:40:43 +0000 (14:40 +0000)
committerdrh <drh@noemail.net>
Sat, 19 Apr 2008 14:40:43 +0000 (14:40 +0000)
insure adequate test coverage of table-driven logic. (CVS 5032)

FossilOrigin-Name: adcef73b3925266a14a552cd9b06c14f22aaefc8

manifest
manifest.uuid
src/where.c

index 09726b55c6efac2c6fd05abf4bb1acba378a2b5f..6cb4b86d29ef42dae0a31fcbef6c0209bc12ab71 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\stypo\sin\sthe\sdocumentation\son\ssqlite3_open_v2().\s(CVS\s5031)
-D 2008-04-19T14:06:28
+C Comment\sand\svariable-name\scleanup\sin\swhere.c.\s\sAdd\stestcase()\smacros\sto\ninsure\sadequate\stest\scoverage\sof\stable-driven\slogic.\s(CVS\s5032)
+D 2008-04-19T14:40:44
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -183,7 +183,7 @@ F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
 F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
 F src/vdbemem.c 237e61216381998ff71c6431e5e7bd03386f6225
 F src/vtab.c f5e78bf73df3b0c1b53861109c1b2e0800b108cc
-F src/where.c 011f866cf0f05c832eea5a30e079eb108253ac64
+F src/where.c 85719d58e0f680b5d8239dc6af82b159775d7376
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test d56a3ca8acdf761204aff0a2e7aa5eb8e11b31e6
@@ -631,7 +631,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P df02175ec0f28d57942b8275b540ff855dfbeb09
-R 6299f6a06e93546f99df6a47ebb09453
+P f7b62daa9fe71dc713bde107507fc7bcb812d62b
+R 6e41e3d0b22d62b812d3d07204f15026
 U drh
-Z 385bf8bab63aafd1f261478c271df70c
+Z 179f0ff656646746a01845fdd389ea41
index 0ea254a6afa9ad28955cff3f7b43be7311ae067d..bc25a98ea9ed02613e3f36b887a0dd549b90f24f 100644 (file)
@@ -1 +1 @@
-f7b62daa9fe71dc713bde107507fc7bcb812d62b
\ No newline at end of file
+adcef73b3925266a14a552cd9b06c14f22aaefc8
\ No newline at end of file
index 5bce2262eec876c4c0eb237cf0b577b04f6f7a7f..c12462822dbdbd61acec3310dc459eddfd78e878 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.301 2008/04/18 10:25:24 danielk1977 Exp $
+** $Id: where.c,v 1.302 2008/04/19 14:40:44 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1272,8 +1272,10 @@ static double bestVirtualIndex(
     ** to this virtual table */
     for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
       if( pTerm->leftCursor != pSrc->iCursor ) continue;
-      if( pTerm->eOperator==WO_IN ) continue;
-      if( pTerm->eOperator==WO_ISNULL ) continue;
+      if( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
+      testcase( pTerm->eOperator==WO_IN );
+      testcase( pTerm->eOperator==WO_ISNULL );
+      if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
       nTerm++;
     }
 
@@ -1320,8 +1322,10 @@ static double bestVirtualIndex(
 
     for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
       if( pTerm->leftCursor != pSrc->iCursor ) continue;
-      if( pTerm->eOperator==WO_IN ) continue;
-      if( pTerm->eOperator==WO_ISNULL ) continue;
+      if( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
+      testcase( pTerm->eOperator==WO_IN );
+      testcase( pTerm->eOperator==WO_ISNULL );
+      if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
       pIdxCons[j].iColumn = pTerm->leftColumn;
       pIdxCons[j].iTermOffset = i;
       pIdxCons[j].op = pTerm->eOperator;
@@ -1867,6 +1871,8 @@ static int codeAllEqualityTerms(
     if( r1!=regBase+j ){
       sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
     }
+    testcase( pTerm->eOperator & WO_ISNULL );
+    testcase( pTerm->eOperator & WO_IN );
     if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
       sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->brk);
     }
@@ -2456,7 +2462,7 @@ WhereInfo *sqlite3WhereBegin(
     }else if( pLevel->flags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
       /* Case 3: A scan using an index.
       **
-      **         The WHERE clause may contain one or more equality 
+      **         The WHERE clause may contain zero or more equality 
       **         terms ("==" or "IN" operators) that refer to the N
       **         left-most columns of the index. It may also contain
       **         inequality constraints (>, <, >= or <=) on the indexed
@@ -2472,10 +2478,15 @@ WhereInfo *sqlite3WhereBegin(
       **            x=5 AND y>5 AND y<10
       **            x=5 AND y=5 AND z<=10
       **
-      **         This cannot be optimized:
+      **         The z<10 term of the following cannot be used, only
+      **         the x=5 term:
       **
       **            x=5 AND z<10
       **
+      **         N may be zero if there are inequality constraints.
+      **         If there are no inequality constraints, then N is at
+      **         least one.
+      **
       **         This case is also used when there are no WHERE clause
       **         constraints but an index is selected anyway, in order
       **         to force the output order to conform to an ORDER BY.
@@ -2505,7 +2516,7 @@ WhereInfo *sqlite3WhereBegin(
       int endEq;                   /* True if range end uses ==, >= or <= */
       int start_constraints;       /* Start of range is constrained */
       int k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */
-      char *ptr;
+      int nConstraint;             /* Number of constraint terms */
       int op;
 
       /* Generate code to evaluate all constraint terms using == or IN
@@ -2545,16 +2556,20 @@ WhereInfo *sqlite3WhereBegin(
       ** a forward order scan on a descending index, interchange the 
       ** start and end terms (pRangeStart and pRangeEnd).
       */
-      if( bRev==((pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)?1:0) ){
+      if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
         SWAP(WhereTerm *, pRangeEnd, pRangeStart);
       }
 
-      startEq = ((!pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE))?1:0);
-      endEq = ((!pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE))?1:0);
-      start_constraints = ((pRangeStart || nEq>0)?1:0);
+      testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
+      testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
+      testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
+      testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
+      startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
+      endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
+      start_constraints = pRangeStart || nEq>0;
 
       /* Seek the index cursor to the start of the range. */
-      ptr = (char *)(sqlite3_intptr_t)nEq;
+      nConstraint = nEq;
       if( pRangeStart ){
         int dcc = pParse->disableColCache;
         if( pRangeEnd ){
@@ -2563,42 +2578,55 @@ WhereInfo *sqlite3WhereBegin(
         sqlite3ExprCode(pParse, pRangeStart->pExpr->pRight, regBase+nEq);
         pParse->disableColCache = dcc;
         sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, nxt);
-        ptr++;
+        nConstraint++;
       }else if( isMinQuery ){
         sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
-        ptr++;
+        nConstraint++;
         startEq = 0;
         start_constraints = 1;
       }
-      codeApplyAffinity(pParse, regBase, (int)ptr, pIdx);
+      codeApplyAffinity(pParse, regBase, nConstraint, pIdx);
       op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
-      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase, ptr, P4_INT32);
+      assert( op!=0 );
+      testcase( op==OP_Rewind );
+      testcase( op==OP_Last );
+      testcase( op==OP_MoveGt );
+      testcase( op==OP_MoveGe );
+      testcase( op==OP_MoveLe );
+      testcase( op==OP_MoveLt );
+      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase, 
+                        (char*)nConstraint, P4_INT32);
 
       /* Load the value for the inequality constraint at the end of the
       ** range (if any).
       */
-      ptr = (char *)(sqlite3_intptr_t)nEq;
+      nConstraint = nEq;
       if( pRangeEnd ){
         sqlite3ExprCode(pParse, pRangeEnd->pExpr->pRight, regBase+nEq);
         sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, nxt);
         codeApplyAffinity(pParse, regBase, nEq+1, pIdx);
-        ptr++;
+        nConstraint++;
       }
 
       /* Top of the loop body */
       pLevel->p2 = sqlite3VdbeCurrentAddr(v);
 
       /* Check if the index cursor is past the end of the range. */
-      op = aEndOp[((pRangeEnd || nEq)?1:0) * (1 + bRev)];
-      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase, ptr, P4_INT32);
+      op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
+      testcase( op==OP_Noop );
+      testcase( op==OP_IdxGE );
+      testcase( op==OP_IdxLT );
+      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase,
+                        (char*)nConstraint, P4_INT32);
       sqlite3VdbeChangeP5(v, endEq!=bRev);
 
-      /* If there are inequality constraints (there may not be if the
-      ** index is only being used to optimize ORDER BY), check that the
-      ** value of the table column the inequality contrains is not NULL.
+      /* If there are inequality constraints, check that the value
+      ** of the table column that the inequality contrains is not NULL.
       ** If it is, jump to the next iteration of the loop.
       */
       r1 = sqlite3GetTempReg(pParse);
+      testcase( pLevel->flags & WHERE_BTM_LIMIT );
+      testcase( pLevel->flags & WHERE_TOP_LIMIT );
       if( pLevel->flags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
         sqlite3VdbeAddOp2(v, OP_IsNull, r1, cont);
@@ -2619,7 +2647,7 @@ WhereInfo *sqlite3WhereBegin(
       disableTerm(pLevel, pRangeStart);
       disableTerm(pLevel, pRangeEnd);
     }else{
-      /* Case 5:  There is no usable index.  We must do a complete
+      /* Case 4:  There is no usable index.  We must do a complete
       **          scan of the entire table.
       */
       assert( omitTable==0 );
@@ -2635,6 +2663,8 @@ WhereInfo *sqlite3WhereBegin(
     */
     for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){
       Expr *pE;
+      testcase( pTerm->flags & TERM_VIRTUAL );
+      testcase( pTerm->flags & TERM_CODED );
       if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
       if( (pTerm->prereqAll & notReady)!=0 ) continue;
       pE = pTerm->pExpr;
@@ -2656,6 +2686,8 @@ WhereInfo *sqlite3WhereBegin(
       sqlite3ExprClearColumnCache(pParse, pLevel->iTabCur);
       sqlite3ExprClearColumnCache(pParse, pLevel->iIdxCur);
       for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
+        testcase( pTerm->flags & TERM_VIRTUAL );
+        testcase( pTerm->flags & TERM_CODED );
         if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
         if( (pTerm->prereqAll & notReady)!=0 ) continue;
         assert( pTerm->pExpr );
@@ -2690,6 +2722,8 @@ WhereInfo *sqlite3WhereBegin(
       }
       sqlite3_query_plan[nQPlan++] = ' ';
     }
+    testcase( pLevel->flags & WHERE_ROWID_EQ );
+    testcase( pLevel->flags & WHERE_ROWID_RANGE );
     if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
       memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
       nQPlan += 2;