Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)