diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 8579b4f09a1f4ff75ef5995bc027888dfc9c398c..534d2a7eb2dcd196f76c06d0148e3e9265a9ad6f 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.13 2000/07/22 04:30:26 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.14 2001/07/10 22:09:27 tgl Exp $ Postgres documentation --> @@ -20,13 +20,17 @@ Postgres documentation </refnamediv> <refsynopsisdiv> <refsynopsisdivinfo> - <date>1999-07-20</date> + <date>2001-07-10</date> </refsynopsisdivinfo> <synopsis> -ALTER USER <replaceable class="PARAMETER">username</replaceable> - [ WITH PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ] - [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] - [ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ] +ALTER USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ] + +where <replaceable class="PARAMETER">option</replaceable> can be: + + PASSWORD '<replaceable class="PARAMETER">password</replaceable>' + | CREATEDB | NOCREATEDB + | CREATEUSER | NOCREATEUSER + | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' </synopsis> <refsect2 id="R2-SQL-ALTERUSER-1"> @@ -138,10 +142,19 @@ ERROR: ALTER USER: user "username" does not exist </title> <para> <command>ALTER USER</command> is used to change the attributes of a user's - <productname>Postgres</productname> account. Only a database superuser + <productname>Postgres</productname> account. Attributes not mentioned + in the command retain their previous settings. + </para> + <para> + Only a database superuser can change privileges and password expiration with this command. Ordinary users can only change their own password. </para> + <para> + <command>ALTER USER</command> cannot change a user's group memberships. + Use <xref linkend="SQL-ALTERGROUP" endterm="SQL-ALTERGROUP-title"> + to do that. + </para> <para> Use <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title"> to create a new user and <xref linkend="SQL-DROPUSER" diff --git a/doc/src/sgml/ref/create_user.sgml b/doc/src/sgml/ref/create_user.sgml index df98765c7f5daa0c2319ee9c0251ff842ff63649..8c97dbcf86795ff0ed2740887a051c1cb1277535 100644 --- a/doc/src/sgml/ref/create_user.sgml +++ b/doc/src/sgml/ref/create_user.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.16 2000/10/12 22:08:42 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.17 2001/07/10 22:09:27 tgl Exp $ Postgres documentation --> @@ -20,16 +20,19 @@ Postgres documentation </refnamediv> <refsynopsisdiv> <refsynopsisdivinfo> - <date>1999-07-20</date> + <date>2001-07-10</date> </refsynopsisdivinfo> <synopsis> -CREATE USER <replaceable class="PARAMETER">username</replaceable> - [ WITH - [ SYSID <replaceable class="PARAMETER">uid</replaceable> ] - [ PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ] ] - [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] - [ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ] - [ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ] +CREATE USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ] + +where <replaceable class="PARAMETER">option</replaceable> can be: + + SYSID <replaceable class="PARAMETER">uid</replaceable> + | PASSWORD '<replaceable class="PARAMETER">password</replaceable>' + | CREATEDB | NOCREATEDB + | CREATEUSER | NOCREATEUSER + | IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] + | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' </synopsis> <refsect2 id="R2-SQL-CREATEUSER-1"> @@ -115,6 +118,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> <listitem> <para> A name of a group into which to insert the user as a new member. + Multiple group names may be listed. </para> </listitem> </varlistentry> @@ -164,7 +168,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> Description </title> <para> - CREATE USER will add a new user to an instance of + <command>CREATE USER</command> will add a new user to an instance of <productname>Postgres</productname>. Refer to the administrator's guide for information about managing users and authentication. You must be a database superuser to use this command. @@ -173,7 +177,8 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> Use <xref linkend="SQL-ALTERUSER" endterm="SQL-ALTERUSER-title"> to change a user's password and privileges, and <xref linkend="SQL-DROPUSER" endterm="SQL-DROPUSER-title"> to remove a user. - Use <command>ALTER GROUP</command> to add or remove the user from other groups. + Use <xref linkend="SQL-ALTERGROUP" endterm="SQL-ALTERGROUP-title"> + to add or remove the user from other groups. <productname>Postgres</productname> comes with a script <xref linkend="APP-CREATEUSER" endterm="APP-CREATEUSER-title"> diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index 7ce61b72cc84a00dbc3ca45d1cad8cb3a3c8b6b1..e8374725b34bd3cc8e98d224ca092a866bd6f5ec 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.16 2001/05/25 15:45:31 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.17 2001/07/10 22:09:28 tgl Exp $ Postgres documentation --> @@ -20,16 +20,16 @@ Postgres documentation </refnamediv> <refsynopsisdiv> <refsynopsisdivinfo> - <date>2001-05-04</date> + <date>2001-07-10</date> </refsynopsisdivinfo> <synopsis> -VACUUM [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ] -VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ] +VACUUM [ FULL ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ] +VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ] </synopsis> <refsect2 id="R2-SQL-VACUUM-1"> <refsect2info> - <date>1998-10-04</date> + <date>2001-07-10</date> </refsect2info> <title> Inputs @@ -37,6 +37,15 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> <para> <variablelist> + <varlistentry> + <term>FULL</term> + <listitem> + <para> + Selects <quote>full</quote> vacuum, which may reclaim more space, + but takes much longer and exclusively locks the table. + </para> + </listitem> + </varlistentry> <varlistentry> <term>VERBOSE</term> <listitem> @@ -58,7 +67,8 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> <term><replaceable class="PARAMETER">table</replaceable></term> <listitem> <para> - The name of a specific table to vacuum. Defaults to all tables. + The name of a specific table to vacuum. Defaults to all tables + in the current database. </para> </listitem> </varlistentry> @@ -138,7 +148,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; <refsect1 id="R1-SQL-VACUUM-1"> <refsect1info> - <date>1998-10-04</date> + <date>2001-07-10</date> </refsect1info> <title> Description @@ -158,6 +168,16 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; only that table. </para> + <para> + Plain <command>VACUUM</command> simply reclaims space and makes it + available for re-use. This form of the command can operate in parallel + with normal reading and writing of the table. <command>VACUUM + FULL</command> does more extensive processing, including moving of tuples + across blocks to try to compact the table to the minimum number of disk + blocks. This is much slower and requires an exclusive lock on each table + while it is being processed. + </para> + <para> <command>VACUUM ANALYZE</command> performs a <command>VACUUM</command> and then an <command>ANALYZE</command> for each selected table. This @@ -168,7 +188,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; <refsect2 id="R2-SQL-VACUUM-3"> <refsect2info> - <date>1998-10-04</date> + <date>2001-07-10</date> </refsect2info> <title> Notes @@ -176,8 +196,8 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; <para> We recommend that active production databases be - <command>VACUUM</command>-ed nightly, in order to remove - expired rows. After copying a large table into + <command>VACUUM</command>-ed frequently (at least nightly), in order to + remove expired rows. After copying a large table into <productname>Postgres</productname> or after deleting a large number of records, it may be a good idea to issue a <command>VACUUM ANALYZE</command> command for the affected table. This will update the @@ -187,6 +207,14 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; choices in planning user queries. </para> + <para> + The <option>FULL</option> option is not recommended for routine use, + but may be useful in special cases. An example is when you have deleted + most of the rows in a table and would like the table to physically shrink + to occupy less disk space. <command>VACUUM FULL</command> will usually + shrink the table more than a plain <command>VACUUM</command> would. + </para> + </refsect2> </refsect1> diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 1efa7fce93bd47ce101ea43af7017f37272ff705..141d2dcd57bfac2d00567422ed42d390397583a5 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.16 2001/03/17 16:27:31 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.17 2001/07/10 22:09:28 tgl Exp $ Postgres documentation --> @@ -24,8 +24,9 @@ Postgres documentation <command>vacuumdb</command> <arg rep="repeat"><replaceable>connection-options</replaceable></arg> <arg><arg>-d</arg> <replaceable>dbname</replaceable></arg> - <group><arg>--analyze</arg><arg>-z</arg></group> + <group><arg>--full</arg><arg>-f</arg></group> <group><arg>--verbose</arg><arg>-v</arg></group> + <group><arg>--analyze</arg><arg>-z</arg></group> <arg>--table '<replaceable>table</replaceable> <arg>( <replaceable class="parameter">column</replaceable> [,...] )</arg>' </arg> @@ -33,8 +34,9 @@ Postgres documentation <command>vacuumdb</command> <arg rep="repeat"><replaceable>connection-options</replaceable></arg> <group><arg>--all</arg><arg>-a</arg></group> - <group><arg>--analyze</arg><arg>-z</arg></group> + <group><arg>--full</arg><arg>-f</arg></group> <group><arg>--verbose</arg><arg>-v</arg></group> + <group><arg>--analyze</arg><arg>-z</arg></group> </cmdsynopsis> <refsect2 id="R2-APP-VACUUMDB-1"> @@ -56,21 +58,21 @@ Postgres documentation </varlistentry> <varlistentry> - <term>-z</term> - <term>--analyze</term> + <term>-a</term> + <term>--alldb</term> <listitem> <para> - Calculate statistics on the database for use by the optimizer. + Vacuum all databases. </para> </listitem> </varlistentry> <varlistentry> - <term>-a</term> - <term>--alldb</term> + <term>-f</term> + <term>--full</term> <listitem> <para> - Vacuum all databases. + Perform <quote>full</quote> vacuuming. </para> </listitem> </varlistentry> @@ -85,6 +87,16 @@ Postgres documentation </listitem> </varlistentry> + <varlistentry> + <term>-z</term> + <term>--analyze</term> + <listitem> + <para> + Calculate statistics for use by the optimizer. + </para> + </listitem> + </varlistentry> + <varlistentry> <term>-t <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term> <term>--table <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term> @@ -257,7 +269,7 @@ Postgres documentation <informalexample> <para> - To analyze for the optimzer a database named + To clean and analyze for the optimizer a database named <literal>bigdb</literal>: <screen> <prompt>$ </prompt><userinput>vacuumdb --analyze bigdb</userinput> @@ -267,9 +279,10 @@ Postgres documentation <informalexample> <para> - To analyze a single column <literal>bar</literal> in table + To clean a single table <literal>foo</literal> in a database named - <literal>xyzzy</literal> for the optimizer: + <literal>xyzzy</literal>, and analyze a single column + <literal>bar</literal> of the table for the optimizer: <screen> <prompt>$ </prompt><userinput>vacuumdb --analyze --verbose --table 'foo(bar)' xyzzy</userinput> </screen> diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 3d003616c09bb2ab137a9044b4b1e07f91de9a1c..e840b9109f8921e607f3f49424bd2a6229a0434a 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 6cf5b35d26664fddc6a9551986740ed4d39dcfb0..1768b881750a31c2a27950e6c81209809d547f9e 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 b12b4c29127e664840f6d1e57a87a71de71d1e4d..b6a34e5f2f5fc27584ce66c6e12039018a1af291 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 7e6f782984e53657fe8af0b2c478e64f71639407..20784ac1705f2d4add06ce800bca0364ac77071e 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 214c995ee25e73339d7fa76d512c3ba35591a6d1..4245279275cecdf7791c5d0ed294d72dc7370c3b 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 42b72e8074afb37dcbc23d395f2bfd344ae02ed3..0e3bd2e4608070bce50a55e9d624cef1b26fb3e3 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 e0626025d8f825355e00b213d06b9aae7a6967e1..6b93e767e3e7da96319bec01fb34544b1db7e5df 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(")")); }