diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index e268bf3423f9571e0271b9865894e5758c132b8f..62970db8c7bdaa75671cb1515ba329f0ae22c749 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -105,6 +105,7 @@ ExecAgg(Agg *node)
 	ProjectionInfo *projInfo;
 	TupleTableSlot *resultSlot;
 	HeapTuple	oneTuple;
+	List	   *alist;
 	char	   *nulls;
 	bool		isDone;
 	bool		isNull = FALSE,
@@ -121,8 +122,17 @@ ExecAgg(Agg *node)
 
 	estate = node->plan.state;
 	econtext = aggstate->csstate.cstate.cs_ExprContext;
-	aggregates = node->aggs;
-	nagg = node->numAgg;
+	nagg = length(node->aggs);
+
+	aggregates = (Aggreg **)palloc(sizeof(Aggreg *) * nagg);
+
+	/* take List* and make it an array that can be quickly indexed */
+	alist = node->aggs;
+	for (i = 0; i < nagg; i++)
+	{
+		aggregates[i] = lfirst(alist);
+		alist = lnext(alist);
+	}
 
 	value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
 	nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
@@ -540,10 +550,10 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
 
 	econtext = aggstate->csstate.cstate.cs_ExprContext;
 	econtext->ecxt_values =
-		(Datum *) palloc(sizeof(Datum) * node->numAgg);
-	MemSet(econtext->ecxt_values, 0, sizeof(Datum) * node->numAgg);
-	econtext->ecxt_nulls = (char *) palloc(node->numAgg);
-	MemSet(econtext->ecxt_nulls, 0, node->numAgg);
+		(Datum *) palloc(sizeof(Datum) * length(node->aggs));
+	MemSet(econtext->ecxt_values, 0, sizeof(Datum) * length(node->aggs));
+	econtext->ecxt_nulls = (char *) palloc(length(node->aggs));
+	MemSet(econtext->ecxt_nulls, 0, length(node->aggs));
 
 	/*
 	 * initializes child nodes
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 28dc982abbf3ec0ea59041efc7681c5a358c13bb..e0ccc63f3504c8dd4ea257d9816b2671f3f7d3ae 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.29 1998/01/11 20:01:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.30 1998/01/15 18:59:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -493,15 +493,10 @@ static Agg *
 _copyAgg(Agg *from)
 {
 	Agg		   *newnode = makeNode(Agg);
-	int			i;
 
 	CopyPlanFields((Plan *) from, (Plan *) newnode);
 
-	newnode->numAgg = from->numAgg;
-    newnode->aggs = palloc(sizeof(Aggreg *));
-	for (i = 0; i < from->numAgg; i++)
-		newnode->aggs[i] = copyObject(from->aggs[i]);
-
+	Node_Copy(from, newnode, aggs);
 	Node_Copy(from, newnode, aggstate);
 
 	return newnode;
@@ -1495,7 +1490,6 @@ static Query *
 _copyQuery(Query *from)
 {
 	Query	   *newnode = makeNode(Query);
-	int i;
 	
 	newnode->commandType = from->commandType;
 	if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
@@ -1522,14 +1516,7 @@ _copyQuery(Query *from)
 	Node_Copy(from, newnode, groupClause);
 	Node_Copy(from, newnode, havingQual);
 
-	newnode->qry_numAgg = from->qry_numAgg;
-	if (from->qry_numAgg > 0)
-	{
-		newnode->qry_aggs =
-			(Aggreg **) palloc(sizeof(Aggreg *) * from->qry_numAgg);
-		for (i=0; i < from->qry_numAgg; i++)
-			newnode->qry_aggs[i] = _copyAggreg(from->qry_aggs[i]);
-	}
+	newnode->hasAggs = from->hasAggs;
 
 	if (from->unionClause)
 	{
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index e68c10284697ca77af8f17d07c4f7fa60583972b..6a7b7e12be6d907e5517e5c2214490c70e7adf33 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.10 1998/01/07 21:03:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.11 1998/01/15 18:59:23 momjian Exp $
  *
  * NOTES
  *	  XXX a few of the following functions are duplicated to handle
@@ -89,6 +89,48 @@ lappendi(List *list, int datum)
 	return nconc(list, lconsi(datum, NIL));
 }
 
+List	   *
+nconc(List *l1, List *l2)
+{
+	List	   *temp;
+
+	if (l1 == NIL)
+		return l2;
+	if (l2 == NIL)
+		return l1;
+	if (l1 == l2)
+		elog(ERROR, "tryout to nconc a list to itself");
+
+	for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
+		;
+
+	lnext(temp) = l2;
+	return (l1);				/* list1 is now list1[]list2  */
+}
+
+
+List	   *
+nreverse(List *list)
+{
+	List	   *rlist = NIL;
+	List	   *p = NIL;
+
+	if (list == NULL)
+		return (NIL);
+
+	if (length(list) == 1)
+		return (list);
+
+	for (p = list; p != NULL; p = lnext(p))
+	{
+		rlist = lcons(lfirst(p), rlist);
+	}
+
+	lfirst(list) = lfirst(rlist);
+	lnext(list) = lnext(rlist);
+	return (list);
+}
+
 Value	   *
 makeInteger(long i)
 {
@@ -227,48 +269,6 @@ intAppend(List *l1, List *l2)
 	return newlist;
 }
 
