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]] \ | |
254 {1 {too many columns in result set}} | |
255 | |
256 #--------------------------------------------------------------------------- | |
257 # Check that adding a WITH clause to an INSERT disables the xfer | |
258 # optimization. | |
259 # | |
260 proc do_xfer_test {tn bXfer sql {res {}}} { | |
261 set ::sqlite3_xferopt_count 0 | |
262 uplevel [list do_test $tn [subst -nocommands { | |
263 set dres [db eval {$sql}] | |
264 list [set ::sqlite3_xferopt_count] [set dres] | |
265 }] [list $bXfer $res]] | |
266 } | |
267 | |
268 do_execsql_test 5.1 { | |
269 DROP TABLE IF EXISTS t1; | |
270 DROP TABLE IF EXISTS t2; | |
271 CREATE TABLE t1(a, b); | |
272 CREATE TABLE t2(a, b); | |
273 } | |
274 | |
275 do_xfer_test 5.2 1 { INSERT INTO t1 SELECT * FROM t2 } | |
276 do_xfer_test 5.3 0 { INSERT INTO t1 SELECT a, b FROM t2 } | |
277 do_xfer_test 5.4 0 { INSERT INTO t1 SELECT b, a FROM t2 } | |
278 do_xfer_test 5.5 0 { | |
279 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM x | |
280 } | |
281 do_xfer_test 5.6 0 { | |
282 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 | |
283 } | |
284 do_xfer_test 5.7 0 { | |
285 INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x | |
286 } | |
287 do_xfer_test 5.8 0 { | |
288 INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x | |
289 } | |
290 | |
291 #--------------------------------------------------------------------------- | |
292 # Check that syntax (and other) errors in statements with WITH clauses | |
293 # attached to them do not cause problems (e.g. memory leaks). | |
294 # | |
295 do_execsql_test 6.1 { | |
296 DROP TABLE IF EXISTS t1; | |
297 DROP TABLE IF EXISTS t2; | |
298 CREATE TABLE t1(a, b); | |
299 CREATE TABLE t2(a, b); | |
300 } | |
301 | |
302 do_catchsql_test 6.2 { | |
303 WITH x AS (SELECT * FROM t1) | |
304 INSERT INTO t2 VALUES(1, 2,); | |
305 } {1 {near ")": syntax error}} | |
306 | |
307 do_catchsql_test 6.3 { | |
308 WITH x AS (SELECT * FROM t1) | |
309 INSERT INTO t2 SELECT a, b, FROM t1; | |
310 } {1 {near "FROM": syntax error}} | |
311 | |
312 do_catchsql_test 6.3 { | |
313 WITH x AS (SELECT * FROM t1) | |
314 INSERT INTO t2 SELECT a, b FROM abc; | |
315 } {1 {no such table: abc}} | |
316 | |
317 do_catchsql_test 6.4 { | |
318 WITH x AS (SELECT * FROM t1) | |
319 INSERT INTO t2 SELECT a, b, FROM t1 a a a; | |
320 } {1 {near "FROM": syntax error}} | |
321 | |
322 do_catchsql_test 6.5 { | |
323 WITH x AS (SELECT * FROM t1) | |
324 DELETE FROM t2 WHERE; | |
325 } {1 {near ";": syntax error}} | |
326 | |
327 do_catchsql_test 6.6 { | |
328 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE | |
329 } {/1 {near .* syntax error}/} | |
330 | |
331 do_catchsql_test 6.7 { | |
332 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1; | |
333 } {/1 {near .* syntax error}/} | |
334 | |
335 do_catchsql_test 6.8 { | |
336 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ; | |
337 } {/1 {near .* syntax error}/} | |
338 | |
339 do_catchsql_test 6.9 { | |
340 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = 1 WHERE a===b; | |
341 } {/1 {near .* syntax error}/} | |
342 | |
343 do_catchsql_test 6.10 { | |
344 WITH x(a,b) AS ( | |
345 SELECT 1, 1 | |
346 UNION ALL | |
347 SELECT a*b,a+b FROM x WHERE c=2 | |
348 ) | |
349 SELECT * FROM x | |
350 } {1 {no such column: c}} | |
351 | |
352 #------------------------------------------------------------------------- | |
353 # Recursive queries in IN(...) expressions. | |
354 # | |
355 do_execsql_test 7.1 { | |
356 CREATE TABLE t5(x INTEGER); | |
357 CREATE TABLE t6(y INTEGER); | |
358 | |
359 WITH s(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM s WHERE x<49 ) | |
360 INSERT INTO t5 | |
361 SELECT * FROM s; | |
362 | |
363 INSERT INTO t6 | |
364 WITH s(x) AS ( VALUES(2) UNION ALL SELECT x+2 FROM s WHERE x<49 ) | |
365 SELECT * FROM s; | |
366 } | |
367 | |
368 do_execsql_test 7.2 { | |
369 SELECT * FROM t6 WHERE y IN (SELECT x FROM t5) | |
370 } {14 28 42} | |
371 | |
372 do_execsql_test 7.3 { | |
373 WITH ss AS (SELECT x FROM t5) | |
374 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) | |
375 } {14 28 42} | |
376 | |
377 do_execsql_test 7.4 { | |
378 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) | |
379 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) | |
380 } {14 28 42} | |
381 | |
382 do_execsql_test 7.5 { | |
383 SELECT * FROM t6 WHERE y IN ( | |
384 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) | |
385 SELECT x FROM ss | |
386 ) | |
387 } {14 28 42} | |
388 | |
389 #------------------------------------------------------------------------- | |
390 # At one point the following was causing an assertion failure and a | |
391 # memory leak. | |
392 # | |
393 do_execsql_test 8.1 { | |
394 CREATE TABLE t7(y); | |
395 INSERT INTO t7 VALUES(NULL); | |
396 CREATE VIEW v AS SELECT * FROM t7 ORDER BY y; | |
397 } | |
398 | |
399 do_execsql_test 8.2 { | |
400 WITH q(a) AS ( | |
401 SELECT 1 | |
402 UNION | |
403 SELECT a+1 FROM q, v WHERE a<5 | |
404 ) | |
405 SELECT * FROM q; | |
406 } {1 2 3 4 5} | |
407 | |
408 do_execsql_test 8.3 { | |
409 WITH q(a) AS ( | |
410 SELECT 1 | |
411 UNION ALL | |
412 SELECT a+1 FROM q, v WHERE a<5 | |
413 ) | |
414 SELECT * FROM q; | |
415 } {1 2 3 4 5} | |
416 | |
417 | |
418 finish_test | |
OLD | NEW |