diff --git a/doc/src/sgml/ref/create_group.sgml b/doc/src/sgml/ref/create_group.sgml
index a512d2ff12af8bbba0662c7cdd8761d334e35548..97c5700b62a49c320e1048d5a791841d64ab6e0a 100644
--- a/doc/src/sgml/ref/create_group.sgml
+++ b/doc/src/sgml/ref/create_group.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_group.sgml,v 1.2 2000/03/27 17:14:42 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_group.sgml,v 1.3 2001/07/12 18:02:58 tgl Exp $
 Postgres documentation
 -->
 
@@ -23,10 +23,12 @@ Postgres documentation
    <date>2000-01-14</date>
   </refsynopsisdivinfo>
   <synopsis>
-CREATE GROUP <replaceable class="PARAMETER">name</replaceable>
-    [ WITH 
-     [ SYSID <replaceable class="PARAMETER">gid</replaceable> ]
-     [ USER  <replaceable class="PARAMETER">username</replaceable> [, ...] ] ]
+CREATE GROUP <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
+
+where <replaceable class="PARAMETER">option</replaceable> can be:
+
+     SYSID <replaceable class="PARAMETER">gid</replaceable>
+   | USER  <replaceable class="PARAMETER">username</replaceable> [, ...]
   </synopsis>
   
   <refsect2 id="R2-SQL-CREATEGROUP-1">
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index e840b9109f8921e607f3f49424bd2a6229a0434a..47c8dfa4313813b90041ba527988e67a857aff1a 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.78 2001/07/10 22:09:28 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.79 2001/07/12 18:02:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -787,13 +787,47 @@ CreateGroup(CreateGroupStmt *stmt)
 	HeapTuple	tuple;
 	TupleDesc	pg_group_dsc;
 	bool		group_exists = false,
-				sysid_exists = false;
+				sysid_exists = false,
+				havesysid = false;
 	int			max_id = 0;
 	Datum		new_record[Natts_pg_group];
 	char		new_record_nulls[Natts_pg_group];
 	List	   *item,
-			   *newlist = NULL;
+               *option,
+			   *newlist = NIL;
 	ArrayType  *userarray;
+    int			sysid = 0;
+    List	   *userElts = NIL;
+    DefElem    *dsysid = NULL;
+    DefElem    *duserElts = NULL;
+
+	foreach(option, stmt->options)
+	{
+		DefElem *defel = (DefElem *) lfirst(option);
+
+        if (strcasecmp(defel->defname, "sysid") == 0) {
+            if (dsysid)
+                elog(ERROR, "CREATE GROUP: conflicting options");
+            dsysid = defel;
+        }
+        else if (strcasecmp(defel->defname, "userElts") == 0) {
+            if (duserElts)
+                elog(ERROR, "CREATE GROUP: conflicting options");
+            duserElts = defel;
+        }
+        else 
+            elog(ERROR,"CREATE GROUP: option \"%s\" not recognized",
+                 defel->defname);
+    }
+
+    if (dsysid)
+	{
+		sysid = intVal(dsysid->arg);
+		havesysid = true;
+	}
+
+    if (duserElts)
+		userElts = (List *) duserElts->arg;
 
 	/*
 	 * Make sure the user can do this.
@@ -819,8 +853,8 @@ CreateGroup(CreateGroupStmt *stmt)
 		datum = heap_getattr(tuple, Anum_pg_group_grosysid,
 							 pg_group_dsc, &null);
 		Assert(!null);
-		if (stmt->sysid >= 0)	/* customized id wanted */
-			sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
+		if (havesysid)	/* customized id wanted */
+			sysid_exists = (DatumGetInt32(datum) == sysid);
 		else
 		{
 			/* pick 1 + max */
@@ -835,19 +869,19 @@ CreateGroup(CreateGroupStmt *stmt)
 			 stmt->name);
 	if (sysid_exists)
 		elog(ERROR, "CREATE GROUP: group sysid %d is already assigned",
-			 stmt->sysid);
+			 sysid);
 
 	/*
 	 * Translate the given user names to ids
 	 */
