3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # Test cases for transitive_closure virtual table.
14 set testdir [file dirname $argv0]
15 source $testdir/tester.tcl
16 set testprefix closure01
18 ifcapable !vtab||!cte { finish_test ; return }
20 load_static_extension db closure
24 CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER);
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);
30 CREATE VIRTUAL TABLE cx
31 USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y);
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 {
43 SELECT t1.x, below.depth+1
44 FROM t1 JOIN below on t1.y=below.id
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/}
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 {
58 SELECT t1.x, below.depth+1
59 FROM t1 JOIN below on t1.y=below.id
62 SELECT id, depth FROM below ORDER BY id;
63 } {32768 0 65536 1 65537 1 131072 2}
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 {
74 SELECT t1.x, below.depth+1
75 FROM t1 JOIN below on t1.y=below.id
78 SELECT id, depth FROM below ORDER BY id;
79 } {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2}
83 SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx
87 } {32768 1 {} t1 x y 32769 1 {} t1 x y}
89 # great-grandparent of 16384
90 do_timed_execsql_test 1.5 {
91 SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx
97 do_timed_execsql_test 1.5-cte {
102 SELECT t1.y, above.depth+1
103 FROM t1 JOIN above ON t1.x=above.id
106 SELECT id FROM above WHERE depth=3;
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 {
119 SELECT t1.x, below.depth+1
120 FROM t1 JOIN below ON t1.y=below.id
123 SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1;
124 } {1 0 2 1 4 2 8 3 16 4}
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}
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;
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;
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;
148 do_timed_execsql_test 1.10-cte {
153 SELECT t1.x, below.depth+1
154 FROM t1 JOIN below ON t1.y=below.id
157 SELECT count(*), min(id), max(id) FROM below WHERE depth=5;
160 # Create a much smaller table t2 with only 32 elements
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);
170 do_execsql_test 2.1 {
171 SELECT count(*), min(id), max(id) FROM c2 WHERE root=1;
174 do_execsql_test 2.2 {
175 SELECT id FROM c2 WHERE root=10;
178 do_execsql_test 2.3 {
179 SELECT id FROM c2 WHERE root=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}
191 do_execsql_test 3.0 {
192 CREATE VIRTUAL TABLE c2up USING transitive_closure(
197 SELECT id FROM c2up WHERE root=20;
201 do_execsql_test 3.1 {
206 AND parentcolumn='x';
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)
215 } {5 10 11 20 21 22 23}
217 # t2 first cousins of 20
218 do_execsql_test 3.3 {
220 WHERE root=(SELECT id FROM c2up
221 WHERE root=20 AND depth=2)
225 WHERE root=(SELECT id FROM c2up
226 WHERE root=20 AND depth=1)
238 AND parentcolumn='x';
240 } {1 {no such table: t3}}
249 AND parentcolumn='x';
251 } {1 {no such column: t2.xyz}}
253 # missing parentcolumn
260 AND parentcolumn='pqr';
262 } {1 {no such column: t2.pqr}}
265 do_execsql_test 5.1 {
266 CREATE VIRTUAL TABLE temp.closure USING transitive_closure;
267 SELECT id FROM closure
274 } {8 9 10 11 12 13 14 15}
276 #-------------------------------------------------------------------------
277 # At one point the following join query was causing a malfunction in
280 do_execsql_test 6.0 {
282 id INTEGER PRIMARY KEY,
286 CREATE VIRTUAL TABLE vt4 USING transitive_closure (
287 idcolumn=id, parentcolumn=parent_id, tablename=t4
291 do_execsql_test 6.1 {
292 SELECT * FROM t4, vt4 WHERE t4.id = vt4.root AND vt4.id=4 AND vt4.depth=2;