diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 3ead26194e37758b429b42f1581081f959893f26..ed54abe70398e037c1255583b5ad7531cb1a2458 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.165 2008/10/04 21:56:54 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.166 2008/10/05 22:20:16 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -297,8 +297,16 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
 			/* not a simple relation, leave it unmarked */
 			break;
 		case RTE_CTE:
-			/* CTE reference: copy up from the subquery */
-			if (attnum != InvalidAttrNumber)
+			/*
+			 * CTE reference: copy up from the subquery, if possible.
+			 * If the RTE is a recursive self-reference then we can't do
+			 * anything because we haven't finished analyzing it yet.
+			 * However, it's no big loss because we must be down inside
+			 * the recursive term of a recursive CTE, and so any markings
+			 * on the current targetlist are not going to affect the results
+			 * anyway.
+			 */
+			if (attnum != InvalidAttrNumber && !rte->self_reference)
 			{
 				CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
 				TargetEntry *ste;
@@ -1195,8 +1203,9 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
 			 */
 			break;
 		case RTE_CTE:
+			/* CTE reference: examine subquery's output expr */
+			if (!rte->self_reference)
 			{
-				/* CTE reference: examine subquery's output expr */
 				CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
 				TargetEntry *ste;
 
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index ac91642c7bdc5b74a07e51a812341138d774c3ce..65afc1a0c670b5d2fbe63bff38a76220ad942792 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -96,20 +96,20 @@ INSERT INTO department VALUES (7, 5, 'G');
 WITH RECURSIVE subdepartment AS
 (
 	-- non recursive term
-	SELECT * FROM department WHERE name = 'A'
+	SELECT name as root_name, * FROM department WHERE name = 'A'
 	UNION ALL
 	-- recursive term
-	SELECT d.* FROM department AS d, subdepartment AS sd
+	SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
 		WHERE d.parent_department = sd.id
 )
 SELECT * FROM subdepartment ORDER BY name;
- id | parent_department | name 
-----+-------------------+------
-  1 |                 0 | A
-  2 |                 1 | B
-  3 |                 2 | C
-  4 |                 2 | D
-  6 |                 4 | F
+ root_name | id | parent_department | name 
+-----------+----+-------------------+------
+ A         |  1 |                 0 | A
+ A         |  2 |                 1 | B
+ A         |  3 |                 2 | C
+ A         |  4 |                 2 | D
+ A         |  6 |                 4 | F
 (5 rows)
 
 -- extract all departments under 'A' with "level" number
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index 0ad59abdc9fe495a3ed93a01c483eedcfc63fd1b..cd8831f4b15654df48a914db44acea817f61bcb0 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -68,12 +68,12 @@ INSERT INTO department VALUES (7, 5, 'G');
 WITH RECURSIVE subdepartment AS
 (
 	-- non recursive term
-	SELECT * FROM department WHERE name = 'A'
+	SELECT name as root_name, * FROM department WHERE name = 'A'
 
 	UNION ALL
 
 	-- recursive term
-	SELECT d.* FROM department AS d, subdepartment AS sd
+	SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
 		WHERE d.parent_department = sd.id
 )
 SELECT * FROM subdepartment ORDER BY name;