]> granicus.if.org Git - postgresql/blob - src/test/regress/expected/with.out
Remove useless whitespace at end of lines
[postgresql] / src / test / regress / expected / with.out
1 --
2 -- Tests for common table expressions (WITH query, ... SELECT ...)
3 --
4 -- Basic WITH
5 WITH q1(x,y) AS (SELECT 1,2)
6 SELECT * FROM q1, q1 AS q2;
7  x | y | x | y 
8 ---+---+---+---
9  1 | 2 | 1 | 2
10 (1 row)
11
12 -- Multiple uses are evaluated only once
13 SELECT count(*) FROM (
14   WITH q1(x) AS (SELECT random() FROM generate_series(1, 5))
15     SELECT * FROM q1
16   UNION
17     SELECT * FROM q1
18 ) ss;
19  count 
20 -------
21      5
22 (1 row)
23
24 -- WITH RECURSIVE
25 -- sum of 1..100
26 WITH RECURSIVE t(n) AS (
27     VALUES (1)
28 UNION ALL
29     SELECT n+1 FROM t WHERE n < 100
30 )
31 SELECT sum(n) FROM t;
32  sum  
33 ------
34  5050
35 (1 row)
36
37 WITH RECURSIVE t(n) AS (
38     SELECT (VALUES(1))
39 UNION ALL
40     SELECT n+1 FROM t WHERE n < 5
41 )
42 SELECT * FROM t;
43  n 
44 ---
45  1
46  2
47  3
48  4
49  5
50 (5 rows)
51
52 -- This is an infinite loop with UNION ALL, but not with UNION
53 WITH RECURSIVE t(n) AS (
54     SELECT 1
55 UNION
56     SELECT 10-n FROM t)
57 SELECT * FROM t;
58  n 
59 ---
60  1
61  9
62 (2 rows)
63
64 -- This'd be an infinite loop, but outside query reads only as much as needed
65 WITH RECURSIVE t(n) AS (
66     VALUES (1)
67 UNION ALL
68     SELECT n+1 FROM t)
69 SELECT * FROM t LIMIT 10;
70  n  
71 ----
72   1
73   2
74   3
75   4
76   5
77   6
78   7
79   8
80   9
81  10
82 (10 rows)
83
84 -- UNION case should have same property
85 WITH RECURSIVE t(n) AS (
86     SELECT 1
87 UNION
88     SELECT n+1 FROM t)
89 SELECT * FROM t LIMIT 10;
90  n  
91 ----
92   1
93   2
94   3
95   4
96   5
97   6
98   7
99   8
100   9
101  10
102 (10 rows)
103
104 -- Test behavior with an unknown-type literal in the WITH
105 WITH q AS (SELECT 'foo' AS x)
106 SELECT x, x IS OF (unknown) as is_unknown FROM q;
107   x  | is_unknown 
108 -----+------------
109  foo | t
110 (1 row)
111
112 WITH RECURSIVE t(n) AS (
113     SELECT 'foo'
114 UNION ALL
115     SELECT n || ' bar' FROM t WHERE length(n) < 20
116 )
117 SELECT n, n IS OF (text) as is_text FROM t;
118             n            | is_text 
119 -------------------------+---------
120  foo                     | t
121  foo bar                 | t
122  foo bar bar             | t
123  foo bar bar bar         | t
124  foo bar bar bar bar     | t
125  foo bar bar bar bar bar | t
126 (6 rows)
127
128 --
129 -- Some examples with a tree
130 --
131 -- department structure represented here is as follows:
132 --
133 -- ROOT-+->A-+->B-+->C
134 --      |         |
135 --      |         +->D-+->F
136 --      +->E-+->G
137 CREATE TEMP TABLE department (
138         id INTEGER PRIMARY KEY,  -- department ID
139         parent_department INTEGER REFERENCES department, -- upper department ID
140         name TEXT -- department name
141 );
142 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "department_pkey" for table "department"
143 INSERT INTO department VALUES (0, NULL, 'ROOT');
144 INSERT INTO department VALUES (1, 0, 'A');
145 INSERT INTO department VALUES (2, 1, 'B');
146 INSERT INTO department VALUES (3, 2, 'C');
147 INSERT INTO department VALUES (4, 2, 'D');
148 INSERT INTO department VALUES (5, 0, 'E');
149 INSERT INTO department VALUES (6, 4, 'F');
150 INSERT INTO department VALUES (7, 5, 'G');
151 -- extract all departments under 'A'. Result should be A, B, C, D and F
152 WITH RECURSIVE subdepartment AS
153 (
154         -- non recursive term
155         SELECT name as root_name, * FROM department WHERE name = 'A'
156         UNION ALL
157         -- recursive term
158         SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
159                 WHERE d.parent_department = sd.id
160 )
161 SELECT * FROM subdepartment ORDER BY name;
162  root_name | id | parent_department | name 
163 -----------+----+-------------------+------
164  A         |  1 |                 0 | A
165  A         |  2 |                 1 | B
166  A         |  3 |                 2 | C
167  A         |  4 |                 2 | D
168  A         |  6 |                 4 | F
169 (5 rows)
170
171 -- extract all departments under 'A' with "level" number
172 WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
173 (
174         -- non recursive term
175         SELECT 1, * FROM department WHERE name = 'A'
176         UNION ALL
177         -- recursive term
178         SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
179                 WHERE d.parent_department = sd.id
180 )
181 SELECT * FROM subdepartment ORDER BY name;
182  level | id | parent_department | name 
183 -------+----+-------------------+------
184      1 |  1 |                 0 | A
185      2 |  2 |                 1 | B
186      3 |  3 |                 2 | C
187      3 |  4 |                 2 | D
188      4 |  6 |                 4 | F
189 (5 rows)
190
191 -- extract all departments under 'A' with "level" number.
192 -- Only shows level 2 or more
193 WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
194 (
195         -- non recursive term
196         SELECT 1, * FROM department WHERE name = 'A'
197         UNION ALL
198         -- recursive term
199         SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
200                 WHERE d.parent_department = sd.id
201 )
202 SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name;
203  level | id | parent_department | name 
204 -------+----+-------------------+------
205      2 |  2 |                 1 | B
206      3 |  3 |                 2 | C
207      3 |  4 |                 2 | D
208      4 |  6 |                 4 | F
209 (4 rows)
210
211 -- "RECURSIVE" is ignored if the query has no self-reference
212 WITH RECURSIVE subdepartment AS
213 (
214         -- note lack of recursive UNION structure
215         SELECT * FROM department WHERE name = 'A'
216 )
217 SELECT * FROM subdepartment ORDER BY name;
218  id | parent_department | name 
219 ----+-------------------+------
220   1 |                 0 | A
221 (1 row)
222
223 -- inside subqueries
224 SELECT count(*) FROM (
225     WITH RECURSIVE t(n) AS (
226         SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500
227     )
228     SELECT * FROM t) AS t WHERE n < (
229         SELECT count(*) FROM (
230             WITH RECURSIVE t(n) AS (
231                    SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100
232                 )
233             SELECT * FROM t WHERE n < 50000
234          ) AS t WHERE n < 100);
235  count 
236 -------
237     98
238 (1 row)
239
240 -- use same CTE twice at different subquery levels
241 WITH q1(x,y) AS (
242     SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred
243   )
244 SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub);
245  count 
246 -------
247     50
248 (1 row)
249
250 -- via a VIEW
251 CREATE TEMPORARY VIEW vsubdepartment AS
252         WITH RECURSIVE subdepartment AS
253         (
254                  -- non recursive term
255                 SELECT * FROM department WHERE name = 'A'
256                 UNION ALL
257                 -- recursive term
258                 SELECT d.* FROM department AS d, subdepartment AS sd
259                         WHERE d.parent_department = sd.id
260         )
261         SELECT * FROM subdepartment;
262 SELECT * FROM vsubdepartment ORDER BY name;
263  id | parent_department | name 
264 ----+-------------------+------
265   1 |                 0 | A
266   2 |                 1 | B
267   3 |                 2 | C
268   4 |                 2 | D
269   6 |                 4 | F
270 (5 rows)
271
272 -- Check reverse listing
273 SELECT pg_get_viewdef('vsubdepartment'::regclass);
274                                                                                                                                                                                     pg_get_viewdef                                                                                                                                                                                     
275 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
276  WITH RECURSIVE subdepartment AS (SELECT department.id, department.parent_department, department.name FROM department WHERE (department.name = 'A'::text) UNION ALL SELECT d.id, d.parent_department, d.name FROM department d, subdepartment sd WHERE (d.parent_department = sd.id)) SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name FROM subdepartment;
277 (1 row)
278
279 SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
280                                     pg_get_viewdef                                    
281 --------------------------------------------------------------------------------------
282   WITH RECURSIVE subdepartment AS (                                                  +
283                   SELECT department.id, department.parent_department, department.name+
284                     FROM department                                                  +
285                    WHERE department.name = 'A'::text                                 +
286          UNION ALL                                                                   +
287                   SELECT d.id, d.parent_department, d.name                           +
288                     FROM department d, subdepartment sd                              +
289                    WHERE d.parent_department = sd.id                                 +
290          )                                                                           +
291   SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name       +
292     FROM subdepartment;
293 (1 row)
294
295 -- corner case in which sub-WITH gets initialized first
296 with recursive q as (
297       select * from department
298     union all
299       (with x as (select * from q)
300        select * from x)
301     )
302 select * from q limit 24;
303  id | parent_department | name 
304 ----+-------------------+------
305   0 |                   | ROOT
306   1 |                 0 | A
307   2 |                 1 | B
308   3 |                 2 | C
309   4 |                 2 | D
310   5 |                 0 | E
311   6 |                 4 | F
312   7 |                 5 | G
313   0 |                   | ROOT
314   1 |                 0 | A
315   2 |                 1 | B
316   3 |                 2 | C
317   4 |                 2 | D
318   5 |                 0 | E
319   6 |                 4 | F
320   7 |                 5 | G
321   0 |                   | ROOT
322   1 |                 0 | A
323   2 |                 1 | B
324   3 |                 2 | C
325   4 |                 2 | D
326   5 |                 0 | E
327   6 |                 4 | F
328   7 |                 5 | G
329 (24 rows)
330
331 with recursive q as (
332       select * from department
333     union all
334       (with recursive x as (
335            select * from department
336          union all
337            (select * from q union all select * from x)
338         )
339        select * from x)
340     )
341 select * from q limit 32;
342  id | parent_department | name 
343 ----+-------------------+------
344   0 |                   | ROOT
345   1 |                 0 | A
346   2 |                 1 | B
347   3 |                 2 | C
348   4 |                 2 | D
349   5 |                 0 | E
350   6 |                 4 | F
351   7 |                 5 | G
352   0 |                   | ROOT
353   1 |                 0 | A
354   2 |                 1 | B
355   3 |                 2 | C
356   4 |                 2 | D
357   5 |                 0 | E
358   6 |                 4 | F
359   7 |                 5 | G
360   0 |                   | ROOT
361   1 |                 0 | A
362   2 |                 1 | B
363   3 |                 2 | C
364   4 |                 2 | D
365   5 |                 0 | E
366   6 |                 4 | F
367   7 |                 5 | G
368   0 |                   | ROOT
369   1 |                 0 | A
370   2 |                 1 | B
371   3 |                 2 | C
372   4 |                 2 | D
373   5 |                 0 | E
374   6 |                 4 | F
375   7 |                 5 | G
376 (32 rows)
377
378 -- recursive term has sub-UNION
379 WITH RECURSIVE t(i,j) AS (
380         VALUES (1,2)
381         UNION ALL
382         SELECT t2.i, t.j+1 FROM
383                 (SELECT 2 AS i UNION ALL SELECT 3 AS i) AS t2
384                 JOIN t ON (t2.i = t.i+1))
385         SELECT * FROM t;
386  i | j 
387 ---+---
388  1 | 2
389  2 | 3
390  3 | 4
391 (3 rows)
392
393 --
394 -- different tree example
395 --
396 CREATE TEMPORARY TABLE tree(
397     id INTEGER PRIMARY KEY,
398     parent_id INTEGER REFERENCES tree(id)
399 );
400 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "tree_pkey" for table "tree"
401 INSERT INTO tree
402 VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3),
403        (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11);
404 --
405 -- get all paths from "second level" nodes to leaf nodes
406 --
407 WITH RECURSIVE t(id, path) AS (
408     VALUES(1,ARRAY[]::integer[])
409 UNION ALL
410     SELECT tree.id, t.path || tree.id
411     FROM tree JOIN t ON (tree.parent_id = t.id)
412 )
413 SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON
414         (t1.path[1] = t2.path[1] AND
415         array_upper(t1.path,1) = 1 AND
416         array_upper(t2.path,1) > 1)
417         ORDER BY t1.id, t2.id;
418  id | path | id |    path     
419 ----+------+----+-------------
420   2 | {2}  |  4 | {2,4}
421   2 | {2}  |  5 | {2,5}
422   2 | {2}  |  6 | {2,6}
423   2 | {2}  |  9 | {2,4,9}
424   2 | {2}  | 10 | {2,4,10}
425   2 | {2}  | 14 | {2,4,9,14}
426   3 | {3}  |  7 | {3,7}
427   3 | {3}  |  8 | {3,8}
428   3 | {3}  | 11 | {3,7,11}
429   3 | {3}  | 12 | {3,7,12}
430   3 | {3}  | 13 | {3,7,13}
431   3 | {3}  | 15 | {3,7,11,15}
432   3 | {3}  | 16 | {3,7,11,16}
433 (13 rows)
434
435 -- just count 'em
436 WITH RECURSIVE t(id, path) AS (
437     VALUES(1,ARRAY[]::integer[])
438 UNION ALL
439     SELECT tree.id, t.path || tree.id
440     FROM tree JOIN t ON (tree.parent_id = t.id)
441 )
442 SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON
443         (t1.path[1] = t2.path[1] AND
444         array_upper(t1.path,1) = 1 AND
445         array_upper(t2.path,1) > 1)
446         GROUP BY t1.id
447         ORDER BY t1.id;
448  id | count 
449 ----+-------
450   2 |     6
451   3 |     7
452 (2 rows)
453
454 -- this variant tickled a whole-row-variable bug in 8.4devel
455 WITH RECURSIVE t(id, path) AS (
456     VALUES(1,ARRAY[]::integer[])
457 UNION ALL
458     SELECT tree.id, t.path || tree.id
459     FROM tree JOIN t ON (tree.parent_id = t.id)
460 )
461 SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON
462 (t1.id=t2.id);
463  id |    path     |         t2         
464 ----+-------------+--------------------
465   1 | {}          | (1,{})
466   2 | {2}         | (2,{2})
467   3 | {3}         | (3,{3})
468   4 | {2,4}       | (4,"{2,4}")
469   5 | {2,5}       | (5,"{2,5}")
470   6 | {2,6}       | (6,"{2,6}")
471   7 | {3,7}       | (7,"{3,7}")
472   8 | {3,8}       | (8,"{3,8}")
473   9 | {2,4,9}     | (9,"{2,4,9}")
474  10 | {2,4,10}    | (10,"{2,4,10}")
475  11 | {3,7,11}    | (11,"{3,7,11}")
476  12 | {3,7,12}    | (12,"{3,7,12}")
477  13 | {3,7,13}    | (13,"{3,7,13}")
478  14 | {2,4,9,14}  | (14,"{2,4,9,14}")
479  15 | {3,7,11,15} | (15,"{3,7,11,15}")
480  16 | {3,7,11,16} | (16,"{3,7,11,16}")
481 (16 rows)
482
483 --
484 -- test cycle detection
485 --
486 create temp table graph( f int, t int, label text );
487 insert into graph values
488         (1, 2, 'arc 1 -> 2'),
489         (1, 3, 'arc 1 -> 3'),
490         (2, 3, 'arc 2 -> 3'),
491         (1, 4, 'arc 1 -> 4'),
492         (4, 5, 'arc 4 -> 5'),
493         (5, 1, 'arc 5 -> 1');
494 with recursive search_graph(f, t, label, path, cycle) as (
495         select *, array[row(g.f, g.t)], false from graph g
496         union all
497         select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
498         from graph g, search_graph sg
499         where g.f = sg.t and not cycle
500 )
501 select * from search_graph;
502  f | t |   label    |                   path                    | cycle 
503 ---+---+------------+-------------------------------------------+-------
504  1 | 2 | arc 1 -> 2 | {"(1,2)"}                                 | f
505  1 | 3 | arc 1 -> 3 | {"(1,3)"}                                 | f
506  2 | 3 | arc 2 -> 3 | {"(2,3)"}                                 | f
507  1 | 4 | arc 1 -> 4 | {"(1,4)"}                                 | f
508  4 | 5 | arc 4 -> 5 | {"(4,5)"}                                 | f
509  5 | 1 | arc 5 -> 1 | {"(5,1)"}                                 | f
510  1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"}                         | f
511  1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"}                         | f
512  1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"}                         | f
513  2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"}                         | f
514  4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"}                         | f
515  5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"}                         | f
516  1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"}                 | f
517  1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"}                 | f
518  1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"}                 | f
519  2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"}                 | f
520  4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"}                 | f
521  5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"}                 | f
522  1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"}         | f
523  1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"}         | f
524  1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"}         | t
525  2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"}         | f
526  4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"}         | t
527  5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"}         | t
528  2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
529 (25 rows)
530
531 -- ordering by the path column has same effect as SEARCH DEPTH FIRST
532 with recursive search_graph(f, t, label, path, cycle) as (
533         select *, array[row(g.f, g.t)], false from graph g
534         union all
535         select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
536         from graph g, search_graph sg
537         where g.f = sg.t and not cycle
538 )
539 select * from search_graph order by path;
540  f | t |   label    |                   path                    | cycle 
541 ---+---+------------+-------------------------------------------+-------
542  1 | 2 | arc 1 -> 2 | {"(1,2)"}                                 | f
543  2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"}                         | f
544  1 | 3 | arc 1 -> 3 | {"(1,3)"}                                 | f
545  1 | 4 | arc 1 -> 4 | {"(1,4)"}                                 | f
546  4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"}                         | f
547  5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"}                 | f
548  1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"}         | f
549  2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
550  1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"}         | f
551  1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"}         | t
552  2 | 3 | arc 2 -> 3 | {"(2,3)"}                                 | f
553  4 | 5 | arc 4 -> 5 | {"(4,5)"}                                 | f
554  5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"}                         | f
555  1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"}                 | f
556  2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"}         | f
557  1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"}                 | f
558  1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"}                 | f
559  4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"}         | t
560  5 | 1 | arc 5 -> 1 | {"(5,1)"}                                 | f
561  1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"}                         | f
562  2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"}                 | f
563  1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"}                         | f
564  1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"}                         | f
565  4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"}                 | f
566  5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"}         | t
567 (25 rows)
568
569 --
570 -- test multiple WITH queries
571 --
572 WITH RECURSIVE
573   y (id) AS (VALUES (1)),
574   x (id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5)
575 SELECT * FROM x;
576  id 
577 ----
578   1
579   2
580   3
581   4
582   5
583 (5 rows)
584
585 -- forward reference OK
586 WITH RECURSIVE
587     x(id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5),
588     y(id) AS (values (1))
589  SELECT * FROM x;
590  id 
591 ----
592   1
593   2
594   3
595   4
596   5
597 (5 rows)
598
599 WITH RECURSIVE
600    x(id) AS
601      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
602    y(id) AS
603      (VALUES (1) UNION ALL SELECT id+1 FROM y WHERE id < 10)
604  SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
605  id | id 
606 ----+----
607   1 |  1
608   2 |  2
609   3 |  3
610   4 |  4
611   5 |  5
612   6 |   
613   7 |   
614   8 |   
615   9 |   
616  10 |   
617 (10 rows)
618
619 WITH RECURSIVE
620    x(id) AS
621      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
622    y(id) AS
623      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 10)
624  SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
625  id | id 
626 ----+----
627   1 |  1
628   2 |  2
629   3 |  3
630   4 |  4
631   5 |  5
632   6 |   
633 (6 rows)
634
635 WITH RECURSIVE
636    x(id) AS
637      (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
638    y(id) AS
639      (SELECT * FROM x UNION ALL SELECT * FROM x),
640    z(id) AS
641      (SELECT * FROM x UNION ALL SELECT id+1 FROM z WHERE id < 10)
642  SELECT * FROM z;
643  id 
644 ----
645   1
646   2
647   3
648   2
649   3
650   4
651   3
652   4
653   5
654   4
655   5
656   6
657   5
658   6
659   7
660   6
661   7
662   8
663   7
664   8
665   9
666   8
667   9
668  10
669   9
670  10
671  10
672 (27 rows)
673
674 WITH RECURSIVE
675    x(id) AS
676      (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
677    y(id) AS
678      (SELECT * FROM x UNION ALL SELECT * FROM x),
679    z(id) AS
680      (SELECT * FROM y UNION ALL SELECT id+1 FROM z WHERE id < 10)
681  SELECT * FROM z;
682  id 
683 ----
684   1
685   2
686   3
687   1
688   2
689   3
690   2
691   3
692   4
693   2
694   3
695   4
696   3
697   4
698   5
699   3
700   4
701   5
702   4
703   5
704   6
705   4
706   5
707   6
708   5
709   6
710   7
711   5
712   6
713   7
714   6
715   7
716   8
717   6
718   7
719   8
720   7
721   8
722   9
723   7
724   8
725   9
726   8
727   9
728  10
729   8
730   9
731  10
732   9
733  10
734   9
735  10
736  10
737  10
738 (54 rows)
739
740 --
741 -- Test WITH attached to a DML statement
742 --
743 CREATE TEMPORARY TABLE y (a INTEGER);
744 INSERT INTO y SELECT generate_series(1, 10);
745 WITH t AS (
746         SELECT a FROM y
747 )
748 INSERT INTO y
749 SELECT a+20 FROM t RETURNING *;
750  a  
751 ----
752  21
753  22
754  23
755  24
756  25
757  26
758  27
759  28
760  29
761  30
762 (10 rows)
763
764 SELECT * FROM y;
765  a  
766 ----
767   1
768   2
769   3
770   4
771   5
772   6
773   7
774   8
775   9
776  10
777  21
778  22
779  23
780  24
781  25
782  26
783  27
784  28
785  29
786  30
787 (20 rows)
788
789 WITH t AS (
790         SELECT a FROM y
791 )
792 UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a;
793  a  
794 ----
795  11
796  12
797  13
798  14
799  15
800  16
801  17
802  18
803  19
804  20
805 (10 rows)
806
807 SELECT * FROM y;
808  a  
809 ----
810   1
811   2
812   3
813   4
814   5
815   6
816   7
817   8
818   9
819  10
820  11
821  12
822  13
823  14
824  15
825  16
826  17
827  18
828  19
829  20
830 (20 rows)
831
832 WITH RECURSIVE t(a) AS (
833         SELECT 11
834         UNION ALL
835         SELECT a+1 FROM t WHERE a < 50
836 )
837 DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a;
838  a  
839 ----
840  11
841  12
842  13
843  14
844  15
845  16
846  17
847  18
848  19
849  20
850 (10 rows)
851
852 SELECT * FROM y;
853  a  
854 ----
855   1
856   2
857   3
858   4
859   5
860   6
861   7
862   8
863   9
864  10
865 (10 rows)
866
867 DROP TABLE y;
868 --
869 -- error cases
870 --
871 -- INTERSECT
872 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
873         SELECT * FROM x;
874 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
875 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x...
876                        ^
877 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x)
878         SELECT * FROM x;
879 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
880 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FR...
881                        ^
882 -- EXCEPT
883 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
884         SELECT * FROM x;
885 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
886 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
887                        ^
888 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x)
889         SELECT * FROM x;
890 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
891 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM ...
892                        ^
893 -- no non-recursive term
894 WITH RECURSIVE x(n) AS (SELECT n FROM x)
895         SELECT * FROM x;
896 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
897 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x)
898                        ^
899 -- recursive term in the left hand side (strictly speaking, should allow this)
900 WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
901         SELECT * FROM x;
902 ERROR:  recursive reference to query "x" must not appear within its non-recursive term
903 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
904                                               ^
905 CREATE TEMPORARY TABLE y (a INTEGER);
906 INSERT INTO y SELECT generate_series(1, 10);
907 -- LEFT JOIN
908 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
909         UNION ALL
910         SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
911 SELECT * FROM x;
912 ERROR:  recursive reference to query "x" must not appear within an outer join
913 LINE 3:  SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
914                                        ^
915 -- RIGHT JOIN
916 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
917         UNION ALL
918         SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
919 SELECT * FROM x;
920 ERROR:  recursive reference to query "x" must not appear within an outer join
921 LINE 3:  SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
922                            ^
923 -- FULL JOIN
924 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
925         UNION ALL
926         SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
927 SELECT * FROM x;
928 ERROR:  recursive reference to query "x" must not appear within an outer join
929 LINE 3:  SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
930                            ^
931 -- subquery
932 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x
933                           WHERE n IN (SELECT * FROM x))
934   SELECT * FROM x;
935 ERROR:  recursive reference to query "x" must not appear within a subquery
936 LINE 2:                           WHERE n IN (SELECT * FROM x))
937                                                             ^
938 -- aggregate functions
939 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x)
940   SELECT * FROM x;
941 ERROR:  aggregate functions not allowed in a recursive query's recursive term
942 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) F...
943                                                           ^
944 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x)
945   SELECT * FROM x;
946 ERROR:  aggregate functions not allowed in a recursive query's recursive term
947 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FRO...
948                                                           ^
949 -- ORDER BY
950 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
951   SELECT * FROM x;
952 ERROR:  ORDER BY in a recursive query is not implemented
953 LINE 1: ...VE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
954                                                                      ^
955 -- LIMIT/OFFSET
956 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
957   SELECT * FROM x;
958 ERROR:  OFFSET in a recursive query is not implemented
959 LINE 1: ... AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
960                                                                      ^
961 -- FOR UPDATE
962 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE)
963   SELECT * FROM x;
964 ERROR:  FOR UPDATE/SHARE in a recursive query is not implemented
965 -- target list has a recursive query name
966 WITH RECURSIVE x(id) AS (values (1)
967     UNION ALL
968     SELECT (SELECT * FROM x) FROM x WHERE id < 5
969 ) SELECT * FROM x;
970 ERROR:  recursive reference to query "x" must not appear within a subquery
971 LINE 3:     SELECT (SELECT * FROM x) FROM x WHERE id < 5
972                                   ^
973 -- mutual recursive query (not implemented)
974 WITH RECURSIVE
975   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5),
976   y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5)
977 SELECT * FROM x;
978 ERROR:  mutual recursion between WITH items is not implemented
979 LINE 2:   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id ...
980           ^
981 -- non-linear recursion is not allowed
982 WITH RECURSIVE foo(i) AS
983     (values (1)
984     UNION ALL
985        (SELECT i+1 FROM foo WHERE i < 10
986           UNION ALL
987        SELECT i+1 FROM foo WHERE i < 5)
988 ) SELECT * FROM foo;
989 ERROR:  recursive reference to query "foo" must not appear more than once
990 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
991                                ^
992 WITH RECURSIVE foo(i) AS
993     (values (1)
994     UNION ALL
995            SELECT * FROM
996        (SELECT i+1 FROM foo WHERE i < 10
997           UNION ALL
998        SELECT i+1 FROM foo WHERE i < 5) AS t
999 ) SELECT * FROM foo;
1000 ERROR:  recursive reference to query "foo" must not appear more than once
1001 LINE 7:        SELECT i+1 FROM foo WHERE i < 5) AS t
1002                                ^
1003 WITH RECURSIVE foo(i) AS
1004     (values (1)
1005     UNION ALL
1006        (SELECT i+1 FROM foo WHERE i < 10
1007           EXCEPT
1008        SELECT i+1 FROM foo WHERE i < 5)
1009 ) SELECT * FROM foo;
1010 ERROR:  recursive reference to query "foo" must not appear within EXCEPT
1011 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
1012                                ^
1013 WITH RECURSIVE foo(i) AS
1014     (values (1)
1015     UNION ALL
1016        (SELECT i+1 FROM foo WHERE i < 10
1017           INTERSECT
1018        SELECT i+1 FROM foo WHERE i < 5)
1019 ) SELECT * FROM foo;
1020 ERROR:  recursive reference to query "foo" must not appear more than once
1021 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
1022                                ^
1023 -- Wrong type induced from non-recursive term
1024 WITH RECURSIVE foo(i) AS
1025    (SELECT i FROM (VALUES(1),(2)) t(i)
1026    UNION ALL
1027    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
1028 SELECT * FROM foo;
1029 ERROR:  recursive query "foo" column 1 has type integer in non-recursive term but type numeric overall
1030 LINE 2:    (SELECT i FROM (VALUES(1),(2)) t(i)
1031                    ^
1032 HINT:  Cast the output of the non-recursive term to the correct type.
1033 -- rejects different typmod, too (should we allow this?)
1034 WITH RECURSIVE foo(i) AS
1035    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
1036    UNION ALL
1037    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
1038 SELECT * FROM foo;
1039 ERROR:  recursive query "foo" column 1 has type numeric(3,0) in non-recursive term but type numeric overall
1040 LINE 2:    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
1041                    ^
1042 HINT:  Cast the output of the non-recursive term to the correct type.
1043 -- disallow OLD/NEW reference in CTE
1044 CREATE TEMPORARY TABLE x (n integer);
1045 CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD
1046     WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t;
1047 ERROR:  cannot refer to OLD within WITH query
1048 --
1049 -- test for bug #4902
1050 --
1051 with cte(foo) as ( values(42) ) values((select foo from cte));
1052  column1 
1053 ---------
1054       42
1055 (1 row)
1056
1057 with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q;
1058  foo 
1059 -----
1060   42
1061 (1 row)
1062
1063 -- test CTE referencing an outer-level variable (to see that changed-parameter
1064 -- signaling still works properly after fixing this bug)
1065 select ( with cte(foo) as ( values(f1) )
1066          select (select foo from cte) )
1067 from int4_tbl;
1068   ?column?   
1069 -------------
1070            0
1071       123456
1072      -123456
1073   2147483647
1074  -2147483647
1075 (5 rows)
1076
1077 select ( with cte(foo) as ( values(f1) )
1078           values((select foo from cte)) )
1079 from int4_tbl;
1080   ?column?   
1081 -------------
1082            0
1083       123456
1084      -123456
1085   2147483647
1086  -2147483647
1087 (5 rows)
1088
1089 --
1090 -- test for nested-recursive-WITH bug
1091 --
1092 WITH RECURSIVE t(j) AS (
1093     WITH RECURSIVE s(i) AS (
1094         VALUES (1)
1095         UNION ALL
1096         SELECT i+1 FROM s WHERE i < 10
1097     )
1098     SELECT i FROM s
1099     UNION ALL
1100     SELECT j+1 FROM t WHERE j < 10
1101 )
1102 SELECT * FROM t;
1103  j  
1104 ----
1105   1
1106   2
1107   3
1108   4
1109   5
1110   6
1111   7
1112   8
1113   9
1114  10
1115   2
1116   3
1117   4
1118   5
1119   6
1120   7
1121   8
1122   9
1123  10
1124   3
1125   4
1126   5
1127   6
1128   7
1129   8
1130   9
1131  10
1132   4
1133   5
1134   6
1135   7
1136   8
1137   9
1138  10
1139   5
1140   6
1141   7
1142   8
1143   9
1144  10
1145   6
1146   7
1147   8
1148   9
1149  10
1150   7
1151   8
1152   9
1153  10
1154   8
1155   9
1156  10
1157   9
1158  10
1159  10
1160 (55 rows)
1161