]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If there is data in both the sqlite_stat4 and sqlite_stat3 tables for a single index...
authordan <dan@noemail.net>
Mon, 12 Aug 2013 17:31:32 +0000 (17:31 +0000)
committerdan <dan@noemail.net>
Mon, 12 Aug 2013 17:31:32 +0000 (17:31 +0000)
FossilOrigin-Name: 2a41736728d83a777ea8112da927cb047ec6684e

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

index 9d210df0ad6248977f7c67f1a5b2d3fe19811317..d7c9529c7f7c722b117bb579572988995ef16e55 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Handle\sa\sNULL\sinput\sto\sdecodeIntArray()\sthat\scan\sresult\sfrom\sa\sprior\sOOM.
-D 2013-08-12T17:00:08.943
+C If\sthere\sis\sdata\sin\sboth\sthe\ssqlite_stat4\sand\ssqlite_stat3\stables\sfor\sa\ssingle\sindex,\signore\sthe\ssqlite_stat3\srecords.
+D 2013-08-12T17:31:32.368
 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 cfbf5b631aa15d122941eb2370589b2700a41c45
+F src/analyze.c c020f2ff9991412d85d8c5c736097de82c38ea51
 F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
@@ -309,7 +309,7 @@ F test/analyze6.test 3c01e084309706a1033f850330ea24f6f7846297
 F test/analyze7.test c0af22c5e0140e2e4ac556a21c2b6fff58229c98
 F test/analyze8.test 8d1f76ff1e47c4093bb7be3971ba08fa56dc470d
 F test/analyze9.test 1b419d03407f2a6f4f1485620d54cb3e1bab3a71
-F test/analyzeA.test 949c3344280e0ca6de0b49805e4f291cdc1daa43
+F test/analyzeA.test 3a24600dd50e4a8815a952e1470ecb610046b069
 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
 F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
 F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
@@ -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 6d45078e621526fc2bac0eaefbb0f9602b9a8ec5
-R a5e2ac56df6a571538e82bfa8985f662
-U drh
-Z ac0a7d3fec5c7e4a46461a76c725cc26
+P fa1588adab6759fd3d1be02524aa19a0d1c6adaa
+R f7aa978164035b98da3c8ba701a7b74c
+U dan
+Z fe069e15f895d55c37e51ff5b63e6804
index 2ca3618189963a753e3438f9f00ac9346043c128..3d11676d20b30d4d1285e08f0564d30e7b6b89ca 100644 (file)
@@ -1 +1 @@
-fa1588adab6759fd3d1be02524aa19a0d1c6adaa
\ No newline at end of file
+2a41736728d83a777ea8112da927cb047ec6684e
\ No newline at end of file
index 15ff54059f7c61855681c69623aaf8a958af76fc..c631854b31db9c56f5cf11132483ab98f31dde98 100644 (file)
@@ -1315,8 +1315,10 @@ static int loadStatTbl(
     if( zIndex==0 ) continue;
     nSample = sqlite3_column_int(pStmt, 1);
     pIdx = sqlite3FindIndex(db, zIndex, zDb);
-    if( pIdx==0 ) continue;
-    assert( pIdx->nSample==0 );
+    assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
+    /* Index.nSample is non-zero at this point if data has already been
+    ** loaded from the stat4 table. In this case ignore stat3 data.  */
+    if( pIdx==0 || pIdx->nSample ) continue;
     if( bStat3==0 ){
       nIdxCol = pIdx->nColumn+1;
       nAvgCol = pIdx->nColumn;
@@ -1368,6 +1370,9 @@ static int loadStatTbl(
       idx = 0;
     }
     assert( idx<pIdx->nSample );
+    /* This next condition is true if data has already been loaded from 
+    ** the sqlite_stat4 table. In this case ignore stat3 data.  */
+    if( bStat3 && pIdx->aSample[idx].anEq[0] ) continue;
     pSample = &pIdx->aSample[idx];
 
     if( bStat3==0 ){
index c1257a2aa9a48309a8c61ff4a9da2383ea2ab462..47fd2f0dd6b9a34ca6d70231f12ac357c9ce7760 100644 (file)
@@ -23,7 +23,9 @@ ifcapable !stat4&&!stat3 {
   return
 }
 
-proc populate_stat3 {} {
+# Populate the stat3 table according to the current contents of the db
+#
+proc populate_stat3 {{bDropTable 1}} {
   # Open a second connection on database "test.db" and run ANALYZE. If this
   # is an ENABLE_STAT3 build, this is all that is required to create and
   # populate the sqlite_stat3 table. 
@@ -42,11 +44,11 @@ proc populate_stat3 {} {
       CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);
       INSERT INTO sqlite_stat3 
       SELECT DISTINCT tbl, idx, 
-      lindex(neq,0), lindex(nlt,0), lindex(ndlt,0), test_extract(sample, 0)
+        lindex(neq,0), lindex(nlt,0), lindex(ndlt,0), test_extract(sample, 0)
       FROM sqlite_stat4;
-      DROP TABLE sqlite_stat4;
-      PRAGMA writable_schema = off;
     } db2
+    if {$bDropTable} { execsql {DROP TABLE sqlite_stat4} db2 }
+    execsql { PRAGMA writable_schema = off }
   }
 
   # Modify the database schema cookie to ensure that the other connection
@@ -59,7 +61,30 @@ proc populate_stat3 {} {
   db2 close
 }
 
+# Populate the stat4 table according to the current contents of the db.
+# Leave deceptive data in the stat3 table. This data should be ignored
+# in favour of that from the stat4 table.
+#
+proc populate_both {} {
+  populate_stat3 0
+
+  sqlite3 db2 test.db
+  execsql {
+    PRAGMA writable_schema = on;
+    UPDATE sqlite_stat3 SET idx = 
+      CASE idx WHEN 't1b' THEN 't1c' ELSE 't1b'
+    END;
+    PRAGMA writable_schema = off;
+    CREATE TABLE obscure_tbl_nm(x);
+    DROP TABLE obscure_tbl_nm;
+  } db2
+
+  db2 close
+}
+
 
+# Populate the stat4 table according to the current contents of the db
+#
 proc populate_stat4 {} {
   execsql { ANALYZE }
 #  ifcapable stat3 {
@@ -77,7 +102,11 @@ proc populate_stat4 {} {
 #  }
 }
 
-foreach {tn analyze_cmd} {1 populate_stat4 2 populate_stat3} {
+foreach {tn analyze_cmd} {
+  1 populate_stat4 
+  2 populate_stat3
+  3 populate_both
+} {
   reset_db
   do_test 1.$tn.1 {
     execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) }
@@ -110,7 +139,6 @@ foreach {tn analyze_cmd} {1 populate_stat4 2 populate_stat3} {
   do_execsql_test 1.$tn.3.2 { 
     SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 50
   } {90}
-
   do_execsql_test 1.$tn.3.3 { 
     SELECT count(*) FROM t1 WHERE b BETWEEN 75 AND 125
   } {90}