diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-07-10 22:09:29 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-07-10 22:09:29 +0000 |
commit | 320b6db09080ec0b6c4ed63e808bdb58f68a6bb0 (patch) | |
tree | 1b95f71aab133cc1387520905daa83500a7ed4b6 /src | |
parent | 21d73aa2113374db4770b6c06df479eb146c5d44 (diff) | |
download | postgresql-320b6db09080ec0b6c4ed63e808bdb58f68a6bb0.tar.gz postgresql-320b6db09080ec0b6c4ed63e808bdb58f68a6bb0.zip |
Changes from Vince Vielhaber to allow the optional clauses of CREATE
USER and ALTER USER to appear in any order, not only the fixed order
they used to be required to appear in.
Also, some changes from Tom Lane to create a FULL option for VACUUM;
it doesn't do anything yet, but I needed to change many of the same
files to make that happen, so now seemed like a good time.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/user.c | 223 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 19 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 24 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 179 | ||||
-rw-r--r-- | src/bin/scripts/vacuumdb | 11 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 19 | ||||
-rw-r--r-- | src/interfaces/ecpg/preproc/preproc.y | 144 |
7 files changed, 368 insertions, 251 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 3d003616c09..e840b9109f8 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.77 2001/06/14 01:09:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.78 2001/07/10 22:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -197,14 +197,80 @@ CreateUser(CreateUserStmt *stmt) char new_record_nulls[Natts_pg_shadow]; bool user_exists = false, sysid_exists = false, - havesysid; + havesysid = false; int max_id = -1; - List *item; - - havesysid = stmt->sysid > 0; + List *item, *option; + char *password = NULL; /* PostgreSQL user password */ + int sysid = 0; /* PgSQL system id (valid if havesysid) */ + bool createdb = false; /* Can the user create databases? */ + bool createuser = false; /* Can this user create users? */ + List *groupElts = NIL; /* The groups the user is a member of */ + char *validUntil = NULL; /* The time the login is valid until */ + DefElem *dpassword = NULL; + DefElem *dsysid = NULL; + DefElem *dcreatedb = NULL; + DefElem *dcreateuser = NULL; + DefElem *dgroupElts = NULL; + DefElem *dvalidUntil = NULL; + + /* Extract options from the statement node tree */ + foreach(option, stmt->options) + { + DefElem *defel = (DefElem *) lfirst(option); + + if (strcasecmp(defel->defname, "password") == 0) { + if (dpassword) + elog(ERROR, "CREATE USER: conflicting options"); + dpassword = defel; + } + else if (strcasecmp(defel->defname, "sysid") == 0) { + if (dsysid) + elog(ERROR, "CREATE USER: conflicting options"); + dsysid = defel; + } + else if (strcasecmp(defel->defname, "createdb") == 0) { + if (dcreatedb) + elog(ERROR, "CREATE USER: conflicting options"); + dcreatedb = defel; + } + else if (strcasecmp(defel->defname, "createuser") == 0) { + if (dcreateuser) + elog(ERROR, "CREATE USER: conflicting options"); + dcreateuser = defel; + } + else if (strcasecmp(defel->defname, "groupElts") == 0) { + if (dgroupElts) + elog(ERROR, "CREATE USER: conflicting options"); + dgroupElts = defel; + } + else if (strcasecmp(defel->defname, "validUntil") == 0) { + if (dvalidUntil) + elog(ERROR, "CREATE USER: conflicting options"); + dvalidUntil = defel; + } + else + elog(ERROR,"CREATE USER: option \"%s\" not recognized", + defel->defname); + } + + if (dcreatedb) + createdb = intVal(dcreatedb->arg) != 0; + if (dcreateuser) + createuser = intVal(dcreateuser->arg) != 0; + if (dsysid) + { + sysid = intVal(dsysid->arg); + havesysid = true; + } + if (dvalidUntil) + validUntil = strVal(dvalidUntil->arg); + if (dpassword) + password = strVal(dpassword->arg); + if (dgroupElts) + groupElts = (List *) dgroupElts->arg; /* Check some permissions first */ - if (stmt->password) + if (password) CheckPgUserAclNotNull(); if (!superuser()) @@ -235,7 +301,7 @@ CreateUser(CreateUserStmt *stmt) pg_shadow_dsc, &null); Assert(!null); if (havesysid) /* customized id wanted */ - sysid_exists = (DatumGetInt32(datum) == stmt->sysid); + sysid_exists = (DatumGetInt32(datum) == sysid); else { /* pick 1 + max */ @@ -249,30 +315,33 @@ CreateUser(CreateUserStmt *stmt) elog(ERROR, "CREATE USER: user name \"%s\" already exists", stmt->user); if (sysid_exists) - elog(ERROR, "CREATE USER: sysid %d is already assigned", - stmt->sysid); + elog(ERROR, "CREATE USER: sysid %d is already assigned", sysid); + + /* If no sysid given, use max existing id + 1 */ + if (! havesysid) + sysid = max_id + 1; /* * Build a tuple to insert */ - new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein, - CStringGetDatum(stmt->user)); - new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); + new_record[Anum_pg_shadow_usename - 1] = + DirectFunctionCall1(namein, CStringGetDatum(stmt->user)); + new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid); - AssertState(BoolIsValid(stmt->createdb)); - new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb); + AssertState(BoolIsValid(createdb)); + new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb); new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false); - AssertState(BoolIsValid(stmt->createuser)); - new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser); + AssertState(BoolIsValid(createuser)); + new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser); /* superuser gets catupd right by default */ - new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(stmt->createuser); + new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser); - if (stmt->password) + if (password) new_record[Anum_pg_shadow_passwd - 1] = - DirectFunctionCall1(textin, CStringGetDatum(stmt->password)); - if (stmt->validUntil) + DirectFunctionCall1(textin, CStringGetDatum(password)); + if (validUntil) new_record[Anum_pg_shadow_valuntil - 1] = - DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil)); + DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil)); new_record_nulls[Anum_pg_shadow_usename - 1] = ' '; new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' '; @@ -282,8 +351,8 @@ CreateUser(CreateUserStmt *stmt) new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' '; - new_record_nulls[Anum_pg_shadow_passwd - 1] = stmt->password ? ' ' : 'n'; - new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n'; + new_record_nulls[Anum_pg_shadow_passwd - 1] = password ? ' ' : 'n'; + new_record_nulls[Anum_pg_shadow_valuntil - 1] = validUntil ? ' ' : 'n'; tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); @@ -310,15 +379,14 @@ CreateUser(CreateUserStmt *stmt) * Add the user to the groups specified. We'll just call the below * AlterGroup for this. */ - foreach(item, stmt->groupElts) + foreach(item, groupElts) { AlterGroupStmt ags; ags.name = strVal(lfirst(item)); /* the group name to add * this in */ ags.action = +1; - ags.listUsers = makeList1(makeInteger(havesysid ? - stmt->sysid : max_id + 1)); + ags.listUsers = makeList1(makeInteger(sysid)); AlterGroup(&ags, "CREATE USER"); } @@ -348,21 +416,69 @@ AlterUser(AlterUserStmt *stmt) HeapTuple tuple, new_tuple; bool null; + List *option; + char *password = NULL; /* PostgreSQL user password */ + int createdb = -1; /* Can the user create databases? */ + int createuser = -1; /* Can this user create users? */ + char *validUntil = NULL; /* The time the login is valid until */ + DefElem *dpassword = NULL; + DefElem *dcreatedb = NULL; + DefElem *dcreateuser = NULL; + DefElem *dvalidUntil = NULL; + + /* Extract options from the statement node tree */ + foreach(option,stmt->options) + { + DefElem *defel = (DefElem *) lfirst(option); - if (stmt->password) + if (strcasecmp(defel->defname, "password") == 0) { + if (dpassword) + elog(ERROR, "ALTER USER: conflicting options"); + dpassword = defel; + } + else if (strcasecmp(defel->defname, "createdb") == 0) { + if (dcreatedb) + elog(ERROR, "ALTER USER: conflicting options"); + dcreatedb = defel; + } + else if (strcasecmp(defel->defname, "createuser") == 0) { + if (dcreateuser) + elog(ERROR, "ALTER USER: conflicting options"); + dcreateuser = defel; + } + else if (strcasecmp(defel->defname, "validUntil") == 0) { + if (dvalidUntil) + elog(ERROR, "ALTER USER: conflicting options"); + dvalidUntil = defel; + } + else + elog(ERROR,"ALTER USER: option \"%s\" not recognized", + defel->defname); + } + + if (dcreatedb) + createdb = intVal(dcreatedb->arg); + if (dcreateuser) + createuser = intVal(dcreateuser->arg); + if (dvalidUntil) + validUntil = strVal(dvalidUntil->arg); + if (dpassword) + password = strVal(dpassword->arg); + + if (password) CheckPgUserAclNotNull(); /* must be superuser or just want to change your own password */ if (!superuser() && - !(stmt->createdb == 0 && - stmt->createuser == 0 && - !stmt->validUntil && - stmt->password && + !(createdb < 0 && + createuser < 0 && + !validUntil && + password && strcmp(GetUserName(GetUserId()), stmt->user) == 0)) elog(ERROR, "ALTER USER: permission denied"); /* changes to the flat password file cannot be rolled back */ - if (IsTransactionBlock() && stmt->password) + if (IsTransactionBlock() && password) elog(NOTICE, "ALTER USER: password changes cannot be rolled back"); /* @@ -391,7 +507,7 @@ AlterUser(AlterUserStmt *stmt) new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' '; /* createdb */ - if (stmt->createdb == 0) + if (createdb < 0) { /* don't change */ new_record[Anum_pg_shadow_usecreatedb - 1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null); @@ -399,7 +515,7 @@ AlterUser(AlterUserStmt *stmt) } else { - new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb > 0 ? true : false); + new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb > 0); new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' '; } @@ -408,7 +524,7 @@ AlterUser(AlterUserStmt *stmt) new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' '; /* createuser (superuser) */ - if (stmt->createuser == 0) + if (createuser < 0) { /* don't change */ new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null); @@ -416,14 +532,14 @@ AlterUser(AlterUserStmt *stmt) } else { - new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser > 0 ? true : false); + new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0); new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; } /* catupd - set to false if someone's superuser priv is being yanked */ - if (stmt->createuser < 0) + if (createuser == 0) { - new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (false); + new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(false); new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' '; } else @@ -434,10 +550,10 @@ AlterUser(AlterUserStmt *stmt) } /* password */ - if (stmt->password) + if (password) { new_record[Anum_pg_shadow_passwd - 1] = - DirectFunctionCall1(textin, CStringGetDatum(stmt->password)); + DirectFunctionCall1(textin, CStringGetDatum(password)); new_record_nulls[Anum_pg_shadow_passwd - 1] = ' '; } else @@ -449,10 +565,10 @@ AlterUser(AlterUserStmt *stmt) } /* valid until */ - if (stmt->validUntil) + if (validUntil) { new_record[Anum_pg_shadow_valuntil - 1] = - DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil)); + DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil)); new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' '; } else @@ -761,9 +877,10 @@ CreateGroup(CreateGroupStmt *stmt) else max_id++; - new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); - new_record[Anum_pg_group_grosysid - 1] = (Datum) (max_id); - new_record[Anum_pg_group_grolist - 1] = (Datum) userarray; + 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_grolist - 1] = PointerGetDatum(userarray); new_record_nulls[Anum_pg_group_groname - 1] = ' '; new_record_nulls[Anum_pg_group_grosysid - 1] = ' '; @@ -832,7 +949,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) * create user */ { Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; + char new_record_nulls[Natts_pg_group]; ArrayType *newarray, *oldarray; List *newlist = NULL, @@ -914,9 +1031,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) /* * Form a tuple with the new array and write it back. */ - new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); + new_record[Anum_pg_group_groname - 1] = + DirectFunctionCall1(namein, CStringGetDatum(stmt->name)); + new_record_nulls[Anum_pg_group_groname - 1] = ' '; new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); + new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' '; new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray); + new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n'; tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple); @@ -950,7 +1071,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) { HeapTuple tuple; Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; + char new_record_nulls[Natts_pg_group]; ArrayType *oldarray, *newarray; List *newlist = NULL, @@ -1014,9 +1135,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) /* * Insert the new tuple with the updated user list */ - new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); + new_record[Anum_pg_group_groname - 1] = + DirectFunctionCall1(namein, CStringGetDatum(stmt->name)); + new_record_nulls[Anum_pg_group_groname - 1] = ' '; new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); + new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' '; new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray); + new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n'; tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 6cf5b35d266..1768b881750 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.145 2001/06/19 22:39:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.146 2001/07/10 22:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2258,6 +2258,7 @@ _copyVacuumStmt(VacuumStmt *from) VacuumStmt *newnode = makeNode(VacuumStmt); newnode->vacuum = from->vacuum; + newnode->full = from->full; newnode->analyze = from->analyze; newnode->verbose = from->verbose; if (from->vacrel) @@ -2404,14 +2405,7 @@ _copyCreateUserStmt(CreateUserStmt *from) if (from->user) newnode->user = pstrdup(from->user); - if (from->password) - newnode->password = pstrdup(from->password); - newnode->sysid = from->sysid; - newnode->createdb = from->createdb; - newnode->createuser = from->createuser; - Node_Copy(from, newnode, groupElts); - if (from->validUntil) - newnode->validUntil = pstrdup(from->validUntil); + Node_Copy(from, newnode, options); return newnode; } @@ -2423,12 +2417,7 @@ _copyAlterUserStmt(AlterUserStmt *from) if (from->user) newnode->user = pstrdup(from->user); - if (from->password) - newnode->password = pstrdup(from->password); - newnode->createdb = from->createdb; - newnode->createuser = from->createuser; - if (from->validUntil) - newnode->validUntil = pstrdup(from->validUntil); + Node_Copy(from, newnode, options); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index b12b4c29127..b6a34e5f2f5 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.93 2001/06/19 22:39:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.94 2001/07/10 22:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1125,6 +1125,8 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b) { if (a->vacuum != b->vacuum) return false; + if (a->full != b->full) + return false; if (a->analyze != b->analyze) return false; if (a->verbose != b->verbose) @@ -1265,17 +1267,7 @@ _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b) { if (!equalstr(a->user, b->user)) return false; - if (!equalstr(a->password, b->password)) - return false; - if (a->sysid != b->sysid) - return false; - if (a->createdb != b->createdb) - return false; - if (a->createuser != b->createuser) - return false; - if (!equal(a->groupElts, b->groupElts)) - return false; - if (!equalstr(a->validUntil, b->validUntil)) + if (!equal(a->options, b->options)) return false; return true; @@ -1286,13 +1278,7 @@ _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b) { if (!equalstr(a->user, b->user)) return false; - if (!equalstr(a->password, b->password)) - return false; - if (a->createdb != b->createdb) - return false; - if (a->createuser != b->createuser) - return false; - if (!equalstr(a->validUntil, b->validUntil)) + if (!equal(a->options, b->options)) return false; return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7e6f782984e..20784ac1705 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.234 2001/07/09 22:18:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.235 2001/07/10 22:09:28 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -155,11 +155,10 @@ static void doNegateFloat(Value *v); %type <ival> opt_lock, lock_type %type <boolean> opt_force -%type <ival> user_createdb_clause, user_createuser_clause -%type <str> user_passwd_clause -%type <ival> sysid_clause -%type <str> user_valid_clause -%type <list> user_list, user_group_clause, users_in_new_group_clause +%type <list> user_list, users_in_new_group_clause + +%type <list> OptUserList +%type <defelt> OptUserElem %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted, opt_procedural @@ -212,7 +211,8 @@ static void doNegateFloat(Value *v); %type <node> substr_from, substr_for %type <boolean> opt_binary, opt_using, opt_instead, opt_cursor -%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, analyze_keyword +%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_full +%type <boolean> analyze_keyword %type <ival> copy_dirn, direction, reindex_type, drop_type, opt_column, event, comment_type, comment_cl, @@ -488,32 +488,18 @@ stmt : AlterSchemaStmt * *****************************************************************************/ -CreateUserStmt: CREATE USER UserId - user_createdb_clause user_createuser_clause user_group_clause - user_valid_clause +CreateUserStmt: CREATE USER UserId OptUserList { CreateUserStmt *n = makeNode(CreateUserStmt); n->user = $3; - n->sysid = -1; - n->password = NULL; - n->createdb = $4 == +1 ? TRUE : FALSE; - n->createuser = $5 == +1 ? TRUE : FALSE; - n->groupElts = $6; - n->validUntil = $7; + n->options = $4; $$ = (Node *)n; } - | CREATE USER UserId WITH sysid_clause user_passwd_clause - user_createdb_clause user_createuser_clause user_group_clause - user_valid_clause + | CREATE USER UserId WITH OptUserList { CreateUserStmt *n = makeNode(CreateUserStmt); n->user = $3; - n->sysid = $5; - n->password = $6; - n->createdb = $7 == +1 ? TRUE : FALSE; - n->createuser = $8 == +1 ? TRUE : FALSE; - n->groupElts = $9; - n->validUntil = $10; + n->options = $5; $$ = (Node *)n; } ; @@ -525,27 +511,18 @@ CreateUserStmt: CREATE USER UserId * *****************************************************************************/ -AlterUserStmt: ALTER USER UserId user_createdb_clause - user_createuser_clause user_valid_clause +AlterUserStmt: ALTER USER UserId OptUserList { AlterUserStmt *n = makeNode(AlterUserStmt); n->user = $3; - n->password = NULL; - n->createdb = $4; - n->createuser = $5; - n->validUntil = $6; + n->options = $4; $$ = (Node *)n; } - | ALTER USER UserId WITH PASSWORD Sconst - user_createdb_clause - user_createuser_clause user_valid_clause + | ALTER USER UserId WITH OptUserList { AlterUserStmt *n = makeNode(AlterUserStmt); n->user = $3; - n->password = $6; - n->createdb = $7; - n->createuser = $8; - n->validUntil = $9; + n->options = $5; $$ = (Node *)n; } ; @@ -565,28 +542,62 @@ DropUserStmt: DROP USER user_list } ; -user_passwd_clause: PASSWORD Sconst { $$ = $2; } - | /*EMPTY*/ { $$ = NULL; } - ; - -sysid_clause: SYSID Iconst - { - if ($2 <= 0) - elog(ERROR, "sysid must be positive"); - $$ = $2; +/* + * Options for CREATE USER and ALTER USER + */ +OptUserList: OptUserList OptUserElem { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } + ; + +OptUserElem: PASSWORD Sconst + { + $$ = makeNode(DefElem); + $$->defname = "password"; + $$->arg = (Node *)makeString($2); + } + | SYSID Iconst + { + $$ = makeNode(DefElem); + $$->defname = "sysid"; + $$->arg = (Node *)makeInteger($2); + } + | CREATEDB + { + $$ = makeNode(DefElem); + $$->defname = "createdb"; + $$->arg = (Node *)makeInteger(TRUE); + } + | NOCREATEDB + { + $$ = makeNode(DefElem); + $$->defname = "createdb"; + $$->arg = (Node *)makeInteger(FALSE); + } + | CREATEUSER + { + $$ = makeNode(DefElem); + $$->defname = "createuser"; + $$->arg = (Node *)makeInteger(TRUE); + } + | NOCREATEUSER + { + $$ = makeNode(DefElem); + $$->defname = "createuser"; + $$->arg = (Node *)makeInteger(FALSE); + } + | IN GROUP user_list + { + $$ = makeNode(DefElem); + $$->defname = "groupElts"; + $$->arg = (Node *)$3; + } + | VALID UNTIL Sconst + { + $$ = makeNode(DefElem); + $$->defname = "validUntil"; + $$->arg = (Node *)makeString($3); } - | /*EMPTY*/ { $$ = -1; } - ; - -user_createdb_clause: CREATEDB { $$ = +1; } - | NOCREATEDB { $$ = -1; } - | /*EMPTY*/ { $$ = 0; } - ; - -user_createuser_clause: CREATEUSER { $$ = +1; } - | NOCREATEUSER { $$ = -1; } - | /*EMPTY*/ { $$ = 0; } - ; + ; user_list: user_list ',' UserId { @@ -598,13 +609,6 @@ user_list: user_list ',' UserId } ; -user_group_clause: IN GROUP user_list { $$ = $3; } - | /*EMPTY*/ { $$ = NULL; } - ; - -user_valid_clause: VALID UNTIL SCONST { $$ = $3; } - | /*EMPTY*/ { $$ = NULL; } - ; /***************************************************************************** @@ -619,21 +623,29 @@ CreateGroupStmt: CREATE GROUP UserId CreateGroupStmt *n = makeNode(CreateGroupStmt); n->name = $3; n->sysid = -1; - n->initUsers = NULL; + n->initUsers = NIL; $$ = (Node *)n; } - | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause + | CREATE GROUP UserId WITH users_in_new_group_clause { CreateGroupStmt *n = makeNode(CreateGroupStmt); n->name = $3; - n->sysid = $5; - n->initUsers = $6; + n->sysid = -1; + n->initUsers = $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 */ { $$ = NULL; } + | /* EMPTY */ { $$ = NIL; } ; /***************************************************************************** @@ -3073,31 +3085,34 @@ ClusterStmt: CLUSTER index_name ON relation_name * *****************************************************************************/ -VacuumStmt: VACUUM opt_verbose +VacuumStmt: VACUUM opt_full opt_verbose { VacuumStmt *n = makeNode(VacuumStmt); n->vacuum = true; n->analyze = false; - n->verbose = $2; + n->full = $2; + n->verbose = $3; n->vacrel = NULL; n->va_cols = NIL; $$ = (Node *)n; } - | VACUUM opt_verbose relation_name + | VACUUM opt_full opt_verbose relation_name { VacuumStmt *n = makeNode(VacuumStmt); n->vacuum = true; n->analyze = false; - n->verbose = $2; - n->vacrel = $3; + n->full = $2; + n->verbose = $3; + n->vacrel = $4; n->va_cols = NIL; $$ = (Node *)n; } - | VACUUM opt_verbose AnalyzeStmt + | VACUUM opt_full opt_verbose AnalyzeStmt { - VacuumStmt *n = (VacuumStmt *) $3; + VacuumStmt *n = (VacuumStmt *) $4; n->vacuum = true; - n->verbose |= $2; + n->full = $2; + n->verbose |= $3; $$ = (Node *)n; } ; @@ -3107,6 +3122,7 @@ AnalyzeStmt: analyze_keyword opt_verbose VacuumStmt *n = makeNode(VacuumStmt); n->vacuum = false; n->analyze = true; + n->full = false; n->verbose = $2; n->vacrel = NULL; n->va_cols = NIL; @@ -3117,6 +3133,7 @@ AnalyzeStmt: analyze_keyword opt_verbose VacuumStmt *n = makeNode(VacuumStmt); n->vacuum = false; n->analyze = true; + n->full = false; n->verbose = $2; n->vacrel = $3; n->va_cols = $4; @@ -3132,6 +3149,10 @@ opt_verbose: VERBOSE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; +opt_full: FULL { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + opt_name_list: '(' name_list ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; diff --git a/src/bin/scripts/vacuumdb b/src/bin/scripts/vacuumdb index 214c995ee25..4245279275c 100644 --- a/src/bin/scripts/vacuumdb +++ b/src/bin/scripts/vacuumdb @@ -12,7 +12,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.16 2001/02/18 18:34:02 momjian Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.17 2001/07/10 22:09:29 tgl Exp $ # #------------------------------------------------------------------------- @@ -20,6 +20,7 @@ CMDNAME=`basename $0` PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"` PSQLOPT= +full= verbose= analyze= table= @@ -97,6 +98,9 @@ do --table=*) table=`echo $1 | sed 's/^--table=//'` ;; + --full|-f) + full="FULL" + ;; --verbose|-v) verbose="VERBOSE" ;; @@ -126,9 +130,10 @@ if [ "$usage" ]; then echo " -W, --password Prompt for password" echo " -d, --dbname=DBNAME Database to vacuum" echo " -a, --all Vacuum all databases" - echo " -z, --analyze Update optimizer hints" echo " -t, --table='TABLE[(columns)]' Vacuum specific table only" + echo " -f, --full Do full vacuuming" echo " -v, --verbose Write a lot of output" + echo " -z, --analyze Update optimizer hints" echo " -e, --echo Show the command being sent to the backend" echo " -q, --quiet Don't write any output" echo @@ -154,7 +159,7 @@ fi for db in $dbname do [ "$alldb" -a "$quiet" -ne 1 ] && echo "Vacuuming $db" - ${PATHNAME}psql $PSQLOPT $ECHOOPT -c "VACUUM $verbose $analyze $table" -d $db + ${PATHNAME}psql $PSQLOPT $ECHOOPT -c "VACUUM $full $verbose $analyze $table" -d $db if [ $? -ne 0 ]; then echo "$CMDNAME: vacuum $table $db failed" 1>&2 exit 1 diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 42b72e8074a..0e3bd2e4608 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.133 2001/06/23 00:07:34 momjian Exp $ + * $Id: parsenodes.h,v 1.134 2001/07/10 22:09:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -339,23 +339,15 @@ typedef struct DropPLangStmt typedef struct CreateUserStmt { NodeTag type; - char *user; /* PostgreSQL user login */ - char *password; /* PostgreSQL user password */ - int sysid; /* PgSQL system id (-1 if don't care) */ - bool createdb; /* Can the user create databases? */ - bool createuser; /* Can this user create users? */ - List *groupElts; /* The groups the user is a member of */ - char *validUntil; /* The time the login is valid until */ + char *user; /* PostgreSQL user login name */ + List *options; /* List of DefElem nodes */ } CreateUserStmt; typedef struct AlterUserStmt { NodeTag type; - char *user; /* PostgreSQL user login */ - char *password; /* PostgreSQL user password */ - int createdb; /* Can the user create databases? */ - int createuser; /* Can this user create users? */ - char *validUntil; /* The time the login is valid until */ + char *user; /* PostgreSQL user login name */ + List *options; /* List of DefElem nodes */ } AlterUserStmt; typedef struct DropUserStmt @@ -715,6 +707,7 @@ typedef struct VacuumStmt { NodeTag type; bool vacuum; /* do VACUUM step */ + bool full; /* do FULL (non-concurrent) vacuum */ bool analyze; /* do ANALYZE step */ bool verbose; /* print progress info */ char *vacrel; /* name of single table to process, or NULL */ diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index e0626025d8f..6b93e767e3e 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -301,7 +301,8 @@ make_name(void) %type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary %type <str> opt_with_copy FetchStmt direction fetch_how_many from_in -%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose func_arg +%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose +%type <str> opt_full func_arg %type <str> analyze_keyword opt_name_list ExplainStmt index_params %type <str> index_list func_index index_elem opt_class access_method_clause %type <str> index_opt_unique IndexStmt func_return ConstInterval @@ -309,14 +310,13 @@ make_name(void) %type <str> def_elem def_list definition DefineStmt select_with_parens %type <str> opt_instead event event_object RuleActionList opt_using %type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type -%type <str> RuleStmt opt_column opt_name oper_argtypes sysid_clause +%type <str> RuleStmt opt_column opt_name oper_argtypes %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause %type <str> RemoveAggrStmt ExtendStmt opt_procedural select_no_parens -%type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause +%type <str> RemoveOperStmt RenameStmt all_Op %type <str> VariableSetStmt var_value zone_value VariableShowStmt %type <str> VariableResetStmt AlterTableStmt DropUserStmt from_list -%type <str> user_passwd_clause user_createdb_clause opt_trans -%type <str> user_createuser_clause user_list user_group_clause +%type <str> opt_trans user_list OptUserList OptUserElem %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt @@ -593,17 +593,13 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); } * *****************************************************************************/ -CreateUserStmt: CREATE USER UserId - user_createdb_clause user_createuser_clause user_group_clause - user_valid_clause - { - $$ = cat_str(6, make_str("create user"), $3, $4, $5, $6, $7); - } - | CREATE USER UserId WITH sysid_clause user_passwd_clause - user_createdb_clause user_createuser_clause user_group_clause - user_valid_clause +CreateUserStmt: CREATE USER UserId OptUserList + { + $$ = cat_str(3, make_str("create user"), $3, $4); + } + | CREATE USER UserId WITH OptUserList { - $$ = cat_str(9, make_str("create user"), $3, make_str("with"), $5, $6, $7, $8, $9, $10); + $$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5); } ; @@ -614,17 +610,14 @@ CreateUserStmt: CREATE USER UserId * *****************************************************************************/ -AlterUserStmt: ALTER USER UserId user_createdb_clause - user_createuser_clause user_valid_clause - { - $$ = cat_str(5, make_str("alter user"), $3, $4, $5, $6); - } - | ALTER USER UserId WITH PASSWORD StringConst - user_createdb_clause - user_createuser_clause user_valid_clause - { - $$ = cat_str(7, make_str("alter user"), $3, make_str("with password"), $6, $7, $8, $9); - } +AlterUserStmt: ALTER USER UserId OptUserList + { + $$ = cat_str(3, make_str("alter user"), $3, $4); + } + | ALTER USER UserId WITH OptUserList + { + $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5); + } ; /***************************************************************************** @@ -640,38 +633,46 @@ DropUserStmt: DROP USER user_list } ; -user_passwd_clause: PASSWORD StringConst { $$ = cat2_str(make_str("password") , $2); } - | /*EMPTY*/ { $$ = EMPTY; } +/* + * Options for CREATE USER and ALTER USER + */ +OptUserList: OptUserList OptUserElem { $$ = cat2_str($1, $2); } + | /* EMPTY */ { $$ = EMPTY; } ; -sysid_clause: SYSID PosIntConst { if (atoi($2) <= 0) - mmerror(ET_ERROR, "sysid must be positive"); - - $$ = cat2_str(make_str("sysid"), $2); } - | /*EMPTY*/ { $$ = EMPTY; } - ; - -user_createdb_clause: CREATEDB +OptUserElem: PASSWORD Sconst + { + $$ = cat2_str(make_str("password"), $2); + } + | SYSID Iconst { + $$ = cat2_str(make_str("sysid"), $2); + } + | CREATEDB + { $$ = make_str("createdb"); } - | NOCREATEDB - { + | NOCREATEDB + { $$ = make_str("nocreatedb"); } - | /*EMPTY*/ { $$ = EMPTY; } - ; - -user_createuser_clause: CREATEUSER - { + | CREATEUSER + { $$ = make_str("createuser"); } - | NOCREATEUSER - { + | NOCREATEUSER + { $$ = make_str("nocreateuser"); } - | /*EMPTY*/ { $$ = NULL; } - ; + | IN GROUP user_list + { + $$ = cat2_str(make_str("in group"), $3); + } + | VALID UNTIL Sconst + { + $$ = cat2_str(make_str("valid until"), $3); + } + ; user_list: user_list ',' UserId { @@ -683,17 +684,6 @@ user_list: user_list ',' UserId } ; -user_group_clause: IN GROUP user_list - { - $$ = cat2_str(make_str("in group"), $3); - } - | /*EMPTY*/ { $$ = EMPTY; } - ; - -user_valid_clause: VALID UNTIL StringConst { $$ = cat2_str(make_str("valid until"), $3); } - | /*EMPTY*/ { $$ = EMPTY; } - ; - /***************************************************************************** * @@ -702,14 +692,18 @@ user_valid_clause: VALID UNTIL StringConst { $$ = cat2_str(make_str("valid un * ****************************************************************************/ CreateGroupStmt: CREATE GROUP UserId - { - $$ = cat2_str(make_str("create group"), $3); - } - | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause - { - $$ = cat_str(5, make_str("create group"), $3, make_str("with"), $5, $6); - } - ; + { + $$ = cat2_str(make_str("create group"), $3); + } + | CREATE GROUP UserId WITH users_in_new_group_clause + { + $$ = 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; } @@ -2289,17 +2283,17 @@ ClusterStmt: CLUSTER index_name ON relation_name * *****************************************************************************/ -VacuumStmt: VACUUM opt_verbose +VacuumStmt: VACUUM opt_full opt_verbose { - $$ = cat_str(2, make_str("vacuum"), $2); + $$ = cat_str(3, make_str("vacuum"), $2, $3); } - | VACUUM opt_verbose relation_name + | VACUUM opt_full opt_verbose relation_name { - $$ = cat_str(3, make_str("vacuum"), $2, $3); + $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); } - | VACUUM opt_verbose AnalyzeStmt + | VACUUM opt_full opt_verbose AnalyzeStmt { - $$ = cat_str(3, make_str("vacuum"), $2, $3); + $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); } ; @@ -2318,7 +2312,11 @@ analyze_keyword: ANALYZE { $$ = make_str("analyze"); } ; opt_verbose: VERBOSE { $$ = make_str("verbose"); } - | /*EMPTY*/ { $$ = EMPTY; } + | /*EMPTY*/ { $$ = EMPTY; } + ; + +opt_full: FULL { $$ = make_str("full"); } + | /*EMPTY*/ { $$ = EMPTY; } ; opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); } |