From: drh Date: Wed, 22 May 2013 20:49:02 +0000 (+0000) Subject: Use the NGQP plan for EXPLAIN QUERY PLAN output. This change causes 207 X-Git-Tag: version-3.8.0~130^2~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ef8663765575762847a9a9f44b6f82817e87b793;p=thirdparty%2Fsqlite.git Use the NGQP plan for EXPLAIN QUERY PLAN output. This change causes 207 errors in veryquick.test, many of which are benign. FossilOrigin-Name: f783e8e6b10de44029c7c5f57e4648a4a677ca1b --- diff --git a/manifest b/manifest index 3b53419b6d..f6c1ed6e1d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\srowid\sat\sthe\send\sof\san\sindex\sto\sbe\sused\sin\sa\sconstraint\son\sthat\sindex. -D 2013-05-22T17:01:17.424 +C Use\sthe\sNGQP\splan\sfor\sEXPLAIN\sQUERY\sPLAN\soutput.\s\sThis\schange\scauses\s207\nerrors\sin\sveryquick.test,\smany\sof\swhich\sare\sbenign. +D 2013-05-22T20:49:02.170 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 3ca12d203c0cca5bc36f0cd408a97ed5a9357047 +F src/where.c 627bf1af3ab30e1efcc7ac362b15e7e945e9250d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -779,7 +779,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl 3b08771e6d601612fe62d13787db0e50aac4cf7b +F test/tester.tcl 693700993b7e0a5b7b2171b291a54cdbad1d86ff F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -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 12c709b4369c7d94d7fb743d0d0da7a9350a3d16 -R 7322735243734361422a3e6e35778930 +P 9bf0524df7ca2e7fcd92b2878a8457264b3c7f6e +R 97f27b7ea9f3efcce127b9443ade87ed U drh -Z fd0ab2669226a74d38406e095d929629 +Z 96c17883fc9fb8d90fa5ada1b6415a79 diff --git a/manifest.uuid b/manifest.uuid index 98ddda464c..0de3a8524f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bf0524df7ca2e7fcd92b2878a8457264b3c7f6e \ No newline at end of file +f783e8e6b10de44029c7c5f57e4648a4a677ca1b \ No newline at end of file diff --git a/src/where.c b/src/where.c index e28fe4d62c..fa38b57383 100644 --- a/src/where.c +++ b/src/where.c @@ -4168,16 +4168,16 @@ static void explainAppendTerm( ** It is the responsibility of the caller to free the buffer when it is ** no longer required. */ -static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ - WherePlan *pPlan = &pLevel->plan; - Index *pIndex = pPlan->u.pIdx; - int nEq = pPlan->nEq; +static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ + Index *pIndex = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; int i, j; Column *aCol = pTab->aCol; int *aiColumn = pIndex->aiColumn; StrAccum txt; - if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ + if( pIndex==0 ) return 0; + if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ return 0; } sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); @@ -4188,11 +4188,11 @@ static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ } j = i; - if( pPlan->wsFlags&WHERE_BTM_LIMIT ){ + if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; explainAppendTerm(&txt, i++, z, ">"); } - if( pPlan->wsFlags&WHERE_TOP_LIMIT ){ + if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; explainAppendTerm(&txt, i, z, "<"); } @@ -4215,7 +4215,6 @@ static void explainOneScan( u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ if( pParse->explain==2 ){ - u32 flags = pLevel->plan.wsFlags; struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ @@ -4223,12 +4222,16 @@ static void explainOneScan( sqlite3_int64 nRow; /* Expected number of rows visited by scan */ int iId = pParse->iSelectId; /* Select id (left-most output column) */ int isSearch; /* True for a SEARCH. False for SCAN. */ + WhereLoop *pLoop; /* The controlling WhereLoop object */ + u32 flags; /* Flags that describe this loop */ + pLoop = pLevel->pWLoop; + flags = pLoop->wsFlags; if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; - isSearch = (pLevel->plan.nEq>0) - || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 - || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); + isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) + || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN"); if( pItem->pSelect ){ @@ -4240,20 +4243,22 @@ static void explainOneScan( if( pItem->zAlias ){ zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); } - if( (flags & WHERE_INDEXED)!=0 ){ - char *zWhere = explainIndexRange(db, pLevel, pItem->pTab); + if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 + && pLoop->u.btree.pIndex!=0 + ){ + char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), ((flags & WHERE_IDX_ONLY)?"COVERING ":""), ((flags & WHERE_TEMP_INDEX)?"":" "), - ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName), + ((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName), zWhere ); sqlite3DbFree(db, zWhere); - }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ + }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_INDEXED)!=0 ){ zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); - if( flags&WHERE_ROWID_EQ ){ + if( flags&WHERE_COLUMN_EQ ){ zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg); }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowidplan.u.pVtabIdx; zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, - pVtabIdx->idxNum, pVtabIdx->idxStr); + pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){ testcase( wctrlFlags & WHERE_ORDERBY_MIN ); nRow = 1; }else{ - nRow = (sqlite3_int64)pLevel->plan.nRow; + nRow = (sqlite3_int64)pLoop->nOut; } zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow); sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); @@ -5263,7 +5267,8 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ memcpy(p->aTerm, pTemplate->aTerm, p->nTerm*sizeof(p->aTerm[0])); } if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ - if( p->u.btree.pIndex && p->u.btree.pIndex && p->u.btree.pIndex->tnum==0 ){ + Index *pIndex = p->u.btree.pIndex; + if( pIndex && pIndex->tnum==0 ){ p->u.btree.pIndex = 0; } }else{ @@ -5310,6 +5315,7 @@ static int whereLoopAddBtreeIndex( }else{ opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE; } + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); if( pNew->u.btree.nEq < pProbe->nColumn ){ iCol = pProbe->aiColumn[pNew->u.btree.nEq]; @@ -5472,6 +5478,7 @@ static int whereLoopAddBtree( for(pTerm=pWC->a; rc==SQLITE_OK && pTermu.btree.nEq = 1; + pNew->u.btree.pIndex = 0; pNew->nTerm = 1; pNew->aTerm[0] = pTerm; pNew->rSetup = 2*rLogSize*pSrc->pTab->nRowEst; @@ -5515,7 +5522,7 @@ static int whereLoopAddBtree( pNew->wsFlags = (m==0) ? WHERE_IDX_ONLY : 0; /* Full scan via index */ - if( m==0 || b ){ + if( (m==0 || b) && pProbe->bUnordered==0 ){ pNew->iSortIdx = b ? iSortIdx : 0; pNew->nOut = rSize; pNew->rRun = (m==0) ? (rSize + rLogSize)*(1+b) : (rSize*rLogSize); @@ -5892,10 +5899,9 @@ static int wherePathSatisfiesOrderBy( if( pLoop->u.btree.nEq!=1 ) isUnique = 0; pIndex = 0; nColumn = 1; - }else if( pLoop->u.btree.pIndex==0 ){ + }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ - pIndex = pLoop->u.btree.pIndex; nColumn = pIndex->nColumn; if( pIndex->onError==OE_None ){ isUnique = 0; diff --git a/test/tester.tcl b/test/tester.tcl index 761a36e355..cad9807ed7 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -793,9 +793,28 @@ proc finalize_testing {} { set nTest [incr_ntest] set nErr [set_test_counter errors] - puts "$nErr errors out of $nTest tests" - if {$nErr>0} { - puts "Failures on these tests: [set_test_counter fail_list]" + set nKnown 0 + if {[file readable known-problems.txt]} { + set fd [open known-problems.txt] + set content [read $fd] + close $fd + foreach x $content {set known_error($x) 1} + foreach x [set_test_counter fail_list] { + if {[info exists known_error($x)]} {incr nKnown} + } + } + if {$nKnown>0} { + puts "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\ + out of $nTest tests" + } else { + puts "$nErr errors out of $nTest tests" + } + if {$nErr>$nKnown} { + puts -nonewline "Failures on these tests:" + foreach x [set_test_counter fail_list] { + if {![info exists known_error($x)]} {puts -nonewline " $x"} + } + puts "" } foreach warning [set_test_counter warn_list] { puts "Warning: $warning"