-	foreach(item, stmt->initUsers)
+	foreach(item, userElts)
 	{
 		const char *groupuser = strVal(lfirst(item));
 		Value	   *v;
 
 		v = makeInteger(get_usesysid(groupuser));
 		if (!member(v, newlist))
-			newlist = lcons(v, newlist);
+			newlist = lappend(newlist, v);
 	}
 
 	/* build an array to insert */
@@ -872,14 +906,12 @@ CreateGroup(CreateGroupStmt *stmt)
 	/*
 	 * Form a tuple to insert
 	 */
-	if (stmt->sysid >= 0)
-		max_id = stmt->sysid;
-	else
-		max_id++;
+	if (!havesysid)
+		sysid = max_id + 1;
 
 	new_record[Anum_pg_group_groname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
-	new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(max_id);
+	new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(sysid);
 	new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(userarray);
 
 	new_record_nulls[Anum_pg_group_groname - 1] = ' ';
@@ -952,7 +984,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 		char		new_record_nulls[Natts_pg_group];
 		ArrayType  *newarray,
 				   *oldarray;
-		List	   *newlist = NULL,
+		List	   *newlist = NIL,
 				   *item;
 		HeapTuple	tuple;
 		bool		null = false;
@@ -976,7 +1008,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 				v = makeInteger(arrval);
 				/* filter out duplicates */
 				if (!member(v, newlist))
-					newlist = lcons(v, newlist);
+					newlist = lappend(newlist, v);
 			}
 
 		/*
@@ -1007,7 +1039,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 			}
 
 			if (!member(v, newlist))
-				newlist = lcons(v, newlist);
+				newlist = lappend(newlist, v);
 			else
 				/*
 				 * we silently assume here that this error will only come
@@ -1074,7 +1106,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 			char		new_record_nulls[Natts_pg_group];
 			ArrayType  *oldarray,
 					   *newarray;
-			List	   *newlist = NULL,
+			List	   *newlist = NIL,
 					   *item;
 			int			i;
 
@@ -1094,7 +1126,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 				v = makeInteger(arrval);
 				/* filter out duplicates */
 				if (!member(v, newlist))
-					newlist = lcons(v, newlist);
+					newlist = lappend(newlist, v);
 			}
 
 			/*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 1768b881750a31c2a27950e6c81209809d547f9e..cd35fdeedf42232a08884af0a950187ed45cbd80 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.146 2001/07/10 22:09:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.147 2001/07/12 18:02:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2462,8 +2462,7 @@ _copyCreateGroupStmt(CreateGroupStmt *from)
 
 	if (from->name)
 		newnode->name = pstrdup(from->name);
-	newnode->sysid = from->sysid;
-	Node_Copy(from, newnode, initUsers);
+	Node_Copy(from, newnode, options);
 
 	return newnode;
 }
@@ -2476,7 +2475,6 @@ _copyAlterGroupStmt(AlterGroupStmt *from)
 	if (from->name)
 		newnode->name = pstrdup(from->name);
 	newnode->action = from->action;
-	newnode->sysid = from->sysid;
 	Node_Copy(from, newnode, listUsers);
 
 	return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b6a34e5f2f5fc27584ce66c6e12039018a1af291..6bc088577ce3c0c80755cad0b6a229ece14a6831 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.94 2001/07/10 22:09:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.95 2001/07/12 18:02:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1320,9 +1320,7 @@ _equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b)
 {
 	if (!equalstr(a->name, b->name))
 		return false;
-	if (a->sysid != b->sysid)
-		return false;
-	if (!equal(a->initUsers, b->initUsers))
+	if (!equal(a->options, b->options))
 		return false;
 
 	return true;
@@ -1335,8 +1333,6 @@ _equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b)
 		return false;
 	if (a->action != b->action)
 		return false;
-	if (a->sysid != b->sysid)
-		return false;
 	if (!equal(a->listUsers, b->listUsers))
 		return false;
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 20784ac1705f2d4add06ce800bca0364ac77071e..b83ca3783fd9a17c9f68d4bc4735b6bbb9ff6084 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.235 2001/07/10 22:09:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.236 2001/07/12 18:02:59 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -155,7 +155,10 @@ static void doNegateFloat(Value *v);
 %type <ival>	opt_lock, lock_type
 %type <boolean>	opt_force
 
-%type <list>	user_list, users_in_new_group_clause
+%type <list>	user_list
+
+%type <list>	OptGroupList
+%type <defelt>	OptGroupElem
 
 %type <list>	OptUserList
 %type <defelt>	OptUserElem
@@ -489,19 +492,19 @@ stmt :	AlterSchemaStmt
  *****************************************************************************/
 
 CreateUserStmt:  CREATE USER UserId OptUserList 
