]> granicus.if.org Git - postgresql/blob - src/test/regress/expected/with.out
Fix oversight in new code for printing rangetable aliases.
[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 INSERT INTO department VALUES (0, NULL, 'ROOT');
143 INSERT INTO department VALUES (1, 0, 'A');
144 INSERT INTO department VALUES (2, 1, 'B');
145 INSERT INTO department VALUES (3, 2, 'C');
146 INSERT INTO department VALUES (4, 2, 'D');
147 INSERT INTO department VALUES (5, 0, 'E');
148 INSERT INTO department VALUES (6, 4, 'F');
149 INSERT INTO department VALUES (7, 5, 'G');
150 -- extract all departments under 'A'. Result should be A, B, C, D and F
151 WITH RECURSIVE subdepartment AS
152 (
153         -- non recursive term
154         SELECT name as root_name, * FROM department WHERE name = 'A'
155         UNION ALL
156         -- recursive term
157         SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
158                 WHERE d.parent_department = sd.id
159 )
160 SELECT * FROM subdepartment ORDER BY name;
161  root_name | id | parent_department | name 
162 -----------+----+-------------------+------
163  A         |  1 |                 0 | A
164  A         |  2 |                 1 | B
165  A         |  3 |                 2 | C
166  A         |  4 |                 2 | D
167  A         |  6 |                 4 | F
168 (5 rows)
169
170 -- extract all departments under 'A' with "level" number
171 WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
172 (
173         -- non recursive term
174         SELECT 1, * FROM department WHERE name = 'A'
175         UNION ALL
176         -- recursive term
177         SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
178                 WHERE d.parent_department = sd.id
179 )
180 SELECT * FROM subdepartment ORDER BY name;
181  level | id | parent_department | name 
182 -------+----+-------------------+------
183      1 |  1 |                 0 | A
184      2 |  2 |                 1 | B
185      3 |  3 |                 2 | C
186      3 |  4 |                 2 | D
187      4 |  6 |                 4 | F
188 (5 rows)
189
190 -- extract all departments under 'A' with "level" number.
191 -- Only shows level 2 or more
192 WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
193 (
194         -- non recursive term
195         SELECT 1, * FROM department WHERE name = 'A'
196         UNION ALL
197         -- recursive term
198         SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
199                 WHERE d.parent_department = sd.id
200 )
201 SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name;
202  level | id | parent_department | name 
203 -------+----+-------------------+------
204      2 |  2 |                 1 | B
205      3 |  3 |                 2 | C
206      3 |  4 |                 2 | D
207      4 |  6 |                 4 | F
208 (4 rows)
209
210 -- "RECURSIVE" is ignored if the query has no self-reference
211 WITH RECURSIVE subdepartment AS
212 (
213         -- note lack of recursive UNION structure
214         SELECT * FROM department WHERE name = 'A'
215 )
216 SELECT * FROM subdepartment ORDER BY name;
217  id | parent_department | name 
218 ----+-------------------+------
219   1 |                 0 | A
220 (1 row)
221
222 -- inside subqueries
223 SELECT count(*) FROM (
224     WITH RECURSIVE t(n) AS (
225         SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500
226     )
227     SELECT * FROM t) AS t WHERE n < (
228         SELECT count(*) FROM (
229             WITH RECURSIVE t(n) AS (
230                    SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100
231                 )
232             SELECT * FROM t WHERE n < 50000
233          ) AS t WHERE n < 100);
234  count 
235 -------
236     98
237 (1 row)
238
239 -- use same CTE twice at different subquery levels
240 WITH q1(x,y) AS (
241     SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred
242   )
243 SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub);
244  count 
245 -------
246     50
247 (1 row)
248
249 -- via a VIEW
250 CREATE TEMPORARY VIEW vsubdepartment AS
251         WITH RECURSIVE subdepartment AS
252         (
253                  -- non recursive term
254                 SELECT * FROM department WHERE name = 'A'
255                 UNION ALL
256                 -- recursive term
257                 SELECT d.* FROM department AS d, subdepartment AS sd
258                         WHERE d.parent_department = sd.id
259         )
260         SELECT * FROM subdepartment;
261 SELECT * FROM vsubdepartment ORDER BY name;
262  id | parent_department | name 
263 ----+-------------------+------
264   1 |                 0 | A
265   2 |                 1 | B
266   3 |                 2 | C
267   4 |                 2 | D
268   6 |                 4 | F
269 (5 rows)
270
271 -- Check reverse listing
272 SELECT pg_get_viewdef('vsubdepartment'::regclass);
273                                                                                                                                                                                     pg_get_viewdef                                                                                                                                                                                     
274 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
275  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;
276 (1 row)
277
278 SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
279                                 pg_get_viewdef                                 
280 -------------------------------------------------------------------------------
281   WITH RECURSIVE subdepartment AS (                                           +
282                   SELECT department.id, department.parent_department,         +
283                      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 -- Another reverse-listing example
296 CREATE VIEW sums_1_100 AS
297 WITH RECURSIVE t(n) AS (
298     VALUES (1)
299 UNION ALL
300     SELECT n+1 FROM t WHERE n < 100
301 )
302 SELECT sum(n) FROM t;
303 \d+ sums_1_100
304               View "public.sums_1_100"
305  Column |  Type  | Modifiers | Storage | Description 
306 --------+--------+-----------+---------+-------------
307  sum    | bigint |           | plain   | 
308 View definition:
309  WITH RECURSIVE t(n) AS (
310                  VALUES (1)
311         UNION ALL 
312                  SELECT t_1.n + 1
313                    FROM t t_1
314                   WHERE t_1.n < 100
315         )
316  SELECT sum(t.n) AS sum
317    FROM t;
318
319 -- corner case in which sub-WITH gets initialized first
320 with recursive q as (
321       select * from department
322     union all
323       (with x as (select * from q)
324        select * from x)
325     )
326 select * from q limit 24;
327  id | parent_department | name 
328 ----+-------------------+------
329   0 |                   | ROOT
330   1 |                 0 | A
331   2 |                 1 | B
332   3 |                 2 | C
333   4 |                 2 | D
334   5 |                 0 | E
335   6 |                 4 | F
336   7 |                 5 | G
337   0 |                   | ROOT
338   1 |                 0 | A
339   2 |                 1 | B
340   3 |                 2 | C
341   4 |                 2 | D
342   5 |                 0 | E
343   6 |                 4 | F
344   7 |                 5 | G
345   0 |                   | ROOT
346   1 |                 0 | A
347   2 |                 1 | B
348   3 |                 2 | C
349   4 |                 2 | D
350   5 |                 0 | E
351   6 |                 4 | F
352   7 |                 5 | G
353 (24 rows)
354
355 with recursive q as (
356       select * from department
357     union all
358       (with recursive x as (
359            select * from department
360          union all
361            (select * from q union all select * from x)
362         )
363        select * from x)
364     )
365 select * from q limit 32;
366  id | parent_department | name 
367 ----+-------------------+------
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   0 |                   | ROOT
377   1 |                 0 | A
378   2 |                 1 | B
379   3 |                 2 | C
380   4 |                 2 | D
381   5 |                 0 | E
382   6 |                 4 | F
383   7 |                 5 | G
384   0 |                   | ROOT
385   1 |                 0 | A
386   2 |                 1 | B
387   3 |                 2 | C
388   4 |                 2 | D
389   5 |                 0 | E
390   6 |                 4 | F
391   7 |                 5 | G
392   0 |                   | ROOT
393   1 |                 0 | A
394   2 |                 1 | B
395   3 |                 2 | C
396   4 |                 2 | D
397   5 |                 0 | E
398   6 |                 4 | F
399   7 |                 5 | G
400 (32 rows)
401
402 -- recursive term has sub-UNION
403 WITH RECURSIVE t(i,j) AS (
404         VALUES (1,2)
405         UNION ALL
406         SELECT t2.i, t.j+1 FROM
407                 (SELECT 2 AS i UNION ALL SELECT 3 AS i) AS t2
408                 JOIN t ON (t2.i = t.i+1))
409         SELECT * FROM t;
410  i | j 
411 ---+---
412  1 | 2
413  2 | 3
414  3 | 4
415 (3 rows)
416
417 --
418 -- different tree example
419 --
420 CREATE TEMPORARY TABLE tree(
421     id INTEGER PRIMARY KEY,
422     parent_id INTEGER REFERENCES tree(id)
423 );
424 INSERT INTO tree
425 VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3),
426        (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11);
427 --
428 -- get all paths from "second level" nodes to leaf nodes
429 --
430 WITH RECURSIVE t(id, path) AS (
431     VALUES(1,ARRAY[]::integer[])
432 UNION ALL
433     SELECT tree.id, t.path || tree.id
434     FROM tree JOIN t ON (tree.parent_id = t.id)
435 )
436 SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON
437         (t1.path[1] = t2.path[1] AND
438         array_upper(t1.path,1) = 1 AND
439         array_upper(t2.path,1) > 1)
440         ORDER BY t1.id, t2.id;
441  id | path | id |    path     
442 ----+------+----+-------------
443   2 | {2}  |  4 | {2,4}
444   2 | {2}  |  5 | {2,5}
445   2 | {2}  |  6 | {2,6}
446   2 | {2}  |  9 | {2,4,9}
447   2 | {2}  | 10 | {2,4,10}
448   2 | {2}  | 14 | {2,4,9,14}
449   3 | {3}  |  7 | {3,7}
450   3 | {3}  |  8 | {3,8}
451   3 | {3}  | 11 | {3,7,11}
452   3 | {3}  | 12 | {3,7,12}
453   3 | {3}  | 13 | {3,7,13}
454   3 | {3}  | 15 | {3,7,11,15}
455   3 | {3}  | 16 | {3,7,11,16}
456 (13 rows)
457
458 -- just count 'em
459 WITH RECURSIVE t(id, path) AS (
460     VALUES(1,ARRAY[]::integer[])
461 UNION ALL
462     SELECT tree.id, t.path || tree.id
463     FROM tree JOIN t ON (tree.parent_id = t.id)
464 )
465 SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON
466         (t1.path[1] = t2.path[1] AND
467         array_upper(t1.path,1) = 1 AND
468         array_upper(t2.path,1) > 1)
469         GROUP BY t1.id
470         ORDER BY t1.id;
471  id | count 
472 ----+-------
473   2 |     6
474   3 |     7
475 (2 rows)
476
477 -- this variant tickled a whole-row-variable bug in 8.4devel
478 WITH RECURSIVE t(id, path) AS (
479     VALUES(1,ARRAY[]::integer[])
480 UNION ALL
481     SELECT tree.id, t.path || tree.id
482     FROM tree JOIN t ON (tree.parent_id = t.id)
483 )
484 SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON
485 (t1.id=t2.id);
486  id |    path     |         t2         
487 ----+-------------+--------------------
488   1 | {}          | (1,{})
489   2 | {2}         | (2,{2})
490   3 | {3}         | (3,{3})
491   4 | {2,4}       | (4,"{2,4}")
492   5 | {2,5}       | (5,"{2,5}")
493   6 | {2,6}       | (6,"{2,6}")
494   7 | {3,7}       | (7,"{3,7}")
495   8 | {3,8}       | (8,"{3,8}")
496   9 | {2,4,9}     | (9,"{2,4,9}")
497  10 | {2,4,10}    | (10,"{2,4,10}")
498  11 | {3,7,11}    | (11,"{3,7,11}")
499  12 | {3,7,12}    | (12,"{3,7,12}")
500  13 | {3,7,13}    | (13,"{3,7,13}")
501  14 | {2,4,9,14}  | (14,"{2,4,9,14}")
502  15 | {3,7,11,15} | (15,"{3,7,11,15}")
503  16 | {3,7,11,16} | (16,"{3,7,11,16}")
504 (16 rows)
505
506 --
507 -- test cycle detection
508 --
509 create temp table graph( f int, t int, label text );
510 insert into graph values
511         (1, 2, 'arc 1 -> 2'),
512         (1, 3, 'arc 1 -> 3'),
513         (2, 3, 'arc 2 -> 3'),
514         (1, 4, 'arc 1 -> 4'),
515         (4, 5, 'arc 4 -> 5'),
516         (5, 1, 'arc 5 -> 1');
517 with recursive search_graph(f, t, label, path, cycle) as (
518         select *, array[row(g.f, g.t)], false from graph g
519         union all
520         select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
521         from graph g, search_graph sg
522         where g.f = sg.t and not cycle
523 )
524 select * from search_graph;
525  f | t |   label    |                   path                    | cycle 
526 ---+---+------------+-------------------------------------------+-------
527  1 | 2 | arc 1 -> 2 | {"(1,2)"}                                 | f
528  1 | 3 | arc 1 -> 3 | {"(1,3)"}                                 | f
529  2 | 3 | arc 2 -> 3 | {"(2,3)"}                                 | f
530  1 | 4 | arc 1 -> 4 | {"(1,4)"}                                 | f
531  4 | 5 | arc 4 -> 5 | {"(4,5)"}                                 | f
532  5 | 1 | arc 5 -> 1 | {"(5,1)"}                                 | f
533  1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"}                         | f
534  1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"}                         | f
535  1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"}                         | f
536  2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"}                         | f
537  4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"}                         | f
538  5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"}                         | f
539  1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"}                 | f
540  1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"}                 | f
541  1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"}                 | f
542  2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"}                 | f
543  4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"}                 | f
544  5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"}                 | f
545  1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"}         | f
546  1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"}         | f
547  1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"}         | t
548  2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"}         | f
549  4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"}         | t
550  5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"}         | t
551  2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
552 (25 rows)
553
554 -- ordering by the path column has same effect as SEARCH DEPTH FIRST
555 with recursive search_graph(f, t, label, path, cycle) as (
556         select *, array[row(g.f, g.t)], false from graph g
557         union all
558         select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
559         from graph g, search_graph sg
560         where g.f = sg.t and not cycle
561 )
562 select * from search_graph order by path;
563  f | t |   label    |                   path                    | cycle 
564 ---+---+------------+-------------------------------------------+-------
565  1 | 2 | arc 1 -> 2 | {"(1,2)"}                                 | f
566  2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"}                         | f
567  1 | 3 | arc 1 -> 3 | {"(1,3)"}                                 | f
568  1 | 4 | arc 1 -> 4 | {"(1,4)"}                                 | f
569  4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"}                         | f
570  5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"}                 | f
571  1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"}         | f
572  2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
573  1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"}         | f
574  1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"}         | t
575  2 | 3 | arc 2 -> 3 | {"(2,3)"}                                 | f
576  4 | 5 | arc 4 -> 5 | {"(4,5)"}                                 | f
577  5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"}                         | f
578  1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"}                 | f
579  2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"}         | f
580  1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"}                 | f
581  1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"}                 | f
582  4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"}         | t
583  5 | 1 | arc 5 -> 1 | {"(5,1)"}                                 | f
584  1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"}                         | f
585  2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"}                 | f
586  1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"}                         | f
587  1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"}                         | f
588  4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"}                 | f
589  5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"}         | t
590 (25 rows)
591
592 --
593 -- test multiple WITH queries
594 --
595 WITH RECURSIVE
596   y (id) AS (VALUES (1)),
597   x (id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5)
598 SELECT * FROM x;
599  id 
600 ----
601   1
602   2
603   3
604   4
605   5
606 (5 rows)
607
608 -- forward reference OK
609 WITH RECURSIVE
610     x(id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5),
611     y(id) AS (values (1))
612  SELECT * FROM x;
613  id 
614 ----
615   1
616   2
617   3
618   4
619   5
620 (5 rows)
621
622 WITH RECURSIVE
623    x(id) AS
624      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
625    y(id) AS
626      (VALUES (1) UNION ALL SELECT id+1 FROM y WHERE id < 10)
627  SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
628  id | id 
629 ----+----
630   1 |  1
631   2 |  2
632   3 |  3
633   4 |  4
634   5 |  5
635   6 |   
636   7 |   
637   8 |   
638   9 |   
639  10 |   
640 (10 rows)
641
642 WITH RECURSIVE
643    x(id) AS
644      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
645    y(id) AS
646      (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 10)
647  SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
648  id | id 
649 ----+----
650   1 |  1
651   2 |  2
652   3 |  3
653   4 |  4
654   5 |  5
655   6 |   
656 (6 rows)
657
658 WITH RECURSIVE
659    x(id) AS
660      (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
661    y(id) AS
662      (SELECT * FROM x UNION ALL SELECT * FROM x),
663    z(id) AS
664      (SELECT * FROM x UNION ALL SELECT id+1 FROM z WHERE id < 10)
665  SELECT * FROM z;
666  id 
667 ----
668   1
669   2
670   3
671   2
672   3
673   4
674   3
675   4
676   5
677   4
678   5
679   6
680   5
681   6
682   7
683   6
684   7
685   8
686   7
687   8
688   9
689   8
690   9
691  10
692   9
693  10
694  10
695 (27 rows)
696
697 WITH RECURSIVE
698    x(id) AS
699      (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
700    y(id) AS
701      (SELECT * FROM x UNION ALL SELECT * FROM x),
702    z(id) AS
703      (SELECT * FROM y UNION ALL SELECT id+1 FROM z WHERE id < 10)
704  SELECT * FROM z;
705  id 
706 ----
707   1
708   2
709   3
710   1
711   2
712   3
713   2
714   3
715   4
716   2
717   3
718   4
719   3
720   4
721   5
722   3
723   4
724   5
725   4
726   5
727   6
728   4
729   5
730   6
731   5
732   6
733   7
734   5
735   6
736   7
737   6
738   7
739   8
740   6
741   7
742   8
743   7
744   8
745   9
746   7
747   8
748   9
749   8
750   9
751  10
752   8
753   9
754  10
755   9
756  10
757   9
758  10
759  10
760  10
761 (54 rows)
762
763 --
764 -- Test WITH attached to a data-modifying statement
765 --
766 CREATE TEMPORARY TABLE y (a INTEGER);
767 INSERT INTO y SELECT generate_series(1, 10);
768 WITH t AS (
769         SELECT a FROM y
770 )
771 INSERT INTO y
772 SELECT a+20 FROM t RETURNING *;
773  a  
774 ----
775  21
776  22
777  23
778  24
779  25
780  26
781  27
782  28
783  29
784  30
785 (10 rows)
786
787 SELECT * FROM y;
788  a  
789 ----
790   1
791   2
792   3
793   4
794   5
795   6
796   7
797   8
798   9
799  10
800  21
801  22
802  23
803  24
804  25
805  26
806  27
807  28
808  29
809  30
810 (20 rows)
811
812 WITH t AS (
813         SELECT a FROM y
814 )
815 UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a;
816  a  
817 ----
818  11
819  12
820  13
821  14
822  15
823  16
824  17
825  18
826  19
827  20
828 (10 rows)
829
830 SELECT * FROM y;
831  a  
832 ----
833   1
834   2
835   3
836   4
837   5
838   6
839   7
840   8
841   9
842  10
843  11
844  12
845  13
846  14
847  15
848  16
849  17
850  18
851  19
852  20
853 (20 rows)
854
855 WITH RECURSIVE t(a) AS (
856         SELECT 11
857         UNION ALL
858         SELECT a+1 FROM t WHERE a < 50
859 )
860 DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a;
861  a  
862 ----
863  11
864  12
865  13
866  14
867  15
868  16
869  17
870  18
871  19
872  20
873 (10 rows)
874
875 SELECT * FROM y;
876  a  
877 ----
878   1
879   2
880   3
881   4
882   5
883   6
884   7
885   8
886   9
887  10
888 (10 rows)
889
890 DROP TABLE y;
891 --
892 -- error cases
893 --
894 -- INTERSECT
895 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
896         SELECT * FROM x;
897 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
898 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x...
899                        ^
900 WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x)
901         SELECT * FROM x;
902 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
903 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FR...
904                        ^
905 -- EXCEPT
906 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
907         SELECT * FROM x;
908 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
909 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
910                        ^
911 WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x)
912         SELECT * FROM x;
913 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
914 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM ...
915                        ^
916 -- no non-recursive term
917 WITH RECURSIVE x(n) AS (SELECT n FROM x)
918         SELECT * FROM x;
919 ERROR:  recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term
920 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x)
921                        ^
922 -- recursive term in the left hand side (strictly speaking, should allow this)
923 WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
924         SELECT * FROM x;
925 ERROR:  recursive reference to query "x" must not appear within its non-recursive term
926 LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
927                                               ^
928 CREATE TEMPORARY TABLE y (a INTEGER);
929 INSERT INTO y SELECT generate_series(1, 10);
930 -- LEFT JOIN
931 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
932         UNION ALL
933         SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
934 SELECT * FROM x;
935 ERROR:  recursive reference to query "x" must not appear within an outer join
936 LINE 3:  SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
937                                        ^
938 -- RIGHT JOIN
939 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
940         UNION ALL
941         SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
942 SELECT * FROM x;
943 ERROR:  recursive reference to query "x" must not appear within an outer join
944 LINE 3:  SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
945                            ^
946 -- FULL JOIN
947 WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
948         UNION ALL
949         SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
950 SELECT * FROM x;
951 ERROR:  recursive reference to query "x" must not appear within an outer join
952 LINE 3:  SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
953                            ^
954 -- subquery
955 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x
956                           WHERE n IN (SELECT * FROM x))
957   SELECT * FROM x;
958 ERROR:  recursive reference to query "x" must not appear within a subquery
959 LINE 2:                           WHERE n IN (SELECT * FROM x))
960                                                             ^
961 -- aggregate functions
962 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x)
963   SELECT * FROM x;
964 ERROR:  aggregate functions are not allowed in a recursive query's recursive term
965 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) F...
966                                                           ^
967 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x)
968   SELECT * FROM x;
969 ERROR:  aggregate functions are not allowed in a recursive query's recursive term
970 LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FRO...
971                                                           ^
972 -- ORDER BY
973 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
974   SELECT * FROM x;
975 ERROR:  ORDER BY in a recursive query is not implemented
976 LINE 1: ...VE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
977                                                                      ^
978 -- LIMIT/OFFSET
979 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
980   SELECT * FROM x;
981 ERROR:  OFFSET in a recursive query is not implemented
982 LINE 1: ... AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
983                                                                      ^
984 -- FOR UPDATE
985 WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE)
986   SELECT * FROM x;
987 ERROR:  FOR UPDATE/SHARE in a recursive query is not implemented
988 -- target list has a recursive query name
989 WITH RECURSIVE x(id) AS (values (1)
990     UNION ALL
991     SELECT (SELECT * FROM x) FROM x WHERE id < 5
992 ) SELECT * FROM x;
993 ERROR:  recursive reference to query "x" must not appear within a subquery
994 LINE 3:     SELECT (SELECT * FROM x) FROM x WHERE id < 5
995                                   ^
996 -- mutual recursive query (not implemented)
997 WITH RECURSIVE
998   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5),
999   y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5)
1000 SELECT * FROM x;
1001 ERROR:  mutual recursion between WITH items is not implemented
1002 LINE 2:   x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id ...
1003           ^
1004 -- non-linear recursion is not allowed
1005 WITH RECURSIVE foo(i) AS
1006     (values (1)
1007     UNION ALL
1008        (SELECT i+1 FROM foo WHERE i < 10
1009           UNION ALL
1010        SELECT i+1 FROM foo WHERE i < 5)
1011 ) SELECT * FROM foo;
1012 ERROR:  recursive reference to query "foo" must not appear more than once
1013 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
1014                                ^
1015 WITH RECURSIVE foo(i) AS
1016     (values (1)
1017     UNION ALL
1018            SELECT * FROM
1019        (SELECT i+1 FROM foo WHERE i < 10
1020           UNION ALL
1021        SELECT i+1 FROM foo WHERE i < 5) AS t
1022 ) SELECT * FROM foo;
1023 ERROR:  recursive reference to query "foo" must not appear more than once
1024 LINE 7:        SELECT i+1 FROM foo WHERE i < 5) AS t
1025                                ^
1026 WITH RECURSIVE foo(i) AS
1027     (values (1)
1028     UNION ALL
1029        (SELECT i+1 FROM foo WHERE i < 10
1030           EXCEPT
1031        SELECT i+1 FROM foo WHERE i < 5)
1032 ) SELECT * FROM foo;
1033 ERROR:  recursive reference to query "foo" must not appear within EXCEPT
1034 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
1035                                ^
1036 WITH RECURSIVE foo(i) AS
1037     (values (1)
1038     UNION ALL
1039        (SELECT i+1 FROM foo WHERE i < 10
1040           INTERSECT
1041        SELECT i+1 FROM foo WHERE i < 5)
1042 ) SELECT * FROM foo;
1043 ERROR:  recursive reference to query "foo" must not appear more than once
1044 LINE 6:        SELECT i+1 FROM foo WHERE i < 5)
1045                                ^
1046 -- Wrong type induced from non-recursive term
1047 WITH RECURSIVE foo(i) AS
1048    (SELECT i FROM (VALUES(1),(2)) t(i)
1049    UNION ALL
1050    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
1051 SELECT * FROM foo;
1052 ERROR:  recursive query "foo" column 1 has type integer in non-recursive term but type numeric overall
1053 LINE 2:    (SELECT i FROM (VALUES(1),(2)) t(i)
1054                    ^
1055 HINT:  Cast the output of the non-recursive term to the correct type.
1056 -- rejects different typmod, too (should we allow this?)
1057 WITH RECURSIVE foo(i) AS
1058    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
1059    UNION ALL
1060    SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
1061 SELECT * FROM foo;
1062 ERROR:  recursive query "foo" column 1 has type numeric(3,0) in non-recursive term but type numeric overall
1063 LINE 2:    (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
1064                    ^
1065 HINT:  Cast the output of the non-recursive term to the correct type.
1066 -- disallow OLD/NEW reference in CTE
1067 CREATE TEMPORARY TABLE x (n integer);
1068 CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD
1069     WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t;
1070 ERROR:  cannot refer to OLD within WITH query
1071 --
1072 -- test for bug #4902
1073 --
1074 with cte(foo) as ( values(42) ) values((select foo from cte));
1075  column1 
1076 ---------
1077       42
1078 (1 row)
1079
1080 with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q;
1081  foo 
1082 -----
1083   42
1084 (1 row)
1085
1086 -- test CTE referencing an outer-level variable (to see that changed-parameter
1087 -- signaling still works properly after fixing this bug)
1088 select ( with cte(foo) as ( values(f1) )
1089          select (select foo from cte) )
1090 from int4_tbl;
1091      foo     
1092 -------------
1093            0
1094       123456
1095      -123456
1096   2147483647
1097  -2147483647
1098 (5 rows)
1099
1100 select ( with cte(foo) as ( values(f1) )
1101           values((select foo from cte)) )
1102 from int4_tbl;
1103    column1   
1104 -------------
1105            0
1106       123456
1107      -123456
1108   2147483647
1109  -2147483647
1110 (5 rows)
1111
1112 --
1113 -- test for nested-recursive-WITH bug
1114 --
1115 WITH RECURSIVE t(j) AS (
1116     WITH RECURSIVE s(i) AS (
1117         VALUES (1)
1118         UNION ALL
1119         SELECT i+1 FROM s WHERE i < 10
1120     )
1121     SELECT i FROM s
1122     UNION ALL
1123     SELECT j+1 FROM t WHERE j < 10
1124 )
1125 SELECT * FROM t;
1126  j  
1127 ----
1128   1
1129   2
1130   3
1131   4
1132   5
1133   6
1134   7
1135   8
1136   9
1137  10
1138   2
1139   3
1140   4
1141   5
1142   6
1143   7
1144   8
1145   9
1146  10
1147   3
1148   4
1149   5
1150   6
1151   7
1152   8
1153   9
1154  10
1155   4
1156   5
1157   6
1158   7
1159   8
1160   9
1161  10
1162   5
1163   6
1164   7
1165   8
1166   9
1167  10
1168   6
1169   7
1170   8
1171   9
1172  10
1173   7
1174   8
1175   9
1176  10
1177   8
1178   9
1179  10
1180   9
1181  10
1182  10
1183 (55 rows)
1184
1185 --
1186 -- test WITH attached to intermediate-level set operation
1187 --
1188 WITH outermost(x) AS (
1189   SELECT 1
1190   UNION (WITH innermost as (SELECT 2)
1191          SELECT * FROM innermost
1192          UNION SELECT 3)
1193 )
1194 SELECT * FROM outermost;
1195  x 
1196 ---
1197  1
1198  2
1199  3
1200 (3 rows)
1201
1202 WITH outermost(x) AS (
1203   SELECT 1
1204   UNION (WITH innermost as (SELECT 2)
1205          SELECT * FROM outermost  -- fail
1206          UNION SELECT * FROM innermost)
1207 )
1208 SELECT * FROM outermost;
1209 ERROR:  relation "outermost" does not exist
1210 LINE 4:          SELECT * FROM outermost  
1211                                ^
1212 DETAIL:  There is a WITH item named "outermost", but it cannot be referenced from this part of the query.
1213 HINT:  Use WITH RECURSIVE, or re-order the WITH items to remove forward references.
1214 WITH RECURSIVE outermost(x) AS (
1215   SELECT 1
1216   UNION (WITH innermost as (SELECT 2)
1217          SELECT * FROM outermost
1218          UNION SELECT * FROM innermost)
1219 )
1220 SELECT * FROM outermost;
1221  x 
1222 ---
1223  1
1224  2
1225 (2 rows)
1226
1227 WITH RECURSIVE outermost(x) AS (
1228   WITH innermost as (SELECT 2 FROM outermost) -- fail
1229     SELECT * FROM innermost
1230     UNION SELECT * from outermost
1231 )
1232 SELECT * FROM outermost;
1233 ERROR:  recursive reference to query "outermost" must not appear within a subquery
1234 LINE 2:   WITH innermost as (SELECT 2 FROM outermost) 
1235                                            ^
1236 --
1237 -- This test will fail with the old implementation of PARAM_EXEC parameter
1238 -- assignment, because the "q1" Var passed down to A's targetlist subselect
1239 -- looks exactly like the "A.id" Var passed down to C's subselect, causing
1240 -- the old code to give them the same runtime PARAM_EXEC slot.  But the
1241 -- lifespans of the two parameters overlap, thanks to B also reading A.
1242 --
1243 with
1244 A as ( select q2 as id, (select q1) as x from int8_tbl ),
1245 B as ( select id, row_number() over (partition by id) as r from A ),
1246 C as ( select A.id, array(select B.id from B where B.id = A.id) from A )
1247 select * from C;
1248         id         |                array                
1249 -------------------+-------------------------------------
1250                456 | {456}
1251   4567890123456789 | {4567890123456789,4567890123456789}
1252                123 | {123}
1253   4567890123456789 | {4567890123456789,4567890123456789}
1254  -4567890123456789 | {-4567890123456789}
1255 (5 rows)
1256
1257 --
1258 -- Test CTEs read in non-initialization orders
1259 --
1260 WITH RECURSIVE
1261   tab(id_key,link) AS (VALUES (1,17), (2,17), (3,17), (4,17), (6,17), (5,17)),
1262   iter (id_key, row_type, link) AS (
1263       SELECT 0, 'base', 17
1264     UNION ALL (
1265       WITH remaining(id_key, row_type, link, min) AS (
1266         SELECT tab.id_key, 'true'::text, iter.link, MIN(tab.id_key) OVER ()
1267         FROM tab INNER JOIN iter USING (link)
1268         WHERE tab.id_key > iter.id_key
1269       ),
1270       first_remaining AS (
1271         SELECT id_key, row_type, link
1272         FROM remaining
1273         WHERE id_key=min
1274       ),
1275       effect AS (
1276         SELECT tab.id_key, 'new'::text, tab.link
1277         FROM first_remaining e INNER JOIN tab ON e.id_key=tab.id_key
1278         WHERE e.row_type = 'false'
1279       )
1280       SELECT * FROM first_remaining
1281       UNION ALL SELECT * FROM effect
1282     )
1283   )
1284 SELECT * FROM iter;
1285  id_key | row_type | link 
1286 --------+----------+------
1287       0 | base     |   17
1288       1 | true     |   17
1289       2 | true     |   17
1290       3 | true     |   17
1291       4 | true     |   17
1292       5 | true     |   17
1293       6 | true     |   17
1294 (7 rows)
1295
1296 WITH RECURSIVE
1297   tab(id_key,link) AS (VALUES (1,17), (2,17), (3,17), (4,17), (6,17), (5,17)),
1298   iter (id_key, row_type, link) AS (
1299       SELECT 0, 'base', 17
1300     UNION (
1301       WITH remaining(id_key, row_type, link, min) AS (
1302         SELECT tab.id_key, 'true'::text, iter.link, MIN(tab.id_key) OVER ()
1303         FROM tab INNER JOIN iter USING (link)
1304         WHERE tab.id_key > iter.id_key
1305       ),
1306       first_remaining AS (
1307         SELECT id_key, row_type, link
1308         FROM remaining
1309         WHERE id_key=min
1310       ),
1311       effect AS (
1312         SELECT tab.id_key, 'new'::text, tab.link
1313         FROM first_remaining e INNER JOIN tab ON e.id_key=tab.id_key
1314         WHERE e.row_type = 'false'
1315       )
1316       SELECT * FROM first_remaining
1317       UNION ALL SELECT * FROM effect
1318     )
1319   )
1320 SELECT * FROM iter;
1321  id_key | row_type | link 
1322 --------+----------+------
1323       0 | base     |   17
1324       1 | true     |   17
1325       2 | true     |   17
1326       3 | true     |   17
1327       4 | true     |   17
1328       5 | true     |   17
1329       6 | true     |   17
1330 (7 rows)
1331
1332 --
1333 -- Data-modifying statements in WITH
1334 --
1335 -- INSERT ... RETURNING
1336 WITH t AS (
1337     INSERT INTO y
1338     VALUES
1339         (11),
1340         (12),
1341         (13),
1342         (14),
1343         (15),
1344         (16),
1345         (17),
1346         (18),
1347         (19),
1348         (20)
1349     RETURNING *
1350 )
1351 SELECT * FROM t;
1352  a  
1353 ----
1354  11
1355  12
1356  13
1357  14
1358  15
1359  16
1360  17
1361  18
1362  19
1363  20
1364 (10 rows)
1365
1366 SELECT * FROM y;
1367  a  
1368 ----
1369   1
1370   2
1371   3
1372   4
1373   5
1374   6
1375   7
1376   8
1377   9
1378  10
1379  11
1380  12
1381  13
1382  14
1383  15
1384  16
1385  17
1386  18
1387  19
1388  20
1389 (20 rows)
1390
1391 -- UPDATE ... RETURNING
1392 WITH t AS (
1393     UPDATE y
1394     SET a=a+1
1395     RETURNING *
1396 )
1397 SELECT * FROM t;
1398  a  
1399 ----
1400   2
1401   3
1402   4
1403   5
1404   6
1405   7
1406   8
1407   9
1408  10
1409  11
1410  12
1411  13
1412  14
1413  15
1414  16
1415  17
1416  18
1417  19
1418  20
1419  21
1420 (20 rows)
1421
1422 SELECT * FROM y;
1423  a  
1424 ----
1425   2
1426   3
1427   4
1428   5
1429   6
1430   7
1431   8
1432   9
1433  10
1434  11
1435  12
1436  13
1437  14
1438  15
1439  16
1440  17
1441  18
1442  19
1443  20
1444  21
1445 (20 rows)
1446
1447 -- DELETE ... RETURNING
1448 WITH t AS (
1449     DELETE FROM y
1450     WHERE a <= 10
1451     RETURNING *
1452 )
1453 SELECT * FROM t;
1454  a  
1455 ----
1456   2
1457   3
1458   4
1459   5
1460   6
1461   7
1462   8
1463   9
1464  10
1465 (9 rows)
1466
1467 SELECT * FROM y;
1468  a  
1469 ----
1470  11
1471  12
1472  13
1473  14
1474  15
1475  16
1476  17
1477  18
1478  19
1479  20
1480  21
1481 (11 rows)
1482
1483 -- forward reference
1484 WITH RECURSIVE t AS (
1485         INSERT INTO y
1486                 SELECT a+5 FROM t2 WHERE a > 5
1487         RETURNING *
1488 ), t2 AS (
1489         UPDATE y SET a=a-11 RETURNING *
1490 )
1491 SELECT * FROM t
1492 UNION ALL
1493 SELECT * FROM t2;
1494  a  
1495 ----
1496  11
1497  12
1498  13
1499  14
1500  15
1501   0
1502   1
1503   2
1504   3
1505   4
1506   5
1507   6
1508   7
1509   8
1510   9
1511  10
1512 (16 rows)
1513
1514 SELECT * FROM y;
1515  a  
1516 ----
1517   0
1518   1
1519   2
1520   3
1521   4
1522   5
1523   6
1524  11
1525   7
1526  12
1527   8
1528  13
1529   9
1530  14
1531  10
1532  15
1533 (16 rows)
1534
1535 -- unconditional DO INSTEAD rule
1536 CREATE RULE y_rule AS ON DELETE TO y DO INSTEAD
1537   INSERT INTO y VALUES(42) RETURNING *;
1538 WITH t AS (
1539         DELETE FROM y RETURNING *
1540 )
1541 SELECT * FROM t;
1542  a  
1543 ----
1544  42
1545 (1 row)
1546
1547 SELECT * FROM y;
1548  a  
1549 ----
1550   0
1551   1
1552   2
1553   3
1554   4
1555   5
1556   6
1557  11
1558   7
1559  12
1560   8
1561  13
1562   9
1563  14
1564  10
1565  15
1566  42
1567 (17 rows)
1568
1569 DROP RULE y_rule ON y;
1570 -- check merging of outer CTE with CTE in a rule action
1571 CREATE TEMP TABLE bug6051 AS
1572   select i from generate_series(1,3) as t(i);
1573 SELECT * FROM bug6051;
1574  i 
1575 ---
1576  1
1577  2
1578  3
1579 (3 rows)
1580
1581 WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
1582 INSERT INTO bug6051 SELECT * FROM t1;
1583 SELECT * FROM bug6051;
1584  i 
1585 ---
1586  1
1587  2
1588  3
1589 (3 rows)
1590
1591 CREATE TEMP TABLE bug6051_2 (i int);
1592 CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD
1593  INSERT INTO bug6051_2
1594  SELECT NEW.i;
1595 WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
1596 INSERT INTO bug6051 SELECT * FROM t1;
1597 SELECT * FROM bug6051;
1598  i 
1599 ---
1600 (0 rows)
1601
1602 SELECT * FROM bug6051_2;
1603  i 
1604 ---
1605  1
1606  2
1607  3
1608 (3 rows)
1609
1610 -- a truly recursive CTE in the same list
1611 WITH RECURSIVE t(a) AS (
1612         SELECT 0
1613                 UNION ALL
1614         SELECT a+1 FROM t WHERE a+1 < 5
1615 ), t2 as (
1616         INSERT INTO y
1617                 SELECT * FROM t RETURNING *
1618 )
1619 SELECT * FROM t2 JOIN y USING (a) ORDER BY a;
1620  a 
1621 ---
1622  0
1623  1
1624  2
1625  3
1626  4
1627 (5 rows)
1628
1629 SELECT * FROM y;
1630  a  
1631 ----
1632   0
1633   1
1634   2
1635   3
1636   4
1637   5
1638   6
1639  11
1640   7
1641  12
1642   8
1643  13
1644   9
1645  14
1646  10
1647  15
1648  42
1649   0
1650   1
1651   2
1652   3
1653   4
1654 (22 rows)
1655
1656 -- data-modifying WITH in a modifying statement
1657 WITH t AS (
1658     DELETE FROM y
1659     WHERE a <= 10
1660     RETURNING *
1661 )
1662 INSERT INTO y SELECT -a FROM t RETURNING *;
1663   a  
1664 -----
1665    0
1666   -1
1667   -2
1668   -3
1669   -4
1670   -5
1671   -6
1672   -7
1673   -8
1674   -9
1675  -10
1676    0
1677   -1
1678   -2
1679   -3
1680   -4
1681 (16 rows)
1682
1683 SELECT * FROM y;
1684   a  
1685 -----
1686   11
1687   12
1688   13
1689   14
1690   15
1691   42
1692    0
1693   -1
1694   -2
1695   -3
1696   -4
1697   -5
1698   -6
1699   -7
1700   -8
1701   -9
1702  -10
1703    0
1704   -1
1705   -2
1706   -3
1707   -4
1708 (22 rows)
1709
1710 -- check that WITH query is run to completion even if outer query isn't
1711 WITH t AS (
1712     UPDATE y SET a = a * 100 RETURNING *
1713 )
1714 SELECT * FROM t LIMIT 10;
1715   a   
1716 ------
1717  1100
1718  1200
1719  1300
1720  1400
1721  1500
1722  4200
1723     0
1724  -100
1725  -200
1726  -300
1727 (10 rows)
1728
1729 SELECT * FROM y;
1730    a   
1731 -------
1732   1100
1733   1200
1734   1300
1735   1400
1736   1500
1737   4200
1738      0
1739   -100
1740   -200
1741   -300
1742   -400
1743   -500
1744   -600
1745   -700
1746   -800
1747   -900
1748  -1000
1749      0
1750   -100
1751   -200
1752   -300
1753   -400
1754 (22 rows)
1755
1756 -- check that run to completion happens in proper ordering
1757 TRUNCATE TABLE y;
1758 INSERT INTO y SELECT generate_series(1, 3);
1759 CREATE TEMPORARY TABLE yy (a INTEGER);
1760 WITH RECURSIVE t1 AS (
1761   INSERT INTO y SELECT * FROM y RETURNING *
1762 ), t2 AS (
1763   INSERT INTO yy SELECT * FROM t1 RETURNING *
1764 )
1765 SELECT 1;
1766  ?column? 
1767 ----------
1768         1
1769 (1 row)
1770
1771 SELECT * FROM y;
1772  a 
1773 ---
1774  1
1775  2
1776  3
1777  1
1778  2
1779  3
1780 (6 rows)
1781
1782 SELECT * FROM yy;
1783  a 
1784 ---
1785  1
1786  2
1787  3
1788 (3 rows)
1789
1790 WITH RECURSIVE t1 AS (
1791   INSERT INTO yy SELECT * FROM t2 RETURNING *
1792 ), t2 AS (
1793   INSERT INTO y SELECT * FROM y RETURNING *
1794 )
1795 SELECT 1;
1796  ?column? 
1797 ----------
1798         1
1799 (1 row)
1800
1801 SELECT * FROM y;
1802  a 
1803 ---
1804  1
1805  2
1806  3
1807  1
1808  2
1809  3
1810  1
1811  2
1812  3
1813  1
1814  2
1815  3
1816 (12 rows)
1817
1818 SELECT * FROM yy;
1819  a 
1820 ---
1821  1
1822  2
1823  3
1824  1
1825  2
1826  3
1827  1
1828  2
1829  3
1830 (9 rows)
1831
1832 -- triggers
1833 TRUNCATE TABLE y;
1834 INSERT INTO y SELECT generate_series(1, 10);
1835 CREATE FUNCTION y_trigger() RETURNS trigger AS $$
1836 begin
1837   raise notice 'y_trigger: a = %', new.a;
1838   return new;
1839 end;
1840 $$ LANGUAGE plpgsql;
1841 CREATE TRIGGER y_trig BEFORE INSERT ON y FOR EACH ROW
1842     EXECUTE PROCEDURE y_trigger();
1843 WITH t AS (
1844     INSERT INTO y
1845     VALUES
1846         (21),
1847         (22),
1848         (23)
1849     RETURNING *
1850 )
1851 SELECT * FROM t;
1852 NOTICE:  y_trigger: a = 21
1853 NOTICE:  y_trigger: a = 22
1854 NOTICE:  y_trigger: a = 23
1855  a  
1856 ----
1857  21
1858  22
1859  23
1860 (3 rows)
1861
1862 SELECT * FROM y;
1863  a  
1864 ----
1865   1
1866   2
1867   3
1868   4
1869   5
1870   6
1871   7
1872   8
1873   9
1874  10
1875  21
1876  22
1877  23
1878 (13 rows)
1879
1880 DROP TRIGGER y_trig ON y;
1881 CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH ROW
1882     EXECUTE PROCEDURE y_trigger();
1883 WITH t AS (
1884     INSERT INTO y
1885     VALUES
1886         (31),
1887         (32),
1888         (33)
1889     RETURNING *
1890 )
1891 SELECT * FROM t LIMIT 1;
1892 NOTICE:  y_trigger: a = 31
1893 NOTICE:  y_trigger: a = 32
1894 NOTICE:  y_trigger: a = 33
1895  a  
1896 ----
1897  31
1898 (1 row)
1899
1900 SELECT * FROM y;
1901  a  
1902 ----
1903   1
1904   2
1905   3
1906   4
1907   5
1908   6
1909   7
1910   8
1911   9
1912  10
1913  21
1914  22
1915  23
1916  31
1917  32
1918  33
1919 (16 rows)
1920
1921 DROP TRIGGER y_trig ON y;
1922 CREATE OR REPLACE FUNCTION y_trigger() RETURNS trigger AS $$
1923 begin
1924   raise notice 'y_trigger';
1925   return null;
1926 end;
1927 $$ LANGUAGE plpgsql;
1928 CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH STATEMENT
1929     EXECUTE PROCEDURE y_trigger();
1930 WITH t AS (
1931     INSERT INTO y
1932     VALUES
1933         (41),
1934         (42),
1935         (43)
1936     RETURNING *
1937 )
1938 SELECT * FROM t;
1939 NOTICE:  y_trigger
1940  a  
1941 ----
1942  41
1943  42
1944  43
1945 (3 rows)
1946
1947 SELECT * FROM y;
1948  a  
1949 ----
1950   1
1951   2
1952   3
1953   4
1954   5
1955   6
1956   7
1957   8
1958   9
1959  10
1960  21
1961  22
1962  23
1963  31
1964  32
1965  33
1966  41
1967  42
1968  43
1969 (19 rows)
1970
1971 DROP TRIGGER y_trig ON y;
1972 DROP FUNCTION y_trigger();
1973 -- WITH attached to inherited UPDATE or DELETE
1974 CREATE TEMP TABLE parent ( id int, val text );
1975 CREATE TEMP TABLE child1 ( ) INHERITS ( parent );
1976 CREATE TEMP TABLE child2 ( ) INHERITS ( parent );
1977 INSERT INTO parent VALUES ( 1, 'p1' );
1978 INSERT INTO child1 VALUES ( 11, 'c11' ),( 12, 'c12' );
1979 INSERT INTO child2 VALUES ( 23, 'c21' ),( 24, 'c22' );
1980 WITH rcte AS ( SELECT sum(id) AS totalid FROM parent )
1981 UPDATE parent SET id = id + totalid FROM rcte;
1982 SELECT * FROM parent;
1983  id | val 
1984 ----+-----
1985  72 | p1
1986  82 | c11
1987  83 | c12
1988  94 | c21
1989  95 | c22
1990 (5 rows)
1991
1992 WITH wcte AS ( INSERT INTO child1 VALUES ( 42, 'new' ) RETURNING id AS newid )
1993 UPDATE parent SET id = id + newid FROM wcte;
1994 SELECT * FROM parent;
1995  id  | val 
1996 -----+-----
1997  114 | p1
1998   42 | new
1999  124 | c11
2000  125 | c12
2001  136 | c21
2002  137 | c22
2003 (6 rows)
2004
2005 WITH rcte AS ( SELECT max(id) AS maxid FROM parent )
2006 DELETE FROM parent USING rcte WHERE id = maxid;
2007 SELECT * FROM parent;
2008  id  | val 
2009 -----+-----
2010  114 | p1
2011   42 | new
2012  124 | c11
2013  125 | c12
2014  136 | c21
2015 (5 rows)
2016
2017 WITH wcte AS ( INSERT INTO child2 VALUES ( 42, 'new2' ) RETURNING id AS newid )
2018 DELETE FROM parent USING wcte WHERE id = newid;
2019 SELECT * FROM parent;
2020  id  | val  
2021 -----+------
2022  114 | p1
2023  124 | c11
2024  125 | c12
2025  136 | c21
2026   42 | new2
2027 (5 rows)
2028
2029 -- check EXPLAIN VERBOSE for a wCTE with RETURNING
2030 EXPLAIN (VERBOSE, COSTS OFF)
2031 WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 )
2032 DELETE FROM a USING wcte WHERE aa = q2;
2033                    QUERY PLAN                   
2034 ------------------------------------------------
2035  Delete on public.a
2036    CTE wcte
2037      ->  Insert on public.int8_tbl
2038            Output: int8_tbl.q2
2039            ->  Result
2040                  Output: 42::bigint, 47::bigint
2041    ->  Nested Loop
2042          Output: a.ctid, wcte.*
2043          Join Filter: (a.aa = wcte.q2)
2044          ->  Seq Scan on public.a
2045                Output: a.ctid, a.aa
2046          ->  CTE Scan on wcte
2047                Output: wcte.*, wcte.q2
2048    ->  Nested Loop
2049          Output: b.ctid, wcte.*
2050          Join Filter: (b.aa = wcte.q2)
2051          ->  Seq Scan on public.b
2052                Output: b.ctid, b.aa
2053          ->  CTE Scan on wcte
2054                Output: wcte.*, wcte.q2
2055    ->  Nested Loop
2056          Output: c.ctid, wcte.*
2057          Join Filter: (c.aa = wcte.q2)
2058          ->  Seq Scan on public.c
2059                Output: c.ctid, c.aa
2060          ->  CTE Scan on wcte
2061                Output: wcte.*, wcte.q2
2062    ->  Nested Loop
2063          Output: d.ctid, wcte.*
2064          Join Filter: (d.aa = wcte.q2)
2065          ->  Seq Scan on public.d
2066                Output: d.ctid, d.aa
2067          ->  CTE Scan on wcte
2068                Output: wcte.*, wcte.q2
2069 (34 rows)
2070
2071 -- error cases
2072 -- data-modifying WITH tries to use its own output
2073 WITH RECURSIVE t AS (
2074         INSERT INTO y
2075                 SELECT * FROM t
2076 )
2077 VALUES(FALSE);
2078 ERROR:  recursive query "t" must not contain data-modifying statements
2079 LINE 1: WITH RECURSIVE t AS (
2080                        ^
2081 -- no RETURNING in a referenced data-modifying WITH
2082 WITH t AS (
2083         INSERT INTO y VALUES(0)
2084 )
2085 SELECT * FROM t;
2086 ERROR:  WITH query "t" does not have a RETURNING clause
2087 LINE 4: SELECT * FROM t;
2088                       ^
2089 -- data-modifying WITH allowed only at the top level
2090 SELECT * FROM (
2091         WITH t AS (UPDATE y SET a=a+1 RETURNING *)
2092         SELECT * FROM t
2093 ) ss;
2094 ERROR:  WITH clause containing a data-modifying statement must be at the top level
2095 LINE 2:  WITH t AS (UPDATE y SET a=a+1 RETURNING *)
2096               ^
2097 -- most variants of rules aren't allowed
2098 CREATE RULE y_rule AS ON INSERT TO y WHERE a=0 DO INSTEAD DELETE FROM y;
2099 WITH t AS (
2100         INSERT INTO y VALUES(0)
2101 )
2102 VALUES(FALSE);
2103 ERROR:  conditional DO INSTEAD rules are not supported for data-modifying statements in WITH
2104 DROP RULE y_rule ON y;