diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 4e0d9ca4e574423468d2907fc06f1ee91ea62a18..a172c5de7ab2bb6e6a96fe90669a8bbe893774f1 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.180 2009/02/15 20:16:21 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.181 2009/03/10 20:58:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -523,6 +523,13 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
 	PlannerInfo *subroot;
 	List	   *pathkeys;
 
+	/*
+	 * Must copy the Query so that planning doesn't mess up the RTE contents
+	 * (really really need to fix the planner to not scribble on its input,
+	 * someday).
+	 */
+	subquery = copyObject(subquery);
+
 	/* We need a workspace for keeping track of set-op type coercions */
 	differentTypes = (bool *)
 		palloc0((list_length(subquery->targetList) + 1) * sizeof(bool));
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index f6dbc0212cd46c983005a3dd53656bf10ca34d44..49ee53741b206686db1dd71095b72ec4c43d2a1c 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -465,3 +465,15 @@ from tc;
          3
 (2 rows)
 
+--
+-- Test case for 8.3 "failed to locate grouping columns" bug
+--
+create temp table t1 (f1 numeric(14,0), f2 varchar(30));
+select * from
+  (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs
+   from t1 up) ss
+group by f1,f2,fs;
+ f1 | f2 | fs 
+----+----+----
+(0 rows)
+
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index 3a3f11793dc6e5dd8fbc930dad5aa7aa8dde17a3..fd8d5df3a01c72cc0ee409d33157e23e063bbb95 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -298,3 +298,14 @@ select
   ( select min(tb.id) from tb
     where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id
 from tc;
+
+--
+-- Test case for 8.3 "failed to locate grouping columns" bug
+--
+
+create temp table t1 (f1 numeric(14,0), f2 varchar(30));
+
+select * from
+  (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs
+   from t1 up) ss
+group by f1,f2,fs;