]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Futher simplifications to the NGQP. Fix some test cases to use
authordrh <drh@noemail.net>
Thu, 30 May 2013 19:29:19 +0000 (19:29 +0000)
committerdrh <drh@noemail.net>
Thu, 30 May 2013 19:29:19 +0000 (19:29 +0000)
EXPLAIN QUERY PLAN rather than the (now obsolete) sqlite_query_plan
global variable.

FossilOrigin-Name: ae985db4fa08b5efbef5a834e852f0b05101264b

manifest
manifest.uuid
src/test1.c
src/where.c
test/where.test

index e5e6cf6db7c39d7c5b357322fb42d14e9507a740..b53641713883456fa0b1d29637a2b582cd4d3325 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sexpected\sresult\sin\sa\stest\scase\scan\sbe\sof\sthe\sform\s"*glob*"\sor\s"~*glob*"\sto\s\nmatch\sor\snot\smatch\sthe\sGLOB\spattern.\s\sThis\sis\suseful\sfor\smatching\nEXPLAIN\sQUERY\sPLAN\soutput\sthat\scontains\sregular\sexpression\ssyntax\scharacters\nlike\s"?",\s"(",\sand\s")".
-D 2013-05-30T19:28:34.431
+C Futher\ssimplifications\sto\sthe\sNGQP.\s\sFix\ssome\stest\scases\sto\suse\nEXPLAIN\sQUERY\sPLAN\srather\sthan\sthe\s(now\sobsolete)\ssqlite_query_plan\nglobal\svariable.
+D 2013-05-30T19:29:19.963
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -225,7 +225,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c 2ecec9937e69bc17560ad886da35195daa7261b8
-F src/test1.c 6d2a340eea1d866bf7059894491652a69a7ee802
+F src/test1.c 5f9837aee1a0708ab2dbf67ce0b9c18e658cd36b
 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
 F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
 F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
-F src/where.c 296baae1cbfd99527d8c87f9773a6c98116f6b8a
+F src/where.c 3e9b7b3323f78ec3056c5e3aa3443661bc590054
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1028,7 +1028,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
 F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
-F test/where.test 15ac8611c9439a2c5f4a6ac10cfe4c1ec9854c24
+F test/where.test 054a6b6f7933c5a5f50d0bcd650b5eccb450cc81
 F test/where2.test 399b3178289925a0aa976b3d60ef139740540ecd
 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@@ -1093,7 +1093,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 001539df4b74dc1cbceb010a91407003ab4d8735
-R ae73b581603fe5cb9a5fdce5dbec1c53
+P a3b4e261bd7e278f150872cce7b020af5ad8d2ed
+R b028bf2657ab598aee5d4698a0488fdc
 U drh
-Z 68529a7f58c35b9a5dca06d2c9973260
+Z 3432943259d0f5aa9c669ba0e80caf85
index 08e57409dd5e79a55cf28ed38ecb1ba62760b764..bdeb520d0105ede87b25ffeda277e4518df17ef9 100644 (file)
@@ -1 +1 @@
-a3b4e261bd7e278f150872cce7b020af5ad8d2ed
\ No newline at end of file
+ae985db4fa08b5efbef5a834e852f0b05101264b
\ No newline at end of file
index bd6d4a4cfd9b6e15fba7714fec256e80c48a1ff1..8edaedab8a2b7c5aeec18683a0e0f96af53d2457 100644 (file)
@@ -6302,8 +6302,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
   extern int sqlite3WalTrace;
 #endif
 #ifdef SQLITE_TEST
-  extern char sqlite3_query_plan[];
-  static char *query_plan = sqlite3_query_plan;
 #ifdef SQLITE_ENABLE_FTS3
   extern int sqlite3_fts3_enable_parentheses;
 #endif
@@ -6357,8 +6355,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
       (char*)&sqlite3_os_type, TCL_LINK_INT);
 #endif
 #ifdef SQLITE_TEST