-List	   *
-nconc(List *l1, List *l2)
-{
-	List	   *temp;
-
-	if (l1 == NIL)
-		return l2;
-	if (l2 == NIL)
-		return l1;
-	if (l1 == l2)
-		elog(ERROR, "tryout to nconc a list to itself");
-
-	for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
-		;
-
-	lnext(temp) = l2;
-	return (l1);				/* list1 is now list1[]list2  */
-}
-
-
-List	   *
-nreverse(List *list)
-{
-	List	   *rlist = NIL;
-	List	   *p = NIL;
-
-	if (list == NULL)
-		return (NIL);
-
-	if (length(list) == 1)
-		return (list);
-
-	for (p = list; p != NULL; p = lnext(p))
-	{
-		rlist = lcons(lfirst(p), rlist);
-	}
-
-	lfirst(list) = lfirst(rlist);
-	lnext(list) = lnext(rlist);
-	return (list);
-}
-
 /*
  *		same
  *
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 8f0daf304052aaa0303350801fb8a7278084c07d..ba4b27f822c41108bc391e8acf9b88a51c12c2fd 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.20 1998/01/07 15:32:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.21 1998/01/15 18:59:26 momjian Exp $
  *
  * NOTES
  *	  Every (plan) node in POSTGRES has an associated "out" routine which
@@ -163,7 +163,6 @@ static void
 _outQuery(StringInfo str, Query *node)
 {
 	char		buf[500];
-	int i;
 	
 	appendStringInfo(str, "QUERY");
 
@@ -229,12 +228,8 @@ _outQuery(StringInfo str, Query *node)
 	_outNode(str, node->groupClause);
 	appendStringInfo(str, " :havingQual ");
  	_outNode(str, node->havingQual);
-	appendStringInfo(str, " :qry_numAgg ");
-	sprintf(buf, " %d ", node->qry_numAgg);
-	appendStringInfo(str, buf);
-	appendStringInfo(str, " :qry_aggs ");
-	for (i=0; i < node->qry_numAgg; i++)
-	 	_outNode(str, node->qry_aggs[i]);
+	appendStringInfo(str, " :hasAggs ");
+	appendStringInfo(str, (node->hasAggs ? "true" : "false"));
 	appendStringInfo(str, " :unionClause ");
  	_outNode(str, node->unionClause);
 }
@@ -505,14 +500,12 @@ _outSort(StringInfo str, Sort *node)
 static void
 _outAgg(StringInfo str, Agg *node)
 {
-	char		buf[500];
 
 	appendStringInfo(str, "AGG");
 	_outPlanInfo(str, (Plan *) node);
 
-	/* the actual Agg fields */
-	sprintf(buf, " :numagg %d ", node->numAgg);
-	appendStringInfo(str, buf);
+	appendStringInfo(str, " :aggs ");
+	_outNode(str, node->aggs);
 }
 
 static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 65038f8c89410ab4981980fcc888970066bc86bc..574d5c69e2c99028339cacf8c14316e39618ec0f 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.17 1998/01/07 21:03:37 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.18 1998/01/15 18:59:31 momjian Exp $
  *
  * NOTES
  *	  Most of the read functions for plan nodes are tested. (In fact, they
@@ -76,7 +76,6 @@ _readQuery()
 	Query	   *local_node;
 	char	   *token;
 	int			length;
-	int			i;
 	
 	local_node = makeNode(Query);
 
@@ -153,19 +152,9 @@ _readQuery()
 	token = lsptok(NULL, &length);		/* skip :havingQual */
 	local_node->havingQual = nodeRead(true);
 
-	token = lsptok(NULL, &length);		/* skip the :qry_numAgg */
-	token = lsptok(NULL, &length);		/* get qry_numAgg */
-	local_node->qry_numAgg = atoi(token);
-
-	token = lsptok(NULL, &length);		/* skip the :qry_Aggs */
-	if (local_node->qry_numAgg == 0)
-		local_node->qry_aggs = NULL;
-	else
-	{
-		local_node->qry_aggs = palloc(sizeof(Aggreg *) * local_node->qry_numAgg);
-		for (i=0; i < local_node->qry_numAgg; i++)
-			local_node->qry_aggs[i] = nodeRead(true);
-	}
+	token = lsptok(NULL, &length);		/* skip the :hasAggs */
+	token = lsptok(NULL, &length);		/* get hasAggs */
+	local_node->hasAggs = (token[0] == 't') ? true : false;
 
 	token = lsptok(NULL, &length);		/* skip :unionClause */
 	local_node->unionClause = nodeRead(true);
@@ -618,9 +607,8 @@ _readAgg()
 	local_node = makeNode(Agg);
 	_getPlan((Plan *) local_node);
 
-	token = lsptok(NULL, &length);		/* eat :numagg */
-	token = lsptok(NULL, &length);		/* get numagg */
-	local_node->numAgg = atoi(token);
+	token = lsptok(NULL, &length);		/* eat :agg */
+	local_node->aggs = nodeRead(true);	/* now read it */
 
 	return (local_node);
 }
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 3640eabcbccbbfe247e2e783b66b5d5e83c0be97..970a6a5ffb7dd47db93ab44e3c5d16695662f327 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.22 1998/01/07 21:04:01 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.23 1998/01/15 18:59:37 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1106,7 +1106,7 @@ make_material(List *tlist,
 }
 
 Agg		   *
