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