-  Tcl_LinkVar(interp, "sqlite_query_plan",
-      (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
+  {
+    static const char *query_plan = "*** OBSOLETE VARIABLE ***";
+    Tcl_LinkVar(interp, "sqlite_query_plan",
+       (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
+  }
 #endif
 #ifdef SQLITE_DEBUG
   Tcl_LinkVar(interp, "sqlite_where_trace",
index a9a431ba9aad73574775f0ca3f8bc47c4d0cd396..8ddbd5d72bc3d510655a43080e7f1433d589b073 100644 (file)
@@ -326,33 +326,22 @@ struct WhereLoopBuilder {
 ** WhereLevel.wsFlags.  These flags determine which search
 ** strategies are appropriate.
 */
-#define WHERE_ROWID_EQ     0x00000001  /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE  0x00000002  /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_NULL_OK      0x00000004  /* Ok to use WO_ISNULL */
-#define WHERE_IPK          0x00000008  /* x is the INTEGER PRIMARY KEY */
-#define WHERE_COLUMN_EQ    0x00000010  /* x=EXPR or x IN (...) or x IS NULL */
-#define WHERE_COLUMN_RANGE 0x00000020  /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN    0x00000040  /* x IN (...) */
-#define WHERE_COLUMN_NULL  0x00000080  /* x IS NULL */
-#define WHERE_INDEXED      0x000000f0  /* Anything that uses an index */
-#define WHERE_NOT_FULLSCAN 0x000200f3  /* Does not do a full table scan */
-#define WHERE_IN_ABLE      0x000100f1  /* Able to support an IN operator */
-#define WHERE_TOP_LIMIT    0x00000100  /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT    0x00000200  /* x>EXPR or x>=EXPR constraint */
-#define WHERE_BOTH_LIMIT   0x00000300  /* Both x>EXPR and x<EXPR */
-#define WHERE_IDX_ONLY     0x00000400  /* Use index only - omit table */
-#define WHERE_ORDERED      0x00000800  /* Output will appear in correct order */
-#define WHERE_REVERSE      0x00001000  /* Scan in reverse order */
-#define WHERE_UNIQUE       0x00002000  /* Selects no more than one row */
-#define WHERE_ALL_UNIQUE   0x00004000  /* This and all prior have one row */
-#define WHERE_OB_UNIQUE    0x00008000  /* Values in ORDER BY columns are 
-                                       ** different for every output row */
-#define WHERE_VIRTUALTABLE 0x00010000  /* Use virtual-table processing */
-#define WHERE_MULTI_OR     0x00020000  /* OR using multiple indices */
-#define WHERE_TEMP_INDEX   0x00040000  /* Uses an ephemeral index */
-#define WHERE_DISTINCT     0x00080000  /* Correct order for DISTINCT */
-#define WHERE_COVER_SCAN   0x00100000  /* Full scan of a covering index */
-#define WHERE_SINGLE_ROW   0x00200000  /* No more than one row guaranteed */
+#define WHERE_COLUMN_EQ    0x00000001  /* x=EXPR or x IN (...) or x IS NULL */
+#define WHERE_COLUMN_RANGE 0x00000002  /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN    0x00000004  /* x IN (...) */
+#define WHERE_COLUMN_NULL  0x00000008  /* x IS NULL */
+#define WHERE_TOP_LIMIT    0x00000010  /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT    0x00000020  /* x>EXPR or x>=EXPR constraint */
+#define WHERE_BOTH_LIMIT   0x00000030  /* Both x>EXPR and x<EXPR */
+#define WHERE_IDX_ONLY     0x00000040  /* Use index only - omit table */
+#define WHERE_IPK          0x00000100  /* x is the INTEGER PRIMARY KEY */
+#define WHERE_INDEXED      0x00000200  /* WhereLoop.u.btree.pIndex is valid */
+#define WHERE_VIRTUALTABLE 0x00000400  /* WhereLoop.u.vtab is valid */
+#define WHERE_IN_ABLE      0x00000800  /* Able to support an IN operator */
+#define WHERE_UNIQUE       0x00001000  /* Selects no more than one row */
+#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
+#define WHERE_TEMP_INDEX   0x00004000  /* Uses an ephemeral index */
+#define WHERE_COVER_SCAN   0x00008000  /* Full scan of a covering index */
 
 /*
 ** This module contains many separate subroutines that work together to
@@ -2671,7 +2660,8 @@ static int codeEqualityTerm(
     }
     iTab = pX->iTable;
     sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
-    assert( pLoop->wsFlags & WHERE_IN_ABLE );
+    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+    pLoop->wsFlags |= WHERE_IN_ABLE;
     if( pLevel->u.in.nIn==0 ){
       pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
     }
@@ -3193,7 +3183,8 @@ static Bitmask codeOneLoopStart(
       sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
       sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
     }
-  }else if( pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ|WHERE_IDX_ONLY) ){
+  }else if( pLoop->wsFlags & (WHERE_COLUMN_RANGE | WHERE_COLUMN_NULL |
+                              WHERE_COLUMN_EQ | WHERE_IDX_ONLY) ){
     /* Case 4: A scan using an index.
     **
     **         The WHERE clause may contain zero or more equality 
@@ -3746,18 +3737,6 @@ static Bitmask codeOneLoopStart(
   return newNotReady;
 }
 
-#if defined(SQLITE_TEST)
-/*
-** The following variable holds a text description of query plan generated
-** by the most recent call to sqlite3WhereBegin().  Each call to WhereBegin
-** overwrites the previous.  This information is used for testing and
-** analysis only.
-*/
-char sqlite3_query_plan[BMS*2*40];  /* Text of the join */
-static int nQPlan = 0;              /* Next free slow in _query_plan[] */
-
-#endif /* SQLITE_TEST */
-
 #ifdef WHERETRACE_ENABLED
 /*
 ** Print a WhereLoop object for debugging purposes
@@ -3793,7 +3772,7 @@ static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){
     sqlite3DebugPrintf(" %-15s", z);
     sqlite3_free(z);
   }
-  sqlite3DebugPrintf(" fg %08x N %d", p->wsFlags, p->nTerm);
+  sqlite3DebugPrintf(" fg %05x N %d", p->wsFlags, p->nTerm);
   sqlite3DebugPrintf(" cost %.2g,%.2g,%.2g\n",
                      p->prereq, p->rSetup, p->rRun, p->nOut);
 }
@@ -3810,6 +3789,10 @@ static void whereLoopClear(sqlite3 *db, WhereLoop *p){
     if( p->u.vtab.needFree ) sqlite3_free(p->u.vtab.idxStr);
     p->u.vtab.needFree = 0;
     p->u.vtab.idxStr = 0;
+  }else if( (p->wsFlags & WHERE_TEMP_INDEX)!=0 && p->u.btree.pIndex!=0 ){
+    sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
+    sqlite3DbFree(db, p->u.btree.pIndex);
+    p->u.btree.pIndex = 0;
   }
 }
 
@@ -3826,16 +3809,6 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
 */
 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
   if( ALWAYS(pWInfo) ){
-    int i;
-    for(i=0; i<pWInfo->nLevel; i++){
-      if( pWInfo->a[i].pWLoop->wsFlags & WHERE_TEMP_INDEX ){
-        Index *pIdx = pWInfo->a[i].pWLoop->u.btree.pIndex;
-        if( pIdx ){
-          sqlite3DbFree(db, pIdx->zColAff);
-          sqlite3DbFree(db, pIdx);
-        }
-      }
-    }
     whereClauseClear(pWInfo->pWC);
     while( pWInfo->pLoops ){
       WhereLoop *p = pWInfo->pLoops;
@@ -4026,10 +3999,14 @@ static int whereLoopAddBtreeIndex(
       }
       pNew->u.btree.nEq++;
       pNew->nOut = (double)iRowEst * nInMul * nIn;
-    }else if( pTerm->eOperator & (WO_EQ|WO_ISNULL) ){
+    }else if( pTerm->eOperator & (WO_EQ) ){
       pNew->wsFlags |= WHERE_COLUMN_EQ;
       pNew->u.btree.nEq++;
       pNew->nOut = (double)iRowEst * nInMul;
+    }else if( pTerm->eOperator & (WO_ISNULL) ){
+      pNew->wsFlags |= WHERE_COLUMN_NULL;
+      pNew->u.btree.nEq++;
+      pNew->nOut = (double)iRowEst * nInMul;
     }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
       pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
       pNew->nOut = savedLoop.nOut/3;
@@ -4197,7 +4174,7 @@ static int whereLoopAddBtree(
           m &= ~(((Bitmask)1)<<x);
         }
       }
-      pNew->wsFlags = (m==0) ? WHERE_IDX_ONLY : 0;
+      pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
 
       /* Full scan via index */
       if( (m==0 || b) && pProbe->bUnordered==0 ){
@@ -5246,62 +5223,7 @@ WhereInfo *sqlite3WhereBegin(
     pWInfo->iContinue = pLevel->addrCont;
   }
 
-#if defined(SQLITE_TEST) && 0  /* For testing and debugging use only */
-  /* Record in the query plan information about the current table
-  ** and the index used to access it (if any).  If the table itself
-  ** is not used, its name is just '{}'.  If no index is used
-  ** the index is listed as "{}".  If the primary key is used the
-  ** index name is '*'.
-  */
-  for(ii=0; ii<nTabList; ii++){
-    char *z;
-    int n;
-    int w;
-    struct SrcList_item *pTabItem;
-
-    pLevel = &pWInfo->a[ii];
-    w = pLevel->plan.wsFlags;
-    pTabItem = &pTabList->a[pLevel->iFrom];
-    z = pTabItem->zAlias;
-    if( z==0 ) z = pTabItem->pTab->zName;
-    n = sqlite3Strlen30(z);
-    if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
-      if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
-        memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
-        nQPlan += 2;
-      }else{
-        memcpy(&sqlite3_query_plan[nQPlan], z, n);
-        nQPlan += n;
-      }
-      sqlite3_query_plan[nQPlan++] = ' ';
-    }
-    testcase( w & WHERE_ROWID_EQ );
-    testcase( w & WHERE_ROWID_RANGE );
-    if( w & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
-      memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
-      nQPlan += 2;
-    }else if( (w & WHERE_INDEXED)!=0 && (w & WHERE_COVER_SCAN)==0 ){
-      n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName);
-      if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
-        memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
-        nQPlan += n;
-        sqlite3_query_plan[nQPlan++] = ' ';
-      }
-    }else{
-      memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
-      nQPlan += 3;
-    }
-  }
-  while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
-    sqlite3_query_plan[--nQPlan] = 0;
-  }
-  sqlite3_query_plan[nQPlan] = 0;
-  nQPlan = 0;
-#endif /* SQLITE_TEST // Testing and debugging use only */
-
-  /* Record the continuation address in the WhereInfo structure.  Then
-  ** clean up and return.
-  */
+  /* Done. */
   return pWInfo;
 
   /* Jump here if malloc fails */
index 2dbc283417d7e1d4217f9b1c1c352b4a061a723b..8610fa6f3dfec54f25680081074a4795fcaad75c 100644 (file)
@@ -65,9 +65,9 @@ proc count sql {
 do_test where-1.1.1 {
   count {SELECT x, y, w FROM t1 WHERE w=10}
 } {3 121 10 3}
-do_test where-1.1.2 {
-  set sqlite_query_plan
-} {t1 i1w}
+do_eqp_test where-1.1.2 {
+  SELECT x, y, w FROM t1 WHERE w=10
+} {*SEARCH TABLE t1 USING INDEX i1w (w=?) *}
 do_test where-1.1.3 {
   db status step
 } {0}
@@ -77,15 +77,15 @@ do_test where-1.1.4 {
 do_test where-1.1.5 {
   db status step
 } {99}
-do_test where-1.1.6 {
-  set sqlite_query_plan
-} {t1 {}}
+do_eqp_test where-1.1.6 {
+  SELECT x, y, w FROM t1 WHERE +w=10
+} {*SCAN TABLE t1 *}
 do_test where-1.1.7 {
   count {SELECT x, y, w AS abc FROM t1 WHERE abc=10}
 } {3 121 10 3}
-do_test where-1.1.8 {
-  set sqlite_query_plan
-} {t1 i1w}
+do_eqp_test where-1.1.8 {
+  SELECT x, y, w AS abc FROM t1 WHERE abc=10
+} {*SEARCH TABLE t1 USING INDEX i1w (w=?) *}
 do_test where-1.1.9 {
   db status step
 } {0}
@@ -104,21 +104,21 @@ do_test where-1.3.2 {
 do_test where-1.4.1 {
   count {SELECT w, x, y FROM t1 WHERE 11=w AND x>2}
 } {11 3 144 3}
-do_test where-1.4.2 {
-  set sqlite_query_plan
-} {t1 i1w}
+do_eqp_test where-1.4.2 {
+  SELECT w, x, y FROM t1 WHERE 11=w AND x>2
+} {*SEARCH TABLE t1 USING INDEX i1w (w=?) *}
 do_test where-1.4.3 {
   count {SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2}
 } {11 3 144 3}
-do_test where-1.4.4 {
-  set sqlite_query_plan
-} {t1 i1w}
+do_eqp_test where-1.4.4 {
+  SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2
+} {*SEARCH TABLE t1 USING INDEX i1w (w=?) *}
 do_test where-1.5 {
   count {SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2}
 } {3 144 3}
-do_test where-1.5.2 {
-  set sqlite_query_plan
-} {t1 i1w}
+do_eqp_test where-1.5.2 {
+  SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2
+} {*SEARCH TABLE t1 USING INDEX i1w (w=?) *}
 do_test where-1.6 {
   count {SELECT x, y FROM t1 WHERE y<200 AND x>2 AND w=11}
 } {3 144 3}
@@ -128,13 +128,12 @@ do_test where-1.7 {
 do_test where-1.8 {
   count {SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3}
 } {3 144 3}
-do_test where-1.8.2 {
-  set sqlite_query_plan
-} {t1 i1xy}
-do_test where-1.8.3 {
-  count {SELECT x, y FROM t1 WHERE y=144 AND x=3}
-  set sqlite_query_plan
-} {{} i1xy}
+do_eqp_test where-1.8.2 {
+  SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3
+} {*SEARCH TABLE t1 USING INDEX i1xy (x=? AND y=?) *}
+do_eqp_test where-1.8.3 {
+  SELECT x, y FROM t1 WHERE y=144 AND x=3
+} {*SEARCH TABLE t1 USING COVERING INDEX i1xy (x=? AND y=?) *}
 do_test where-1.9 {
   count {SELECT x, y FROM t1 WHERE y=144 AND w>10 AND x=3}
 } {3 144 3}