]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not allow auxiliary columns in the rtree to interfere with query planning.
authordrh <drh@noemail.net>
Wed, 16 May 2018 19:07:07 +0000 (19:07 +0000)
committerdrh <drh@noemail.net>
Wed, 16 May 2018 19:07:07 +0000 (19:07 +0000)
Begin adding test cases.

FossilOrigin-Name: 9abe023e1afa7dc1a7eba7fbb3128401de129873d86b7c71c221decca26a821c

ext/rtree/rtree.c
ext/rtree/rtree3.test
ext/rtree/rtreeC.test
ext/rtree/rtreeH.test [new file with mode: 0644]
manifest
manifest.uuid

index c43c304ff1dfb6c99b1f0d48dc7f1f479f1a25dd..104feb789b8f64c8818110ab73d4a08155b25865 100644 (file)
 **
 **   CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
 **   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
-**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
+**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
 **
 ** The data for each node of the r-tree structure is stored in the %_node
 ** table. For each node that is not the root node of the r-tree, there is
 ** an entry in the %_parent table associating the node with its parent.
 ** And for each row of data in the table, there is an entry in the %_rowid
 ** table that maps from the entries rowid to the id of the node that it
-** is stored on.
+** is stored on.  If the r-tree contains auxiliary columns, those are stored
+** on the end of the %_rowid table.
 **
 ** The root node of an r-tree always exists, even if the r-tree table is
 ** empty. The nodeno of the root node is always 1. All other nodes in the
@@ -1890,7 +1891,10 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
       return SQLITE_OK;
     }
 
