OLD | NEW |
| (Empty) |
1 # 2013-04-25 | |
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 # | |
12 # Test cases for transitive_closure virtual table. | |
13 | |
14 set testdir [file dirname $argv0] | |
15 source $testdir/tester.tcl | |
16 set testprefix closure01 | |
17 | |
18 ifcapable !vtab||!cte { finish_test ; return } | |
19 | |
20 load_static_extension db closure | |
21 | |
22 do_execsql_test 1.0 { | |
23 BEGIN; | |
24 CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER); | |
25 WITH RECURSIVE | |
26 cnt(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM cnt LIMIT 131072) | |
27 INSERT INTO t1(x, y) SELECT i, nullif(i,1)/2 FROM cnt; | |
28 CREATE INDEX t1y ON t1(y); | |
29 COMMIT; | |
30 CREATE VIRTUAL TABLE cx | |
31 USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y); | |
32 } {} | |
33 | |
34 # The entire table | |
35 do_timed_execsql_test 1.1 { | |
36 SELECT count(*), depth FROM cx WHERE root=1 GROUP BY depth ORDER BY 1; | |
37 } {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} | |
38 do_timed_execsql_test 1.1-cte { | |
39 WITH RECURSIVE | |
40 below(id,depth) AS ( | |
41 VALUES(1,0) | |
42 UNION ALL | |
43 SELECT t1.x, below.depth+1 | |
44 FROM t1 JOIN below on t1.y=below.id | |
45 ) | |
46 SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; | |
47 } {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} | |
48 | |
49 # descendents of 32768 | |
50 do_timed_execsql_test 1.2 { | |
51 SELECT * FROM cx WHERE root=32768 ORDER BY id; | |
52 } {32768 0 65536 1 65537 1 131072 2} | |
53 do_timed_execsql_test 1.2-cte { | |
54 WITH RECURSIVE | |
55 below(id,depth) AS ( | |
56 VALUES(32768,0) | |
57 UNION ALL | |
58 SELECT t1.x, below.depth+1 | |
59 FROM t1 JOIN below on t1.y=below.id | |
60 WHERE below.depth<2 | |
61 ) | |
62 SELECT id, depth FROM below ORDER BY id; | |
63 } {32768 0 65536 1 65537 1 131072 2} | |
64 | |
65 # descendents of 16384 | |
66 do_timed_execsql_test 1.3 { | |
67 SELECT * FROM cx WHERE root=16384 AND depth<=2 ORDER BY id; | |
68 } {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} | |
69 do_timed_execsql_test 1.3-cte { | |
70 WITH RECURSIVE | |
71 below(id,depth) AS ( | |
72 VALUES(16384,0) | |
73 UNION ALL | |
74 SELECT t1.x, below.depth+1 | |
75 FROM t1 JOIN below on t1.y=below.id | |
76 WHERE below.depth<2 | |
77 ) | |
78 SELECT id, depth FROM below ORDER BY id; | |
79 } {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} | |
80 | |
81 # children of 16384 | |
82 do_execsql_test 1.4 { | |
83 SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx | |
84 WHERE root=16384 | |
85 AND depth=1 | |
86 ORDER BY id; | |
87 } {32768 1 {} t1 x y 32769 1 {} t1 x y} | |
88 | |
89 # great-grandparent of 16384 | |
90 do_timed_execsql_test 1.5 { | |
91 SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx | |
92 WHERE root=16384 | |
93 AND depth=3 | |
94 AND idcolumn='Y' | |
95 AND parentcolumn='X'; | |
96 } {2048 3 {} t1 Y X} | |
97 do_timed_execsql_test 1.5-cte { | |
98 WITH RECURSIVE | |
99 above(id,depth) AS ( | |
100 VALUES(16384,0) | |
101 UNION ALL | |
102 SELECT t1.y, above.depth+1 | |
103 FROM t1 JOIN above ON t1.x=above.id | |
104 WHERE above.depth<3 | |
105 ) | |
106 SELECT id FROM above WHERE depth=3; | |
107 } {2048} | |
108 | |
109 # depth<5 | |
110 do_timed_execsql_test 1.6 { | |
111 SELECT count(*), depth FROM cx WHERE root=1 AND depth<5 | |
112 GROUP BY depth ORDER BY 1; | |
113 } {1 0 2 1 4 2 8 3 16 4} | |
114 do_timed_execsql_test 1.6-cte { | |
115 WITH RECURSIVE | |
116 below(id,depth) AS ( | |
117 VALUES(1,0) | |
118 UNION ALL | |
119 SELECT t1.x, below.depth+1 | |
120 FROM t1 JOIN below ON t1.y=below.id | |
121 WHERE below.depth<4 | |
122 ) | |
123 SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; | |
124 } {1 0 2 1 4 2 8 3 16 4} | |
125 | |
126 # depth<=5 | |
127 do_execsql_test 1.7 { | |
128 SELECT count(*), depth FROM cx WHERE root=1 AND depth<=5 | |
129 GROUP BY depth ORDER BY 1; | |
130 } {1 0 2 1 4 2 8 3 16 4 32 5} | |
131 | |
132 # depth==5 | |
133 do_execsql_test 1.8 { | |
134 SELECT count(*), depth FROM cx WHERE root=1 AND depth=5 | |
135 GROUP BY depth ORDER BY 1; | |
136 } {32 5} | |
137 | |
138 # depth BETWEEN 3 AND 5 | |
139 do_execsql_test 1.9 { | |
140 SELECT count(*), depth FROM cx WHERE root=1 AND depth BETWEEN 3 AND 5 | |
141 GROUP BY depth ORDER BY 1; | |
142 } {8 3 16 4 32 5} | |
143 | |
144 # depth==5 with min() and max() | |
145 do_timed_execsql_test 1.10 { | |
146 SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND depth=5; | |
147 } {32 32 63} | |
148 do_timed_execsql_test 1.10-cte { | |
149 WITH RECURSIVE | |
150 below(id,depth) AS ( | |
151 VALUES(1,0) | |
152 UNION ALL | |
153 SELECT t1.x, below.depth+1 | |
154 FROM t1 JOIN below ON t1.y=below.id | |
155 WHERE below.depth<5 | |
156 ) | |
157 SELECT count(*), min(id), max(id) FROM below WHERE depth=5; | |
158 } {32 32 63} | |
159 | |
160 # Create a much smaller table t2 with only 32 elements | |
161 db eval { | |
162 CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER); | |
163 INSERT INTO t2 SELECT x, y FROM t1 WHERE x<32; | |
164 CREATE INDEX t2y ON t2(y); | |
165 CREATE VIRTUAL TABLE c2 | |
166 USING transitive_closure(tablename=t2, idcolumn=x, parentcolumn=y); | |
167 } | |
168 | |
169 # t2 full-table | |
170 do_execsql_test 2.1 { | |
171 SELECT count(*), min(id), max(id) FROM c2 WHERE root=1; | |
172 } {31 1 31} | |
173 # t2 root=10 | |
174 do_execsql_test 2.2 { | |
175 SELECT id FROM c2 WHERE root=10; | |
176 } {10 20 21} | |
177 # t2 root=11 | |
178 do_execsql_test 2.3 { | |
179 SELECT id FROM c2 WHERE root=12; | |
180 } {12 24 25} | |
181 # t2 root IN [10,12] | |
182 do_execsql_test 2.4 { | |
183 SELECT id FROM c2 WHERE root IN (10,12) ORDER BY id; | |
184 } {10 12 20 21 24 25} | |
185 # t2 root IN [10,12] (sorted) | |
186 do_execsql_test 2.5 { | |
187 SELECT id FROM c2 WHERE root IN (10,12) ORDER BY +id; | |
188 } {10 12 20 21 24 25} | |
189 | |
190 # t2 c2up from 20 | |
191 do_execsql_test 3.0 { | |
192 CREATE VIRTUAL TABLE c2up USING transitive_closure( | |
193 tablename = t2, | |
194 idcolumn = y, | |
195 parentcolumn = x | |
196 ); | |
197 SELECT id FROM c2up WHERE root=20; | |
198 } {1 2 5 10 20} | |
199 | |
200 # cx as c2up | |
201 do_execsql_test 3.1 { | |
202 SELECT id FROM cx | |
203 WHERE root=20 | |
204 AND tablename='t2' | |
205 AND idcolumn='y' | |
206 AND parentcolumn='x'; | |
207 } {1 2 5 10 20} | |
208 | |
209 # t2 first cousins of 20 | |
210 do_execsql_test 3.2 { | |
211 SELECT DISTINCT id FROM c2 | |
212 WHERE root IN (SELECT id FROM c2up | |
213 WHERE root=20 AND depth<=2) | |
214 ORDER BY id; | |
215 } {5 10 11 20 21 22 23} | |
216 | |
217 # t2 first cousins of 20 | |
218 do_execsql_test 3.3 { | |
219 SELECT id FROM c2 | |
220 WHERE root=(SELECT id FROM c2up | |
221 WHERE root=20 AND depth=2) | |
222 AND depth=2 | |
223 EXCEPT | |
224 SELECT id FROM c2 | |
225 WHERE root=(SELECT id FROM c2up | |
226 WHERE root=20 AND depth=1) | |
227 AND depth<=1 | |
228 ORDER BY id; | |
229 } {22 23} | |
230 | |
231 # missing tablename. | |
232 do_test 4.1 { | |
233 catchsql { | |
234 SELECT id FROM cx | |
235 WHERE root=20 | |
236 AND tablename='t3' | |
237 AND idcolumn='y' | |
238 AND parentcolumn='x'; | |
239 } | |
240 } {1 {no such table: t3}} | |
241 | |
242 # missing idcolumn | |
243 do_test 4.2 { | |
244 catchsql { | |
245 SELECT id FROM cx | |
246 WHERE root=20 | |
247 AND tablename='t2' | |
248 AND idcolumn='xyz' | |
249 AND parentcolumn='x'; | |
250 } | |
251 } {1 {no such column: t2.xyz}} | |
252 | |
253 # missing parentcolumn | |
254 do_test 4.3 { | |
255 catchsql { | |
256 SELECT id FROM cx | |
257 WHERE root=20 | |
258 AND tablename='t2' | |
259 AND idcolumn='x' | |
260 AND parentcolumn='pqr'; | |
261 } | |
262 } {1 {no such column: t2.pqr}} | |
263 | |
264 # generic closure | |
265 do_execsql_test 5.1 { | |
266 CREATE VIRTUAL TABLE temp.closure USING transitive_closure; | |
267 SELECT id FROM closure | |
268 WHERE root=1 | |
269 AND depth=3 | |
270 AND tablename='t1' | |
271 AND idcolumn='x' | |
272 AND parentcolumn='y' | |
273 ORDER BY id; | |
274 } {8 9 10 11 12 13 14 15} | |
275 | |
276 finish_test | |
OLD | NEW |