-make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree)
+make_agg(List *tlist, Plan *lefttree)
 {
 	Agg		   *node = makeNode(Agg);
 
@@ -1116,8 +1116,7 @@ make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree)
 	node->plan.targetlist = tlist;
 	node->plan.lefttree = lefttree;
 	node->plan.righttree = (Plan *) NULL;
-	node->numAgg = nagg;
-	node->aggs = aggs;
+	node->aggs = NIL;
 
 	return (node);
 }
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index 69186d82c00234db9d1dcbb3f7babc5158999297..b8b99149ce5a8e0440426b741c21614e2fe0e404 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.15 1998/01/07 21:04:04 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.16 1998/01/15 18:59:44 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,7 +71,7 @@ query_planner(Query *root,
 	List	   *constant_qual = NIL;
 	List	   *var_only_tlist = NIL;
 	List	   *level_tlist = NIL;
-	Plan	   *subplan = (Plan *) NULL;
+	Plan	   *subplan = NULL;
 
 	/*
 	 * A command without a target list or qualification is an error,
@@ -174,20 +174,19 @@ query_planner(Query *root,
 	 */
 	if (constant_qual)
 	{
-		Plan	   *plan;
-
-		plan = (Plan *) make_result(tlist,
-									(Node *) constant_qual,
-									subplan);
+		subplan = (Plan *)make_result((!root->hasAggs && !root->groupClause)
+											? tlist : subplan->targetlist,
+										(Node *) constant_qual,
+										subplan);
 
 		/*
 		 * Change all varno's of the Result's node target list.
 		 */
-		set_result_tlist_references((Result *) plan);
+		if (!root->hasAggs && !root->groupClause)
+			set_tlist_references(subplan);
 
-		return (plan);
+		return subplan;
 	}
-
 	/*
 	 * fix up the flattened target list of the plan root node so that
 	 * expressions are evaluated.  this forces expression evaluations that
@@ -201,12 +200,14 @@ query_planner(Query *root,
 	 * aggregates fixing only other entries (i.e. - GroupBy-ed and so
 	 * fixed by make_groupPlan).	 - vadim 04/05/97
 	 */
-	if (root->groupClause == NULL && root->qry_aggs == NULL)
-	{
-		subplan->targetlist = flatten_tlist_vars(tlist,
+	 else
+	 {
+		if (!root->hasAggs && !root->groupClause)
+			subplan->targetlist = flatten_tlist_vars(tlist,
 												 subplan->targetlist);
-	}
-
+		return subplan;
+	 }
+	 
 #ifdef NOT_USED
 	/*
 	 * Destructively modify the query plan's targetlist to add fjoin lists
@@ -215,7 +216,6 @@ query_planner(Query *root,
 	subplan->targetlist = generate_fjoin(subplan->targetlist);
 #endif
 
-	return (subplan);
 }
 
 /*
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 77419112d7433d871974c08eacbc17be929230da..5643b675f96392f5ba1e97737124bf199346914c 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.20 1998/01/07 21:04:05 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.21 1998/01/15 18:59:48 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -117,7 +117,7 @@ planner(Query *parse)
 	 * If we have a GROUP BY clause, insert a group node (with the
 	 * appropriate sort node.)
 	 */
-	if (parse->groupClause != NULL)
+	if (parse->groupClause)
 	{
 		bool		tuplePerGroup;
 
@@ -127,7 +127,7 @@ planner(Query *parse)
 		 * present. Otherwise, need every tuple from the group to do the
 		 * aggregation.)
 		 */
-		tuplePerGroup = (parse->qry_aggs) ? TRUE : FALSE;
+		tuplePerGroup = parse->hasAggs;
 
 		result_plan =
 			make_groupPlan( &tlist,
@@ -140,22 +140,16 @@ planner(Query *parse)
 	/*
 	 * If aggregate is present, insert the agg node
 	 */
-	if (parse->qry_aggs)
+	if (parse->hasAggs)
 	{
-		result_plan = (Plan *)make_agg(tlist,
-							parse->qry_numAgg,
-							parse->qry_aggs,
-							result_plan);
+		result_plan = (Plan *)make_agg(tlist, result_plan);
 
 		/*
 		 * set the varno/attno entries to the appropriate references to
-		 * the result tuple of the subplans. (We need to set those in the
-		 * array of aggreg's in the Agg node also. Even though they're
-		 * pointers, after a few dozen's of copying, they're not the same
-		 * as those in the target list.)
+		 * the result tuple of the subplans.
 		 */
-		set_agg_tlist_references((Agg *)result_plan);
-		set_agg_agglist_references((Agg *)result_plan);
+		((Agg *)result_plan)->aggs =
+			set_agg_tlist_references((Agg *)result_plan);
 	}
 
 	/*
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 644ff36ee908869b6c893a41dc9b8f4ee12d0fcb..fe80a658f0a1f08838f3ae33723719178937934a 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.14 1998/01/14 19:55:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.15 1998/01/15 18:59:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,7 @@ static Var *replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist)
 static List *tlist_temp_references(Oid tempid, List *tlist);
 static void replace_result_clause(Node *clause, List *subplanTargetList);
 static bool OperandIsInner(Node *opnd, int inner_relid);
-static void replace_agg_clause(Node *expr, List *targetlist);
+static List *replace_agg_clause(Node *expr, List *targetlist);
 static Node *del_agg_clause(Node *clause);
 
 /*****************************************************************************
@@ -536,13 +536,9 @@ set_result_tlist_references(Result *resultNode)
 	 */
 	subplan = ((Plan *) resultNode)->lefttree;
 	if (subplan != NULL)
-	{
 		subplanTargetList = subplan->targetlist;
-	}
 	else
-	{
 		subplanTargetList = NIL;
-	}
 
 	/*
 	 * now for traverse all the entris of the target list. These should be
@@ -695,13 +691,16 @@ OperandIsInner(Node *opnd, int inner_relid)
  *	  changes the target list of an Agg node so that it points to
  *	  the tuples returned by its left tree subplan.
  *
+ *	We now also generate a linked list of Aggreg pointers for Agg.
+ *
  */
-void
+List *
 set_agg_tlist_references(Agg *aggNode)
 {
 	List	   *aggTargetList;
 	List	   *subplanTargetList;
 	List	   *tl;
+	List	   *aggreg_list = NIL;
 
 	aggTargetList = aggNode->plan.targetlist;
 	subplanTargetList = aggNode->plan.lefttree->targetlist;
@@ -710,30 +709,18 @@ set_agg_tlist_references(Agg *aggNode)
 	{
 		TargetEntry *tle = lfirst(tl);
 
-		replace_agg_clause(tle->expr, subplanTargetList);
-	}
-}
-
-void
-set_agg_agglist_references(Agg *aggNode)
-{
-	List	   *subplanTargetList;
-	Aggreg	  **aggs;
-	int			i;
-
-	aggs = aggNode->aggs;
-	subplanTargetList = aggNode->plan.lefttree->targetlist;
-
-	for (i = 0; i < aggNode->numAgg; i++)
-	{
-		replace_agg_clause(aggs[i]->target, subplanTargetList);
+		aggreg_list = nconc(
+			replace_agg_clause(tle->expr, subplanTargetList),aggreg_list);
 	}
+	return aggreg_list;
 }
 
-static void
+static List *
 replace_agg_clause(Node *clause, List *subplanTargetList)
 {
 	List	   *t;
+	List *agg_list = NIL;
+
 	if (IsA(clause, Var))
 	{
 		TargetEntry *subplanVar;
@@ -748,41 +735,51 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
 		 *
 		 */
 		((Var *) clause)->varattno = subplanVar->resdom->resno;
+
+		return NIL;
 	}
 	else if (is_funcclause(clause))
 	{
-
 		/*
 		 * This is a function. Recursively call this routine for its
 		 * arguments...
 		 */
 		foreach(t, ((Expr *) clause)->args)
 		{
-			replace_agg_clause(lfirst(t), subplanTargetList);
+			agg_list = nconc(agg_list,
+				replace_agg_clause(lfirst(t), subplanTargetList));
 		}
+		return agg_list;
 	}
 	else if (IsA(clause, Aggreg))
 	{
-		replace_agg_clause(((Aggreg *) clause)->target, subplanTargetList);
+		return lcons(clause,
+			replace_agg_clause(((Aggreg *) clause)->target, subplanTargetList));
 	}
 	else if (IsA(clause, ArrayRef))
 	{
 		ArrayRef   *aref = (ArrayRef *) clause;
-
+		
 		/*
 		 * This is an arrayref. Recursively call this routine for its
 		 * expression and its index expression...
 		 */
 		foreach(t, aref->refupperindexpr)
 		{
-			replace_agg_clause(lfirst(t), subplanTargetList);
+			agg_list = nconc(agg_list,
+				replace_agg_clause(lfirst(t), subplanTargetList));
 		}
 		foreach(t, aref->reflowerindexpr)
 		{
-			replace_agg_clause(lfirst(t), subplanTargetList);
+			agg_list = nconc(agg_list,
+				replace_agg_clause(lfirst(t), subplanTargetList));
 		}
-		replace_agg_clause(aref->refexpr, subplanTargetList);
-		replace_agg_clause(aref->refassgnexpr, subplanTargetList);
+		agg_list = nconc(agg_list,
+			replace_agg_clause(aref->refexpr, subplanTargetList));
+		agg_list = nconc(agg_list,
+			replace_agg_clause(aref->refassgnexpr, subplanTargetList));
+
+		return agg_list;
 	}
 	else if (is_opclause(clause))
 	{
@@ -792,15 +789,20 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
 		 */
 		Node	   *left = (Node *) get_leftop((Expr *) clause);
 		Node	   *right = (Node *) get_rightop((Expr *) clause);
-
+		
 		if (left != (Node *) NULL)
-			replace_agg_clause(left, subplanTargetList);
+			agg_list = nconc(agg_list,
+				replace_agg_clause(left, subplanTargetList));
 		if (right != (Node *) NULL)
-			replace_agg_clause(right, subplanTargetList);
+			agg_list = nconc(agg_list,
+				replace_agg_clause(right, subplanTargetList));
+
+		return agg_list;
 	}
 	else if (IsA(clause, Param) ||IsA(clause, Const))
 	{
 		/* do nothing! */
+		return NIL;
 	}
 	else
 	{
@@ -809,8 +811,8 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
 		 * Ooops! we can not handle that!
 		 */
 		elog(ERROR, "replace_agg_clause: Can not handle this tlist!\n");
+		return NIL;
 	}
-
 }
 
 /*
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index e942173a74548b6bba658244c4158e2b89bd960d..119e054578f691c94d038bd47af57870fb64b18b 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.17 1997/12/29 04:31:23 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.18 1998/01/15 18:59:53 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,8 +185,7 @@ plan_union_queries(Query *parse)
 		parse->uniqueFlag = NULL;
 
 	parse->havingQual = NULL;
-	parse->qry_numAgg = 0;
-	parse->qry_aggs = NULL;
+	parse->hasAggs = false;
 
 	return (make_append(union_plans,
 						union_rts,
@@ -267,11 +266,9 @@ plan_inherit_query(List *relids,
 		new_root->uniqueFlag = NULL;
 		new_root->sortClause = NULL;
 		new_root->groupClause = NULL;
-		if (new_root->qry_numAgg != 0)
+		if (new_root->hasAggs)
 		{
-			new_root->qry_numAgg = 0;
-			pfree(new_root->qry_aggs);
-			new_root->qry_aggs = NULL;
+			new_root->hasAggs = false;
 			del_agg_tlist_references(new_root->targetList);
 		}
 		fix_parsetree_attnums(rt_index,
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index dcb9eecb5db5cb01420c9b204f24a357e8b0410b..45c5d1406ba9e333bd158dc1d221c840b14b8798 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.64 1998/01/11 03:41:35 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.65 1998/01/15 18:59:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -219,7 +219,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
 	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
 	/* make sure we don't have aggregates in the where clause */
-	if (pstate->p_numAgg > 0)
+	if (pstate->p_hasAggs)
 		parseCheckAggregates(pstate, qry);
 
 	return (Query *) qry;
@@ -334,7 +334,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 										  qry->targetList,
 										  qry->uniqueFlag);
 
-	if (pstate->p_numAgg > 0)
+	if (pstate->p_hasAggs)
 		finalizeAggregates(pstate, qry);
 
 	qry->unionall = stmt->unionall;	/* in child, so unionClause may be false */
@@ -796,8 +796,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
 
 		pstate->p_last_resno = 1;
 		pstate->p_is_rule = true;		/* for expand all */
-		pstate->p_numAgg = 0;
-		pstate->p_aggs = NULL;
+		pstate->p_hasAggs = false;
 
 		lfirst(actions) = transformStmt(pstate, lfirst(actions));
 		actions = lnext(actions);
@@ -853,7 +852,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 											qry->targetList);
 	qry->rtable = pstate->p_rtable;
 
-	if (pstate->p_numAgg > 0)
+	if (pstate->p_hasAggs)
 		finalizeAggregates(pstate, qry);
 
 	qry->unionall = stmt->unionall;	/* in child, so unionClause may be false */
@@ -890,11 +889,11 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 	qry->rtable = pstate->p_rtable;
 	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
-	if (pstate->p_numAgg > 0)
+	if (pstate->p_hasAggs)
 		finalizeAggregates(pstate, qry);
 
 	/* make sure we don't have aggregates in the where clause */
-	if (pstate->p_numAgg > 0)
+	if (pstate->p_hasAggs)
 		parseCheckAggregates(pstate, qry);
 
 	return (Query *) qry;
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index dfaaa991843c50058940a35a758e34f829deb9e1..15413ecb7390873f121612d373ad0c8ebf38a0ba 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.6 1998/01/05 03:32:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.7 1998/01/15 18:59:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,64 +34,17 @@ static bool contain_agg_clause(Node *clause);
 static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
 static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause);
 
-/*
- * AddAggToParseState -
- *	  add the aggregate to the list of unique aggregates in pstate.
- *
- * SIDE EFFECT: aggno in target list entry will be modified
- */
-void
-AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
-{
-	List	   *ag;
-	int			i;
-
-	/*
-	 * see if we have the aggregate already (we only need to record the
-	 * aggregate once)
-	 */
-	i = 0;
-	foreach(ag, pstate->p_aggs)
-	{
-		Aggreg	   *a = lfirst(ag);
-
-		if (!strcmp(a->aggname, aggreg->aggname) &&
-			equal(a->target, aggreg->target))
-		{
-
-			/* fill in the aggno and we're done */
-			aggreg->aggno = i;
-			return;
-		}
-		i++;
-	}
-
-	/* not found, new aggregate */
-	aggreg->aggno = i;
-	pstate->p_numAgg++;
-	pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
-	return;
-}
-
 /*
  * finalizeAggregates -
- *	  fill in qry_aggs from pstate. Also checks to make sure that aggregates
+ *	  fill in hasAggs from pstate. Also checks to make sure that aggregates
  *	  are used in the proper place.
  */
 void
 finalizeAggregates(ParseState *pstate, Query *qry)
 {
-	List	   *l;
-	int			i;
-
 	parseCheckAggregates(pstate, qry);
 
-	qry->qry_numAgg = pstate->p_numAgg;
-	qry->qry_aggs =
-		(Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
-	i = 0;
-	foreach(l, pstate->p_aggs)
-		qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
+	qry->hasAggs = pstate->p_hasAggs;
 }
 
 /*
@@ -240,7 +193,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 {
 	List	   *tl;
 
-	Assert(pstate->p_numAgg > 0);
+	Assert(pstate->p_hasAggs);
 
 	/*
 	 * aggregates never appear in WHERE clauses. (we have to check where
@@ -393,6 +346,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 	if (usenulls)
 		aggreg->usenulls = true;
 
+	pstate->p_hasAggs = true;
+
 	return aggreg;
 }
 
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index be93156e3c12271c1d76b1bae464b21330865ceb..76782fc7ad90f406b7b278bc813b089a8db4de61 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.5 1998/01/05 03:32:28 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.6 1998/01/15 19:00:02 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -221,13 +221,8 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
 									PointerGetDatum(funcname),
 									ObjectIdGetDatum(basetype),
 									0, 0))
-			{
-				Aggreg	   *aggreg = ParseAgg(pstate, funcname, basetype,
+				return (Node *)ParseAgg(pstate, funcname, basetype,
 										fargs, precedence);
-
-				AddAggToParseState(pstate, aggreg);
-				return (Node *) aggreg;
-			}
 		}
 	}
 
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 503e42c8250d82e9e5044a54819d3ec38586da72..04b40041b9df3629817a1298ae80d5fcac75e830 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.5 1998/01/05 03:32:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.6 1998/01/15 19:00:04 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,8 +49,7 @@ make_parsestate(void)
 	pstate = palloc(sizeof(ParseState));
 	pstate->p_last_resno = 1;
 	pstate->p_rtable = NIL;
-	pstate->p_numAgg = 0;
-	pstate->p_aggs = NIL;
+	pstate->p_hasAggs = false;
 	pstate->p_is_insert = false;
 	pstate->p_insert_columns = NIL;
 	pstate->p_is_update = false;
diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c
index 70dc37080e2a5d098accbc08d17d3d5d7fdec8c9..b0557b042e1ed1f782c67749efd9a94cb886e65a 100644
--- a/src/backend/rewrite/locks.c
+++ b/src/backend/rewrite/locks.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.6 1998/01/04 04:31:27 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.7 1998/01/15 19:00:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -95,7 +95,6 @@ thisLockWasTriggered(int varno,
 					 AttrNumber attnum,
 					 Query *parsetree)
 {
-	int i;
 	
 	if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum))
 		return true;
@@ -103,10 +102,6 @@ thisLockWasTriggered(int varno,
 	if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum))
 		return true;
 
-	for(i=0; i < parsetree->qry_numAgg; i++)
-		if (nodeThisLockWasTriggered(parsetree->qry_aggs[i]->target,
-					varno, attnum))
-			return true;
 	return false;
 		
 }
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 122067a2424feb91ef9ca3a877656131b869cfce..cd5f5e16a4d73c365adbfca5e1e515073ae9b1ce 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.9 1998/01/04 04:31:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.10 1998/01/15 19:00:07 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -420,16 +420,12 @@ HandleRIRAttributeRule(Query *parsetree,
 					   int *modified,
 					   int *badsql)
 {
-	int i;
 	
 	nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
 							   targetlist, rt_index, attr_num,
 							   modified, badsql);
 	nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
 							   rt_index, attr_num, modified, badsql);
-	for(i=0; i < parsetree->qry_numAgg; i++)
-		nodeHandleRIRAttributeRule(&parsetree->qry_aggs[i]->target, rtable,
-					targetlist, rt_index, attr_num, modified, badsql);
 }
 
 
@@ -521,13 +517,9 @@ HandleViewRule(Query *parsetree,
 			   int rt_index,
 			   int *modified)
 {
-	int i;
-	
+
 	nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
 					   modified);
 	nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
 					   rt_index, modified);
-	for(i=0; i < parsetree->qry_numAgg; i++)
-		nodeHandleViewRule(&parsetree->qry_aggs[i]->target, rtable, targetlist, rt_index,
-					   modified);
 }
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 65718fc6e16d47f308994ff1a3b0b7266fcc86a7..c56363ddf0c8a80fe679529f742c8afdb174de01 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.43 1998/01/11 03:41:49 momjian Exp $
+ * $Id: parsenodes.h,v 1.44 1998/01/15 19:00:11 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,6 +44,7 @@ typedef struct Query
 	bool		isPortal;		/* is this a retrieve into portal? */
 	bool		isBinary;		/* binary portal? */
 	bool		unionall;		/* union without unique sort */
+	bool		hasAggs;		/* has aggregates in target list */
 	
 	char	   *uniqueFlag;		/* NULL, '*', or Unique attribute name */
 	List	   *sortClause;		/* a list of SortClause's */
@@ -56,9 +57,6 @@ typedef struct Query
 								 * BY */
 	Node	   *havingQual;		/* qualification of each group */
 
-	int			qry_numAgg;		/* number of aggregates in the target list */
-	Aggreg	  **qry_aggs;		/* the aggregates */
-
 	List	   *unionClause;	/* unions are linked under the previous query */
 
 	/* internal to planner */
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 2dc464c2a7af104299a498bca52bc7f9ba707129..871afacbc4b71a91a4c7791c21e4a107df5553b0 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.12 1997/12/27 06:41:41 momjian Exp $
+ * $Id: plannodes.h,v 1.13 1998/01/15 19:00:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -214,8 +214,7 @@ typedef struct HashJoin
 typedef struct Agg
 {
 	Plan		plan;
-	int			numAgg;
-	Aggreg	  **aggs;
+	List 		*aggs;
 	AggState   *aggstate;
 } Agg;
 
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 04363edd03e94627eba276f47f0bb1c42eb8b330..041a48b612ad5b648aabab6b5886d12628d9bb5f 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: planmain.h,v 1.9 1997/12/20 07:59:43 momjian Exp $
+ * $Id: planmain.h,v 1.10 1998/01/15 19:00:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,7 @@ extern SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid,
 			 Plan *lefttree);
 extern Sort *make_sort(List *tlist, Oid tempid, Plan *lefttree,
 		  int keycount);
-extern Agg *make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree);
+extern Agg *make_agg(List *tlist, Plan *lefttree);
 extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp,
 		   AttrNumber *grpColIdx, Sort *lefttree);
 extern Unique *make_unique(List *tlist, Plan *lefttree, char *uniqueAttr);
@@ -55,7 +55,7 @@ extern List *join_references(List *clauses, List *outer_tlist,
 extern List *index_outerjoin_references(List *inner_indxqual,
 						   List *outer_tlist, Index inner_relid);
 extern void set_result_tlist_references(Result *resultNode);
-extern void set_agg_tlist_references(Agg *aggNode);
+extern List *set_agg_tlist_references(Agg *aggNode);
 extern void set_agg_agglist_references(Agg *aggNode);
 extern void del_agg_tlist_references(List *tlist);
 
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index de6b03a1ad01b9e8aeade1ab06532db567c99bbf..be49fe7a0fa421f08130e80e3b49270575c87e06 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.3 1997/11/26 03:43:13 momjian Exp $
+ * $Id: parse_node.h,v 1.4 1998/01/15 19:00:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,10 +30,9 @@ typedef struct ParseState
 {
 	int			p_last_resno;
 	List	   *p_rtable;
-	int			p_numAgg;
-	List	   *p_aggs;
-	bool		p_is_insert;
 	List	   *p_insert_columns;
+	bool		p_hasAggs;
+	bool		p_is_insert;
 	bool		p_is_update;
 	bool		p_is_rule;
 	bool		p_in_where_clause;