]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Prevent the rtree module from reading sqlite_stat1 data from the wrong database.
authordan <dan@noemail.net>
Wed, 12 Mar 2014 12:44:46 +0000 (12:44 +0000)
committerdan <dan@noemail.net>
Wed, 12 Mar 2014 12:44:46 +0000 (12:44 +0000)
FossilOrigin-Name: 7ce03c1b5552d830300575c5b41a874db7a2ec77

ext/rtree/rtree.c
ext/rtree/rtreeC.test
manifest
manifest.uuid

index 577e19d4c6170a48d495852d2aeb285b271f5e67..cd652a3936c293ff1212aaced2b4eee811d2fc6d 100644 (file)
@@ -2947,26 +2947,32 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
 ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
 */
 static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
-  const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
+  const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
+  char *zSql;
   sqlite3_stmt *p;
   int rc;
   i64 nRow = 0;
 
-  rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
-  if( rc==SQLITE_OK ){
-    sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
-    if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
-    rc = sqlite3_finalize(p);
-  }else if( rc!=SQLITE_NOMEM ){
-    rc = SQLITE_OK;
-  }
+  zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
+  if( zSql==0 ){
+    rc = SQLITE_NOMEM;
+  }else{
+    rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
+    if( rc==SQLITE_OK ){
+      if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
+      rc = sqlite3_finalize(p);
+    }else if( rc!=SQLITE_NOMEM ){
+      rc = SQLITE_OK;
+    }
 
-  if( rc==SQLITE_OK ){
-    if( nRow==0 ){
-      pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
-    }else{
-      pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
+    if( rc==SQLITE_OK ){
+      if( nRow==0 ){
+        pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
+      }else{
+        pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
+      }
     }
+    sqlite3_free(zSql);
   }
 
   return rc;
index 2e5bedec965e7049dbe7a67ff8ca9b07bb362f8a..b72007245f16a621ff6ca480504fa608dd2d8997 100644 (file)
@@ -158,5 +158,91 @@ do_execsql_test 4.3 {
   SELECT b, a FROM t2 LEFT JOIN t1 ON (+a = +b);
 } {1 1 3 {}}
 
+#--------------------------------------------------------------------
+# Test that the sqlite_stat1 data is used correctly.
+#
+reset_db
+do_execsql_test 5.1 {
+  CREATE TABLE t1(x PRIMARY KEY, y);
+  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
+
+  INSERT INTO t1(x) VALUES(1);
+  INSERT INTO t1(x) SELECT x+1 FROM t1;   --   2
+  INSERT INTO t1(x) SELECT x+2 FROM t1;   --   4
+  INSERT INTO t1(x) SELECT x+4 FROM t1;   --   8
+  INSERT INTO t1(x) SELECT x+8 FROM t1;   --  16
+  INSERT INTO t1(x) SELECT x+16 FROM t1;  --  32
+  INSERT INTO t1(x) SELECT x+32 FROM t1;  --  64
+  INSERT INTO t1(x) SELECT x+64 FROM t1;  -- 128
+  INSERT INTO t1(x) SELECT x+128 FROM t1; -- 256
+  INSERT INTO t1(x) SELECT x+256 FROM t1; -- 512
+  INSERT INTO t1(x) SELECT x+512 FROM t1; --1024
+
+  INSERT INTO rt SELECT x, x, x+1 FROM t1 WHERE x<=5;
+}
+
+# First test a query with no ANALYZE data at all. The outer loop is
+# real table "t1".
+#
+do_eqp_test 5.2 {
+  SELECT * FROM t1, rt WHERE x==id;
+} {
+  0 0 0 {SCAN TABLE t1} 
+  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
+}
+
+# Now create enough ANALYZE data to tell SQLite that virtual table "rt"
+# contains very few rows. This causes it to move "rt" to the outer loop.
+#
+do_execsql_test 5.3 {
+  ANALYZE;
+  DELETE FROM sqlite_stat1 WHERE tbl='t1';
+}
+db close
+sqlite3 db test.db
+do_eqp_test 5.4 {
+  SELECT * FROM t1, rt WHERE x==id;
+} {
+  0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:} 
+  0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)}
+}
+
+# Delete the ANALYZE data. "t1" should be the outer loop again.
+#
+do_execsql_test 5.5 { DROP TABLE sqlite_stat1; }
+db close
+sqlite3 db test.db
+do_eqp_test 5.6 {
+  SELECT * FROM t1, rt WHERE x==id;
+} {
+  0 0 0 {SCAN TABLE t1} 
+  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
+}
+
+# This time create and attach a database that contains ANALYZE data for
+# tables of the same names as those used internally by virtual table
+# "rt". Check that the rtree module is not fooled into using this data.
+# Table "t1" should remain the outer loop.
+#
+do_test 5.7 {
+  db backup test.db2
+  sqlite3 db2 test.db2
+  db2 eval {
+    ANALYZE;
+    DELETE FROM sqlite_stat1 WHERE tbl='t1';
+  }
+  db2 close
+  db close
+  sqlite3 db test.db
+  execsql { ATTACH 'test.db2' AS aux; }
+} {}
+do_eqp_test 5.8 {
+  SELECT * FROM t1, rt WHERE x==id;
+} {
+  0 0 0 {SCAN TABLE t1} 
+  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
+}
+
+
 finish_test
 
index 219399a93b6095b3065e8a15c6d046f762798881..8dd646f40adc8f4d9949c88304fd4270316751f4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Version\s3.8.4.1
-D 2014-03-11T15:27:36.923
+C Prevent\sthe\srtree\smodule\sfrom\sreading\ssqlite_stat1\sdata\sfrom\sthe\swrong\sdatabase.
+D 2014-03-12T12:44:46.777
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
 F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
-F ext/rtree/rtree.c a4e18b2c150adad20aecbeb3408cd235a0a57441
+F ext/rtree/rtree.c d963b961f7ebb3842a6dbc959ed8c3f3534206c4
 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
 F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -133,7 +133,7 @@ F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
 F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
 F ext/rtree/rtreeB.test 983e567b49b5dca165940f66b87e161aa30e82b2
-F ext/rtree/rtreeC.test 03975565f40a0bee165f613143e4dec716dd5a59
+F ext/rtree/rtreeC.test afe930ac948c79fd12e48691c478d3f3bfc763d8
 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
@@ -1156,10 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 33f5694fa42d9a521ca081de4ddd1e9dc8952b16
-R 581994aed374f15c1c6bac5b0a9a5df5
-T +bgcolor * #d0c0ff
-T +sym-release *
-T +sym-version-3.8.4.1 *
-U drh
-Z c1ec45dc8a92b80bfa16f4c74ccfeec8
+P 018d317b1257ce68a92908b05c9c7cf1494050d0
+R 771148b6f32577641865e57d520a643c
+U dan
+Z 84dfe23ccda2d3e1d846c6ac2ce685a0
index 1f0b42178bebb295371364dab721f7aa3ebb9e9d..b36a223a45ec3cb29d7f1e89d25b4d0777690e5d 100644 (file)
@@ -1 +1 @@
-018d317b1257ce68a92908b05c9c7cf1494050d0
\ No newline at end of file
+7ce03c1b5552d830300575c5b41a874db7a2ec77
\ No newline at end of file