]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add tests for sqlite_stat4 sample selection. And a fix for the same.
authordan <dan@noemail.net>
Thu, 15 Aug 2013 14:39:09 +0000 (14:39 +0000)
committerdan <dan@noemail.net>
Thu, 15 Aug 2013 14:39:09 +0000 (14:39 +0000)
FossilOrigin-Name: 1fb4d9d6f2675515feb8e3d971bbd54716372549

manifest
manifest.uuid
src/analyze.c
test/analyze9.test

index 35822cf8b7b046a753cafc96554feb69f89503bc..7dbb565005aec588876d83a10e013aee0d7bb7e9 100644 (file)
--- 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
index c82b437d55d39ef6e2d4a2570320cef7b6736be5..40e0dcd524d542ca6391abb31a196983d4056b55 100644 (file)
@@ -1 +1 @@
-bdce612b35193abf72de1a563ea7962375b3574e
\ No newline at end of file
+1fb4d9d6f2675515feb8e3d971bbd54716372549
\ No newline at end of file
index d8edadf88576939d47a0b9850b796e131bcbd641..ac9ba5edebd190cf23bf334d06104ff73d296a7e 100644 (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. */
index cbb2319f8c9b7fec761f4af0a418c1cabb73da23..51531c5895a032452ebf4e8b5bf32a407f90f90d 100644 (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