diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 8aea35692777dfabc5448f0dca37ac253ea7afc1..d806ec2059c0709a6015c97f1dce4e95a2c5de2b 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.62 1998/01/09 20:05:49 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.63 1998/01/10 04:29:47 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,7 +39,7 @@ static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
-static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
+static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
 
 List   *extras = NIL;
@@ -175,12 +175,11 @@ transformStmt(ParseState *pstate, Node *parseTree)
 			result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
 			break;
 
-		case T_CursorStmt:
-			result = transformCursorStmt(pstate, (CursorStmt *) parseTree);
-			break;
-
 		case T_SelectStmt:
-			result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
+			if (!((SelectStmt *)parseTree)->portalname)
+				result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
+			else
+				result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
 			break;
 
 		default:
@@ -873,6 +872,9 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 	qry->rtable = pstate->p_rtable;
 	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
+	if (pstate->p_numAgg > 0)
+		finalizeAggregates(pstate, qry);
+
 	/* make sure we don't have aggregates in the where clause */
 	if (pstate->p_numAgg > 0)
 		parseCheckAggregates(pstate, qry);
@@ -886,47 +888,15 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
  *
  */
 static Query *
-transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
+transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
 {
-	Query	   *qry = makeNode(Query);
-
-	/*
-	 * in the old days, a cursor statement is a 'retrieve into portal'; If
-	 * you change the following, make sure you also go through the code in
-	 * various places that tests the kind of operation.
-	 */
-	qry->commandType = CMD_SELECT;
+	Query	   *qry;
 
-	/* set up a range table */
-	makeRangeTable(pstate, NULL, stmt->fromClause);
-
-	qry->uniqueFlag = stmt->unique;
+	qry = transformSelectStmt(pstate, stmt);
 
 	qry->into = stmt->portalname;
 	qry->isPortal = TRUE;
 	qry->isBinary = stmt->binary;		/* internal portal */
 
-	/* fix the target list */
-	qry->targetList = transformTargetList(pstate, stmt->targetList);
-
-	/* fix where clause */
-	qry->qual = transformWhereClause(pstate, stmt->whereClause);
-
-	/* fix order clause */
-	qry->sortClause = transformSortClause(pstate,
-										  stmt->sortClause,
-										  NIL,
-										  qry->targetList,
-										  qry->uniqueFlag);
-	/* fix group by clause */
-	qry->groupClause = transformGroupClause(pstate,
-											stmt->groupClause,
-											qry->targetList);
-
-	qry->rtable = pstate->p_rtable;
-
-	if (pstate->p_numAgg > 0)
-		finalizeAggregates(pstate, qry);
-
-	return (Query *) qry;
+	return qry;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1d9d59e95b248fd844bf0fe42e034e1ebe37f801..d79fa91bd424664fd5b7bbb38f2c64e76bfc8c62 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.87 1998/01/09 21:26:12 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.88 1998/01/10 04:29:50 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -2226,12 +2226,13 @@ UpdateStmt:  UPDATE relation_name
  *				CURSOR STATEMENTS
  *
  *****************************************************************************/
-
 CursorStmt:  DECLARE name opt_binary CURSOR FOR
-			 SELECT opt_unique res_target_list2
-			 from_clause where_clause group_clause sort_clause
+ 			 SELECT opt_unique res_target_list2
+			 from_clause where_clause
+			 group_clause having_clause
+			 union_clause sort_clause
 				{
-					CursorStmt *n = makeNode(CursorStmt);
+					SelectStmt *n = makeNode(SelectStmt);
 
 					/* from PORTAL name */
 					/*
@@ -2251,7 +2252,9 @@ CursorStmt:  DECLARE name opt_binary CURSOR FOR
 					n->fromClause = $9;
 					n->whereClause = $10;
 					n->groupClause = $11;
-					n->sortClause = $12;
+					n->havingClause = $12;
+					n->unionClause = $13;
+					n->sortClause = $14;
 					$$ = (Node *)n;
 				}
 		;
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index d6d787c93a7dc7aacebea5ef49d3773662b01382..3f87ca202ace52d3baec271219cd84fb05428da8 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.21 1998/01/09 21:13:43 momjian Exp $
+ * $Id: nodes.h,v 1.22 1998/01/10 04:30:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -145,7 +145,6 @@ typedef enum NodeTag
 	T_InsertStmt,
 	T_DeleteStmt,
 	T_UpdateStmt,
-	T_CursorStmt,
 	T_SelectStmt,
 	T_AddAttrStmt,
 	T_AggregateStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index f898880f6de9c5f4a70972033fc7c5add524a230..9bc99568573656b173613e30c3c3e6857bea6a5e 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.41 1998/01/09 20:06:08 momjian Exp $
+ * $Id: parsenodes.h,v 1.42 1998/01/10 04:30:11 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -604,23 +604,6 @@ typedef struct UpdateStmt
 	List	   *fromClause;		/* the from clause */
 } UpdateStmt;
 
-/* ----------------------
- *		Create Cursor Statement
- * ----------------------
- */
-typedef struct CursorStmt
-{
-	NodeTag		type;
-	char	   *portalname;		/* the portal (cursor) to create */
-	bool		binary;			/* a binary (internal) portal? */
-	char	   *unique;			/* NULL, "*", or unique attribute name */
-	List	   *targetList;		/* the target list (of ResTarget) */
-	List	   *fromClause;		/* the from clause */
-	Node	   *whereClause;	/* qualifications */
-	List	   *groupClause;	/* group by clause */
-	List	   *sortClause;		/* sort clause (a list of SortGroupBy's) */
-} CursorStmt;
-
 /* ----------------------
  *		Select Statement
  * ----------------------
@@ -637,6 +620,8 @@ typedef struct SelectStmt
 	Node	   *havingClause;	/* having conditional-expression */
 	List	   *unionClause;	/* union subselect parameters */
 	List	   *sortClause;		/* sort clause (a list of SortGroupBy's) */
+	char	   *portalname;		/* the portal (cursor) to create */
+	bool		binary;			/* a binary (internal) portal? */
 	bool		unionall;		/* union without unique sort */
 } SelectStmt;