Skip to content

Commit 0814250

Browse files
committed
Fix markTargetListOrigin() to not fail on a simple-Var reference to a
recursive CTE that we're still in progress of analyzing. Add a similar guard to the similar code in expandRecordVariable(), and tweak regression tests to cover this case. Per report from Dickson S. Guedes.
1 parent 6151e89 commit 0814250

File tree

3 files changed

+24
-15
lines changed

3 files changed

+24
-15
lines changed

src/backend/parser/parse_target.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.165 2008/10/04 21:56:54 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.166 2008/10/05 22:20:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -297,8 +297,16 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
297297
/* not a simple relation, leave it unmarked */
298298
break;
299299
case RTE_CTE:
300-
/* CTE reference: copy up from the subquery */
301-
if (attnum != InvalidAttrNumber)
300+
/*
301+
* CTE reference: copy up from the subquery, if possible.
302+
* If the RTE is a recursive self-reference then we can't do
303+
* anything because we haven't finished analyzing it yet.
304+
* However, it's no big loss because we must be down inside
305+
* the recursive term of a recursive CTE, and so any markings
306+
* on the current targetlist are not going to affect the results
307+
* anyway.
308+
*/
309+
if (attnum != InvalidAttrNumber && !rte->self_reference)
302310
{
303311
CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
304312
TargetEntry *ste;
@@ -1195,8 +1203,9 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
11951203
*/
11961204
break;
11971205
case RTE_CTE:
1206+
/* CTE reference: examine subquery's output expr */
1207+
if (!rte->self_reference)
11981208
{
1199-
/* CTE reference: examine subquery's output expr */
12001209
CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
12011210
TargetEntry *ste;
12021211

src/test/regress/expected/with.out

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,20 @@ INSERT INTO department VALUES (7, 5, 'G');
9696
WITH RECURSIVE subdepartment AS
9797
(
9898
-- non recursive term
99-
SELECT * FROM department WHERE name = 'A'
99+
SELECT name as root_name, * FROM department WHERE name = 'A'
100100
UNION ALL
101101
-- recursive term
102-
SELECT d.* FROM department AS d, subdepartment AS sd
102+
SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
103103
WHERE d.parent_department = sd.id
104104
)
105105
SELECT * FROM subdepartment ORDER BY name;
106-
id | parent_department | name
107-
----+-------------------+------
108-
1 | 0 | A
109-
2 | 1 | B
110-
3 | 2 | C
111-
4 | 2 | D
112-
6 | 4 | F
106+
root_name | id | parent_department | name
107+
-----------+----+-------------------+------
108+
A | 1 | 0 | A
109+
A | 2 | 1 | B
110+
A | 3 | 2 | C
111+
A | 4 | 2 | D
112+
A | 6 | 4 | F
113113
(5 rows)
114114

115115
-- extract all departments under 'A' with "level" number

src/test/regress/sql/with.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ INSERT INTO department VALUES (7, 5, 'G');
6868
WITH RECURSIVE subdepartment AS
6969
(
7070
-- non recursive term
71-
SELECT * FROM department WHERE name = 'A'
71+
SELECT name as root_name, * FROM department WHERE name = 'A'
7272

7373
UNION ALL
7474

7575
-- recursive term
76-
SELECT d.* FROM department AS d, subdepartment AS sd
76+
SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
7777
WHERE d.parent_department = sd.id
7878
)
7979
SELECT * FROM subdepartment ORDER BY name;

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