From: drh Date: Tue, 11 Jun 2013 01:50:08 +0000 (+0000) Subject: Handle virtual tables correctly when using logarithmic costs. Fixes X-Git-Tag: version-3.8.0~130^2~12^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8636e9c55cb46f8923ebbb8a1014010d9c813472;p=thirdparty%2Fsqlite.git Handle virtual tables correctly when using logarithmic costs. Fixes to test cases. FossilOrigin-Name: e612664aa2e24ed5e222be2c7fe16e210ac9bded --- diff --git a/manifest b/manifest index c92fe224c3..cda6c0adff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\scases\sfor\sthe\snew\sEXPLAIN\sQUERY\sPLAN\sformat.\s\sAdd\sthe\nwherecosttest\stool.\s\sOther\sfixes\sto\slogarithm\scost. -D 2013-06-10T23:30:09.637 +C Handle\svirtual\stables\scorrectly\swhen\susing\slogarithmic\scosts.\s\sFixes\nto\stest\scases. +D 2013-06-11T01:50:08.263 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -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 672b76db7422b7bbc94fe1be42183c6356e56e96 +F src/where.c 72f9aa6c35dadf0d432c2d80fd117d8887f70473 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -303,7 +303,7 @@ F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae F test/analyze3.test 69863b446539f8849a996c2aa0b50461c9cecea4 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 -F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e +F test/analyze5.test 3e57f192307be931f9ab2f6ff456f9063358ac77 F test/analyze6.test cdbf9887d40ab41301f570fe85c6e1525dd3b1c9 F test/analyze7.test 7de3ab66e1981303e783102a012d62cb876bf1d5 F test/analyze8.test ea4972c76820ac8d6a0754e6f5b851292f0f5a61 @@ -335,7 +335,7 @@ F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa -F test/between.test e6896728a636e3e610bcb2f87c9305120c809bc5 +F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 7c79f1ef0c6c2c2bc1e7bd895596fab32bfb4796 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 @@ -440,7 +440,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test ac506be979f611719a2a2de8476fe608fc9d66a4 +F test/eqp.test 68dd66c8fa05551d056ebd7fc8ae3b2e1cb5836e F test/errmsg.test 050717f1c6a5685de9c79f5f9f6b83d7c592f73a F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75 @@ -1095,7 +1095,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c 4d0393bdbe7230adb712e925863744dd2b7ffc5b F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 69cf877283d362915edddf1822fbf7a9f86278b3 -R 6bac639abb86e2ec49ce16ea155e2dc3 +P aa580e368e3c398b8377b80342dfdd906324c248 +R dc216beb84f13406fad3ccd046a844fe U drh -Z f81162c822de40652566c68321ce2c25 +Z a1ab90c9180f43596814678177a2e938 diff --git a/manifest.uuid b/manifest.uuid index 072a7b4e84..b4b006445a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa580e368e3c398b8377b80342dfdd906324c248 \ No newline at end of file +e612664aa2e24ed5e222be2c7fe16e210ac9bded \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2b0049b9c3..4a27b9e382 100644 --- a/src/where.c +++ b/src/where.c @@ -1882,6 +1882,23 @@ static WhereCost whereCostFromInt(tRowcnt x){ return a[x&7] + y - 10; } +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Convert a double (as received from xBestIndex of a virtual table) +** into a WhereCost +*/ +static WhereCost whereCostFromDouble(double x){ + u64 a; + WhereCost e; + assert( sizeof(x)==8 && sizeof(a)==8 ); + if( x<=1 ) return 0; + if( x<=2000000000 ) return whereCostFromInt((tRowcnt)x); + memcpy(&a, &x, 8); + e = (a>>52) - 1022; + return e*10; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + /* ** Prepare a crude estimate of the logarithm of the input value. ** The results need not be exact. This is only used for estimating @@ -4088,6 +4105,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** more terms of the index */ pNext = p->pNextLoop; break; + }else if( p->nOut>pTemplate->nOut + && p->rSetup==pTemplate->rSetup + && p->rRun==pTemplate->rRun + ){ + /* Overwrite an existing WhereLoop with the same cost but more + ** outputs */ + pNext = p->pNextLoop; + break; }else{ /* pTemplate is not helpful. ** Return without changing or adding anything */ @@ -4263,7 +4288,7 @@ static int whereLoopAddBtreeIndex( WhereCost rDiv; whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq, pBtm, pTop, &rDiv); - pNew->nOut = saved_nOut - rDiv; + pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; } #ifdef SQLITE_ENABLE_STAT3 if( pNew->u.btree.nEq==1 && pProbe->nSample ){ @@ -4482,6 +4507,7 @@ static int whereLoopAddBtree( return rc; } +#ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Add all WhereLoop objects for a table of the join identified by ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. @@ -4569,8 +4595,7 @@ static int whereLoopAddVirtual( pIdxInfo->idxNum = 0; pIdxInfo->needToFreeIdxStr = 0; pIdxInfo->orderByConsumed = 0; - /* ((WhereCost)2) In case of SQLITE_OMIT_FLOATING_POINT... */ - pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((WhereCost)2); + pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; rc = vtabBestIndex(pParse, pTab, pIdxInfo); if( rc ) goto whereLoopAddVtab_exit; pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; @@ -4624,7 +4649,7 @@ static int whereLoopAddVirtual( pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) && pIdxInfo->orderByConsumed); pNew->rSetup = 0; - pNew->rRun = whereCostFromInt((tRowcnt)pIdxInfo->estimatedCost); + pNew->rRun = whereCostFromDouble(pIdxInfo->estimatedCost); pNew->nOut = 46; assert( 46 == whereCostFromInt(25) ); whereLoopInsert(pBuilder, pNew); if( pNew->u.vtab.needFree ){ @@ -4639,6 +4664,7 @@ whereLoopAddVtab_exit: sqlite3DbFree(db, pIdxInfo); return rc; } +#endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Add WhereLoop entries to handle OR terms. This works for either @@ -4695,9 +4721,12 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ sBest.maskSelf = 0; sBest.rSetup = 0; sBest.rRun = 0; +#ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ rc = whereLoopAddVirtual(&sSubBuild, mExtra); - }else{ + }else +#endif + { rc = whereLoopAddBtree(&sSubBuild, mExtra); } if( sBest.maskSelf==0 ) break; diff --git a/test/analyze5.test b/test/analyze5.test index 1041d709d2..c400780fff 100644 --- a/test/analyze5.test +++ b/test/analyze5.test @@ -156,13 +156,14 @@ foreach {testid where index rows} { } { # Verify that the expected index is used with the expected row count - do_test analyze5-1.${testid}a { - set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] - set idx {} - regexp {INDEX (t1.) } $x all idx - regexp {~([0-9]+) rows} $x all nrow - list $idx $nrow - } [list $index $rows] + # No longer valid due to an EXPLAIN QUERY PLAN output format change + # do_test analyze5-1.${testid}a { + # set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] + # set idx {} + # regexp {INDEX (t1.) } $x all idx + # regexp {~([0-9]+) rows} $x all nrow + # list $idx $nrow + # } [list $index $rows] # Verify that the same result is achieved regardless of whether or not # the index is used @@ -202,15 +203,14 @@ foreach {testid where index rows} { } { # Verify that the expected index is used with the expected row count -if {$testid==50299} {breakpoint; set sqlite_where_trace 1} - do_test analyze5-1.${testid}a { - set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] - set idx {} - regexp {INDEX (t1.) } $x all idx - regexp {~([0-9]+) rows} $x all nrow - list $idx $nrow - } [list $index $rows] -if {$testid==50299} exit + # No longer valid due to an EXPLAIN QUERY PLAN format change + # do_test analyze5-1.${testid}a { + # set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] + # set idx {} + # regexp {INDEX (t1.) } $x all idx + # regexp {~([0-9]+) rows} $x all nrow + # list $idx $nrow + # } [list $index $rows] # Verify that the same result is achieved regardless of whether or not # the index is used diff --git a/test/between.test b/test/between.test index f089cd95d3..df4c67995c 100644 --- a/test/between.test +++ b/test/between.test @@ -58,10 +58,10 @@ proc queryplan {sql} { set eqp [execsql "EXPLAIN QUERY PLAN $sql"] # puts eqp=$eqp foreach {a b c x} $eqp { - if {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\W} \ + if {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \ $x all as tab idx]} { lappend data $tab $idx - } elseif {[regexp { TABLE (\w+ AS )?(\w+)\W} $x all as tab]} { + } elseif {[regexp { TABLE (\w+ AS )?(\w+)\y} $x all as tab]} { lappend data $tab * } } diff --git a/test/eqp.test b/test/eqp.test index f137920309..ad7d4edad2 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -554,7 +554,7 @@ det 7.1 "SELECT count(*) FROM t1" { } det 7.2 "SELECT count(*) FROM t2" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~1000000 rows)} + 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1} } do_execsql_test 7.3 { @@ -576,7 +576,7 @@ det 7.4 "SELECT count(*) FROM t1" { } det 7.5 "SELECT count(*) FROM t2" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~3 rows)} + 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1} }