]> granicus.if.org Git - postgresql/blob - src/test/regress/expected/with.out
Fix handling of changed-Param signaling for CteScan plan nodes. We were using
[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 -- error cases
742 --
743 -- INTERSECT
744 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
745         SELECT * FROM x;
746 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
747 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x...
748                        ^
749 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x)
750         SELECT * FROM x;
751 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
752 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FR...
753                        ^
754 -- EXCEPT
755 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
756         SELECT * FROM x;
757 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
758 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
759                        ^
760 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x)
761         SELECT * FROM x;
762 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
763 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM ...
764                        ^
765 -- no non-recursive term
766 WITH RECURSIVE x(n) AS (SELECT n FROM x)
767         SELECT * FROM x;
768 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
769 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x)
770                        ^
771 -- recursive term in the left hand side (strictly speaking, should allow this)
772 WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
773         SELECT * FROM x;
774 ERROR:  recursive reference to query "x" must not appear within its non-recursive term
775 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
776                                               ^
777 CREATE TEMPORARY TABLE y (a INTEGER);
778 INSERT INTO y SELECT generate_series(1, 10);
779 -- LEFT JOIN
780 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
781         UNION ALL
782         SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
783 SELECT * FROM x;
784 ERROR:  recursive reference to query "x" must not appear within an outer join
785 LINE 3:  SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
786                                        ^
787 -- RIGHT JOIN
788 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
789         UNION ALL
790         SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
791 SELECT * FROM x;
792 ERROR:  recursive reference to query "x" must not appear within an outer join
793 LINE 3:  SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
794                            ^
795 -- FULL JOIN
796 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
797         UNION ALL
798         SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
799 SELECT * FROM x;
800 ERROR:  recursive reference to query "x" must not appear within an outer join
801 LINE 3:  SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
802                            ^
803 -- subquery
804 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x
805                           WHERE n IN (SELECT * FROM x))
806   SELECT * FROM x;
807 ERROR:  recursive reference to query "x" must not appear within a subquery
808 LINE 2:                           WHERE n IN (SELECT * FROM x))
809                                                             ^
810 -- aggregate functions
811 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x)
812   SELECT * FROM x;
813 ERROR:  aggregate functions not allowed in a recursive query's recursive term
814 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) F...
815                                                           ^
816 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x)
817   SELECT * FROM x;
818 ERROR:  aggregate functions not allowed in a recursive query's recursive term
819 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FRO...
820                                                           ^
821 -- ORDER BY
822 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
823   SELECT * FROM x;
824 ERROR:  ORDER BY in a recursive query is not implemented
825 LINE 1: ...VE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
826                                                                      ^
827 -- LIMIT/OFFSET
828 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
829   SELECT * FROM x;
830 ERROR:  OFFSET in a recursive query is not implemented
831 LINE 1: ... AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
832                                                                      ^
833 -- FOR UPDATE
834 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE)
835   SELECT * FROM x;
836 ERROR:  FOR UPDATE/SHARE in a recursive query is not implemented
837 -- target list has a recursive query name
838 WITH RECURSIVE x(id) AS (values (1)
839     UNION ALL
840     SELECT (SELECT * FROM x) FROM x WHERE id < 5
841 ) SELECT * FROM x;
842 ERROR:  recursive reference to query "x" must not appear within a subquery
843 LINE 3:     SELECT (SELECT * FROM x) FROM x WHERE id < 5
844                                   ^
845 -- mutual recursive query (not implemented)
846 WITH RECURSIVE
847   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5),
848   y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5)
849 SELECT * FROM x;
850 ERROR:  mutual recursion between WITH items is not implemented
851 LINE 2:   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id ...
852           ^
853 -- non-linear recursion is not allowed
854 WITH RECURSIVE foo(i) AS
855     (values (1)
856     UNION ALL
857        (SELECT i+1 FROM foo WHERE i < 10
858           UNION ALL
859        SELECT i+1 FROM foo WHERE i < 5)
860 ) SELECT * FROM foo;
861 ERROR:  recursive reference to query "foo" must not appear more than once
862 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
863                                ^
864 WITH RECURSIVE foo(i) AS
865     (values (1)
866     UNION ALL
867            SELECT * FROM
868        (SELECT i+1 FROM foo WHERE i < 10
869           UNION ALL
870        SELECT i+1 FROM foo WHERE i < 5) AS t
871 ) SELECT * FROM foo;
872 ERROR:  recursive reference to query "foo" must not appear more than once
873 LINE 7:        SELECT i+1 FROM foo WHERE i < 5) AS t
874                                ^
875 WITH RECURSIVE foo(i) AS
876     (values (1)
877     UNION ALL
878        (SELECT i+1 FROM foo WHERE i < 10
879           EXCEPT
880        SELECT i+1 FROM foo WHERE i < 5)
881 ) SELECT * FROM foo;
882 ERROR:  recursive reference to query "foo" must not appear within EXCEPT
883 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
884                                ^
885 WITH RECURSIVE foo(i) AS
886     (values (1)
887     UNION ALL
888        (SELECT i+1 FROM foo WHERE i < 10
889           INTERSECT
890        SELECT i+1 FROM foo WHERE i < 5)
891 ) SELECT * FROM foo;
892 ERROR:  recursive reference to query "foo" must not appear more than once
893 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
894                                ^
895 -- Wrong type induced from non-recursive term
896 WITH RECURSIVE foo(i) AS
897    (SELECT i FROM (VALUES(1),(2)) t(i)
898    UNION ALL
899    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
900 SELECT * FROM foo;
901 ERROR:  recursive query "foo" column 1 has type integer in non-recursive term but type numeric overall
902 LINE 2:    (SELECT i FROM (VALUES(1),(2)) t(i)
903                    ^
904 HINT:  Cast the output of the non-recursive term to the correct type.
905 -- rejects different typmod, too (should we allow this?)
906 WITH RECURSIVE foo(i) AS
907    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
908    UNION ALL
909    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
910 SELECT * FROM foo;
911 ERROR:  recursive query "foo" column 1 has type numeric(3,0) in non-recursive term but type numeric overall
912 LINE 2:    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
913                    ^
914 HINT:  Cast the output of the non-recursive term to the correct type.
915 --
916 -- test for bug #4902
917 --
918 with cte(foo) as ( values(42) ) values((select foo from cte));
919  column1 
920 ---------
921       42
922 (1 row)
923
924 with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q;
925  foo 
926 -----
927   42
928 (1 row)
929
930 -- test CTE referencing an outer-level variable (to see that changed-parameter
931 -- signaling still works properly after fixing this bug)
932 select ( with cte(foo) as ( values(f1) )
933          select (select foo from cte) )
934 from int4_tbl;
935   ?column?   
936 -------------
937            0
938       123456
939      -123456
940   2147483647
941  -2147483647
942 (5 rows)
943
944 select ( with cte(foo) as ( values(f1) )
945           values((select foo from cte)) )
946 from int4_tbl;
947   ?column?   
948 -------------
949            0
950       123456
951      -123456
952   2147483647
953  -2147483647
954 (5 rows)
955