cipher_migrate will use MoveFileExW on windows platforms
[sqlcipher.git] / test / with2.test
blob004ec94b97498c8ef7ff16e0589e72297bb660c1
1 # 2014 January 11
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 #***********************************************************************
11 # This file implements regression tests for SQLite library.  The
12 # focus of this file is testing the WITH clause.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set ::testprefix with2
19 ifcapable {!cte} {
20   finish_test
21   return
24 do_execsql_test 1.0 {
25   CREATE TABLE t1(a);
26   INSERT INTO t1 VALUES(1);
27   INSERT INTO t1 VALUES(2);
30 do_execsql_test 1.1 {
31   WITH x1 AS (SELECT * FROM t1)
32   SELECT sum(a) FROM x1;
33 } {3}
35 do_execsql_test 1.2 {
36   WITH x1 AS (SELECT * FROM t1)
37   SELECT (SELECT sum(a) FROM x1);
38 } {3}
40 do_execsql_test 1.3 {
41   WITH x1 AS (SELECT * FROM t1)
42   SELECT (SELECT sum(a) FROM x1);
43 } {3}
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);
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}
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}
65 do_execsql_test 1.6 {
66   CREATE TABLE t3 AS SELECT 3 AS x;
67   CREATE TABLE t4 AS SELECT 4 AS x;
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}
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}
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}
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}
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}
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}
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) )
125   SELECT * FROM r;
126 } {. .. ... .... ..... ...... ....... ........ ......... ..........}
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) )
136   SELECT * FROM r ORDER BY length(i) DESC;
137 } {.......... ......... ........ ....... ...... ..... .... ... .. .}
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}
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}
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}}
170 #---------------------------------------------------------------------------
171 # Check that variables can be used in CTEs.
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}
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}
189 #---------------------------------------------------------------------------
190 # Check that circular references are rejected.
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}}
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}}
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}}
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}}
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}}
228 #---------------------------------------------------------------------------
229 # Try empty and very long column lists.
231 do_catchsql_test 4.1 {
232   WITH x() AS ( SELECT 1,2,3 )
233   SELECT * FROM x;
234 } {1 {near ")": syntax error}}
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   "
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}}
256 #---------------------------------------------------------------------------
257 # Check that adding a WITH clause to an INSERT disables the xfer 
258 # optimization.
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]]
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);
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 
281 do_xfer_test 5.6 0 { 
282   WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 
284 do_xfer_test 5.7 0 { 
285  INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x
287 do_xfer_test 5.8 0 { 
288  INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x
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).
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);
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}}
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}}
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}}
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}}
322 do_catchsql_test 6.5 {
323   WITH x AS (SELECT * FROM t1)
324   DELETE FROM t2 WHERE;
325 } {1 {near ";": syntax error}}
327 do_catchsql_test 6.6 { 
328   WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE
329 } {1 {incomplete input}}
331 do_catchsql_test 6.7 { 
332   WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1;
333 } {/1 {near .* syntax error}/}
335 do_catchsql_test 6.8 { 
336   WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ;
337 } {/1 {near .* syntax error}/}
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}/}
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}}
352 #-------------------------------------------------------------------------
353 # Recursive queries in IN(...) expressions.
355 do_execsql_test 7.1 {
356   CREATE TABLE t5(x INTEGER);
357   CREATE TABLE t6(y INTEGER);
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;
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;
368 do_execsql_test 7.2 {
369   SELECT * FROM t6 WHERE y IN (SELECT x FROM t5)
370 } {14 28 42}
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}
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}
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}
389 #-------------------------------------------------------------------------
390 # At one point the following was causing an assertion failure and a 
391 # memory leak.
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;
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}
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}
418 finish_test