From d15cb17174cc9c7649dc018701ab5a055ac74a6a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 May 2013 19:23:10 +0000 Subject: [PATCH] Enhanced "wheretrace" output in the NGQP solver routine. FossilOrigin-Name: 04dfb85a2a7025d4b5056b73fa8477691323919f --- manifest | 14 +++--- manifest.uuid | 2 +- src/where.c | 104 ++++++++++++++++++++++++++++++++++---------- test/boundary3.test | 1 + 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index ac6a9e67b4..785a029e3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\stoward\simproving\sthe\sNGQP's\sability\sto\soptimize\sout\sORDER\sBY\sclauses. -D 2013-05-21T15:52:07.219 +C Enhanced\s"wheretrace"\soutput\sin\sthe\sNGQP\ssolver\sroutine. +D 2013-05-21T19:23:10.944 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f6b58b7bdf6535f0f0620c486dd59aa4662c0b4f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -265,7 +265,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 a01d93b37fbce377326849fe810dbcd2334d40c6 +F src/where.c 759c34becf7a414b4bebddd30ad65109eb4510fc F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -324,7 +324,7 @@ F test/boundary1.test 66d7f4706ccdb42d58eafdb081de07b0eb42d77b F test/boundary2.tcl e34ef4e930cf1083150d4d2c603e146bd3b76bcb F test/boundary2.test 9ae758d7dab7e882c8b6cc4a6a10278385bff8fa F test/boundary3.tcl 8901d6a503d0bf64251dd81cc74e5ad3add4b119 -F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 +F test/boundary3.test 04c269017471f1562da2dd6310359f16073a2a65 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/btreefault.test f52c593513bda80a506c848325c73c840590884d @@ -1065,7 +1065,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 14ab6675e5eab3761256a06dad23d2b11220788a -R fc1fe5e0f9d1ee7dd6bc32ff7b604dd6 +P 67367f1e1f0c3eb6be65eea9873910aa62b49884 +R 26b15d08d00e63218ca6971b3d46c9f6 U drh -Z 0d777b81f154f68ed82e3cd424f83c9e +Z 6ae4459022aa081e691ba708466a0da1 diff --git a/manifest.uuid b/manifest.uuid index 75cf59ccb0..d686a351db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67367f1e1f0c3eb6be65eea9873910aa62b49884 \ No newline at end of file +04dfb85a2a7025d4b5056b73fa8477691323919f \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0f61f6ed24..a5a01ce071 100644 --- a/src/where.c +++ b/src/where.c @@ -28,6 +28,7 @@ #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) # define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 #else # define WHERETRACE(X) #endif @@ -56,6 +57,9 @@ typedef struct WhereVtabPlan WhereVtabPlan; struct WhereLoop { Bitmask prereq; /* Bitmask of other loops that must run first */ Bitmask maskSelf; /* Bitmask identifying table iTab */ +#ifdef SQLITE_DEBUG + char cId; /* Symbolic ID of this loop for debugging use */ +#endif u8 iTab; /* Position in FROM clause of table coded by this loop */ u8 iSortIdx; /* Sorting index number. 0==None */ u16 nTerm; /* Number of entries in aTerm[] */ @@ -1835,7 +1839,7 @@ static double estLog(double N){ ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines ** are no-ops. */ -#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ int i; if( !sqlite3WhereTrace ) return; @@ -5066,8 +5070,7 @@ static int nQPlan = 0; /* Next free slow in _query_plan[] */ #endif /* SQLITE_TEST */ -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +#ifdef WHERETRACE_ENABLED /* ** Print a WhereLoop object for debugging purposes */ @@ -5075,7 +5078,7 @@ static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){ int nb = 2*((pTabList->nSrc+15)/16); struct SrcList_item *pItem = pTabList->a + p->iTab; Table *pTab = pItem->pTab; - sqlite3DebugPrintf("%2d.%0*llx.%0*llx", + sqlite3DebugPrintf("%c %2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq); sqlite3DebugPrintf(" %8s", pItem->zAlias ? pItem->zAlias : pTab->zName); @@ -5102,7 +5105,7 @@ static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){ sqlite3_free(z); } sqlite3DebugPrintf(" fg %08x N %2d", p->wsFlags, p->nTerm); - sqlite3DebugPrintf(" cost %.4g,%.4g,%.4g\n", + sqlite3DebugPrintf(" cost %.2g,%.2g,%.2g\n", p->prereq, p->rSetup, p->rRun, p->nOut); } #endif @@ -5877,7 +5880,8 @@ static int wherePathSatisfiesOrderBy( assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); isUnique = 1; if( pLoop->wsFlags & WHERE_IPK ){ - if( (pLoop->wsFlags & WHERE_COLUMN_EQ)!=0 ) isUnique = 0; + if( (pLoop->wsFlags & WHERE_COLUMN_IN)!=0 ) isUnique = 0; + if( pLoop->u.btree.nEq!=1 ) isUnique = 0; pIndex = 0; nColumn = 1; }else if( pLoop->u.btree.pIndex==0 ){ @@ -5936,6 +5940,18 @@ static int wherePathSatisfiesOrderBy( return -1; } +#ifdef WHERETRACE_ENABLED +/* For debugging use only: */ +static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ + static char zName[65]; + int i; + for(i=0; iaLoop[i]->cId; } + if( pLast ) zName[i++] = pLast->cId; + zName[i] = 0; + return zName; +} +#endif + /* ** Given the list of WhereLoop objects on pWInfo->pLoops, this routine @@ -6044,15 +6060,59 @@ static int wherePathSolver(WhereInfo *pWInfo){ } } if( jj>=nTo ){ - if( nTo>=mxChoice && rCost>=mxCost ) continue; + if( nTo>=mxChoice && rCost>=mxCost ){ +#ifdef WHERETRACE_ENABLE + if( sqlite3WhereTrace>=3 ){ + sqlite3DebugPrintf("Skip %s cost=%-7.2g order=%c\n", + wherePathName(pFrom, iLoop, pWLoop), rCost, + isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); + } +#endif + continue; + } + /* Add a new Path to the aTo[] set */ if( nTo0); } } pTo = &aTo[jj]; +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace>=3 ){ + sqlite3DebugPrintf("New %s cost=%-7.2g order=%c\n", + wherePathName(pFrom, iLoop, pWLoop), rCost, + isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); + } +#endif }else{ - if( pTo->rCost<=rCost ) continue; + if( pTo->rCost<=rCost ){ +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace>=3 ){ + sqlite3DebugPrintf( + "Skip %s cost=%-7.2g order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, + isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); + sqlite3DebugPrintf(" vs %s cost=%-7.2g order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, + pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); + } +#endif + continue; + } + /* A new and better score for a previously created equivalent path */ +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace>=3 ){ + sqlite3DebugPrintf( + "Update %s cost=%-7.2g order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, + isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); + sqlite3DebugPrintf(" was %s cost=%-7.2g order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, + pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); + } +#endif } /* pWLoop is a winner. Add it to the set of best so far */ pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; @@ -6072,15 +6132,13 @@ static int wherePathSolver(WhereInfo *pWInfo){ } } -#if 0 - if( sqlite3WhereTrace ){ - sqlite3DebugPrintf("---- round %d ---- nTo=%d\n", iLoop, nTo); - for(ii=0; iipTabList); - } +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace>=2 ){ + sqlite3DebugPrintf("---- round %d ----\n", iLoop); + for(ii=0, pTo=aTo; iirCost, pTo->nRow, + pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); } } #endif @@ -6361,11 +6419,14 @@ WhereInfo *sqlite3WhereBegin( if( rc ) goto whereBeginError; /* Display all of the WhereLoop objects if wheretrace is enabled */ -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +#ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ WhereLoop *p; + int i = 0; + static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; for(p=pWInfo->pLoops; p; p=p->pNextLoop){ + p->cId = zLabel[(i++)%sizeof(zLabel)]; whereLoopPrint(p, pTabList); } } @@ -6373,8 +6434,7 @@ WhereInfo *sqlite3WhereBegin( wherePathSolver(pWInfo); if( db->mallocFailed ) goto whereBeginError; -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +#ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ int ii; sqlite3DebugPrintf("------------ Solution -------------"); @@ -6668,7 +6728,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY; } -#if 0 +#if 1 /* Scaffolding: Check the new query plan against the old. Report any ** discrepencies */ for(ii=0; ii