OLD | NEW |
| (Empty) |
1 # 2014 January 11 | |
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 # This file implements regression tests for SQLite library. The | |
12 # focus of this file is testing the WITH clause. | |
13 # | |
14 | |
15 set testdir [file dirname $argv0] | |
16 source $testdir/tester.tcl | |
17 set ::testprefix with2 | |
18 | |
19 ifcapable {!cte} { | |
20 finish_test | |
21 return | |
22 } | |
23 | |
24 do_execsql_test 1.0 { | |
25 CREATE TABLE t1(a); | |
26 INSERT INTO t1 VALUES(1); | |
27 INSERT INTO t1 VALUES(2); | |
28 } | |
29 | |
30 do_execsql_test 1.1 { | |
31 WITH x1 AS (SELECT * FROM t1) | |
32 SELECT sum(a) FROM x1; | |
33 } {3} | |
34 | |
35 do_execsql_test 1.2 { | |
36 WITH x1 AS (SELECT * FROM t1) | |
37 SELECT (SELECT sum(a) FROM x1); | |
38 } {3} | |
39 | |
40 do_execsql_test 1.3 { | |
41 WITH x1 AS (SELECT * FROM t1) | |
42 SELECT (SELECT sum(a) FROM x1); | |
43 } {3} | |
44 | |
45 do_execsql_test 1.4 { | |
46 CREATE TABLE t2(i); | |
47 INSERT INTO t2 VALUES(2); | |
48 INSERT INTO t2 VALUES(3); | |
49 INSERT INTO t2 VALUES(5); | |
50 | |
51 WITH x1 AS (SELECT i FROM t2), | |
52 i(a) AS ( | |
53 SELECT min(i)-1 FROM x1 UNION SELECT a+1 FROM i WHERE a<10 | |
54 ) | |
55 SELECT a FROM i WHERE a NOT IN x1 | |
56 } {1 4 6 7 8 9 10} | |
57 | |
58 do_execsql_test 1.5 { | |
59 WITH x1 AS (SELECT a FROM t1), | |
60 x2 AS (SELECT i FROM t2), | |
61 x3 AS (SELECT * FROM x1, x2 WHERE x1.a IN x2 AND x2.i IN x1) | |
62 SELECT * FROM x3 | |
63 } {2 2} | |
64 | |
65 do_execsql_test 1.6 { | |
66 CREATE TABLE t3 AS SELECT 3 AS x; | |
67 CREATE TABLE t4 AS SELECT 4 AS x; | |
68 | |
69 WITH x1 AS (SELECT * FROM t3), | |
70 x2 AS ( | |
71 WITH t3 AS (SELECT * FROM t4) | |
72 SELECT * FROM x1 | |
73 ) | |
74 SELECT * FROM x2; | |
75 } {3} | |
76 | |
77 do_execsql_test 1.7 { | |
78 WITH x2 AS ( | |
79 WITH t3 AS (SELECT * FROM t4) | |
80 SELECT * FROM t3 | |
81 ) | |
82 SELECT * FROM x2; | |
83 } {4} | |
84 | |
85 do_execsql_test 1.8 { | |
86 WITH x2 AS ( | |
87 WITH t3 AS (SELECT * FROM t4) | |
88 SELECT * FROM main.t3 | |
89 ) | |
90 SELECT * FROM x2; | |
91 } {3} | |
92 | |
93 do_execsql_test 1.9 { | |
94 WITH x1 AS (SELECT * FROM t1) | |
95 SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1); | |
96 } {3 2} | |
97 | |
98 do_execsql_test 1.10 { | |
99 WITH x1 AS (SELECT * FROM t1) | |
100 SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1), a FROM x1; | |
101 } {3 2 1 3 2 2} | |
102 | |
103 do_execsql_test 1.11 { | |
104 WITH | |
105 i(x) AS ( | |
106 WITH | |
107 j(x) AS ( SELECT * FROM i ), | |
108 i(x) AS ( SELECT * FROM t1 ) | |
109 SELECT * FROM j | |
110 ) | |
111 SELECT * FROM i; | |
112 } {1 2} | |
113 | |
114 do_execsql_test 1.12 { | |
115 WITH r(i) AS ( | |
116 VALUES('.') | |
117 UNION ALL | |
118 SELECT i || '.' FROM r, ( | |
119 SELECT x FROM x INTERSECT SELECT y FROM y | |
120 ) WHERE length(i) < 10 | |
121 ), | |
122 x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) ), | |
123 y(y) AS ( VALUES(2) UNION ALL VALUES(4) UNION ALL VALUES(6) ) | |
124 | |
125 SELECT * FROM r; | |
126 } {. .. ... .... ..... ...... ....... ........ ......... ..........} | |
127 | |
128 do_execsql_test 1.13 { | |
129 WITH r(i) AS ( | |
130 VALUES('.') | |
131 UNION ALL | |
132 SELECT i || '.' FROM r, ( SELECT x FROM x WHERE x=2 ) WHERE length(i) < 10 | |
133 ), | |
134 x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) ) | |
135 | |
136 SELECT * FROM r ORDER BY length(i) DESC; | |
137 } {.......... ......... ........ ....... ...... ..... .... ... .. .} | |
138 | |
139 do_execsql_test 1.14 { | |
140 WITH | |
141 t4(x) AS ( | |
142 VALUES(4) | |
143 UNION ALL | |
144 SELECT x+1 FROM t4 WHERE x<10 | |
145 ) | |
146 SELECT * FROM t4; | |
147 } {4 5 6 7 8 9 10} | |
148 | |
149 do_execsql_test 1.15 { | |
150 WITH | |
151 t4(x) AS ( | |
152 VALUES(4) | |
153 UNION ALL | |
154 SELECT x+1 FROM main.t4 WHERE x<10 | |
155 ) | |
156 SELECT * FROM t4; | |
157 } {4 5} | |
158 | |
159 do_catchsql_test 1.16 { | |
160 WITH | |
161 t4(x) AS ( | |
162 VALUES(4) | |
163 UNION ALL | |
164 SELECT x+1 FROM t4, main.t4, t4 WHERE x<10 | |
165 ) | |
166 SELECT * FROM t4; | |
167 } {1 {multiple references to recursive table: t4}} | |
168 | |
169 | |
170 #--------------------------------------------------------------------------- | |
171 # Check that variables can be used in CTEs. | |
172 # | |
173 set ::min [expr 3] | |
174 set ::max [expr 9] | |
175 do_execsql_test 2.1 { | |
176 WITH i(x) AS ( | |
177 VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max | |
178 ) | |
179 SELECT * FROM i; | |
180 } {3 4 5 6 7 8 9} | |
181 | |
182 do_execsql_test 2.2 { | |
183 WITH i(x) AS ( | |
184 VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max | |
185 ) | |
186 SELECT x FROM i JOIN i AS j USING (x); | |
187 } {3 4 5 6 7 8 9} | |
188 | |
189 #--------------------------------------------------------------------------- | |
190 # Check that circular references are rejected. | |
191 # | |
192 do_catchsql_test 3.1 { | |
193 WITH i(x, y) AS ( VALUES(1, (SELECT x FROM i)) ) | |
194 SELECT * FROM i; | |
195 } {1 {circular reference: i}} | |
196 | |
197 do_catchsql_test 3.2 { | |
198 WITH | |
199 i(x) AS ( SELECT * FROM j ), | |
200 j(x) AS ( SELECT * FROM k ), | |
201 k(x) AS ( SELECT * FROM i ) | |
202 SELECT * FROM i; | |
203 } {1 {circular reference: i}} | |
204 | |
205 do_catchsql_test 3.3 { | |
206 WITH | |
207 i(x) AS ( SELECT * FROM (SELECT * FROM j) ), | |
208 j(x) AS ( SELECT * FROM (SELECT * FROM i) ) | |
209 SELECT * FROM i; | |
210 } {1 {circular reference: i}} | |
211 | |
212 do_catchsql_test 3.4 { | |
213 WITH | |
214 i(x) AS ( SELECT * FROM (SELECT * FROM j) ), | |
215 j(x) AS ( SELECT * FROM (SELECT * FROM i) ) | |
216 SELECT * FROM j; | |
217 } {1 {circular reference: j}} | |
218 | |
219 do_catchsql_test 3.5 { | |
220 WITH | |
221 i(x) AS ( | |
222 WITH j(x) AS ( SELECT * FROM i ) | |
223 SELECT * FROM j | |
224 ) | |
225 SELECT * FROM i; | |
226 } {1 {circular reference: i}} | |
227 | |
228 #--------------------------------------------------------------------------- | |
229 # Try empty and very long column lists. | |
230 # | |
231 do_catchsql_test 4.1 { | |
232 WITH x() AS ( SELECT 1,2,3 ) | |
233 SELECT * FROM x; | |
234 } {1 {near ")": syntax error}} | |
235 | |
236 proc genstmt {n} { | |
237 for {set i 1} {$i<=$n} {incr i} { | |
238 lappend cols "c$i" | |
239 lappend vals $i | |
240 } | |
241 return " | |
242 WITH x([join $cols ,]) AS (SELECT [join $vals ,]) | |
243 SELECT (c$n == $n) FROM x | |
244 " | |
245 } | |
246 | |
247 do_execsql_test 4.2 [genstmt 10] 1 | |
248 do_execsql_test 4.3 [genstmt 100] 1 | |
249 do_execsql_test 4.4 [genstmt 255] 1 | |
250 set nLimit [sqlite3_limit db SQLITE_LIMIT_COLUMN -1] | |
251 do_execsql_test 4.5 [genstmt [expr $nLimit-1]] 1 | |
252 do_execsql_test 4.6 [genstmt $nLimit] 1 | |
253 do_catchsql_test 4.7 [genstmt [expr $nLimit+1]] {1 {too many columns in index}} | |
254 | |
255 #--------------------------------------------------------------------------- | |
256 # Check that adding a WITH clause to an INSERT disables the xfer | |
257 # optimization. | |
258 # | |
259 proc do_xfer_test {tn bXfer sql {res {}}} { | |
260 set ::sqlite3_xferopt_count 0 | |
261 uplevel [list do_test $tn [subst -nocommands { | |
262 set dres [db eval {$sql}] | |
263 list [set ::sqlite3_xferopt_count] [set dres] | |
264 }] [list $bXfer $res]] | |
265 } | |
266 | |
267 do_execsql_test 5.1 { | |
268 DROP TABLE IF EXISTS t1; | |
269 DROP TABLE IF EXISTS t2; | |
270 CREATE TABLE t1(a, b); | |
271 CREATE TABLE t2(a, b); | |
272 } | |
273 | |
274 do_xfer_test 5.2 1 { INSERT INTO t1 SELECT * FROM t2 } | |
275 do_xfer_test 5.3 0 { INSERT INTO t1 SELECT a, b FROM t2 } | |
276 do_xfer_test 5.4 0 { INSERT INTO t1 SELECT b, a FROM t2 } | |
277 do_xfer_test 5.5 0 { | |
278 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM x | |
279 } | |
280 do_xfer_test 5.6 0 { | |
281 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 | |
282 } | |
283 do_xfer_test 5.7 0 { | |
284 INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x | |
285 } | |
286 do_xfer_test 5.8 0 { | |
287 INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x | |
288 } | |
289 | |
290 #--------------------------------------------------------------------------- | |
291 # Check that syntax (and other) errors in statements with WITH clauses | |
292 # attached to them do not cause problems (e.g. memory leaks). | |
293 # | |
294 do_execsql_test 6.1 { | |
295 DROP TABLE IF EXISTS t1; | |
296 DROP TABLE IF EXISTS t2; | |
297 CREATE TABLE t1(a, b); | |
298 CREATE TABLE t2(a, b); | |
299 } | |
300 | |
301 do_catchsql_test 6.2 { | |
302 WITH x AS (SELECT * FROM t1) | |
303 INSERT INTO t2 VALUES(1, 2,); | |
304 } {1 {near ")": syntax error}} | |
305 | |
306 do_catchsql_test 6.3 { | |
307 WITH x AS (SELECT * FROM t1) | |
308 INSERT INTO t2 SELECT a, b, FROM t1; | |
309 } {1 {near "FROM": syntax error}} | |
310 | |
311 do_catchsql_test 6.3 { | |
312 WITH x AS (SELECT * FROM t1) | |
313 INSERT INTO t2 SELECT a, b FROM abc; | |
314 } {1 {no such table: abc}} | |
315 | |
316 do_catchsql_test 6.4 { | |
317 WITH x AS (SELECT * FROM t1) | |
318 INSERT INTO t2 SELECT a, b, FROM t1 a a a; | |
319 } {1 {near "FROM": syntax error}} | |
320 | |
321 do_catchsql_test 6.5 { | |
322 WITH x AS (SELECT * FROM t1) | |
323 DELETE FROM t2 WHERE; | |
324 } {1 {near ";": syntax error}} | |
325 | |
326 do_catchsql_test 6.6 { | |
327 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE | |
328 } {/1 {near .* syntax error}/} | |
329 | |
330 do_catchsql_test 6.7 { | |
331 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1; | |
332 } {/1 {near .* syntax error}/} | |
333 | |
334 do_catchsql_test 6.8 { | |
335 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ; | |
336 } {/1 {near .* syntax error}/} | |
337 | |
338 do_catchsql_test 6.9 { | |
339 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = 1 WHERE a===b; | |
340 } {/1 {near .* syntax error}/} | |
341 | |
342 do_catchsql_test 6.10 { | |
343 WITH x(a,b) AS ( | |
344 SELECT 1, 1 | |
345 UNION ALL | |
346 SELECT a*b,a+b FROM x WHERE c=2 | |
347 ) | |
348 SELECT * FROM x | |
349 } {1 {no such column: c}} | |
350 | |
351 #------------------------------------------------------------------------- | |
352 # Recursive queries in IN(...) expressions. | |
353 # | |
354 do_execsql_test 7.1 { | |
355 CREATE TABLE t5(x INTEGER); | |
356 CREATE TABLE t6(y INTEGER); | |
357 | |
358 WITH s(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM s WHERE x<49 ) | |
359 INSERT INTO t5 | |
360 SELECT * FROM s; | |
361 | |
362 INSERT INTO t6 | |
363 WITH s(x) AS ( VALUES(2) UNION ALL SELECT x+2 FROM s WHERE x<49 ) | |
364 SELECT * FROM s; | |
365 } | |
366 | |
367 do_execsql_test 7.2 { | |
368 SELECT * FROM t6 WHERE y IN (SELECT x FROM t5) | |
369 } {14 28 42} | |
370 | |
371 do_execsql_test 7.3 { | |
372 WITH ss AS (SELECT x FROM t5) | |
373 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) | |
374 } {14 28 42} | |
375 | |
376 do_execsql_test 7.4 { | |
377 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) | |
378 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) | |
379 } {14 28 42} | |
380 | |
381 do_execsql_test 7.5 { | |
382 SELECT * FROM t6 WHERE y IN ( | |
383 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) | |
384 SELECT x FROM ss | |
385 ) | |
386 } {14 28 42} | |
387 | |
388 #------------------------------------------------------------------------- | |
389 # At one point the following was causing an assertion failure and a | |
390 # memory leak. | |
391 # | |
392 do_execsql_test 8.1 { | |
393 CREATE TABLE t7(y); | |
394 INSERT INTO t7 VALUES(NULL); | |
395 CREATE VIEW v AS SELECT * FROM t7 ORDER BY y; | |
396 } | |
397 | |
398 do_execsql_test 8.2 { | |
399 WITH q(a) AS ( | |
400 SELECT 1 | |
401 UNION | |
402 SELECT a+1 FROM q, v WHERE a<5 | |
403 ) | |
404 SELECT * FROM q; | |
405 } {1 2 3 4 5} | |
406 | |
407 do_execsql_test 8.3 { | |
408 WITH q(a) AS ( | |
409 SELECT 1 | |
410 UNION ALL | |
411 SELECT a+1 FROM q, v WHERE a<5 | |
412 ) | |
413 SELECT * FROM q; | |
414 } {1 2 3 4 5} | |
415 | |
416 | |
417 finish_test | |
418 | |
OLD | NEW |