-				{
+				  {
 					CreateUserStmt *n = makeNode(CreateUserStmt);
 					n->user = $3;
 					n->options = $4;
 					$$ = (Node *)n;
-				}
-                | CREATE USER UserId WITH OptUserList
-               {
+				  }
+                 | CREATE USER UserId WITH OptUserList
+                  {
 					CreateUserStmt *n = makeNode(CreateUserStmt);
 					n->user = $3;
 					n->options = $5;
 					$$ = (Node *)n;
-               }                   
+                  }                   
 		;
 
 /*****************************************************************************
@@ -512,19 +515,19 @@ CreateUserStmt:  CREATE USER UserId OptUserList
  *****************************************************************************/
 
 AlterUserStmt:  ALTER USER UserId OptUserList
-				{
+				 {
 					AlterUserStmt *n = makeNode(AlterUserStmt);
 					n->user = $3;
 					n->options = $4;
 					$$ = (Node *)n;
-				}
-			| ALTER USER UserId WITH OptUserList
-				{
+				 }
+			    | ALTER USER UserId WITH OptUserList
+				 {
 					AlterUserStmt *n = makeNode(AlterUserStmt);
 					n->user = $3;
 					n->options = $5;
 					$$ = (Node *)n;
-				}
+				 }
 		;
 
 /*****************************************************************************
@@ -618,35 +621,43 @@ user_list:  user_list ',' UserId
  *
  *****************************************************************************/
 
-CreateGroupStmt:  CREATE GROUP UserId 
-				{
+CreateGroupStmt:  CREATE GROUP UserId OptGroupList
+				   {
 					CreateGroupStmt *n = makeNode(CreateGroupStmt);
 					n->name = $3;
-					n->sysid = -1;
-					n->initUsers = NIL;
+					n->options = $4;
 					$$ = (Node *)n;
-				}
-			| CREATE GROUP UserId WITH users_in_new_group_clause
-				{
+				   }
+			      | CREATE GROUP UserId WITH OptGroupList
+				   {
 					CreateGroupStmt *n = makeNode(CreateGroupStmt);
 					n->name = $3;
-					n->sysid = -1;
-					n->initUsers = $5;
+					n->options = $5;
 					$$ = (Node *)n;
+				   }
+		;
+
+/*
+ * Options for CREATE GROUP
+ */
+OptGroupList: OptGroupList OptGroupElem		{ $$ = lappend($1, $2); }
+			| /* EMPTY */					{ $$ = NIL; }
+		;
+
+OptGroupElem:  USER user_list
+                { 
+				  $$ = makeNode(DefElem);
+				  $$->defname = "userElts";
+				  $$->arg = (Node *)$2;
 				}
-			| CREATE GROUP UserId WITH SYSID Iconst users_in_new_group_clause
+               | SYSID Iconst
 				{
-					CreateGroupStmt *n = makeNode(CreateGroupStmt);
-					n->name = $3;
-					n->sysid = $6;
-					n->initUsers = $7;
-					$$ = (Node *)n;
+				  $$ = makeNode(DefElem);
+				  $$->defname = "sysid";
+				  $$->arg = (Node *)makeInteger($2);
 				}
-		;
+        ;
 
-users_in_new_group_clause:  USER user_list		{ $$ = $2; }
-			| /* EMPTY */						{ $$ = NIL; }
-		;                         
 
 /*****************************************************************************
  *
@@ -659,7 +670,6 @@ AlterGroupStmt:  ALTER GROUP UserId ADD USER user_list
 				{
 					AlterGroupStmt *n = makeNode(AlterGroupStmt);
 					n->name = $3;
-					n->sysid = -1;
 					n->action = +1;
 					n->listUsers = $6;
 					$$ = (Node *)n;
@@ -668,13 +678,13 @@ AlterGroupStmt:  ALTER GROUP UserId ADD USER user_list
 				{
 					AlterGroupStmt *n = makeNode(AlterGroupStmt);
 					n->name = $3;
-					n->sysid = -1;
 					n->action = -1;
 					n->listUsers = $6;
 					$$ = (Node *)n;
 				}
 			;
 
+
 /*****************************************************************************
  *
  * Drop a postgresql group
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 0e3bd2e4608070bce50a55e9d624cef1b26fb3e3..73fab4f9525b8ebea9d7ec42655a032affc1e1f6 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.134 2001/07/10 22:09:29 tgl Exp $
+ * $Id: parsenodes.h,v 1.135 2001/07/12 18:03:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -365,8 +365,7 @@ typedef struct CreateGroupStmt
 {
 	NodeTag		type;
 	char	   *name;			/* name of the new group */
-	int			sysid;			/* group id (-1 if pick default) */
-	List	   *initUsers;		/* list of initial users */
+	List	   *options;		/* List of DefElem nodes */
 } CreateGroupStmt;
 
 typedef struct AlterGroupStmt
