From 3284758a17b23a7d475171b21f72dec7134e89be Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 12 Jul 2001 18:03:00 +0000 Subject: [PATCH] Remove grammar restrictions on order of optional clauses in CREATE GROUP. From Vince Vielhaber. --- doc/src/sgml/ref/create_group.sgml | 12 ++-- src/backend/commands/user.c | 68 +++++++++++++++++------ src/backend/nodes/copyfuncs.c | 6 +- src/backend/nodes/equalfuncs.c | 8 +-- src/backend/parser/gram.y | 80 +++++++++++++++------------ src/include/nodes/parsenodes.h | 6 +- src/interfaces/ecpg/preproc/preproc.y | 33 +++++++---- 7 files changed, 129 insertions(+), 84 deletions(-) diff --git a/doc/src/sgml/ref/create_group.sgml b/doc/src/sgml/ref/create_group.sgml index a512d2ff12..97c5700b62 100644 --- a/doc/src/sgml/ref/create_group.sgml +++ b/doc/src/sgml/ref/create_group.sgml @@ -1,5 +1,5 @@ @@ -23,10 +23,12 @@ Postgres documentation 2000-01-14 -CREATE GROUP name - [ WITH - [ SYSID gid ] - [ USER username [, ...] ] ] +CREATE GROUP name [ [ WITH ] option [ ... ] ] + +where option can be: + + SYSID gid + | USER username [, ...] diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index e840b9109f..47c8dfa431 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 1768b88175..cd35fdeedf 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 b6a34e5f2f..6bc088577c 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 20784ac170..b83ca3783f 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 opt_lock, lock_type %type opt_force -%type user_list, users_in_new_group_clause +%type user_list + +%type OptGroupList +%type OptGroupElem %type OptUserList %type 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; - } - | CREATE GROUP UserId WITH SYSID Iconst users_in_new_group_clause - { - CreateGroupStmt *n = makeNode(CreateGroupStmt); - n->name = $3; - n->sysid = $6; - n->initUsers = $7; - $$ = (Node *)n; - } + } ; -users_in_new_group_clause: USER user_list { $$ = $2; } - | /* EMPTY */ { $$ = NIL; } - ; +/* + * Options for CREATE GROUP + */ +OptGroupList: OptGroupList OptGroupElem { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } + ; + +OptGroupElem: USER user_list + { + $$ = makeNode(DefElem); + $$->defname = "userElts"; + $$->arg = (Node *)$2; + } + | SYSID Iconst + { + $$ = makeNode(DefElem); + $$->defname = "sysid"; + $$->arg = (Node *)makeInteger($2); + } + ; + /***************************************************************************** * @@ -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 0e3bd2e460..73fab4f952 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 41455566be..902b177412 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -331,7 +331,7 @@ make_name(void) %type select_clause opt_select_limit select_limit_value ConstraintTimeSpec %type select_offset_value ReindexStmt join_type opt_boolean %type join_qual update_list AlterSchemaStmt joined_table -%type opt_level opt_lock lock_type users_in_new_group_clause +%type opt_level opt_lock lock_type OptGroupList OptGroupElem %type OptConstrFromTable comment_op OptTempTableName StringConst %type constraints_set_list constraints_set_namelist comment_fn %type 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 - { - $$ = cat_str(5, make_str("create group"), $3, make_str("with sysid"), $6, $7); - } - ; + ; -users_in_new_group_clause: USER user_list { $$ = cat2_str(make_str("user"), $2); } - | /* EMPTY */ { $$ = EMPTY; } - ; +/* + * 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 + { + $$ = cat2_str(make_str("sysid"), $2); + } + ; /*****************************************************************************