From: dan Date: Thu, 15 Aug 2013 14:39:09 +0000 (+0000) Subject: Add tests for sqlite_stat4 sample selection. And a fix for the same. X-Git-Tag: version-3.8.1~132^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f616ad8fad687e51e9df2100769b57b637cb4dc;p=thirdparty%2Fsqlite.git Add tests for sqlite_stat4 sample selection. And a fix for the same. FossilOrigin-Name: 1fb4d9d6f2675515feb8e3d971bbd54716372549 --- diff --git a/manifest b/manifest index 35822cf8b7..7dbb565005 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sway\sANALYZE\sworks\sto\suse\sa\ssingle\scursor\swhen\sscanning\sindices. -D 2013-08-14T19:54:12.120 +C Add\stests\sfor\ssqlite_stat4\ssample\sselection.\sAnd\sa\sfix\sfor\sthe\ssame. +D 2013-08-15T14:39:09.873 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 -F src/analyze.c 37b78257fcf73790fd443b2c62b7ce62b78c3c98 +F src/analyze.c f7494349f8c26cbffff3fab198834d7583f52c4f F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165 @@ -308,7 +308,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test 19151da2c4e918905d2081b74ac5c4d47fc850ab F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88 -F test/analyze9.test 1b419d03407f2a6f4f1485620d54cb3e1bab3a71 +F test/analyze9.test f75d1f2edd7707c8bbf5703be998e53212312abe F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -1107,7 +1107,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cca8bf4372ab7a0258aa5c9397818415c6cf0abf -R 798b6e107d9cfc4282515cb67b7b0a49 +P bdce612b35193abf72de1a563ea7962375b3574e +R cae3925a5ea9d2d41d5f5a62ca3fba06 U dan -Z 0758340c46c18a215a897e2672d1ddd5 +Z 071feb0454ff17e1bc198cd08a86a76d diff --git a/manifest.uuid b/manifest.uuid index c82b437d55..40e0dcd524 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdce612b35193abf72de1a563ea7962375b3574e \ No newline at end of file +1fb4d9d6f2675515feb8e3d971bbd54716372549 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index d8edadf885..ac9ba5edeb 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -411,23 +411,29 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ assert( IsStat4 || nEqZero==0 ); if( pNew->isPSample==0 ){ + Stat4Sample *pUpgrade = 0; assert( pNew->anEq[pNew->iCol]>0 ); /* This sample is being added because the prefix that ends in column ** iCol occurs many times in the table. However, if we have already ** added a sample that shares this prefix, there is no need to add - ** this one. Instead, upgrade the priority of the existing sample. */ + ** this one. Instead, upgrade the priority of the highest priority + ** existing sample that shares this prefix. */ for(i=p->nSample-1; i>=0; i--){ Stat4Sample *pOld = &p->a[i]; if( pOld->anEq[pNew->iCol]==0 ){ - if( pOld->isPSample==0 ){ - assert( sampleIsBetter(pNew, pOld) ); - assert( pOld->iCol>pNew->iCol ); - pOld->iCol = pNew->iCol; + if( pOld->isPSample ) return; + assert( sampleIsBetter(pNew, pOld) ); + if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ + pUpgrade = pOld; } - goto find_new_min; } } + if( pUpgrade ){ + pUpgrade->iCol = pNew->iCol; + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; + goto find_new_min; + } } /* If necessary, remove sample iMin to make room for the new sample. */ diff --git a/test/analyze9.test b/test/analyze9.test index cbb2319f8c..51531c5895 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -147,5 +147,114 @@ do_execsql_test 3.4 { SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND 60; } {three-d three-e three-f} +#------------------------------------------------------------------------- +# These tests verify that the sample selection for stat4 appears to be +# working as designed. +# + +reset_db +db func lindex lindex +db func lrange lrange + +do_execsql_test 4.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a, b, c); + CREATE INDEX i1 ON t1(c, b, a); +} + + +proc insert_filler_rows_n {iStart args} { + set A(-ncopy) 1 + set A(-nval) 1 + + foreach {k v} $args { + if {[info exists A($k)]==0} { error "no such option: $k" } + set A($k) $v + } + if {[llength $args] % 2} { + error "option requires an argument: [lindex $args end]" + } + + for {set i 0} {$i < $A(-nval)} {incr i} { + set iVal [expr $iStart+$i] + for {set j 0} {$j < $A(-ncopy)} {incr j} { + execsql { INSERT INTO t1 VALUES($iVal, $iVal, $iVal) } + } + } +} + +do_test 4.1 { + execsql { BEGIN } + insert_filler_rows_n 0 -ncopy 10 -nval 19 + insert_filler_rows_n 20 -ncopy 1 -nval 100 + + execsql { + INSERT INTO t1(c, b, a) VALUES(200, 1, 'a'); + INSERT INTO t1(c, b, a) VALUES(200, 1, 'b'); + INSERT INTO t1(c, b, a) VALUES(200, 1, 'c'); + + INSERT INTO t1(c, b, a) VALUES(200, 2, 'e'); + INSERT INTO t1(c, b, a) VALUES(200, 2, 'f'); + + INSERT INTO t1(c, b, a) VALUES(201, 3, 'g'); + INSERT INTO t1(c, b, a) VALUES(201, 4, 'h'); + + ANALYZE; + SELECT count(*) FROM sqlite_stat4; + SELECT count(*) FROM t1; + } +} {24 297} + +do_execsql_test 4.2 { + SELECT + neq, + lrange(nlt, 0, 2), + lrange(ndlt, 0, 2), + lrange(test_decode(sample), 0, 2) + FROM sqlite_stat4 + ORDER BY rowid LIMIT 16; +} { + {10 10 10 1} {0 0 0} {0 0 0} {0 0 0} + {10 10 10 1} {10 10 10} {1 1 1} {1 1 1} + {10 10 10 1} {20 20 20} {2 2 2} {2 2 2} + {10 10 10 1} {30 30 30} {3 3 3} {3 3 3} + {10 10 10 1} {40 40 40} {4 4 4} {4 4 4} + {10 10 10 1} {50 50 50} {5 5 5} {5 5 5} + {10 10 10 1} {60 60 60} {6 6 6} {6 6 6} + {10 10 10 1} {70 70 70} {7 7 7} {7 7 7} + {10 10 10 1} {80 80 80} {8 8 8} {8 8 8} + {10 10 10 1} {90 90 90} {9 9 9} {9 9 9} + {10 10 10 1} {100 100 100} {10 10 10} {10 10 10} + {10 10 10 1} {110 110 110} {11 11 11} {11 11 11} + {10 10 10 1} {120 120 120} {12 12 12} {12 12 12} + {10 10 10 1} {130 130 130} {13 13 13} {13 13 13} + {10 10 10 1} {140 140 140} {14 14 14} {14 14 14} + {10 10 10 1} {150 150 150} {15 15 15} {15 15 15} +} + +do_execsql_test 4.3 { + SELECT + neq, + lrange(nlt, 0, 2), + lrange(ndlt, 0, 2), + lrange(test_decode(sample), 0, 1) + FROM sqlite_stat4 + ORDER BY rowid DESC LIMIT 2; +} { + {2 1 1 1} {295 296 296} {120 122 125} {201 4} + {5 3 1 1} {290 290 292} {119 119 121} {200 1} +} + +do_execsql_test 4.4 { SELECT count(DISTINCT c) FROM t1 WHERE c<201 } 120 +do_execsql_test 4.5 { SELECT count(DISTINCT c) FROM t1 WHERE c<200 } 119 + +# Check that the perioidic samples are present. +do_execsql_test 4.6 { + SELECT count(*) FROM sqlite_stat4 + WHERE lindex(test_decode(sample), 3) IN + ('34', '68', '102', '136', '170', '204', '238', '272') +} {8} + + finish_test