Skip to content

Commit 000128b

Browse files
committed
Fix order of shutdown processing when CTEs contain inter-references.
We need ExecutorEnd to run the ModifyTable nodes to completion in reverse order of initialization, not forward order. Easily done by constructing the list back-to-front.
1 parent 389af95 commit 000128b

File tree

3 files changed

+108
-3
lines changed

3 files changed

+108
-3
lines changed

src/backend/executor/nodeModifyTable.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,11 +1147,14 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
11471147
* Lastly, if this is not the primary (canSetTag) ModifyTable node, add it
11481148
* to estate->es_auxmodifytables so that it will be run to completion by
11491149
* ExecPostprocessPlan. (It'd actually work fine to add the primary
1150-
* ModifyTable node too, but there's no need.)
1150+
* ModifyTable node too, but there's no need.) Note the use of lcons
1151+
* not lappend: we need later-initialized ModifyTable nodes to be shut
1152+
* down before earlier ones. This ensures that we don't throw away
1153+
* RETURNING rows that need to be seen by a later CTE subplan.
11511154
*/
11521155
if (!mtstate->canSetTag)
1153-
estate->es_auxmodifytables = lappend(estate->es_auxmodifytables,
1154-
mtstate);
1156+
estate->es_auxmodifytables = lcons(mtstate,
1157+
estate->es_auxmodifytables);
11551158

11561159
return mtstate;
11571160
}

src/test/regress/expected/with.out

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,82 @@ SELECT * FROM y;
15431543
-400
15441544
(22 rows)
15451545

1546+
-- check that run to completion happens in proper ordering
1547+
TRUNCATE TABLE y;
1548+
INSERT INTO y SELECT generate_series(1, 3);
1549+
CREATE TEMPORARY TABLE yy (a INTEGER);
1550+
WITH RECURSIVE t1 AS (
1551+
INSERT INTO y SELECT * FROM y RETURNING *
1552+
), t2 AS (
1553+
INSERT INTO yy SELECT * FROM t1 RETURNING *
1554+
)
1555+
SELECT 1;
1556+
?column?
1557+
----------
1558+
1
1559+
(1 row)
1560+
1561+
SELECT * FROM y;
1562+
a
1563+
---
1564+
1
1565+
2
1566+
3
1567+
1
1568+
2
1569+
3
1570+
(6 rows)
1571+
1572+
SELECT * FROM yy;
1573+
a
1574+
---
1575+
1
1576+
2
1577+
3
1578+
(3 rows)
1579+
1580+
WITH RECURSIVE t1 AS (
1581+
INSERT INTO yy SELECT * FROM t2 RETURNING *
1582+
), t2 AS (
1583+
INSERT INTO y SELECT * FROM y RETURNING *
1584+
)
1585+
SELECT 1;
1586+
?column?
1587+
----------
1588+
1
1589+
(1 row)
1590+
1591+
SELECT * FROM y;
1592+
a
1593+
---
1594+
1
1595+
2
1596+
3
1597+
1
1598+
2
1599+
3
1600+
1
1601+
2
1602+
3
1603+
1
1604+
2
1605+
3
1606+
(12 rows)
1607+
1608+
SELECT * FROM yy;
1609+
a
1610+
---
1611+
1
1612+
2
1613+
3
1614+
1
1615+
2
1616+
3
1617+
1
1618+
2
1619+
3
1620+
(9 rows)
1621+
15461622
-- triggers
15471623
TRUNCATE TABLE y;
15481624
INSERT INTO y SELECT generate_series(1, 10);

src/test/regress/sql/with.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,32 @@ SELECT * FROM t LIMIT 10;
641641

642642
SELECT * FROM y;
643643

644+
-- check that run to completion happens in proper ordering
645+
646+
TRUNCATE TABLE y;
647+
INSERT INTO y SELECT generate_series(1, 3);
648+
CREATE TEMPORARY TABLE yy (a INTEGER);
649+
650+
WITH RECURSIVE t1 AS (
651+
INSERT INTO y SELECT * FROM y RETURNING *
652+
), t2 AS (
653+
INSERT INTO yy SELECT * FROM t1 RETURNING *
654+
)
655+
SELECT 1;
656+
657+
SELECT * FROM y;
658+
SELECT * FROM yy;
659+
660+
WITH RECURSIVE t1 AS (
661+
INSERT INTO yy SELECT * FROM t2 RETURNING *
662+
), t2 AS (
663+
INSERT INTO y SELECT * FROM y RETURNING *
664+
)
665+
SELECT 1;
666+
667+
SELECT * FROM y;
668+
SELECT * FROM yy;
669+
644670
-- triggers
645671

646672
TRUNCATE TABLE y;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy