-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
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
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
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
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
** 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
}
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);
}
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
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
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);
}
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;
}
}
*/
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;
}
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;
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 ){
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 */
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}
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}
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}
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}