-    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
+    if( p->usable
+    && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
+        || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
+    ){
       u8 op;
       switch( p->op ){
         case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
@@ -3584,9 +3588,9 @@ static int rtreeInit(
   pSql = sqlite3_str_new(db);
   sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
   for(ii=4; ii<argc; ii++){
-    if( sqlite3_strlike("aux:%", argv[ii], 0)==0 ){
+    if( argv[ii][0]=='+' ){
       pRtree->nAux++;
-      sqlite3_str_appendf(pSql, ",%s", argv[ii]+4);
+      sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
     }else if( pRtree->nAux>0 ){
       break;
     }else{
@@ -3867,7 +3871,7 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
 ** two tables are:
 **
 **   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
-**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
+**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
 **
 ** In both cases, this function checks that there exists an entry with
 ** IPK value iKey and the second column set to iVal.
@@ -3882,8 +3886,8 @@ static void rtreeCheckMapping(
   int rc;
   sqlite3_stmt *pStmt;
   const char *azSql[2] = {
-    "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?",
-    "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?"
+    "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1",
+    "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1"
   };
 
   assert( bLeaf==0 || bLeaf==1 );
index 1d863c6cc2c477e75a130b0ac61fa2bf8423fb13..e37d18ee8472cd58c2775067dc818b301ef8c246 100644 (file)
@@ -81,7 +81,7 @@ do_faultsim_test rtree3-2 -faults oom* -prep {
 do_malloc_test rtree3-3.prep {
   faultsim_delete_and_reopen
   execsql {
-    CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2);
+    CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2, +a1, +a2);
     INSERT INTO rt VALUES(NULL, 3, 5, 7, 9);
   }
   faultsim_save_and_close
index f983b220f41c3f3677ed8578692be02fa3bad0ca..19a1f7fe6c2a1ee7563122b9b06c7dcf290a78a7 100644 (file)
@@ -178,7 +178,7 @@ do_execsql_test 4.3 {
 reset_db
 do_execsql_test 5.1 {
   CREATE TABLE t1(x PRIMARY KEY, y);
-  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
+  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, +d1);
 
   INSERT INTO t1(x) VALUES(1);
   INSERT INTO t1(x) SELECT x+1 FROM t1;   --   2
@@ -192,7 +192,7 @@ do_execsql_test 5.1 {
   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;
+  INSERT INTO rt SELECT x, x, x+1, printf('x%04xy',x) FROM t1 WHERE x<=5;
 }
 do_rtree_integrity_test 5.1.1 rt
 
diff --git a/ext/rtree/rtreeH.test b/ext/rtree/rtreeH.test
new file mode 100644 (file)
index 0000000..bff765d
--- /dev/null
@@ -0,0 +1,80 @@
+# 2018-05-16
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file contains tests for the r-tree module, specifically the
+# auxiliary column mechanism.
+
+if {![info exists testdir]} {
+  set testdir [file join [file dirname [info script]] .. .. test]
+} 
+source [file join [file dirname [info script]] rtree_util.tcl]
+source $testdir/tester.tcl
+ifcapable !rtree { finish_test ; return }
+
+do_execsql_test rtreeH-100 {
+  CREATE VIRTUAL TABLE t1 USING rtree(id,x0,x1,y0,y1,+label,+other);
+  INSERT INTO t1(x0,x1,y0,y1,label) VALUES
+    (0,10,0,10,'lower-left corner'),
+    (0,10,90,100,'upper-left corner'),
+    (90,100,0,10,'lower-right corner'),
+    (90,100,90,100,'upper-right corner'),
+    (40,60,40,60,'center'),
+    (0,5,0,100,'left edge'),
+    (95,100,0,100,'right edge'),
+    (0,100,0,5,'bottom edge'),
+    (0,100,95,100,'top edge'),
+    (0,100,0,100,'the whole thing'),
+    (0,50,0,100,'left half'),
+    (51,100,0,100,'right half'),
+    (0,100,0,50,'bottom half'),
+    (0,100,51,100,'top half');
+} {}
+do_execsql_test rtreeH-101 {
+  SELECT * FROM t1_rowid ORDER BY rowid
+} {1 1 {lower-left corner} {} 2 1 {upper-left corner} {} 3 1 {lower-right corner} {} 4 1 {upper-right corner} {} 5 1 center {} 6 1 {left edge} {} 7 1 {right edge} {} 8 1 {bottom edge} {} 9 1 {top edge} {} 10 1 {the whole thing} {} 11 1 {left half} {} 12 1 {right half} {} 13 1 {bottom half} {} 14 1 {top half} {}}
+
+do_execsql_test rtreeH-102 {
+  SELECT * FROM t1 WHERE rowid=5;
+} {5 40.0 60.0 40.0 60.0 center {}}
+do_execsql_test rtreeH-103 {
+  SELECT * FROM t1 WHERE label='center';
+} {5 40.0 60.0 40.0 60.0 center {}}
+
+do_rtree_integrity_test rtreeH-110 t1
+
+do_execsql_test rtreeH-120 {
+  SELECT label FROM t1 WHERE x1<=50 ORDER BY id
+} {{lower-left corner} {upper-left corner} {left edge} {left half}}
+do_execsql_test rtreeH-121 {
+  SELECT label FROM t1 WHERE x1<=50 AND label NOT LIKE '%corner%' ORDER BY id
+} {{left edge} {left half}}
+
+do_execsql_test rtreeH-200 {
+  WITH RECURSIVE
+    c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<99),
+    c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<99)
+  INSERT INTO t1(id, x0,x1,y0,y1,label)
+    SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
+} {}
+
+do_execsql_test rtreeH-210 {
+  SELECT label FROM t1 WHERE x0>=48 AND x1<=50 AND y0>=48 AND y1<=50
+     ORDER BY id;
+} {box-48,48 box-49,48 box-48,49 box-49,49}
+
+do_execsql_test rtreeH-300 {
+  UPDATE t1 SET label='x'||label
+    WHERE x0>=49 AND x1<=50 AND y0>=49 AND y1<=50;
+  SELECT label FROM t1 WHERE x0>=48 AND x1<=50 AND y0>=48 AND y1<=50
+     ORDER BY id;
+} {box-48,48 box-49,48 box-48,49 xbox-49,49}
+
+
+finish_test
index fbcbd84a28b3163fb8f95c30715e20096f8b762f..6cb645124ed9468eb4677920214d94540c8dc647 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sOOM\sissue\smentioned\sin\sthe\sprevious\scheck-in.
-D 2018-05-16T18:18:24.545
+C Do\snot\sallow\sauxiliary\scolumns\sin\sthe\srtree\sto\sinterfere\swith\squery\splanning.\nBegin\sadding\stest\scases.
+D 2018-05-16T19:07:07.322
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -355,11 +355,11 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
 F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
-F ext/rtree/rtree.c 8176ca2bef95655f259b7320ae779e504b9d86edb181fc267cde94f9db3742b1
+F ext/rtree/rtree.c 762823491d82fccfe51628d4ed4e3c2444c839416e4c9e4fb5ff7267538a8759
 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
 F ext/rtree/rtree1.test 47e2095bebea6813754fd7afa6a20e2b7b4ebcd5cb7dbcb6932b6c9f86bbf972
 F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
-F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482
+F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499
 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
 F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142
 F ext/rtree/rtree6.test 593e0d36510d5ac1d1fb39b018274ff17604fe8fdca8cf1f8e16559cea1477f4
@@ -368,11 +368,12 @@ F ext/rtree/rtree8.test 649f5a37ec656028a4a32674b9b1183104285a7625a09d2a8f52a1ce
 F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf
 F ext/rtree/rtreeA.test 20623ca337ca3bd7e008cc9fb49e44dbe97f1a80b238e10a12bb4afcd0da3776
 F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9
-F ext/rtree/rtreeC.test 55e40c4bd9735d9944280f0e664f39374e71bcd9cd3fe4e82786d20b48017fb5
+F ext/rtree/rtreeC.test 128928549d22b65c381ab1366760d08703cd75e34f6a7a506ece38f9330b7282
 F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc
 F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9
 F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331
 F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c
+F ext/rtree/rtreeH.test aa08cc4fa8005b4c67446c7110205055b4d6da90e760e6f44b82dfa4cdf8d87a
 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
 F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b587936f5f6bceed
 F ext/rtree/rtreecheck.test 4d29103d1e16fcbf90135d1c637b833688492b063b2971dfb5dc6ba76555cfee
@@ -1728,7 +1729,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 0c87fec970221f954e0a92f3ef0437b382255479fac5b403ee37b1bb5ab29719
-R 1a66dc3ed24af9af189a9d927f133deb
+P c489d8e44eac4cd355096ab66bb40f13ef662f31e080c9f1f2ee379fe55b207a
+R f1ba39e4f92eb847a2aa6e82a35e3a11
 U drh
-Z 426a969e38bb74296bdc875c7051db68
+Z 5b179b6d81cfc68160024bb335ccee53
index 2a0e277de3a894831647d4aa6f5175b09a2f201d..328ec449f9d424300f7766c742ce1ee1d8148623 100644 (file)
@@ -1 +1 @@
-c489d8e44eac4cd355096ab66bb40f13ef662f31e080c9f1f2ee379fe55b207a
\ No newline at end of file
+9abe023e1afa7dc1a7eba7fbb3128401de129873d86b7c71c221decca26a821c
\ No newline at end of file