Add tests for sqlite_stat4 sample selection. And a fix for the same.

FossilOrigin-Name: 1fb4d9d6f2675515feb8e3d971bbd54716372549
This commit is contained in:
dan 2013-08-15 14:39:09 +00:00
parent f00e902580
commit 1f616ad8fa
4 changed files with 129 additions and 14 deletions

View File

@ -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

View File

@ -1 +1 @@
bdce612b35193abf72de1a563ea7962375b3574e
1fb4d9d6f2675515feb8e3d971bbd54716372549

View File

@ -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. */

View File

@ -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