<!--
-$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
-->
</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">
</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"
<!--
-$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
-->
</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">
<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>
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.
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">
<!--
-$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
-->
</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
<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>
<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>
<refsect1 id="R1-SQL-VACUUM-1">
<refsect1info>
- <date>1998-10-04</date>
+ <date>2001-07-10</date>
</refsect1info>
<title>
Description
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
<refsect2 id="R2-SQL-VACUUM-3">
<refsect2info>
- <date>1998-10-04</date>
+ <date>2001-07-10</date>
</refsect2info>
<title>
Notes
<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
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>
<!--
-$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
-->
<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>
<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">
</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>
</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>
<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>
<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>
* 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 $
*
*-------------------------------------------------------------------------
*/
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())
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 */
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] = ' ';
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);
* 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");
}
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");
/*
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);
}
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_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);
}
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
}
/* 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
}
/* 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
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] = ' ';
* 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,
/*
* 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);
{
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,
/*
* 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);
* 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 $
*
*-------------------------------------------------------------------------
*/
VacuumStmt *newnode = makeNode(VacuumStmt);
newnode->vacuum = from->vacuum;
+ newnode->full = from->full;
newnode->analyze = from->analyze;
newnode->verbose = from->verbose;
if (from->vacrel)
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;
}
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;
}
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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)
{
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;
{
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;
*
*
* 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
%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
%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,
*
*****************************************************************************/
-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;
}
;
*
*****************************************************************************/
-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;
}
;
}
;
-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
{
}
;
-user_group_clause: IN GROUP user_list { $$ = $3; }
- | /*EMPTY*/ { $$ = NULL; }
- ;
-
-user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
- | /*EMPTY*/ { $$ = NULL; }
- ;
/*****************************************************************************
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; }
;
/*****************************************************************************
*
*****************************************************************************/
-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;
}
;
VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = false;
n->analyze = true;
+ n->full = false;
n->verbose = $2;
n->vacrel = NULL;
n->va_cols = NIL;
VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = false;
n->analyze = true;
+ n->full = false;
n->verbose = $2;
n->vacrel = $3;
n->va_cols = $4;
| /*EMPTY*/ { $$ = FALSE; }
;
+opt_full: FULL { $$ = TRUE; }
+ | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
opt_name_list: '(' name_list ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
#
#
# 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 $
#
#-------------------------------------------------------------------------
PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"`
PSQLOPT=
+full=
verbose=
analyze=
table=
--table=*)
table=`echo $1 | sed 's/^--table=//'`
;;
+ --full|-f)
+ full="FULL"
+ ;;
--verbose|-v)
verbose="VERBOSE"
;;
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
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
* 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 $
*
*-------------------------------------------------------------------------
*/
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
{
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 */
%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
%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
*
*****************************************************************************/
-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);
}
;
*
*****************************************************************************/
-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);
+ }
;
/*****************************************************************************
}
;
-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
{
}
;
-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; }
- ;
-
/*****************************************************************************
*
*
****************************************************************************/
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; }
*
*****************************************************************************/
-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);
}
;
;
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(")")); }