@@ -374,7 +373,6 @@ typedef struct AlterGroupStmt
 	NodeTag		type;
 	char	   *name;			/* name of group to alter */
 	int			action;			/* +1 = add, -1 = drop user */
-	int			sysid;			/* sysid change */
 	List	   *listUsers;		/* list of users to add/drop */
 } AlterGroupStmt;
 
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 41455566be07acf6418789a3a3dc198fd90a31e4..902b17741219261268b1fd243e9bd995dd6327fd 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -331,7 +331,7 @@ make_name(void)
 %type  <str>    select_clause opt_select_limit select_limit_value ConstraintTimeSpec
 %type  <str>    select_offset_value ReindexStmt join_type opt_boolean
 %type  <str>	join_qual update_list AlterSchemaStmt joined_table
-%type  <str>	opt_level opt_lock lock_type users_in_new_group_clause
+%type  <str>	opt_level opt_lock lock_type OptGroupList OptGroupElem
 %type  <str>    OptConstrFromTable comment_op OptTempTableName StringConst
 %type  <str>    constraints_set_list constraints_set_namelist comment_fn
 %type  <str>	constraints_set_mode comment_type comment_cl comment_ag
@@ -691,23 +691,32 @@ user_list:  user_list ',' UserId
  *
  *
  ****************************************************************************/
-CreateGroupStmt: CREATE GROUP UserId
+CreateGroupStmt:  CREATE GROUP UserId OptGroupList
 				{
-					$$ = cat2_str(make_str("create group"), $3);
+					$$ = cat_str(3, make_str("create group"), $3, $4);
 				}
-			| CREATE GROUP UserId WITH users_in_new_group_clause
+			| CREATE GROUP UserId WITH OptGroupList
 				{
 					$$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5);
 				}
-			| CREATE GROUP UserId WITH SYSID Iconst users_in_new_group_clause
+		;
+
+/*
+ * Options for CREATE GROUP
+ */
+OptGroupList: OptGroupList OptGroupElem		{ $$ = cat2_str($1, $2); }
+			| /* EMPTY */					{ $$ = EMPTY; }
+		;
+
+OptGroupElem:  USER user_list
+                { 
+					$$ = cat2_str(make_str("user"), $2);
+				}
+               | SYSID Iconst
 				{
-					$$ = cat_str(5, make_str("create group"), $3, make_str("with sysid"), $6, $7);
+					$$ = cat2_str(make_str("sysid"), $2);
 				}
-			;
-
-users_in_new_group_clause:  USER user_list   { $$ = cat2_str(make_str("user"), $2); }
-                            | /* EMPTY */          { $$ = EMPTY; }
-               ;
+        ;
 
 
 /*****************************************************************************