diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 4a251b63de4666c1155ab6dcb81b85e273f233d2..2b1eddbcf09716e70af213abc2d11284e4267397 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.299 2004/05/05 04:48:46 tgl Exp $
+ *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.300 2004/05/23 17:10:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1929,17 +1929,17 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 	 */
 	qry->sortClause = transformSortClause(pstate,
 										  stmt->sortClause,
-										  qry->targetList,
+										  &qry->targetList,
 										  true /* fix unknowns */ );
 
 	qry->groupClause = transformGroupClause(pstate,
 											stmt->groupClause,
-											qry->targetList,
+											&qry->targetList,
 											qry->sortClause);
 
 	qry->distinctClause = transformDistinctClause(pstate,
 												  stmt->distinctClause,
-												  qry->targetList,
+												  &qry->targetList,
 												  &qry->sortClause);
 
 	qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
@@ -2145,7 +2145,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 
 	qry->sortClause = transformSortClause(pstate,
 										  sortClause,
-										  qry->targetList,
+										  &qry->targetList,
 									  false /* no unknowns expected */ );
 
 	pstate->p_namespace = sv_namespace;
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index c15dd9b78922d269952b28c0cf995ecbacb1aadc..2c6e99428997906ac90522481034d39d65d58ee4 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.128 2004/04/18 18:12:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.129 2004/05/23 17:10:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,7 +58,7 @@ static Node *transformFromClauseItem(ParseState *pstate, Node *n,
 static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype,
 				   Var *l_colvar, Var *r_colvar);
 static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
-					List *tlist, int clause);
+					List **tlist, int clause);
 
 
 /*
@@ -1076,12 +1076,11 @@ transformLimitClause(ParseState *pstate, Node *clause,
  *	  list as a "resjunk" node.
  *
  * node		the ORDER BY, GROUP BY, or DISTINCT ON expression to be matched
- * tlist	the existing target list (NB: this will never be NIL, which is a
- *			good thing since we'd be unable to append to it if it were...)
- * clause	identifies clause type being processed.
+ * tlist	the target list (passed by reference so we can append to it)
+ * clause	identifies clause type being processed
  */
 static TargetEntry *
-findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
+findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
 {
 	TargetEntry *target_result = NULL;
 	List	   *tl;
@@ -1157,7 +1156,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
 
 		if (name != NULL)
 		{
-			foreach(tl, tlist)
+			foreach(tl, *tlist)
 			{
 				TargetEntry *tle = (TargetEntry *) lfirst(tl);
 				Resdom	   *resnode = tle->resdom;
@@ -1196,7 +1195,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
 					 errmsg("non-integer constant in %s",
 							clauseText[clause])));
 		target_pos = intVal(val);
-		foreach(tl, tlist)
+		foreach(tl, *tlist)
 		{
 			TargetEntry *tle = (TargetEntry *) lfirst(tl);
 			Resdom	   *resnode = tle->resdom;
@@ -1224,7 +1223,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
 	 */
 	expr = transformExpr(pstate, node);
 
-	foreach(tl, tlist)
+	foreach(tl, *tlist)
 	{
 		TargetEntry *tle = (TargetEntry *) lfirst(tl);
 
@@ -1238,7 +1237,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
 	 * that it will not be projected into the final tuple.
 	 */
 	target_result = transformTargetEntry(pstate, node, expr, NULL, true);
-	lappend(tlist, target_result);
+
+	*tlist = lappend(*tlist, target_result);
 
 	return target_result;
 }
@@ -1247,10 +1247,13 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
 /*
  * transformGroupClause -
  *	  transform a GROUP BY clause
+ *
+ * GROUP BY items will be added to the targetlist (as resjunk columns)
+ * if not already present, so the targetlist must be passed by reference.
  */
 List *
 transformGroupClause(ParseState *pstate, List *grouplist,
-					 List *targetlist, List *sortClause)
+					 List **targetlist, List *sortClause)
 {
 	List	   *glist = NIL,
 			   *gl;
@@ -1304,7 +1307,7 @@ transformGroupClause(ParseState *pstate, List *grouplist,
 		}
 
 		grpcl = makeNode(GroupClause);
-		grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
+		grpcl->tleSortGroupRef = assignSortGroupRef(tle, *targetlist);
 		grpcl->sortop = ordering_op;
 		glist = lappend(glist, grpcl);
 	}
@@ -1315,11 +1318,14 @@ transformGroupClause(ParseState *pstate, List *grouplist,
 /*
  * transformSortClause -
  *	  transform an ORDER BY clause
+ *
+ * ORDER BY items will be added to the targetlist (as resjunk columns)
+ * if not already present, so the targetlist must be passed by reference.
  */
 List *
 transformSortClause(ParseState *pstate,
 					List *orderlist,
-					List *targetlist,
+					List **targetlist,
 					bool resolveUnknown)
 {
 	List	   *sortlist = NIL;
@@ -1334,7 +1340,7 @@ transformSortClause(ParseState *pstate,
 								  targetlist, ORDER_CLAUSE);
 
 		sortlist = addTargetToSortList(pstate, tle,
-									   sortlist, targetlist,
+									   sortlist, *targetlist,
 									   sortby->sortby_kind,
 									   sortby->useOp,
 									   resolveUnknown);
@@ -1348,13 +1354,11 @@ transformSortClause(ParseState *pstate,
  *	  transform a DISTINCT or DISTINCT ON clause
  *
  * Since we may need to add items to the query's sortClause list, that list
- * is passed by reference.	We might also need to add items to the query's
- * targetlist, but we assume that cannot be empty initially, so we can
- * lappend to it even though the pointer is passed by value.
+ * is passed by reference.	Likewise for the targetlist.
  */
 List *
 transformDistinctClause(ParseState *pstate, List *distinctlist,
-						List *targetlist, List **sortClause)
+						List **targetlist, List **sortClause)
 {
 	List	   *result = NIL;
 	List	   *slitem;
@@ -1377,7 +1381,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 		 */
 		*sortClause = addAllTargetsToSortList(pstate,
 											  *sortClause,
-											  targetlist,
+											  *targetlist,
 											  true);
 
 		/*
@@ -1390,7 +1394,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 		foreach(slitem, *sortClause)
 		{
 			SortClause *scl = (SortClause *) lfirst(slitem);
-			TargetEntry *tle = get_sortgroupclause_tle(scl, targetlist);
+			TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);
 
 			if (tle->resdom->resjunk)
 				ereport(ERROR,
@@ -1442,7 +1446,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 			else
 			{
 				*sortClause = addTargetToSortList(pstate, tle,
-												  *sortClause, targetlist,
+												  *sortClause, *targetlist,
 												  SORTBY_ASC, NIL, true);
 
 				/*
diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h
index fbe1f06c22aadf4a089c2de53ea3a4cbef82075a..923f2e23af4367bf5fa891e17c50d93e2947936d 100644
--- a/src/include/parser/parse_clause.h
+++ b/src/include/parser/parse_clause.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.40 2004/01/23 02:13:12 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.41 2004/05/23 17:10:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,11 +27,11 @@ extern Node *transformWhereClause(ParseState *pstate, Node *clause,
 extern Node *transformLimitClause(ParseState *pstate, Node *clause,
 					 const char *constructName);
 extern List *transformGroupClause(ParseState *pstate, List *grouplist,
-					 List *targetlist, List *sortClause);
+					 List **targetlist, List *sortClause);
 extern List *transformSortClause(ParseState *pstate, List *orderlist,
-					List *targetlist, bool resolveUnknown);
+					List **targetlist, bool resolveUnknown);
 extern List *transformDistinctClause(ParseState *pstate, List *distinctlist,
-						List *targetlist, List **sortClause);
+						List **targetlist, List **sortClause);
 
 extern List *addAllTargetsToSortList(ParseState *pstate,
 						List *sortlist, List *targetlist,