OLD | NEW |
| (Empty) |
1 # 2011 March 2 | |
2 # | |
3 # The author disclaims copyright to this source code. In place of | |
4 # a legal notice, here is a blessing: | |
5 # | |
6 # May you do good and not evil. | |
7 # May you find forgiveness for yourself and forgive others. | |
8 # May you share freely, never taking more than you give. | |
9 # | |
10 #*********************************************************************** | |
11 # Make sure the rtreenode() testing function can handle entries with | |
12 # 64-bit rowids. | |
13 # | |
14 | |
15 if {![info exists testdir]} { | |
16 set testdir [file join [file dirname [info script]] .. .. test] | |
17 } | |
18 source $testdir/tester.tcl | |
19 ifcapable !rtree { finish_test ; return } | |
20 set testprefix rtreeC | |
21 | |
22 do_execsql_test 1.0 { | |
23 CREATE VIRTUAL TABLE r_tree USING rtree(id, min_x, max_x, min_y, max_y); | |
24 CREATE TABLE t(x, y); | |
25 } | |
26 | |
27 do_eqp_test 1.1 { | |
28 SELECT * FROM r_tree, t | |
29 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y | |
30 } { | |
31 0 0 1 {SCAN TABLE t} | |
32 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
33 } | |
34 | |
35 do_eqp_test 1.2 { | |
36 SELECT * FROM t, r_tree | |
37 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y | |
38 } { | |
39 0 0 0 {SCAN TABLE t} | |
40 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
41 } | |
42 | |
43 do_eqp_test 1.3 { | |
44 SELECT * FROM t, r_tree | |
45 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y | |
46 } { | |
47 0 0 0 {SCAN TABLE t} | |
48 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
49 } | |
50 | |
51 do_eqp_test 1.5 { | |
52 SELECT * FROM t, r_tree | |
53 } { | |
54 0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:} | |
55 0 1 0 {SCAN TABLE t} | |
56 } | |
57 | |
58 do_execsql_test 2.0 { | |
59 INSERT INTO t VALUES(0, 0); | |
60 INSERT INTO t VALUES(0, 1); | |
61 INSERT INTO t VALUES(0, 2); | |
62 INSERT INTO t VALUES(0, 3); | |
63 INSERT INTO t VALUES(0, 4); | |
64 INSERT INTO t VALUES(0, 5); | |
65 INSERT INTO t VALUES(0, 6); | |
66 INSERT INTO t VALUES(0, 7); | |
67 INSERT INTO t VALUES(0, 8); | |
68 INSERT INTO t VALUES(0, 9); | |
69 | |
70 INSERT INTO t SELECT x+1, y FROM t; | |
71 INSERT INTO t SELECT x+2, y FROM t; | |
72 INSERT INTO t SELECT x+4, y FROM t; | |
73 INSERT INTO r_tree SELECT NULL, x-1, x+1, y-1, y+1 FROM t; | |
74 ANALYZE; | |
75 } | |
76 | |
77 db close | |
78 sqlite3 db test.db | |
79 | |
80 do_eqp_test 2.1 { | |
81 SELECT * FROM r_tree, t | |
82 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y | |
83 } { | |
84 0 0 1 {SCAN TABLE t} | |
85 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
86 } | |
87 | |
88 do_eqp_test 2.2 { | |
89 SELECT * FROM t, r_tree | |
90 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y | |
91 } { | |
92 0 0 0 {SCAN TABLE t} | |
93 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
94 } | |
95 | |
96 do_eqp_test 2.3 { | |
97 SELECT * FROM t, r_tree | |
98 WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y | |
99 } { | |
100 0 0 0 {SCAN TABLE t} | |
101 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} | |
102 } | |
103 | |
104 do_eqp_test 2.5 { | |
105 SELECT * FROM t, r_tree | |
106 } { | |
107 0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:} | |
108 0 1 0 {SCAN TABLE t} | |
109 } | |
110 | |
111 #------------------------------------------------------------------------- | |
112 # Test that the special CROSS JOIN handling works with rtree tables. | |
113 # | |
114 do_execsql_test 3.1 { | |
115 CREATE TABLE t1(x); | |
116 CREATE TABLE t2(y); | |
117 CREATE VIRTUAL TABLE t3 USING rtree(z, x1,x2, y1,y2); | |
118 } | |
119 | |
120 do_eqp_test 3.2.1 { SELECT * FROM t1 CROSS JOIN t2 } { | |
121 0 0 0 {SCAN TABLE t1} | |
122 0 1 1 {SCAN TABLE t2} | |
123 } | |
124 do_eqp_test 3.2.2 { SELECT * FROM t2 CROSS JOIN t1 } { | |
125 0 0 0 {SCAN TABLE t2} 0 1 1 {SCAN TABLE t1} | |
126 } | |
127 | |
128 do_eqp_test 3.3.1 { SELECT * FROM t1 CROSS JOIN t3 } { | |
129 0 0 0 {SCAN TABLE t1} | |
130 0 1 1 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} | |
131 } | |
132 do_eqp_test 3.3.2 { SELECT * FROM t3 CROSS JOIN t1 } { | |
133 0 0 0 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} | |
134 0 1 1 {SCAN TABLE t1} | |
135 } | |
136 | |
137 #-------------------------------------------------------------------- | |
138 # Test that LEFT JOINs are not reordered if the right-hand-side is | |
139 # a virtual table. | |
140 # | |
141 reset_db | |
142 do_execsql_test 4.1 { | |
143 CREATE TABLE t1(a); | |
144 CREATE VIRTUAL TABLE t2 USING rtree(b, x1,x2); | |
145 | |
146 INSERT INTO t1 VALUES(1); | |
147 INSERT INTO t1 VALUES(2); | |
148 | |
149 INSERT INTO t2 VALUES(1, 0.0, 0.1); | |
150 INSERT INTO t2 VALUES(3, 0.0, 0.1); | |
151 } | |
152 | |
153 do_execsql_test 4.2 { | |
154 SELECT a, b FROM t1 LEFT JOIN t2 ON (+a = +b); | |
155 } {1 1 2 {}} | |
156 | |
157 do_execsql_test 4.3 { | |
158 SELECT b, a FROM t2 LEFT JOIN t1 ON (+a = +b); | |
159 } {1 1 3 {}} | |
160 | |
161 #-------------------------------------------------------------------- | |
162 # Test that the sqlite_stat1 data is used correctly. | |
163 # | |
164 reset_db | |
165 do_execsql_test 5.1 { | |
166 CREATE TABLE t1(x PRIMARY KEY, y); | |
167 CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2); | |
168 | |
169 INSERT INTO t1(x) VALUES(1); | |
170 INSERT INTO t1(x) SELECT x+1 FROM t1; -- 2 | |
171 INSERT INTO t1(x) SELECT x+2 FROM t1; -- 4 | |
172 INSERT INTO t1(x) SELECT x+4 FROM t1; -- 8 | |
173 INSERT INTO t1(x) SELECT x+8 FROM t1; -- 16 | |
174 INSERT INTO t1(x) SELECT x+16 FROM t1; -- 32 | |
175 INSERT INTO t1(x) SELECT x+32 FROM t1; -- 64 | |
176 INSERT INTO t1(x) SELECT x+64 FROM t1; -- 128 | |
177 INSERT INTO t1(x) SELECT x+128 FROM t1; -- 256 | |
178 INSERT INTO t1(x) SELECT x+256 FROM t1; -- 512 | |
179 INSERT INTO t1(x) SELECT x+512 FROM t1; --1024 | |
180 | |
181 INSERT INTO rt SELECT x, x, x+1 FROM t1 WHERE x<=5; | |
182 } | |
183 | |
184 # First test a query with no ANALYZE data at all. The outer loop is | |
185 # real table "t1". | |
186 # | |
187 do_eqp_test 5.2 { | |
188 SELECT * FROM t1, rt WHERE x==id; | |
189 } { | |
190 0 0 0 {SCAN TABLE t1} | |
191 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} | |
192 } | |
193 | |
194 # Now create enough ANALYZE data to tell SQLite that virtual table "rt" | |
195 # contains very few rows. This causes it to move "rt" to the outer loop. | |
196 # | |
197 do_execsql_test 5.3 { | |
198 ANALYZE; | |
199 DELETE FROM sqlite_stat1 WHERE tbl='t1'; | |
200 } | |
201 db close | |
202 sqlite3 db test.db | |
203 do_eqp_test 5.4 { | |
204 SELECT * FROM t1, rt WHERE x==id; | |
205 } { | |
206 0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:} | |
207 0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)} | |
208 } | |
209 | |
210 # Delete the ANALYZE data. "t1" should be the outer loop again. | |
211 # | |
212 do_execsql_test 5.5 { DROP TABLE sqlite_stat1; } | |
213 db close | |
214 sqlite3 db test.db | |
215 do_eqp_test 5.6 { | |
216 SELECT * FROM t1, rt WHERE x==id; | |
217 } { | |
218 0 0 0 {SCAN TABLE t1} | |
219 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} | |
220 } | |
221 | |
222 # This time create and attach a database that contains ANALYZE data for | |
223 # tables of the same names as those used internally by virtual table | |
224 # "rt". Check that the rtree module is not fooled into using this data. | |
225 # Table "t1" should remain the outer loop. | |
226 # | |
227 do_test 5.7 { | |
228 db backup test.db2 | |
229 sqlite3 db2 test.db2 | |
230 db2 eval { | |
231 ANALYZE; | |
232 DELETE FROM sqlite_stat1 WHERE tbl='t1'; | |
233 } | |
234 db2 close | |
235 db close | |
236 sqlite3 db test.db | |
237 execsql { ATTACH 'test.db2' AS aux; } | |
238 } {} | |
239 do_eqp_test 5.8 { | |
240 SELECT * FROM t1, rt WHERE x==id; | |
241 } { | |
242 0 0 0 {SCAN TABLE t1} | |
243 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} | |
244 } | |
245 | |
246 #-------------------------------------------------------------------- | |
247 # Test that having a second connection drop the sqlite_stat1 table | |
248 # before it is required by rtreeConnect() does not cause problems. | |
249 # | |
250 ifcapable rtree { | |
251 reset_db | |
252 do_execsql_test 6.1 { | |
253 CREATE TABLE t1(x); | |
254 CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2); | |
255 INSERT INTO t1 VALUES(1); | |
256 INSERT INTO rt VALUES(1,2,3); | |
257 ANALYZE; | |
258 } | |
259 db close | |
260 sqlite3 db test.db | |
261 do_execsql_test 6.2 { SELECT * FROM t1 } {1} | |
262 | |
263 do_test 6.3 { | |
264 sqlite3 db2 test.db | |
265 db2 eval { DROP TABLE sqlite_stat1 } | |
266 db2 close | |
267 execsql { SELECT * FROM rt } | |
268 } {1 2.0 3.0} | |
269 db close | |
270 } | |
271 | |
272 | |
273 finish_test | |
OLD | NEW |