Commit 320b6db0 authored by Tom Lane's avatar Tom Lane

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.
parent 21d73aa2
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -20,13 +20,17 @@ Postgres documentation ...@@ -20,13 +20,17 @@ Postgres documentation
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<refsynopsisdivinfo> <refsynopsisdivinfo>
<date>1999-07-20</date> <date>2001-07-10</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
ALTER USER <replaceable class="PARAMETER">username</replaceable> ALTER USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
[ WITH PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ]
[ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] where <replaceable class="PARAMETER">option</replaceable> can be:
[ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ]
PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
| CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>'
</synopsis> </synopsis>
<refsect2 id="R2-SQL-ALTERUSER-1"> <refsect2 id="R2-SQL-ALTERUSER-1">
...@@ -138,10 +142,19 @@ ERROR: ALTER USER: user "username" does not exist ...@@ -138,10 +142,19 @@ ERROR: ALTER USER: user "username" does not exist
</title> </title>
<para> <para>
<command>ALTER USER</command> is used to change the attributes of a user's <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 can change privileges and password expiration with this command. Ordinary
users can only change their own password. users can only change their own password.
</para> </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> <para>
Use <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title"> Use <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title">
to create a new user and <xref linkend="SQL-DROPUSER" to create a new user and <xref linkend="SQL-DROPUSER"
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -20,16 +20,19 @@ Postgres documentation ...@@ -20,16 +20,19 @@ Postgres documentation
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<refsynopsisdivinfo> <refsynopsisdivinfo>
<date>1999-07-20</date> <date>2001-07-10</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
CREATE USER <replaceable class="PARAMETER">username</replaceable> CREATE USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
[ WITH
[ SYSID <replaceable class="PARAMETER">uid</replaceable> ] where <replaceable class="PARAMETER">option</replaceable> can be:
[ PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ] ]
[ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] SYSID <replaceable class="PARAMETER">uid</replaceable>
[ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ] | PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
[ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ] | CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...]
| VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>'
</synopsis> </synopsis>
<refsect2 id="R2-SQL-CREATEUSER-1"> <refsect2 id="R2-SQL-CREATEUSER-1">
...@@ -115,6 +118,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> ...@@ -115,6 +118,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
<listitem> <listitem>
<para> <para>
A name of a group into which to insert the user as a new member. A name of a group into which to insert the user as a new member.
Multiple group names may be listed.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -164,7 +168,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> ...@@ -164,7 +168,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
Description Description
</title> </title>
<para> <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 <productname>Postgres</productname>. Refer to the administrator's
guide for information about managing users and authentication. guide for information about managing users and authentication.
You must be a database superuser to use this command. You must be a database superuser to use this command.
...@@ -173,7 +177,8 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> ...@@ -173,7 +177,8 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
Use <xref linkend="SQL-ALTERUSER" endterm="SQL-ALTERUSER-title"> Use <xref linkend="SQL-ALTERUSER" endterm="SQL-ALTERUSER-title">
to change a user's password and privileges, and <xref linkend="SQL-DROPUSER" to change a user's password and privileges, and <xref linkend="SQL-DROPUSER"
endterm="SQL-DROPUSER-title"> to remove a user. 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> <productname>Postgres</productname>
comes with a script <xref linkend="APP-CREATEUSER" comes with a script <xref linkend="APP-CREATEUSER"
endterm="APP-CREATEUSER-title"> endterm="APP-CREATEUSER-title">
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -20,16 +20,16 @@ Postgres documentation ...@@ -20,16 +20,16 @@ Postgres documentation
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<refsynopsisdivinfo> <refsynopsisdivinfo>
<date>2001-05-04</date> <date>2001-07-10</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
VACUUM [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ] VACUUM [ FULL ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ] VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
</synopsis> </synopsis>
<refsect2 id="R2-SQL-VACUUM-1"> <refsect2 id="R2-SQL-VACUUM-1">
<refsect2info> <refsect2info>
<date>1998-10-04</date> <date>2001-07-10</date>
</refsect2info> </refsect2info>
<title> <title>
Inputs Inputs
...@@ -37,6 +37,15 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> ...@@ -37,6 +37,15 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable>
<para> <para>
<variablelist> <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> <varlistentry>
<term>VERBOSE</term> <term>VERBOSE</term>
<listitem> <listitem>
...@@ -58,7 +67,8 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> ...@@ -58,7 +67,8 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable>
<term><replaceable class="PARAMETER">table</replaceable></term> <term><replaceable class="PARAMETER">table</replaceable></term>
<listitem> <listitem>
<para> <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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -138,7 +148,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -138,7 +148,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
<refsect1 id="R1-SQL-VACUUM-1"> <refsect1 id="R1-SQL-VACUUM-1">
<refsect1info> <refsect1info>
<date>1998-10-04</date> <date>2001-07-10</date>
</refsect1info> </refsect1info>
<title> <title>
Description Description
...@@ -158,6 +168,16 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -158,6 +168,16 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
only that table. only that table.
</para> </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> <para>
<command>VACUUM ANALYZE</command> performs a <command>VACUUM</command> <command>VACUUM ANALYZE</command> performs a <command>VACUUM</command>
and then an <command>ANALYZE</command> for each selected table. This and then an <command>ANALYZE</command> for each selected table. This
...@@ -168,7 +188,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -168,7 +188,7 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
<refsect2 id="R2-SQL-VACUUM-3"> <refsect2 id="R2-SQL-VACUUM-3">
<refsect2info> <refsect2info>
<date>1998-10-04</date> <date>2001-07-10</date>
</refsect2info> </refsect2info>
<title> <title>
Notes Notes
...@@ -176,8 +196,8 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -176,8 +196,8 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
<para> <para>
We recommend that active production databases be We recommend that active production databases be
<command>VACUUM</command>-ed nightly, in order to remove <command>VACUUM</command>-ed frequently (at least nightly), in order to
expired rows. After copying a large table into remove expired rows. After copying a large table into
<productname>Postgres</productname> or after deleting a large number <productname>Postgres</productname> or after deleting a large number
of records, it may be a good idea to issue a <command>VACUUM of records, it may be a good idea to issue a <command>VACUUM
ANALYZE</command> command for the affected table. This will update the ANALYZE</command> command for the affected table. This will update the
...@@ -187,6 +207,14 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -187,6 +207,14 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
choices in planning user queries. choices in planning user queries.
</para> </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> </refsect2>
</refsect1> </refsect1>
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -24,8 +24,9 @@ Postgres documentation ...@@ -24,8 +24,9 @@ Postgres documentation
<command>vacuumdb</command> <command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-options</replaceable></arg> <arg rep="repeat"><replaceable>connection-options</replaceable></arg>
<arg><arg>-d</arg> <replaceable>dbname</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>--verbose</arg><arg>-v</arg></group>
<group><arg>--analyze</arg><arg>-z</arg></group>
<arg>--table '<replaceable>table</replaceable> <arg>--table '<replaceable>table</replaceable>
<arg>( <replaceable class="parameter">column</replaceable> [,...] )</arg>' <arg>( <replaceable class="parameter">column</replaceable> [,...] )</arg>'
</arg> </arg>
...@@ -33,8 +34,9 @@ Postgres documentation ...@@ -33,8 +34,9 @@ Postgres documentation
<command>vacuumdb</command> <command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-options</replaceable></arg> <arg rep="repeat"><replaceable>connection-options</replaceable></arg>
<group><arg>--all</arg><arg>-a</arg></group> <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>--verbose</arg><arg>-v</arg></group>
<group><arg>--analyze</arg><arg>-z</arg></group>
</cmdsynopsis> </cmdsynopsis>
<refsect2 id="R2-APP-VACUUMDB-1"> <refsect2 id="R2-APP-VACUUMDB-1">
...@@ -56,21 +58,21 @@ Postgres documentation ...@@ -56,21 +58,21 @@ Postgres documentation
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>-z</term> <term>-a</term>
<term>--analyze</term> <term>--alldb</term>
<listitem> <listitem>
<para> <para>
Calculate statistics on the database for use by the optimizer. Vacuum all databases.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>-a</term> <term>-f</term>
<term>--alldb</term> <term>--full</term>
<listitem> <listitem>
<para> <para>
Vacuum all databases. Perform <quote>full</quote> vacuuming.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -85,6 +87,16 @@ Postgres documentation ...@@ -85,6 +87,16 @@ Postgres documentation
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>-z</term>
<term>--analyze</term>
<listitem>
<para>
Calculate statistics for use by the optimizer.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>-t <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term> <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> <term>--table <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term>
...@@ -257,7 +269,7 @@ Postgres documentation ...@@ -257,7 +269,7 @@ Postgres documentation
<informalexample> <informalexample>
<para> <para>
To analyze for the optimzer a database named To clean and analyze for the optimizer a database named
<literal>bigdb</literal>: <literal>bigdb</literal>:
<screen> <screen>
<prompt>$ </prompt><userinput>vacuumdb --analyze bigdb</userinput> <prompt>$ </prompt><userinput>vacuumdb --analyze bigdb</userinput>
...@@ -267,9 +279,10 @@ Postgres documentation ...@@ -267,9 +279,10 @@ Postgres documentation
<informalexample> <informalexample>
<para> <para>
To analyze a single column <literal>bar</literal> in table To clean a single table
<literal>foo</literal> in a database named <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> <screen>
<prompt>$ </prompt><userinput>vacuumdb --analyze --verbose --table 'foo(bar)' xyzzy</userinput> <prompt>$ </prompt><userinput>vacuumdb --analyze --verbose --table 'foo(bar)' xyzzy</userinput>
</screen> </screen>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -197,14 +197,80 @@ CreateUser(CreateUserStmt *stmt)
char new_record_nulls[Natts_pg_shadow]; char new_record_nulls[Natts_pg_shadow];
bool user_exists = false, bool user_exists = false,
sysid_exists = false, sysid_exists = false,
havesysid; havesysid = false;
int max_id = -1; int max_id = -1;
List *item; 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);
}
havesysid = stmt->sysid > 0; 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 */ /* Check some permissions first */
if (stmt->password) if (password)
CheckPgUserAclNotNull(); CheckPgUserAclNotNull();
if (!superuser()) if (!superuser())
...@@ -235,7 +301,7 @@ CreateUser(CreateUserStmt *stmt) ...@@ -235,7 +301,7 @@ CreateUser(CreateUserStmt *stmt)
pg_shadow_dsc, &null); pg_shadow_dsc, &null);
Assert(!null); Assert(!null);
if (havesysid) /* customized id wanted */ if (havesysid) /* customized id wanted */
sysid_exists = (DatumGetInt32(datum) == stmt->sysid); sysid_exists = (DatumGetInt32(datum) == sysid);
else else
{ {
/* pick 1 + max */ /* pick 1 + max */
...@@ -249,30 +315,33 @@ CreateUser(CreateUserStmt *stmt) ...@@ -249,30 +315,33 @@ CreateUser(CreateUserStmt *stmt)
elog(ERROR, "CREATE USER: user name \"%s\" already exists", elog(ERROR, "CREATE USER: user name \"%s\" already exists",
stmt->user); stmt->user);
if (sysid_exists) if (sysid_exists)
elog(ERROR, "CREATE USER: sysid %d is already assigned", elog(ERROR, "CREATE USER: sysid %d is already assigned", sysid);
stmt->sysid);
/* If no sysid given, use max existing id + 1 */
if (! havesysid)
sysid = max_id + 1;
/* /*
* Build a tuple to insert * Build a tuple to insert
*/ */
new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein, new_record[Anum_pg_shadow_usename - 1] =
CStringGetDatum(stmt->user)); DirectFunctionCall1(namein, CStringGetDatum(stmt->user));
new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid);
AssertState(BoolIsValid(stmt->createdb)); AssertState(BoolIsValid(createdb));
new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb); new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb);
new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false); new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false);
AssertState(BoolIsValid(stmt->createuser)); AssertState(BoolIsValid(createuser));
new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser); new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser);
/* superuser gets catupd right by default */ /* 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] = new_record[Anum_pg_shadow_passwd - 1] =
DirectFunctionCall1(textin, CStringGetDatum(stmt->password)); DirectFunctionCall1(textin, CStringGetDatum(password));
if (stmt->validUntil) if (validUntil)
new_record[Anum_pg_shadow_valuntil - 1] = 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_usename - 1] = ' ';
new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' '; new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' ';
...@@ -282,8 +351,8 @@ CreateUser(CreateUserStmt *stmt) ...@@ -282,8 +351,8 @@ CreateUser(CreateUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
new_record_nulls[Anum_pg_shadow_usecatupd - 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_passwd - 1] = password ? ' ' : 'n';
new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n'; new_record_nulls[Anum_pg_shadow_valuntil - 1] = validUntil ? ' ' : 'n';
tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls);
...@@ -310,15 +379,14 @@ CreateUser(CreateUserStmt *stmt) ...@@ -310,15 +379,14 @@ CreateUser(CreateUserStmt *stmt)
* Add the user to the groups specified. We'll just call the below * Add the user to the groups specified. We'll just call the below
* AlterGroup for this. * AlterGroup for this.
*/ */
foreach(item, stmt->groupElts) foreach(item, groupElts)
{ {
AlterGroupStmt ags; AlterGroupStmt ags;
ags.name = strVal(lfirst(item)); /* the group name to add ags.name = strVal(lfirst(item)); /* the group name to add
* this in */ * this in */
ags.action = +1; ags.action = +1;
ags.listUsers = makeList1(makeInteger(havesysid ? ags.listUsers = makeList1(makeInteger(sysid));
stmt->sysid : max_id + 1));
AlterGroup(&ags, "CREATE USER"); AlterGroup(&ags, "CREATE USER");
} }
...@@ -348,21 +416,69 @@ AlterUser(AlterUserStmt *stmt) ...@@ -348,21 +416,69 @@ AlterUser(AlterUserStmt *stmt)
HeapTuple tuple, HeapTuple tuple,
new_tuple; new_tuple;
bool null; 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(); CheckPgUserAclNotNull();
/* must be superuser or just want to change your own password */ /* must be superuser or just want to change your own password */
if (!superuser() && if (!superuser() &&
!(stmt->createdb == 0 && !(createdb < 0 &&
stmt->createuser == 0 && createuser < 0 &&
!stmt->validUntil && !validUntil &&
stmt->password && password &&
strcmp(GetUserName(GetUserId()), stmt->user) == 0)) strcmp(GetUserName(GetUserId()), stmt->user) == 0))
elog(ERROR, "ALTER USER: permission denied"); elog(ERROR, "ALTER USER: permission denied");
/* changes to the flat password file cannot be rolled back */ /* 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"); elog(NOTICE, "ALTER USER: password changes cannot be rolled back");
/* /*
...@@ -391,7 +507,7 @@ AlterUser(AlterUserStmt *stmt) ...@@ -391,7 +507,7 @@ AlterUser(AlterUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' '; new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' ';
/* createdb */ /* createdb */
if (stmt->createdb == 0) if (createdb < 0)
{ {
/* don't change */ /* don't change */
new_record[Anum_pg_shadow_usecreatedb - 1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null); 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) ...@@ -399,7 +515,7 @@ AlterUser(AlterUserStmt *stmt)
} }
else 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] = ' '; new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' ';
} }
...@@ -408,7 +524,7 @@ AlterUser(AlterUserStmt *stmt) ...@@ -408,7 +524,7 @@ AlterUser(AlterUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' '; new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' ';
/* createuser (superuser) */ /* createuser (superuser) */
if (stmt->createuser == 0) if (createuser < 0)
{ {
/* don't change */ /* don't change */
new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null); 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) ...@@ -416,14 +532,14 @@ AlterUser(AlterUserStmt *stmt)
} }
else 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] = ' '; new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
} }
/* catupd - set to false if someone's superuser priv is being yanked */ /* 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] = ' '; new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' ';
} }
else else
...@@ -434,10 +550,10 @@ AlterUser(AlterUserStmt *stmt) ...@@ -434,10 +550,10 @@ AlterUser(AlterUserStmt *stmt)
} }
/* password */ /* password */
if (stmt->password) if (password)
{ {
new_record[Anum_pg_shadow_passwd - 1] = new_record[Anum_pg_shadow_passwd - 1] =
DirectFunctionCall1(textin, CStringGetDatum(stmt->password)); DirectFunctionCall1(textin, CStringGetDatum(password));
new_record_nulls[Anum_pg_shadow_passwd - 1] = ' '; new_record_nulls[Anum_pg_shadow_passwd - 1] = ' ';
} }
else else
...@@ -449,10 +565,10 @@ AlterUser(AlterUserStmt *stmt) ...@@ -449,10 +565,10 @@ AlterUser(AlterUserStmt *stmt)
} }
/* valid until */ /* valid until */
if (stmt->validUntil) if (validUntil)
{ {
new_record[Anum_pg_shadow_valuntil - 1] = new_record[Anum_pg_shadow_valuntil - 1] =
DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil)); DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' '; new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' ';
} }
else else
...@@ -761,9 +877,10 @@ CreateGroup(CreateGroupStmt *stmt) ...@@ -761,9 +877,10 @@ CreateGroup(CreateGroupStmt *stmt)
else else
max_id++; max_id++;
new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); new_record[Anum_pg_group_groname - 1] =
new_record[Anum_pg_group_grosysid - 1] = (Datum) (max_id); DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
new_record[Anum_pg_group_grolist - 1] = (Datum) userarray; 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_groname - 1] = ' ';
new_record_nulls[Anum_pg_group_grosysid - 1] = ' '; new_record_nulls[Anum_pg_group_grosysid - 1] = ' ';
...@@ -832,7 +949,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) ...@@ -832,7 +949,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
* create user */ * create user */
{ {
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; char new_record_nulls[Natts_pg_group];
ArrayType *newarray, ArrayType *newarray,
*oldarray; *oldarray;
List *newlist = NULL, List *newlist = NULL,
...@@ -914,9 +1031,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) ...@@ -914,9 +1031,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
/* /*
* Form a tuple with the new array and write it back. * 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[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[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); tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple); simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);
...@@ -950,7 +1071,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) ...@@ -950,7 +1071,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
{ {
HeapTuple tuple; HeapTuple tuple;
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; char new_record_nulls[Natts_pg_group];
ArrayType *oldarray, ArrayType *oldarray,
*newarray; *newarray;
List *newlist = NULL, List *newlist = NULL,
...@@ -1014,9 +1135,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag) ...@@ -1014,9 +1135,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
/* /*
* Insert the new tuple with the updated user list * 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[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[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); tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple); simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -2258,6 +2258,7 @@ _copyVacuumStmt(VacuumStmt *from)
VacuumStmt *newnode = makeNode(VacuumStmt); VacuumStmt *newnode = makeNode(VacuumStmt);
newnode->vacuum = from->vacuum; newnode->vacuum = from->vacuum;
newnode->full = from->full;
newnode->analyze = from->analyze; newnode->analyze = from->analyze;
newnode->verbose = from->verbose; newnode->verbose = from->verbose;
if (from->vacrel) if (from->vacrel)
...@@ -2404,14 +2405,7 @@ _copyCreateUserStmt(CreateUserStmt *from) ...@@ -2404,14 +2405,7 @@ _copyCreateUserStmt(CreateUserStmt *from)
if (from->user) if (from->user)
newnode->user = pstrdup(from->user); newnode->user = pstrdup(from->user);
if (from->password) Node_Copy(from, newnode, options);
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);
return newnode; return newnode;
} }
...@@ -2423,12 +2417,7 @@ _copyAlterUserStmt(AlterUserStmt *from) ...@@ -2423,12 +2417,7 @@ _copyAlterUserStmt(AlterUserStmt *from)
if (from->user) if (from->user)
newnode->user = pstrdup(from->user); newnode->user = pstrdup(from->user);
if (from->password) Node_Copy(from, newnode, options);
newnode->password = pstrdup(from->password);
newnode->createdb = from->createdb;
newnode->createuser = from->createuser;
if (from->validUntil)
newnode->validUntil = pstrdup(from->validUntil);
return newnode; return newnode;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1125,6 +1125,8 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
{ {
if (a->vacuum != b->vacuum) if (a->vacuum != b->vacuum)
return false; return false;
if (a->full != b->full)
return false;
if (a->analyze != b->analyze) if (a->analyze != b->analyze)
return false; return false;
if (a->verbose != b->verbose) if (a->verbose != b->verbose)
...@@ -1265,17 +1267,7 @@ _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b) ...@@ -1265,17 +1267,7 @@ _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
{ {
if (!equalstr(a->user, b->user)) if (!equalstr(a->user, b->user))
return false; return false;
if (!equalstr(a->password, b->password)) if (!equal(a->options, b->options))
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))
return false; return false;
return true; return true;
...@@ -1286,13 +1278,7 @@ _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b) ...@@ -1286,13 +1278,7 @@ _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
{ {
if (!equalstr(a->user, b->user)) if (!equalstr(a->user, b->user))
return false; return false;
if (!equalstr(a->password, b->password)) if (!equal(a->options, b->options))
return false;
if (a->createdb != b->createdb)
return false;
if (a->createuser != b->createuser)
return false;
if (!equalstr(a->validUntil, b->validUntil))
return false; return false;
return true; return true;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -155,11 +155,10 @@ static void doNegateFloat(Value *v); ...@@ -155,11 +155,10 @@ static void doNegateFloat(Value *v);
%type <ival> opt_lock, lock_type %type <ival> opt_lock, lock_type
%type <boolean> opt_force %type <boolean> opt_force
%type <ival> user_createdb_clause, user_createuser_clause %type <list> user_list, users_in_new_group_clause
%type <str> user_passwd_clause
%type <ival> sysid_clause %type <list> OptUserList
%type <str> user_valid_clause %type <defelt> OptUserElem
%type <list> user_list, user_group_clause, users_in_new_group_clause
%type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted, opt_procedural %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted, opt_procedural
...@@ -212,7 +211,8 @@ static void doNegateFloat(Value *v); ...@@ -212,7 +211,8 @@ static void doNegateFloat(Value *v);
%type <node> substr_from, substr_for %type <node> substr_from, substr_for
%type <boolean> opt_binary, opt_using, opt_instead, opt_cursor %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, %type <ival> copy_dirn, direction, reindex_type, drop_type,
opt_column, event, comment_type, comment_cl, opt_column, event, comment_type, comment_cl,
...@@ -488,32 +488,18 @@ stmt : AlterSchemaStmt ...@@ -488,32 +488,18 @@ stmt : AlterSchemaStmt
* *
*****************************************************************************/ *****************************************************************************/
CreateUserStmt: CREATE USER UserId CreateUserStmt: CREATE USER UserId OptUserList
user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{ {
CreateUserStmt *n = makeNode(CreateUserStmt); CreateUserStmt *n = makeNode(CreateUserStmt);
n->user = $3; n->user = $3;
n->sysid = -1; n->options = $4;
n->password = NULL;
n->createdb = $4 == +1 ? TRUE : FALSE;
n->createuser = $5 == +1 ? TRUE : FALSE;
n->groupElts = $6;
n->validUntil = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE USER UserId WITH sysid_clause user_passwd_clause | CREATE USER UserId WITH OptUserList
user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{ {
CreateUserStmt *n = makeNode(CreateUserStmt); CreateUserStmt *n = makeNode(CreateUserStmt);
n->user = $3; n->user = $3;
n->sysid = $5; n->options = $5;
n->password = $6;
n->createdb = $7 == +1 ? TRUE : FALSE;
n->createuser = $8 == +1 ? TRUE : FALSE;
n->groupElts = $9;
n->validUntil = $10;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -525,27 +511,18 @@ CreateUserStmt: CREATE USER UserId ...@@ -525,27 +511,18 @@ CreateUserStmt: CREATE USER UserId
* *
*****************************************************************************/ *****************************************************************************/
AlterUserStmt: ALTER USER UserId user_createdb_clause AlterUserStmt: ALTER USER UserId OptUserList
user_createuser_clause user_valid_clause
{ {
AlterUserStmt *n = makeNode(AlterUserStmt); AlterUserStmt *n = makeNode(AlterUserStmt);
n->user = $3; n->user = $3;
n->password = NULL; n->options = $4;
n->createdb = $4;
n->createuser = $5;
n->validUntil = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER USER UserId WITH PASSWORD Sconst | ALTER USER UserId WITH OptUserList
user_createdb_clause
user_createuser_clause user_valid_clause
{ {
AlterUserStmt *n = makeNode(AlterUserStmt); AlterUserStmt *n = makeNode(AlterUserStmt);
n->user = $3; n->user = $3;
n->password = $6; n->options = $5;
n->createdb = $7;
n->createuser = $8;
n->validUntil = $9;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -565,27 +542,61 @@ DropUserStmt: DROP USER user_list ...@@ -565,27 +542,61 @@ DropUserStmt: DROP USER user_list
} }
; ;
user_passwd_clause: PASSWORD Sconst { $$ = $2; } /*
| /*EMPTY*/ { $$ = NULL; } * Options for CREATE USER and ALTER USER
*/
OptUserList: OptUserList OptUserElem { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; }
; ;
sysid_clause: SYSID Iconst OptUserElem: PASSWORD Sconst
{ {
if ($2 <= 0) $$ = makeNode(DefElem);
elog(ERROR, "sysid must be positive"); $$->defname = "password";
$$ = $2; $$->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 user_list: user_list ',' UserId
...@@ -598,13 +609,6 @@ 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 ...@@ -619,21 +623,29 @@ CreateGroupStmt: CREATE GROUP UserId
CreateGroupStmt *n = makeNode(CreateGroupStmt); CreateGroupStmt *n = makeNode(CreateGroupStmt);
n->name = $3; n->name = $3;
n->sysid = -1; n->sysid = -1;
n->initUsers = NULL; n->initUsers = NIL;
$$ = (Node *)n; $$ = (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); CreateGroupStmt *n = makeNode(CreateGroupStmt);
n->name = $3; n->name = $3;
n->sysid = $5; n->sysid = -1;
n->initUsers = $6; 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; $$ = (Node *)n;
} }
; ;
users_in_new_group_clause: USER user_list { $$ = $2; } users_in_new_group_clause: USER user_list { $$ = $2; }
| /* EMPTY */ { $$ = NULL; } | /* EMPTY */ { $$ = NIL; }
; ;
/***************************************************************************** /*****************************************************************************
...@@ -3073,31 +3085,34 @@ ClusterStmt: CLUSTER index_name ON relation_name ...@@ -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); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true; n->vacuum = true;
n->analyze = false; n->analyze = false;
n->verbose = $2; n->full = $2;
n->verbose = $3;
n->vacrel = NULL; n->vacrel = NULL;
n->va_cols = NIL; n->va_cols = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| VACUUM opt_verbose relation_name | VACUUM opt_full opt_verbose relation_name
{ {
VacuumStmt *n = makeNode(VacuumStmt); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true; n->vacuum = true;
n->analyze = false; n->analyze = false;
n->verbose = $2; n->full = $2;
n->vacrel = $3; n->verbose = $3;
n->vacrel = $4;
n->va_cols = NIL; n->va_cols = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| VACUUM opt_verbose AnalyzeStmt | VACUUM opt_full opt_verbose AnalyzeStmt
{ {
VacuumStmt *n = (VacuumStmt *) $3; VacuumStmt *n = (VacuumStmt *) $4;
n->vacuum = true; n->vacuum = true;
n->verbose |= $2; n->full = $2;
n->verbose |= $3;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -3107,6 +3122,7 @@ AnalyzeStmt: analyze_keyword opt_verbose ...@@ -3107,6 +3122,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
VacuumStmt *n = makeNode(VacuumStmt); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = false; n->vacuum = false;
n->analyze = true; n->analyze = true;
n->full = false;
n->verbose = $2; n->verbose = $2;
n->vacrel = NULL; n->vacrel = NULL;
n->va_cols = NIL; n->va_cols = NIL;
...@@ -3117,6 +3133,7 @@ AnalyzeStmt: analyze_keyword opt_verbose ...@@ -3117,6 +3133,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
VacuumStmt *n = makeNode(VacuumStmt); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = false; n->vacuum = false;
n->analyze = true; n->analyze = true;
n->full = false;
n->verbose = $2; n->verbose = $2;
n->vacrel = $3; n->vacrel = $3;
n->va_cols = $4; n->va_cols = $4;
...@@ -3132,6 +3149,10 @@ opt_verbose: VERBOSE { $$ = TRUE; } ...@@ -3132,6 +3149,10 @@ opt_verbose: VERBOSE { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; }
; ;
opt_full: FULL { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_name_list: '(' name_list ')' { $$ = $2; } opt_name_list: '(' name_list ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; }
; ;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# #
# #
# IDENTIFICATION # 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` ...@@ -20,6 +20,7 @@ CMDNAME=`basename $0`
PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"` PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"`
PSQLOPT= PSQLOPT=
full=
verbose= verbose=
analyze= analyze=
table= table=
...@@ -97,6 +98,9 @@ do ...@@ -97,6 +98,9 @@ do
--table=*) --table=*)
table=`echo $1 | sed 's/^--table=//'` table=`echo $1 | sed 's/^--table=//'`
;; ;;
--full|-f)
full="FULL"
;;
--verbose|-v) --verbose|-v)
verbose="VERBOSE" verbose="VERBOSE"
;; ;;
...@@ -126,9 +130,10 @@ if [ "$usage" ]; then ...@@ -126,9 +130,10 @@ if [ "$usage" ]; then
echo " -W, --password Prompt for password" echo " -W, --password Prompt for password"
echo " -d, --dbname=DBNAME Database to vacuum" echo " -d, --dbname=DBNAME Database to vacuum"
echo " -a, --all Vacuum all databases" echo " -a, --all Vacuum all databases"
echo " -z, --analyze Update optimizer hints"
echo " -t, --table='TABLE[(columns)]' Vacuum specific table only" echo " -t, --table='TABLE[(columns)]' Vacuum specific table only"
echo " -f, --full Do full vacuuming"
echo " -v, --verbose Write a lot of output" 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 " -e, --echo Show the command being sent to the backend"
echo " -q, --quiet Don't write any output" echo " -q, --quiet Don't write any output"
echo echo
...@@ -154,7 +159,7 @@ fi ...@@ -154,7 +159,7 @@ fi
for db in $dbname for db in $dbname
do do
[ "$alldb" -a "$quiet" -ne 1 ] && echo "Vacuuming $db" [ "$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 if [ $? -ne 0 ]; then
echo "$CMDNAME: vacuum $table $db failed" 1>&2 echo "$CMDNAME: vacuum $table $db failed" 1>&2
exit 1 exit 1
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -339,23 +339,15 @@ typedef struct DropPLangStmt
typedef struct CreateUserStmt typedef struct CreateUserStmt
{ {
NodeTag type; NodeTag type;
char *user; /* PostgreSQL user login */ char *user; /* PostgreSQL user login name */
char *password; /* PostgreSQL user password */ List *options; /* List of DefElem nodes */
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 */
} CreateUserStmt; } CreateUserStmt;
typedef struct AlterUserStmt typedef struct AlterUserStmt
{ {
NodeTag type; NodeTag type;
char *user; /* PostgreSQL user login */ char *user; /* PostgreSQL user login name */
char *password; /* PostgreSQL user password */ List *options; /* List of DefElem nodes */
int createdb; /* Can the user create databases? */
int createuser; /* Can this user create users? */
char *validUntil; /* The time the login is valid until */
} AlterUserStmt; } AlterUserStmt;
typedef struct DropUserStmt typedef struct DropUserStmt
...@@ -715,6 +707,7 @@ typedef struct VacuumStmt ...@@ -715,6 +707,7 @@ typedef struct VacuumStmt
{ {
NodeTag type; NodeTag type;
bool vacuum; /* do VACUUM step */ bool vacuum; /* do VACUUM step */
bool full; /* do FULL (non-concurrent) vacuum */
bool analyze; /* do ANALYZE step */ bool analyze; /* do ANALYZE step */
bool verbose; /* print progress info */ bool verbose; /* print progress info */
char *vacrel; /* name of single table to process, or NULL */ char *vacrel; /* name of single table to process, or NULL */
......
...@@ -301,7 +301,8 @@ make_name(void) ...@@ -301,7 +301,8 @@ make_name(void)
%type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null %type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary %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> 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> analyze_keyword opt_name_list ExplainStmt index_params
%type <str> index_list func_index index_elem opt_class access_method_clause %type <str> index_list func_index index_elem opt_class access_method_clause
%type <str> index_opt_unique IndexStmt func_return ConstInterval %type <str> index_opt_unique IndexStmt func_return ConstInterval
...@@ -309,14 +310,13 @@ make_name(void) ...@@ -309,14 +310,13 @@ make_name(void)
%type <str> def_elem def_list definition DefineStmt select_with_parens %type <str> def_elem def_list definition DefineStmt select_with_parens
%type <str> opt_instead event event_object RuleActionList opt_using %type <str> opt_instead event event_object RuleActionList opt_using
%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type %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> MathOp RemoveFuncStmt aggr_argtype for_update_clause
%type <str> RemoveAggrStmt ExtendStmt opt_procedural select_no_parens %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> VariableSetStmt var_value zone_value VariableShowStmt
%type <str> VariableResetStmt AlterTableStmt DropUserStmt from_list %type <str> VariableResetStmt AlterTableStmt DropUserStmt from_list
%type <str> user_passwd_clause user_createdb_clause opt_trans %type <str> opt_trans user_list OptUserList OptUserElem
%type <str> user_createuser_clause user_list user_group_clause
%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
%type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
...@@ -593,17 +593,13 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); } ...@@ -593,17 +593,13 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); }
* *
*****************************************************************************/ *****************************************************************************/
CreateUserStmt: CREATE USER UserId CreateUserStmt: CREATE USER UserId OptUserList
user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{ {
$$ = cat_str(6, make_str("create user"), $3, $4, $5, $6, $7); $$ = cat_str(3, make_str("create user"), $3, $4);
} }
| CREATE USER UserId WITH sysid_clause user_passwd_clause | CREATE USER UserId WITH OptUserList
user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{ {
$$ = 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,16 +610,13 @@ CreateUserStmt: CREATE USER UserId ...@@ -614,16 +610,13 @@ CreateUserStmt: CREATE USER UserId
* *
*****************************************************************************/ *****************************************************************************/
AlterUserStmt: ALTER USER UserId user_createdb_clause AlterUserStmt: ALTER USER UserId OptUserList
user_createuser_clause user_valid_clause
{ {
$$ = cat_str(5, make_str("alter user"), $3, $4, $5, $6); $$ = cat_str(3, make_str("alter user"), $3, $4);
} }
| ALTER USER UserId WITH PASSWORD StringConst | ALTER USER UserId WITH OptUserList
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); $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5);
} }
; ;
...@@ -640,18 +633,22 @@ DropUserStmt: DROP USER user_list ...@@ -640,18 +633,22 @@ 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); }
sysid_clause: SYSID PosIntConst { if (atoi($2) <= 0) | /* EMPTY */ { $$ = EMPTY; }
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"); $$ = make_str("createdb");
} }
...@@ -659,10 +656,7 @@ user_createdb_clause: CREATEDB ...@@ -659,10 +656,7 @@ user_createdb_clause: CREATEDB
{ {
$$ = make_str("nocreatedb"); $$ = make_str("nocreatedb");
} }
| /*EMPTY*/ { $$ = EMPTY; } | CREATEUSER
;
user_createuser_clause: CREATEUSER
{ {
$$ = make_str("createuser"); $$ = make_str("createuser");
} }
...@@ -670,7 +664,14 @@ user_createuser_clause: CREATEUSER ...@@ -670,7 +664,14 @@ user_createuser_clause: CREATEUSER
{ {
$$ = make_str("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 user_list: user_list ',' UserId
...@@ -683,17 +684,6 @@ 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; }
;
/***************************************************************************** /*****************************************************************************
* *
...@@ -705,9 +695,13 @@ CreateGroupStmt: CREATE GROUP UserId ...@@ -705,9 +695,13 @@ CreateGroupStmt: CREATE GROUP UserId
{ {
$$ = cat2_str(make_str("create group"), $3); $$ = cat2_str(make_str("create group"), $3);
} }
| CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause | 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"), $5, $6); $$ = cat_str(5, make_str("create group"), $3, make_str("with sysid"), $6, $7);
} }
; ;
...@@ -2289,17 +2283,17 @@ ClusterStmt: CLUSTER index_name ON relation_name ...@@ -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);
} }
; ;
...@@ -2321,6 +2315,10 @@ opt_verbose: VERBOSE { $$ = make_str("verbose"); } ...@@ -2321,6 +2315,10 @@ 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(")")); } opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| /*EMPTY*/ { $$ = EMPTY; } | /*EMPTY*/ { $$ = EMPTY; }
; ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment