diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 59e1e0c20441e616d864bd808da4e3a65a59d3be..fa733e2da09f12b6a0337403b276ca982e0b1508 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -13,7 +13,7 @@
  *	  columns. (ie. tuples from the same group are consecutive)
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.16 1998/02/10 16:02:58 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.17 1998/02/18 12:40:43 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,7 +31,7 @@
 static TupleTableSlot *ExecGroupEveryTuple(Group *node);
 static TupleTableSlot *ExecGroupOneTuple(Group *node);
 static bool
-sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot,
+sameGroup(HeapTuple oldslot, HeapTuple newslot,
 		  int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc);
 
 /* ---------------------------------------
@@ -71,8 +71,8 @@ ExecGroupEveryTuple(Group *node)
 	ExprContext *econtext;
 
 	HeapTuple	outerTuple = NULL;
-	TupleTableSlot *outerslot,
-			   *lastslot;
+	HeapTuple	firsttuple;
+	TupleTableSlot *outerslot;
 	ProjectionInfo *projInfo;
 	TupleTableSlot *resultSlot;
 
@@ -90,18 +90,14 @@ ExecGroupEveryTuple(Group *node)
 
 	econtext = grpstate->csstate.cstate.cs_ExprContext;
 
-	if (grpstate->grp_useLastTuple)
+	/* if we haven't returned first tuple of new group yet ... */
+	if (grpstate->grp_useFirstTuple)
 	{
+		grpstate->grp_useFirstTuple = FALSE;
 
-		/*
-		 * we haven't returned last tuple yet because it is not of the
-		 * same group
-		 */
-		grpstate->grp_useLastTuple = FALSE;
-
-		ExecStoreTuple(grpstate->grp_lastSlot->val,
+		ExecStoreTuple(grpstate->grp_firstTuple,
 					   grpstate->csstate.css_ScanTupleSlot,
-					   grpstate->grp_lastSlot->ttc_buffer,
+					   InvalidBuffer,
 					   false);
 	}
 	else
@@ -115,29 +111,28 @@ ExecGroupEveryTuple(Group *node)
 			return NULL;
 		}
 
-		/* ----------------
-		 *	Compare with last tuple and see if this tuple is of
-		 *	the same group.
-		 * ----------------
-		 */
-		lastslot = grpstate->csstate.css_ScanTupleSlot;
-
-		if (lastslot->val != NULL &&
-			(!sameGroup(lastslot, outerslot,
-						node->numCols, node->grpColIdx,
-						ExecGetScanType(&grpstate->csstate))))
+		firsttuple = grpstate->grp_firstTuple;
+		/* this should occur on the first call only */
+		if (firsttuple == NULL)	
+		{
+			grpstate->grp_firstTuple = heap_copytuple (outerTuple);
+		}
+		else
 		{
-/*						ExecGetResultType(&grpstate->csstate.cstate)))) {*/
-
-			grpstate->grp_useLastTuple = TRUE;
-
-			/* save it for next time */
-			grpstate->grp_lastSlot = outerslot;
-
 			/*
-			 * signifies the end of the group
+			 *	Compare with first tuple and see if this tuple is of
+			 *	the same group.
 			 */
-			return NULL;
+			if (!sameGroup(firsttuple, outerslot->val,
+						node->numCols, node->grpColIdx,
+						ExecGetScanType(&grpstate->csstate)))
+			{
+				grpstate->grp_useFirstTuple = TRUE;
+				pfree (firsttuple);
+				grpstate->grp_firstTuple = heap_copytuple (outerTuple);
+				
+				return NULL;	/* signifies the end of the group */
+			}
 		}
 
 		ExecStoreTuple(outerTuple,
@@ -172,8 +167,8 @@ ExecGroupOneTuple(Group *node)
 	ExprContext *econtext;
 
 	HeapTuple	outerTuple = NULL;
-	TupleTableSlot *outerslot,
-			   *lastslot;
+	HeapTuple	firsttuple;
+	TupleTableSlot *outerslot;
 	ProjectionInfo *projInfo;
 	TupleTableSlot *resultSlot;
 
@@ -191,15 +186,9 @@ ExecGroupOneTuple(Group *node)
 
 	econtext = node->grpstate->csstate.cstate.cs_ExprContext;
 
-	if (grpstate->grp_useLastTuple)
-	{
-		grpstate->grp_useLastTuple = FALSE;
-		ExecStoreTuple(grpstate->grp_lastSlot->val,
-					   grpstate->csstate.css_ScanTupleSlot,
-					   grpstate->grp_lastSlot->ttc_buffer,
-					   false);
-	}
-	else
+	firsttuple = grpstate->grp_firstTuple;
+	/* this should occur on the first call only */
+	if (firsttuple == NULL)	
 	{
 		outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
 		if (outerslot)
@@ -209,12 +198,8 @@ ExecGroupOneTuple(Group *node)
 			grpstate->grp_done = TRUE;
 			return NULL;
 		}
-		ExecStoreTuple(outerTuple,
-					   grpstate->csstate.css_ScanTupleSlot,
-					   outerslot->ttc_buffer,
-					   false);
+		grpstate->grp_firstTuple = firsttuple = heap_copytuple (outerTuple);
 	}
-	lastslot = grpstate->csstate.css_ScanTupleSlot;
 
 	/*
 	 * find all tuples that belong to a group
@@ -225,49 +210,21 @@ ExecGroupOneTuple(Group *node)
 		outerTuple = (outerslot) ? outerslot->val : NULL;
 		if (!HeapTupleIsValid(outerTuple))
 		{
-
-			/*
-			 * we have at least one tuple (lastslot) if we reach here
-			 */
 			grpstate->grp_done = TRUE;
-
-			/* return lastslot */
 			break;
 		}
 
 		/* ----------------
-		 *	Compare with last tuple and see if this tuple is of
+		 *	Compare with first tuple and see if this tuple is of
 		 *	the same group.
 		 * ----------------
 		 */
-		if ((!sameGroup(lastslot, outerslot,
+		if ((!sameGroup(firsttuple, outerslot->val,
 						node->numCols, node->grpColIdx,
 						ExecGetScanType(&grpstate->csstate))))
-		{
-/*						ExecGetResultType(&grpstate->csstate.cstate)))) {*/
-
-			grpstate->grp_useLastTuple = TRUE;
-
-			/* save it for next time */
-			grpstate->grp_lastSlot = outerslot;
-
-			/* return lastslot */
 			break;
-		}
-
-		ExecStoreTuple(outerTuple,
-					   grpstate->csstate.css_ScanTupleSlot,
-					   outerslot->ttc_buffer,
-					   false);
-
-		lastslot = grpstate->csstate.css_ScanTupleSlot;
 	}
 
-	ExecStoreTuple(lastslot->val,
-				   grpstate->csstate.css_ScanTupleSlot,
-				   lastslot->ttc_buffer,
-				   false);
-
 	/* ----------------
 	 *	form a projection tuple, store it in the result tuple
 	 *	slot and return it.
@@ -275,8 +232,19 @@ ExecGroupOneTuple(Group *node)
 	 */
 	projInfo = grpstate->csstate.cstate.cs_ProjInfo;
 
-	econtext->ecxt_scantuple = lastslot;
+	ExecStoreTuple(firsttuple,
+				   grpstate->csstate.css_ScanTupleSlot,
+				   InvalidBuffer,
+				   false);
+	econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
 	resultSlot = ExecProject(projInfo, &isDone);
+	
+	/* save outerTuple if we are not done yet */
+	if (!grpstate->grp_done)
+	{
+		pfree (firsttuple);
+		grpstate->grp_firstTuple = heap_copytuple (outerTuple);
+	}
 
 	return resultSlot;
 }
@@ -304,7 +272,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
 	 */
 	grpstate = makeNode(GroupState);
 	node->grpstate = grpstate;
-	grpstate->grp_useLastTuple = FALSE;
+	grpstate->grp_useFirstTuple = FALSE;
 	grpstate->grp_done = FALSE;
 
 	/*
@@ -370,6 +338,11 @@ ExecEndGroup(Group *node)
 
 	/* clean up tuple table */
 	ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
+	if (grpstate->grp_firstTuple != NULL)
+	{
+		pfree (grpstate->grp_firstTuple);
+		grpstate->grp_firstTuple = NULL;
+	}
 }
 
 /*****************************************************************************
@@ -380,8 +353,8 @@ ExecEndGroup(Group *node)
  * code swiped from nodeUnique.c
  */
 static bool
-sameGroup(TupleTableSlot *oldslot,
-		  TupleTableSlot *newslot,
+sameGroup(HeapTuple oldtuple,
+		  HeapTuple newtuple,
 		  int numCols,
 		  AttrNumber *grpColIdx,
 		  TupleDesc tupdesc)
@@ -401,12 +374,12 @@ sameGroup(TupleTableSlot *oldslot,
 		att = grpColIdx[i];
 		typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
 
-		attr1 = heap_getattr(oldslot->val,
+		attr1 = heap_getattr(oldtuple,
 							 att,
 							 tupdesc,
 							 &isNull1);
 
-		attr2 = heap_getattr(newslot->val,
+		attr2 = heap_getattr(newtuple,
 							 att,
 							 tupdesc,
 							 &isNull2);
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c
index abdf44bc89071bb40de7c1e44b9f296ba1d85607..ddeae78904d9106bf226dc28664816e44ae556e5 100644
--- a/src/backend/executor/nodeUnique.c
+++ b/src/backend/executor/nodeUnique.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.14 1998/02/10 16:03:03 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.15 1998/02/18 12:40:44 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -208,9 +208,14 @@ ExecUnique(Unique *node)
 				 * use strcmp for comparison
 				 */
 				if (strcmp(val1, val2) == 0)	/* they are equal */
+				{
+					pfree (val1);
+					pfree (val2);
 					continue;
-				else
-					break;
+				}
+				pfree (val1);
+				pfree (val2);
+				break;
 			}
 			else
 /* one is null and the other isn't, they aren't equal */