bug-16801-fix.patch
text/x-diff
Filename: bug-16801-fix.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/parser/parse_cte.c | 6 | 6 |
| src/test/regress/expected/with.out | 23 | 0 |
| src/test/regress/sql/with.sql | 19 | 0 |
diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c
index f4f7041ead..f46d63d451 100644
--- a/src/backend/parser/parse_cte.c
+++ b/src/backend/parser/parse_cte.c
@@ -730,15 +730,15 @@ makeDependencyGraphWalker(Node *node, CteState *cstate)
* In the non-RECURSIVE case, query names are visible to the
* WITH items after them and to the main query.
*/
- ListCell *cell1;
-
cstate->innerwiths = lcons(NIL, cstate->innerwiths);
- cell1 = list_head(cstate->innerwiths);
foreach(lc, stmt->withClause->ctes)
{
CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
+ ListCell *cell1;
(void) makeDependencyGraphWalker(cte->ctequery, cstate);
+ /* note that recursion could mutate innerwiths list */
+ cell1 = list_head(cstate->innerwiths);
lfirst(cell1) = lappend((List *) lfirst(cell1), cte);
}
(void) raw_expression_tree_walker(node,
@@ -1006,15 +1006,15 @@ checkWellFormedRecursionWalker(Node *node, CteState *cstate)
* In the non-RECURSIVE case, query names are visible to the
* WITH items after them and to the main query.
*/
- ListCell *cell1;
-
cstate->innerwiths = lcons(NIL, cstate->innerwiths);
- cell1 = list_head(cstate->innerwiths);
foreach(lc, stmt->withClause->ctes)
{
CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
+ ListCell *cell1;
(void) checkWellFormedRecursionWalker(cte->ctequery, cstate);
+ /* note that recursion could mutate innerwiths list */
+ cell1 = list_head(cstate->innerwiths);
lfirst(cell1) = lappend((List *) lfirst(cell1), cte);
}
checkWellFormedSelectStmt(stmt, cstate);
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index c519a61c4f..be4ba1825f 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -176,6 +176,29 @@ ERROR: operator does not exist: text + integer
LINE 4: SELECT n+1 FROM t WHERE n < 10
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
+-- Deeply nested WITH caused a list-munging problem in v13
+with recursive w1(c1) as
+ (with w2(c2) as
+ (with w3(c3) as
+ (with w4(c4) as
+ (with w5(c5) as
+ (with recursive w6(c6) as
+ (with w6(c6) as
+ (with w8(c8) as
+ (select 1)
+ select * from w8)
+ select * from w6)
+ select * from w6)
+ select * from w5)
+ select * from w4)
+ select * from w3)
+ select * from w2)
+select * from w1;
+ c1
+----
+ 1
+(1 row)
+
--
-- Some examples with a tree
--
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index f4ba0d8e39..b2f9ac07e8 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -95,6 +95,25 @@ UNION ALL
)
SELECT n, pg_typeof(n) FROM t;
+-- Deeply nested WITH caused a list-munging problem in v13
+with recursive w1(c1) as
+ (with w2(c2) as
+ (with w3(c3) as
+ (with w4(c4) as
+ (with w5(c5) as
+ (with recursive w6(c6) as
+ (with w6(c6) as
+ (with w8(c8) as
+ (select 1)
+ select * from w8)
+ select * from w6)
+ select * from w6)
+ select * from w5)
+ select * from w4)
+ select * from w3)
+ select * from w2)
+select * from w1;
+
--
-- Some examples with a tree
--