]> granicus.if.org Git - postgresql/commitdiff
Changes from Vince Vielhaber to allow the optional clauses of CREATE
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Jul 2001 22:09:29 +0000 (22:09 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Jul 2001 22:09:29 +0000 (22:09 +0000)
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.

doc/src/sgml/ref/alter_user.sgml
doc/src/sgml/ref/create_user.sgml
doc/src/sgml/ref/vacuum.sgml
doc/src/sgml/ref/vacuumdb.sgml
src/backend/commands/user.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/bin/scripts/vacuumdb
src/include/nodes/parsenodes.h
src/interfaces/ecpg/preproc/preproc.y

index 8579b4f09a1f4ff75ef5995bc027888dfc9c398c..534d2a7eb2dcd196f76c06d0148e3e9265a9ad6f 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.13 2000/07/22 04:30:26 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.14 2001/07/10 22:09:27 tgl Exp $
 Postgres documentation
 -->
 
@@ -20,13 +20,17 @@ Postgres documentation
  </refnamediv>
  <refsynopsisdiv>
   <refsynopsisdivinfo>
-   <date>1999-07-20</date>
+   <date>2001-07-10</date>
   </refsynopsisdivinfo>
   <synopsis>
-ALTER USER <replaceable class="PARAMETER">username</replaceable>
-    [ WITH PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ]
-    [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ]
-    [ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ]
+ALTER USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
+
+where <replaceable class="PARAMETER">option</replaceable> can be:
+
+         PASSWORD '<replaceable class="PARAMETER">password</replaceable>' 
+        | CREATEDB | NOCREATEDB
+        | CREATEUSER | NOCREATEUSER 
+        | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>'
   </synopsis>
 
   <refsect2 id="R2-SQL-ALTERUSER-1">
@@ -138,10 +142,19 @@ ERROR:  ALTER USER: user "username" does not exist
   </title>
   <para>
    <command>ALTER USER</command> is used to change the attributes of a user's
-   <productname>Postgres</productname> account. Only a database superuser
+   <productname>Postgres</productname> account.  Attributes not mentioned
+   in the command retain their previous settings.
+  </para>
+  <para>
+   Only a database superuser
    can change privileges and password expiration with this command. Ordinary
    users can only change their own password.
   </para>
+  <para>
+   <command>ALTER USER</command> cannot change a user's group memberships.
+   Use <xref linkend="SQL-ALTERGROUP" endterm="SQL-ALTERGROUP-title">
+   to do that.
+  </para>
   <para>
    Use <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title">
    to create a new user and <xref linkend="SQL-DROPUSER"
index df98765c7f5daa0c2319ee9c0251ff842ff63649..8c97dbcf86795ff0ed2740887a051c1cb1277535 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.16 2000/10/12 22:08:42 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.17 2001/07/10 22:09:27 tgl Exp $
 Postgres documentation
 -->
 
@@ -20,16 +20,19 @@ Postgres documentation
  </refnamediv>
  <refsynopsisdiv>
   <refsynopsisdivinfo>
-   <date>1999-07-20</date>
+   <date>2001-07-10</date>
   </refsynopsisdivinfo>
   <synopsis>
-CREATE USER <replaceable class="PARAMETER">username</replaceable>
-    [ WITH
-     [ SYSID <replaceable class="PARAMETER">uid</replaceable> ]
-     [ PASSWORD '<replaceable class="PARAMETER">password</replaceable>' ] ]
-    [ CREATEDB   | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ]
-    [ IN GROUP     <replaceable class="PARAMETER">groupname</replaceable> [, ...] ]
-    [ VALID UNTIL  '<replaceable class="PARAMETER">abstime</replaceable>' ]
+CREATE USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
+
+where <replaceable class="PARAMETER">option</replaceable> can be:
+    
+         SYSID <replaceable class="PARAMETER">uid</replaceable> 
+        | PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+        | CREATEDB | NOCREATEDB
+        | CREATEUSER | NOCREATEUSER
+        | IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...]
+        | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' 
   </synopsis>
   
   <refsect2 id="R2-SQL-CREATEUSER-1">
@@ -115,6 +118,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
       <listitem>
        <para>
        A name of a group into which to insert the user as a new member.
+       Multiple group names may be listed.
        </para>
       </listitem>
      </varlistentry>
@@ -164,7 +168,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
    Description
   </title>
   <para>
-   CREATE USER will add a new user to an instance of 
+   <command>CREATE USER</command> will add a new user to an instance of 
    <productname>Postgres</productname>. Refer to the administrator's
    guide for information about managing users and authentication.
    You must be a database superuser to use this command.
@@ -173,7 +177,8 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable>
    Use <xref linkend="SQL-ALTERUSER" endterm="SQL-ALTERUSER-title">
    to change a user's password and privileges, and <xref linkend="SQL-DROPUSER"
    endterm="SQL-DROPUSER-title"> to remove a user.
-   Use <command>ALTER GROUP</command> to add or remove the user from other groups.
+   Use <xref linkend="SQL-ALTERGROUP" endterm="SQL-ALTERGROUP-title">
+   to add or remove the user from other groups.
    <productname>Postgres</productname>
    comes with a script <xref linkend="APP-CREATEUSER"
    endterm="APP-CREATEUSER-title">
index 7ce61b72cc84a00dbc3ca45d1cad8cb3a3c8b6b1..e8374725b34bd3cc8e98d224ca092a866bd6f5ec 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.16 2001/05/25 15:45:31 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.17 2001/07/10 22:09:28 tgl Exp $
 Postgres documentation
 -->
 
@@ -20,16 +20,16 @@ Postgres documentation
  </refnamediv>
  <refsynopsisdiv>
   <refsynopsisdivinfo>
-   <date>2001-05-04</date>
+   <date>2001-07-10</date>
   </refsynopsisdivinfo>
   <synopsis>
-VACUUM [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
-VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
+VACUUM [ FULL ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
+VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
   </synopsis>
 
   <refsect2 id="R2-SQL-VACUUM-1">
    <refsect2info>
-    <date>1998-10-04</date>
+    <date>2001-07-10</date>
    </refsect2info>
    <title>
     Inputs
@@ -37,6 +37,15 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable>
 
    <para>
     <variablelist>
+     <varlistentry>
+      <term>FULL</term>
+      <listitem>
+       <para>
+        Selects <quote>full</quote> vacuum, which may reclaim more space,
+       but takes much longer and exclusively locks the table.
+       </para>
+      </listitem>
+     </varlistentry>
      <varlistentry>
       <term>VERBOSE</term>
       <listitem>
@@ -58,7 +67,8 @@ VACUUM [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable>
       <term><replaceable class="PARAMETER">table</replaceable></term>
       <listitem>
        <para>
-       The name of a specific table to vacuum. Defaults to all tables.
+       The name of a specific table to vacuum. Defaults to all tables
+       in the current database.
        </para>
       </listitem>
      </varlistentry>
@@ -138,7 +148,7 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
 
  <refsect1 id="R1-SQL-VACUUM-1">
   <refsect1info>
-   <date>1998-10-04</date>
+   <date>2001-07-10</date>
   </refsect1info>
   <title>
    Description
@@ -158,6 +168,16 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
    only that table.
   </para>
 
+  <para>
+   Plain <command>VACUUM</command> simply reclaims space and makes it
+   available for re-use.  This form of the command can operate in parallel
+   with normal reading and writing of the table.  <command>VACUUM
+   FULL</command> does more extensive processing, including moving of tuples
+   across blocks to try to compact the table to the minimum number of disk
+   blocks.  This is much slower and requires an exclusive lock on each table
+   while it is being processed.
+  </para>
+
   <para>
    <command>VACUUM ANALYZE</command> performs a <command>VACUUM</command>
    and then an <command>ANALYZE</command> for each selected table.  This
@@ -168,7 +188,7 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
 
   <refsect2 id="R2-SQL-VACUUM-3">
    <refsect2info>
-    <date>1998-10-04</date>
+    <date>2001-07-10</date>
    </refsect2info>
    <title>
     Notes
@@ -176,8 +196,8 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
 
    <para>
     We recommend that active production databases be
-    <command>VACUUM</command>-ed nightly, in order to remove
-    expired rows. After copying a large table into
+    <command>VACUUM</command>-ed frequently (at least nightly), in order to
+    remove expired rows. After copying a large table into
     <productname>Postgres</productname> or after deleting a large number
     of records, it may be a good idea to issue a <command>VACUUM
     ANALYZE</command> command for the affected table. This will update the
@@ -187,6 +207,14 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
     choices in planning user queries.
    </para>
 
+   <para>
+    The <option>FULL</option> option is not recommended for routine use,
+    but may be useful in special cases.  An example is when you have deleted
+    most of the rows in a table and would like the table to physically shrink
+    to occupy less disk space.  <command>VACUUM FULL</command> will usually
+    shrink the table more than a plain <command>VACUUM</command> would.
+   </para>
+
   </refsect2>
  </refsect1>
 
index 1efa7fce93bd47ce101ea43af7017f37272ff705..141d2dcd57bfac2d00567422ed42d390397583a5 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.16 2001/03/17 16:27:31 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.17 2001/07/10 22:09:28 tgl Exp $
 Postgres documentation
 -->
 
@@ -24,8 +24,9 @@ Postgres documentation
    <command>vacuumdb</command>
    <arg rep="repeat"><replaceable>connection-options</replaceable></arg>
    <arg><arg>-d</arg> <replaceable>dbname</replaceable></arg>
-   <group><arg>--analyze</arg><arg>-z</arg></group>
+   <group><arg>--full</arg><arg>-f</arg></group>
    <group><arg>--verbose</arg><arg>-v</arg></group>
+   <group><arg>--analyze</arg><arg>-z</arg></group>
    <arg>--table '<replaceable>table</replaceable>
     <arg>( <replaceable class="parameter">column</replaceable> [,...] )</arg>'
    </arg>
@@ -33,8 +34,9 @@ Postgres documentation
    <command>vacuumdb</command>
    <arg rep="repeat"><replaceable>connection-options</replaceable></arg>
    <group><arg>--all</arg><arg>-a</arg></group>
-   <group><arg>--analyze</arg><arg>-z</arg></group>
+   <group><arg>--full</arg><arg>-f</arg></group>
    <group><arg>--verbose</arg><arg>-v</arg></group>
+   <group><arg>--analyze</arg><arg>-z</arg></group>
   </cmdsynopsis>
 
   <refsect2 id="R2-APP-VACUUMDB-1">
@@ -56,21 +58,21 @@ Postgres documentation
      </varlistentry>
 
      <varlistentry>
-      <term>-z</term>
-      <term>--analyze</term>
+      <term>-a</term>
+      <term>--alldb</term>
       <listitem>
        <para>
-       Calculate statistics on the database for use by the optimizer.
+       Vacuum all databases.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term>-a</term>
-      <term>--alldb</term>
+      <term>-f</term>
+      <term>--full</term>
       <listitem>
        <para>
-       Vacuum all databases.
+        Perform <quote>full</quote> vacuuming.
        </para>
       </listitem>
      </varlistentry>
@@ -85,6 +87,16 @@ Postgres documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term>-z</term>
+      <term>--analyze</term>
+      <listitem>
+       <para>
+       Calculate statistics for use by the optimizer.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term>-t <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term>
       <term>--table <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</term>
@@ -257,7 +269,7 @@ Postgres documentation
 
   <informalexample>
    <para>
-    To analyze for the optimzer a database named
+    To clean and analyze for the optimizer a database named
     <literal>bigdb</literal>:
 <screen>
 <prompt>$ </prompt><userinput>vacuumdb --analyze bigdb</userinput>
@@ -267,9 +279,10 @@ Postgres documentation
 
   <informalexample>
    <para>
-    To analyze a single column <literal>bar</literal> in table
+    To clean a single table
     <literal>foo</literal> in a database named
-    <literal>xyzzy</literal> for the optimizer:
+    <literal>xyzzy</literal>, and analyze a single column
+    <literal>bar</literal> of the table for the optimizer:
 <screen>
 <prompt>$ </prompt><userinput>vacuumdb --analyze --verbose --table 'foo(bar)' xyzzy</userinput>
 </screen>
index 3d003616c09bb2ab137a9044b4b1e07f91de9a1c..e840b9109f8921e607f3f49424bd2a6229a0434a 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.77 2001/06/14 01:09:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.78 2001/07/10 22:09:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -197,14 +197,80 @@ CreateUser(CreateUserStmt *stmt)
        char            new_record_nulls[Natts_pg_shadow];
        bool            user_exists = false,
                                sysid_exists = false,
-                               havesysid;
+                               havesysid = false;
        int                     max_id = -1;
-       List       *item;
-
-       havesysid = stmt->sysid > 0;
+       List       *item, *option;
+       char       *password = NULL;    /* PostgreSQL user password */
+       int                     sysid = 0;                      /* PgSQL system id (valid if havesysid) */
+       bool            createdb = false;       /* Can the user create databases? */
+       bool            createuser = false;     /* Can this user create users? */
+       List       *groupElts = NIL;    /* The groups the user is a member of */
+       char       *validUntil = NULL;  /* The time the login is valid until */
+    DefElem    *dpassword = NULL;
+    DefElem    *dsysid = NULL;
+    DefElem    *dcreatedb = NULL;
+    DefElem    *dcreateuser = NULL;
+    DefElem    *dgroupElts = NULL;
+    DefElem    *dvalidUntil = NULL;
+
+       /* Extract options from the statement node tree */
+       foreach(option, stmt->options)
+       {
+               DefElem *defel = (DefElem *) lfirst(option);
+
+        if (strcasecmp(defel->defname, "password") == 0) {
+            if (dpassword)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dpassword = defel;
+        }
+        else if (strcasecmp(defel->defname, "sysid") == 0) {
+            if (dsysid)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dsysid = defel;
+        }
+        else if (strcasecmp(defel->defname, "createdb") == 0) {
+            if (dcreatedb)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dcreatedb = defel;
+        }
+        else if (strcasecmp(defel->defname, "createuser") == 0) {
+            if (dcreateuser)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dcreateuser = defel;
+        } 
+        else if (strcasecmp(defel->defname, "groupElts") == 0) {
+            if (dgroupElts)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dgroupElts = defel;
+        }
+        else if (strcasecmp(defel->defname, "validUntil") == 0) {
+            if (dvalidUntil)
+                elog(ERROR, "CREATE USER: conflicting options");
+            dvalidUntil = defel;
+        }
+        else 
+            elog(ERROR,"CREATE USER: option \"%s\" not recognized",
+                 defel->defname);
+    }
+
+    if (dcreatedb)
+               createdb = intVal(dcreatedb->arg) != 0;
+    if (dcreateuser)
+               createuser = intVal(dcreateuser->arg) != 0;
+    if (dsysid)
+       {
+               sysid = intVal(dsysid->arg);
+               havesysid = true;
+       }
+    if (dvalidUntil)
+               validUntil = strVal(dvalidUntil->arg);
+    if (dpassword)
+               password = strVal(dpassword->arg);
+    if (dgroupElts)
+               groupElts = (List *) dgroupElts->arg;
 
        /* Check some permissions first */
-       if (stmt->password)
+       if (password)
                CheckPgUserAclNotNull();
 
        if (!superuser())
@@ -235,7 +301,7 @@ CreateUser(CreateUserStmt *stmt)
                                                         pg_shadow_dsc, &null);
                Assert(!null);
                if (havesysid)                  /* customized id wanted */
-                       sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
+                       sysid_exists = (DatumGetInt32(datum) == sysid);
                else
                {
                        /* pick 1 + max */
@@ -249,30 +315,33 @@ CreateUser(CreateUserStmt *stmt)
                elog(ERROR, "CREATE USER: user name \"%s\" already exists",
                         stmt->user);
        if (sysid_exists)
-               elog(ERROR, "CREATE USER: sysid %d is already assigned",
-                        stmt->sysid);
+               elog(ERROR, "CREATE USER: sysid %d is already assigned", sysid);
+
+       /* If no sysid given, use max existing id + 1 */
+       if (! havesysid)
+               sysid = max_id + 1;
 
        /*
         * Build a tuple to insert
         */
-       new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein,
-                                                                                       CStringGetDatum(stmt->user));
-       new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1);
+       new_record[Anum_pg_shadow_usename - 1] =
+               DirectFunctionCall1(namein, CStringGetDatum(stmt->user));
+       new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid);
 
-       AssertState(BoolIsValid(stmt->createdb));
-       new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb);
+       AssertState(BoolIsValid(createdb));
+       new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb);
        new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false);
-       AssertState(BoolIsValid(stmt->createuser));
-       new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser);
+       AssertState(BoolIsValid(createuser));
+       new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser);
        /* superuser gets catupd right by default */
-       new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(stmt->createuser);
+       new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser);
 
-       if (stmt->password)
+       if (password)
                new_record[Anum_pg_shadow_passwd - 1] =
-                       DirectFunctionCall1(textin, CStringGetDatum(stmt->password));
-       if (stmt->validUntil)
+                       DirectFunctionCall1(textin, CStringGetDatum(password));
+       if (validUntil)
                new_record[Anum_pg_shadow_valuntil - 1] =
-                       DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil));
+                       DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
 
        new_record_nulls[Anum_pg_shadow_usename - 1] = ' ';
        new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' ';
@@ -282,8 +351,8 @@ CreateUser(CreateUserStmt *stmt)
        new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
        new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' ';
 
-       new_record_nulls[Anum_pg_shadow_passwd - 1] = stmt->password ? ' ' : 'n';
-       new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n';
+       new_record_nulls[Anum_pg_shadow_passwd - 1] = password ? ' ' : 'n';
+       new_record_nulls[Anum_pg_shadow_valuntil - 1] = validUntil ? ' ' : 'n';
 
        tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls);
 
@@ -310,15 +379,14 @@ CreateUser(CreateUserStmt *stmt)
         * Add the user to the groups specified. We'll just call the below
         * AlterGroup for this.
         */
-       foreach(item, stmt->groupElts)
+       foreach(item, groupElts)
        {
                AlterGroupStmt ags;
 
                ags.name = strVal(lfirst(item));                /* the group name to add
                                                                                                 * this in */
                ags.action = +1;
-               ags.listUsers = makeList1(makeInteger(havesysid ?
-                                                                                         stmt->sysid : max_id + 1));
+               ags.listUsers = makeList1(makeInteger(sysid));
                AlterGroup(&ags, "CREATE USER");
        }
 
@@ -348,21 +416,69 @@ AlterUser(AlterUserStmt *stmt)
        HeapTuple       tuple,
                                new_tuple;
        bool            null;
+       List       *option;
+       char       *password = NULL;    /* PostgreSQL user password */
+       int                     createdb = -1;          /* Can the user create databases? */
+       int                     createuser = -1;        /* Can this user create users? */
+       char       *validUntil = NULL;  /* The time the login is valid until */
+       DefElem    *dpassword = NULL;
+       DefElem    *dcreatedb = NULL;
+       DefElem    *dcreateuser = NULL;
+       DefElem    *dvalidUntil = NULL;
+
+       /* Extract options from the statement node tree */
+       foreach(option,stmt->options)
+       {
+               DefElem *defel = (DefElem *) lfirst(option);
 
-       if (stmt->password)
+               if (strcasecmp(defel->defname, "password") == 0) {
+                       if (dpassword)
+                               elog(ERROR, "ALTER USER: conflicting options");
+                       dpassword = defel;
+               }
+               else if (strcasecmp(defel->defname, "createdb") == 0) {
+                       if (dcreatedb)
+                               elog(ERROR, "ALTER USER: conflicting options");
+                       dcreatedb = defel;
+               }
+               else if (strcasecmp(defel->defname, "createuser") == 0) {
+                       if (dcreateuser)
+                               elog(ERROR, "ALTER USER: conflicting options");
+                       dcreateuser = defel;
+               } 
+               else if (strcasecmp(defel->defname, "validUntil") == 0) {
+                       if (dvalidUntil)
+                               elog(ERROR, "ALTER USER: conflicting options");
+                       dvalidUntil = defel;
+               }
+               else 
+                       elog(ERROR,"ALTER USER: option \"%s\" not recognized",
+                                defel->defname);
+       }
+       if (dcreatedb)
+               createdb = intVal(dcreatedb->arg);
+       if (dcreateuser)
+               createuser = intVal(dcreateuser->arg);
+       if (dvalidUntil)
+               validUntil = strVal(dvalidUntil->arg);
+       if (dpassword)
+               password = strVal(dpassword->arg);
+       if (password)
                CheckPgUserAclNotNull();
 
        /* must be superuser or just want to change your own password */
        if (!superuser() &&
-               !(stmt->createdb == 0 &&
-                 stmt->createuser == 0 &&
-                 !stmt->validUntil &&
-                 stmt->password &&
+               !(createdb < 0 &&
+                 createuser < 0 &&
+                 !validUntil &&
+                 password &&
                  strcmp(GetUserName(GetUserId()), stmt->user) == 0))
                elog(ERROR, "ALTER USER: permission denied");
 
        /* changes to the flat password file cannot be rolled back */
-       if (IsTransactionBlock() && stmt->password)
+       if (IsTransactionBlock() && password)
                elog(NOTICE, "ALTER USER: password changes cannot be rolled back");
 
        /*
@@ -391,7 +507,7 @@ AlterUser(AlterUserStmt *stmt)
        new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' ';
 
        /* createdb */
-       if (stmt->createdb == 0)
+       if (createdb < 0)
        {
                /* don't change */
                new_record[Anum_pg_shadow_usecreatedb - 1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null);
@@ -399,7 +515,7 @@ AlterUser(AlterUserStmt *stmt)
        }
        else
        {
-               new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb > 0 ? true : false);
+               new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb > 0);
                new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' ';
        }
 
@@ -408,7 +524,7 @@ AlterUser(AlterUserStmt *stmt)
        new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' ';
 
        /* createuser (superuser) */
-       if (stmt->createuser == 0)
+       if (createuser < 0)
        {
                /* don't change */
                new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null);
@@ -416,14 +532,14 @@ AlterUser(AlterUserStmt *stmt)
        }
        else
        {
-               new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser > 0 ? true : false);
+               new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0);
                new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
        }
 
        /* catupd - set to false if someone's superuser priv is being yanked */
-       if (stmt->createuser < 0)
+       if (createuser == 0)
        {
-               new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (false);
+               new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(false);
                new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' ';
        }
        else
@@ -434,10 +550,10 @@ AlterUser(AlterUserStmt *stmt)
        }
 
        /* password */
-       if (stmt->password)
+       if (password)
        {
                new_record[Anum_pg_shadow_passwd - 1] =
-                       DirectFunctionCall1(textin, CStringGetDatum(stmt->password));
+                       DirectFunctionCall1(textin, CStringGetDatum(password));
                new_record_nulls[Anum_pg_shadow_passwd - 1] = ' ';
        }
        else
@@ -449,10 +565,10 @@ AlterUser(AlterUserStmt *stmt)
        }
 
        /* valid until */
-       if (stmt->validUntil)
+       if (validUntil)
        {
                new_record[Anum_pg_shadow_valuntil - 1] =
-                       DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil));
+                       DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
                new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' ';
        }
        else
@@ -761,9 +877,10 @@ CreateGroup(CreateGroupStmt *stmt)
        else
                max_id++;
 
-       new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
-       new_record[Anum_pg_group_grosysid - 1] = (Datum) (max_id);
-       new_record[Anum_pg_group_grolist - 1] = (Datum) userarray;
+       new_record[Anum_pg_group_groname - 1] =
+               DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+       new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(max_id);
+       new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(userarray);
 
        new_record_nulls[Anum_pg_group_groname - 1] = ' ';
        new_record_nulls[Anum_pg_group_grosysid - 1] = ' ';
@@ -832,7 +949,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
                                                                 * create user */
        {
                Datum           new_record[Natts_pg_group];
-               char            new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
+               char            new_record_nulls[Natts_pg_group];
                ArrayType  *newarray,
                                   *oldarray;
                List       *newlist = NULL,
@@ -914,9 +1031,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
                /*
                 * Form a tuple with the new array and write it back.
                 */
-               new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
+               new_record[Anum_pg_group_groname - 1] =
+                       DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+               new_record_nulls[Anum_pg_group_groname - 1] = ' ';
                new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
+               new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' ';
                new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray);
+               new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n';
 
                tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
                simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);
@@ -950,7 +1071,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
                {
                        HeapTuple       tuple;
                        Datum           new_record[Natts_pg_group];
-                       char            new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
+                       char            new_record_nulls[Natts_pg_group];
                        ArrayType  *oldarray,
                                           *newarray;
                        List       *newlist = NULL,
@@ -1014,9 +1135,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
                        /*
                         * Insert the new tuple with the updated user list
                         */
-                       new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
+                       new_record[Anum_pg_group_groname - 1] =
+                               DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+                       new_record_nulls[Anum_pg_group_groname - 1] = ' ';
                        new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
+                       new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' ';
                        new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray);
+                       new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n';
 
                        tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
                        simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);
index 6cf5b35d26664fddc6a9551986740ed4d39dcfb0..1768b881750a31c2a27950e6c81209809d547f9e 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.145 2001/06/19 22:39:11 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.146 2001/07/10 22:09:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2258,6 +2258,7 @@ _copyVacuumStmt(VacuumStmt *from)
        VacuumStmt *newnode = makeNode(VacuumStmt);
 
        newnode->vacuum = from->vacuum;
+       newnode->full = from->full;
        newnode->analyze = from->analyze;
        newnode->verbose = from->verbose;
        if (from->vacrel)
@@ -2404,14 +2405,7 @@ _copyCreateUserStmt(CreateUserStmt *from)
 
        if (from->user)
                newnode->user = pstrdup(from->user);
-       if (from->password)
-               newnode->password = pstrdup(from->password);
-       newnode->sysid = from->sysid;
-       newnode->createdb = from->createdb;
-       newnode->createuser = from->createuser;
-       Node_Copy(from, newnode, groupElts);
-       if (from->validUntil)
-               newnode->validUntil = pstrdup(from->validUntil);
+       Node_Copy(from, newnode, options);
 
        return newnode;
 }
@@ -2423,12 +2417,7 @@ _copyAlterUserStmt(AlterUserStmt *from)
 
        if (from->user)
                newnode->user = pstrdup(from->user);
-       if (from->password)
-               newnode->password = pstrdup(from->password);
-       newnode->createdb = from->createdb;
-       newnode->createuser = from->createuser;
-       if (from->validUntil)
-               newnode->validUntil = pstrdup(from->validUntil);
+       Node_Copy(from, newnode, options);
 
        return newnode;
 }
index b12b4c29127e664840f6d1e57a87a71de71d1e4d..b6a34e5f2f5fc27584ce66c6e12039018a1af291 100644 (file)
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.93 2001/06/19 22:39:11 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.94 2001/07/10 22:09:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1125,6 +1125,8 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
 {
        if (a->vacuum != b->vacuum)
                return false;
+       if (a->full != b->full)
+               return false;
        if (a->analyze != b->analyze)
                return false;
        if (a->verbose != b->verbose)
@@ -1265,17 +1267,7 @@ _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
 {
        if (!equalstr(a->user, b->user))
                return false;
-       if (!equalstr(a->password, b->password))
-               return false;
-       if (a->sysid != b->sysid)
-               return false;
-       if (a->createdb != b->createdb)
-               return false;
-       if (a->createuser != b->createuser)
-               return false;
-       if (!equal(a->groupElts, b->groupElts))
-               return false;
-       if (!equalstr(a->validUntil, b->validUntil))
+       if (!equal(a->options, b->options))
                return false;
 
        return true;
@@ -1286,13 +1278,7 @@ _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
 {
        if (!equalstr(a->user, b->user))
                return false;
-       if (!equalstr(a->password, b->password))
-               return false;
-       if (a->createdb != b->createdb)
-               return false;
-       if (a->createuser != b->createuser)
-               return false;
-       if (!equalstr(a->validUntil, b->validUntil))
+       if (!equal(a->options, b->options))
                return false;
 
        return true;
index 7e6f782984e53657fe8af0b2c478e64f71639407..20784ac1705f2d4add06ce800bca0364ac77071e 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.234 2001/07/09 22:18:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.235 2001/07/10 22:09:28 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -155,11 +155,10 @@ static void doNegateFloat(Value *v);
 %type <ival>   opt_lock, lock_type
 %type <boolean>        opt_force
 
-%type <ival>    user_createdb_clause, user_createuser_clause
-%type <str>            user_passwd_clause
-%type <ival>            sysid_clause
-%type <str>            user_valid_clause
-%type <list>   user_list, user_group_clause, users_in_new_group_clause
+%type <list>   user_list, users_in_new_group_clause
+
+%type <list>   OptUserList
+%type <defelt> OptUserElem
 
 %type <boolean>        TriggerActionTime, TriggerForSpec, PLangTrusted, opt_procedural
 
@@ -212,7 +211,8 @@ static void doNegateFloat(Value *v);
 %type <node>   substr_from, substr_for
 
 %type <boolean>        opt_binary, opt_using, opt_instead, opt_cursor
-%type <boolean>        opt_with_copy, index_opt_unique, opt_verbose, analyze_keyword
+%type <boolean>        opt_with_copy, index_opt_unique, opt_verbose, opt_full
+%type <boolean>        analyze_keyword
 
 %type <ival>   copy_dirn, direction, reindex_type, drop_type,
                opt_column, event, comment_type, comment_cl,
@@ -488,32 +488,18 @@ stmt :    AlterSchemaStmt
  *
  *****************************************************************************/
 
-CreateUserStmt:  CREATE USER UserId
-                 user_createdb_clause user_createuser_clause user_group_clause
-                 user_valid_clause
+CreateUserStmt:  CREATE USER UserId OptUserList 
                                {
                                        CreateUserStmt *n = makeNode(CreateUserStmt);
                                        n->user = $3;
-                    n->sysid = -1;
-                                       n->password = NULL;
-                                       n->createdb = $4 == +1 ? TRUE : FALSE;
-                                       n->createuser = $5 == +1 ? TRUE : FALSE;
-                                       n->groupElts = $6;
-                                       n->validUntil = $7;
+                                       n->options = $4;
                                        $$ = (Node *)n;
                                }
-                | CREATE USER UserId WITH sysid_clause user_passwd_clause
-                user_createdb_clause user_createuser_clause user_group_clause
-                user_valid_clause
+                | CREATE USER UserId WITH OptUserList
                {
                                        CreateUserStmt *n = makeNode(CreateUserStmt);
                                        n->user = $3;
-                    n->sysid = $5;
-                                       n->password = $6;
-                                       n->createdb = $7 == +1 ? TRUE : FALSE;
-                                       n->createuser = $8 == +1 ? TRUE : FALSE;
-                                       n->groupElts = $9;
-                                       n->validUntil = $10;
+                                       n->options = $5;
                                        $$ = (Node *)n;
                }                   
                ;
@@ -525,27 +511,18 @@ CreateUserStmt:  CREATE USER UserId
  *
  *****************************************************************************/
 
-AlterUserStmt:  ALTER USER UserId user_createdb_clause
-                               user_createuser_clause user_valid_clause
+AlterUserStmt:  ALTER USER UserId OptUserList
                                {
                                        AlterUserStmt *n = makeNode(AlterUserStmt);
                                        n->user = $3;
-                                       n->password = NULL;
-                                       n->createdb = $4;
-                                       n->createuser = $5;
-                                       n->validUntil = $6;
+                                       n->options = $4;
                                        $$ = (Node *)n;
                                }
-                       | ALTER USER UserId WITH PASSWORD Sconst
-                         user_createdb_clause
-                         user_createuser_clause user_valid_clause
+                       | ALTER USER UserId WITH OptUserList
                                {
                                        AlterUserStmt *n = makeNode(AlterUserStmt);
                                        n->user = $3;
-                                       n->password = $6;
-                                       n->createdb = $7;
-                                       n->createuser = $8;
-                                       n->validUntil = $9;
+                                       n->options = $5;
                                        $$ = (Node *)n;
                                }
                ;
@@ -565,28 +542,62 @@ DropUserStmt:  DROP USER user_list
                                }
                ;
 
-user_passwd_clause:  PASSWORD Sconst                   { $$ = $2; }
-                       | /*EMPTY*/                                                     { $$ = NULL; }
-               ;
-
-sysid_clause: SYSID Iconst
-                               {
-                                       if ($2 <= 0)
-                                               elog(ERROR, "sysid must be positive");
-                                       $$ = $2;
+/*
+ * Options for CREATE USER and ALTER USER
+ */
+OptUserList: OptUserList OptUserElem           { $$ = lappend($1, $2); }
+                       | /* EMPTY */                                   { $$ = NIL; }
+               ;
+
+OptUserElem:  PASSWORD Sconst
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "password";
+                                 $$->arg = (Node *)makeString($2);
+                               }
+              | SYSID Iconst
+                               {
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "sysid";
+                                 $$->arg = (Node *)makeInteger($2);
+                               }
+              | CREATEDB
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "createdb";
+                                 $$->arg = (Node *)makeInteger(TRUE);
+                               }
+              | NOCREATEDB
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "createdb";
+                                 $$->arg = (Node *)makeInteger(FALSE);
+                               }
+              | CREATEUSER
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "createuser";
+                                 $$->arg = (Node *)makeInteger(TRUE);
+                               }
+              | NOCREATEUSER
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "createuser";
+                                 $$->arg = (Node *)makeInteger(FALSE);
+                               }
+              | IN GROUP user_list
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "groupElts";
+                                 $$->arg = (Node *)$3;
+                               }
+              | VALID UNTIL Sconst
+                { 
+                                 $$ = makeNode(DefElem);
+                                 $$->defname = "validUntil";
+                                 $$->arg = (Node *)makeString($3);
                                }
-                       | /*EMPTY*/                                                     { $$ = -1; }
-               ;
-
-user_createdb_clause:  CREATEDB                                        { $$ = +1; }
-                       | NOCREATEDB                                            { $$ = -1; }
-                       | /*EMPTY*/                                                     { $$ = 0; }
-               ;
-
-user_createuser_clause:  CREATEUSER                            { $$ = +1; }
-                       | NOCREATEUSER                                          { $$ = -1; }
-                       | /*EMPTY*/                                                     { $$ = 0; }
-               ;
+        ;
 
 user_list:  user_list ',' UserId
                                {
@@ -598,13 +609,6 @@ user_list:  user_list ',' UserId
                                }
                ;
 
-user_group_clause:  IN GROUP user_list                 { $$ = $3; }
-                       | /*EMPTY*/                                                     { $$ = NULL; }
-               ;
-
-user_valid_clause:  VALID UNTIL SCONST                 { $$ = $3; }
-                       | /*EMPTY*/                                                     { $$ = NULL; }
-               ;
 
 
 /*****************************************************************************
@@ -619,21 +623,29 @@ CreateGroupStmt:  CREATE GROUP UserId
                                        CreateGroupStmt *n = makeNode(CreateGroupStmt);
                                        n->name = $3;
                                        n->sysid = -1;
-                                       n->initUsers = NULL;
+                                       n->initUsers = NIL;
                                        $$ = (Node *)n;
                                }
-                       | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
+                       | CREATE GROUP UserId WITH users_in_new_group_clause
                                {
                                        CreateGroupStmt *n = makeNode(CreateGroupStmt);
                                        n->name = $3;
-                                       n->sysid = $5;
-                                       n->initUsers = $6;
+                                       n->sysid = -1;
+                                       n->initUsers = $5;
+                                       $$ = (Node *)n;
+                               }
+                       | CREATE GROUP UserId WITH SYSID Iconst users_in_new_group_clause
+                               {
+                                       CreateGroupStmt *n = makeNode(CreateGroupStmt);
+                                       n->name = $3;
+                                       n->sysid = $6;
+                                       n->initUsers = $7;
                                        $$ = (Node *)n;
                                }
                ;
 
 users_in_new_group_clause:  USER user_list             { $$ = $2; }
-                       | /* EMPTY */                                           { $$ = NULL; }
+                       | /* EMPTY */                                           { $$ = NIL; }
                ;                         
 
 /*****************************************************************************
@@ -3073,31 +3085,34 @@ ClusterStmt:  CLUSTER index_name ON relation_name
  *
  *****************************************************************************/
 
-VacuumStmt:  VACUUM opt_verbose
+VacuumStmt:  VACUUM opt_full opt_verbose
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = true;
                                        n->analyze = false;
-                                       n->verbose = $2;
+                                       n->full = $2;
+                                       n->verbose = $3;
                                        n->vacrel = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
                                }
-               | VACUUM opt_verbose relation_name
+               | VACUUM opt_full opt_verbose relation_name
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = true;
                                        n->analyze = false;
-                                       n->verbose = $2;
-                                       n->vacrel = $3;
+                                       n->full = $2;
+                                       n->verbose = $3;
+                                       n->vacrel = $4;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
                                }
-               | VACUUM opt_verbose AnalyzeStmt
+               | VACUUM opt_full opt_verbose AnalyzeStmt
                                {
-                                       VacuumStmt *n = (VacuumStmt *) $3;
+                                       VacuumStmt *n = (VacuumStmt *) $4;
                                        n->vacuum = true;
-                                       n->verbose |= $2;
+                                       n->full = $2;
+                                       n->verbose |= $3;
                                        $$ = (Node *)n;
                                }
                ;
@@ -3107,6 +3122,7 @@ AnalyzeStmt:  analyze_keyword opt_verbose
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = false;
                                        n->analyze = true;
+                                       n->full = false;
                                        n->verbose = $2;
                                        n->vacrel = NULL;
                                        n->va_cols = NIL;
@@ -3117,6 +3133,7 @@ AnalyzeStmt:  analyze_keyword opt_verbose
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = false;
                                        n->analyze = true;
+                                       n->full = false;
                                        n->verbose = $2;
                                        n->vacrel = $3;
                                        n->va_cols = $4;
@@ -3132,6 +3149,10 @@ opt_verbose:  VERBOSE                                                    { $$ = TRUE; }
                | /*EMPTY*/                                                             { $$ = FALSE; }
                ;
 
+opt_full:  FULL                                                                        { $$ = TRUE; }
+               | /*EMPTY*/                                                             { $$ = FALSE; }
+               ;
+
 opt_name_list:  '(' name_list ')'                              { $$ = $2; }
                | /*EMPTY*/                                                             { $$ = NIL; }
                ;
index 214c995ee25e73339d7fa76d512c3ba35591a6d1..4245279275cecdf7791c5d0ed294d72dc7370c3b 100644 (file)
@@ -12,7 +12,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.16 2001/02/18 18:34:02 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.17 2001/07/10 22:09:29 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -20,6 +20,7 @@ CMDNAME=`basename $0`
 PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"`
 
 PSQLOPT=
+full=
 verbose=
 analyze=
 table=
@@ -97,6 +98,9 @@ do
         --table=*)
                 table=`echo $1 | sed 's/^--table=//'`
                 ;;
+       --full|-f)
+               full="FULL"
+               ;;
        --verbose|-v)
                verbose="VERBOSE"
                ;;
@@ -126,9 +130,10 @@ if [ "$usage" ]; then
        echo "  -W, --password                  Prompt for password"
        echo "  -d, --dbname=DBNAME             Database to vacuum"
        echo "  -a, --all                       Vacuum all databases"
-       echo "  -z, --analyze                   Update optimizer hints"
        echo "  -t, --table='TABLE[(columns)]'  Vacuum specific table only"
+       echo "  -f, --full                      Do full vacuuming"
        echo "  -v, --verbose                   Write a lot of output"
+       echo "  -z, --analyze                   Update optimizer hints"
        echo "  -e, --echo                      Show the command being sent to the backend"
         echo "  -q, --quiet                     Don't write any output"
         echo
@@ -154,7 +159,7 @@ fi
 for db in $dbname
 do
         [ "$alldb" -a "$quiet" -ne 1 ] && echo "Vacuuming $db"
-       ${PATHNAME}psql $PSQLOPT $ECHOOPT -c "VACUUM $verbose $analyze $table" -d $db
+       ${PATHNAME}psql $PSQLOPT $ECHOOPT -c "VACUUM $full $verbose $analyze $table" -d $db
        if [ $? -ne 0 ]; then
            echo "$CMDNAME: vacuum $table $db failed" 1>&2
            exit 1
index 42b72e8074afb37dcbc23d395f2bfd344ae02ed3..0e3bd2e4608070bce50a55e9d624cef1b26fb3e3 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.133 2001/06/23 00:07:34 momjian Exp $
+ * $Id: parsenodes.h,v 1.134 2001/07/10 22:09:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -339,23 +339,15 @@ typedef struct DropPLangStmt
 typedef struct CreateUserStmt
 {
        NodeTag         type;
-       char       *user;                       /* PostgreSQL user login                          */
-       char       *password;           /* PostgreSQL user password                       */
-       int                     sysid;                  /* PgSQL system id (-1 if don't care) */
-       bool            createdb;               /* Can the user create databases?         */
-       bool            createuser;             /* Can this user create users?            */
-       List       *groupElts;          /* The groups the user is a member of */
-       char       *validUntil;         /* The time the login is valid until  */
+       char       *user;                       /* PostgreSQL user login name */
+       List       *options;            /* List of DefElem nodes */
 } CreateUserStmt;
 
 typedef struct AlterUserStmt
 {
        NodeTag         type;
-       char       *user;                       /* PostgreSQL user login                          */
-       char       *password;           /* PostgreSQL user password                       */
-       int                     createdb;               /* Can the user create databases?         */
-       int                     createuser;             /* Can this user create users?            */
-       char       *validUntil;         /* The time the login is valid until  */
+       char       *user;                       /* PostgreSQL user login name */
+       List       *options;            /* List of DefElem nodes */
 } AlterUserStmt;
 
 typedef struct DropUserStmt
@@ -715,6 +707,7 @@ typedef struct VacuumStmt
 {
        NodeTag         type;
        bool            vacuum;                 /* do VACUUM step */
+       bool            full;                   /* do FULL (non-concurrent) vacuum */
        bool            analyze;                /* do ANALYZE step */
        bool            verbose;                /* print progress info */
        char       *vacrel;                     /* name of single table to process, or NULL */
index e0626025d8f825355e00b213d06b9aae7a6967e1..6b93e767e3e7da96319bec01fb34544b1db7e5df 100644 (file)
@@ -301,7 +301,8 @@ make_name(void)
 %type  <str>    NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
 %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type  <str>    opt_with_copy FetchStmt direction fetch_how_many from_in
-%type  <str>    ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose func_arg
+%type  <str>    ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
+%type  <str>    opt_full func_arg
 %type  <str>    analyze_keyword opt_name_list ExplainStmt index_params
 %type  <str>    index_list func_index index_elem opt_class access_method_clause
 %type  <str>    index_opt_unique IndexStmt func_return ConstInterval
@@ -309,14 +310,13 @@ make_name(void)
 %type  <str>    def_elem def_list definition DefineStmt select_with_parens
 %type  <str>    opt_instead event event_object RuleActionList opt_using
 %type  <str>   RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type  <str>    RuleStmt opt_column opt_name oper_argtypes sysid_clause
+%type  <str>    RuleStmt opt_column opt_name oper_argtypes
 %type  <str>    MathOp RemoveFuncStmt aggr_argtype for_update_clause
 %type  <str>    RemoveAggrStmt ExtendStmt opt_procedural select_no_parens
-%type  <str>    RemoveOperStmt RenameStmt all_Op user_valid_clause
+%type  <str>    RemoveOperStmt RenameStmt all_Op
 %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
 %type  <str>    VariableResetStmt AlterTableStmt DropUserStmt from_list
-%type  <str>    user_passwd_clause user_createdb_clause opt_trans
-%type  <str>    user_createuser_clause user_list user_group_clause
+%type  <str>    opt_trans user_list OptUserList OptUserElem
 %type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
 %type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
 %type  <str>   DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
@@ -593,17 +593,13 @@ stmt:  AlterSchemaStmt                    { output_statement($1, 0, NULL, connection); }
  *
  *****************************************************************************/
 
-CreateUserStmt: CREATE USER UserId
-               user_createdb_clause user_createuser_clause user_group_clause
-               user_valid_clause
-                               {
-                                       $$ = cat_str(6, make_str("create user"), $3, $4, $5, $6, $7);
-                               }
-               | CREATE USER UserId WITH sysid_clause user_passwd_clause
-               user_createdb_clause user_createuser_clause user_group_clause
-               user_valid_clause
+CreateUserStmt: CREATE USER UserId OptUserList
+               {
+                       $$ = cat_str(3, make_str("create user"), $3, $4);
+               }
+              | CREATE USER UserId WITH OptUserList
                {
-                                       $$ = cat_str(9, make_str("create user"), $3, make_str("with"), $5, $6, $7, $8, $9, $10);
+                       $$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5);
                }
                ;
 
@@ -614,17 +610,14 @@ CreateUserStmt: CREATE USER UserId
  *
  *****************************************************************************/
 
-AlterUserStmt:  ALTER USER UserId user_createdb_clause
-                               user_createuser_clause user_valid_clause
-                               {
-                                       $$ = cat_str(5, make_str("alter user"), $3, $4, $5, $6);
-                               }
-                       | ALTER USER UserId WITH PASSWORD StringConst
-                               user_createdb_clause
-                               user_createuser_clause user_valid_clause
-                               {
-                                       $$ = cat_str(7, make_str("alter user"), $3, make_str("with password"), $6, $7, $8, $9);
-                               }
+AlterUserStmt: ALTER USER UserId OptUserList
+               {
+                       $$ = cat_str(3, make_str("alter user"), $3, $4);
+               }
+              | ALTER USER UserId WITH OptUserList
+               {
+                       $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5);
+               }
                ;
 
 /*****************************************************************************
@@ -640,38 +633,46 @@ DropUserStmt:  DROP USER user_list
                                }
                ;
 
-user_passwd_clause:  PASSWORD StringConst      { $$ = cat2_str(make_str("password") , $2); }
-                       | /*EMPTY*/     { $$ = EMPTY; }
+/*
+ * Options for CREATE USER and ALTER USER
+ */
+OptUserList: OptUserList OptUserElem           { $$ = cat2_str($1, $2); }
+                       | /* EMPTY */                                   { $$ = EMPTY; }
                ;
 
-sysid_clause:  SYSID PosIntConst       { if (atoi($2) <= 0)
-                                               mmerror(ET_ERROR, "sysid must be positive");
-
-                                         $$ = cat2_str(make_str("sysid"), $2); }
-                       | /*EMPTY*/     { $$ = EMPTY; }
-                ;
-
-user_createdb_clause:  CREATEDB
+OptUserElem:  PASSWORD Sconst
+                { 
+                                       $$ = cat2_str(make_str("password"), $2);
+                               }
+              | SYSID Iconst
                                {
+                                       $$ = cat2_str(make_str("sysid"), $2);
+                               }
+              | CREATEDB
+                { 
                                        $$ = make_str("createdb");
                                }
-                       | NOCREATEDB
-                               {
+              | NOCREATEDB
+                { 
                                        $$ = make_str("nocreatedb");
                                }
-                       | /*EMPTY*/             { $$ = EMPTY; }
-               ;
-
-user_createuser_clause:  CREATEUSER
-                               {
+              | CREATEUSER
+                { 
                                        $$ = make_str("createuser");
                                }
-                       | NOCREATEUSER
-                               {
+              | NOCREATEUSER
+                { 
                                        $$ = make_str("nocreateuser");
                                }
-                       | /*EMPTY*/             { $$ = NULL; }
-               ;
+              | IN GROUP user_list
+                { 
+                                       $$ = cat2_str(make_str("in group"), $3); 
+                               }
+              | VALID UNTIL Sconst
+                { 
+                                       $$ = cat2_str(make_str("valid until"), $3); 
+                               }
+        ;
 
 user_list:  user_list ',' UserId
                                {
@@ -683,17 +684,6 @@ user_list:  user_list ',' UserId
                                }
                ;
 
-user_group_clause:  IN GROUP user_list
-                       {
-                               $$ = cat2_str(make_str("in group"), $3); 
-                       }
-                       | /*EMPTY*/             { $$ = EMPTY; }
-               ;
-
-user_valid_clause:  VALID UNTIL StringConst                    { $$ = cat2_str(make_str("valid until"), $3); }
-                       | /*EMPTY*/                     { $$ = EMPTY; }
-               ;
-
 
 /*****************************************************************************
  *
@@ -702,14 +692,18 @@ user_valid_clause:  VALID UNTIL StringConst                       { $$ = cat2_str(make_str("valid un
  *
  ****************************************************************************/
 CreateGroupStmt: CREATE GROUP UserId
-                 {
-                       $$ = cat2_str(make_str("create group"), $3);
-                }
-               | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
-                 {
-                       $$ = cat_str(5, make_str("create group"), $3, make_str("with"), $5, $6);
-                 }
-                ;
+                               {
+                                       $$ = cat2_str(make_str("create group"), $3);
+                               }
+                       | CREATE GROUP UserId WITH users_in_new_group_clause
+                               {
+                                       $$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5);
+                               }
+                       | CREATE GROUP UserId WITH SYSID Iconst users_in_new_group_clause
+                               {
+                                       $$ = cat_str(5, make_str("create group"), $3, make_str("with sysid"), $6, $7);
+                               }
+                       ;
 
 users_in_new_group_clause:  USER user_list   { $$ = cat2_str(make_str("user"), $2); }
                             | /* EMPTY */          { $$ = EMPTY; }
@@ -2289,17 +2283,17 @@ ClusterStmt:  CLUSTER index_name ON relation_name
  *
  *****************************************************************************/
 
-VacuumStmt:  VACUUM opt_verbose
+VacuumStmt:  VACUUM opt_full opt_verbose
                                {
-                                       $$ = cat_str(2, make_str("vacuum"), $2);
+                                       $$ = cat_str(3, make_str("vacuum"), $2, $3);
                                }
-               | VACUUM opt_verbose relation_name
+               | VACUUM opt_full opt_verbose relation_name
                                {
-                                       $$ = cat_str(3, make_str("vacuum"), $2, $3);
+                                       $$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
                                }
-               | VACUUM opt_verbose AnalyzeStmt
+               | VACUUM opt_full opt_verbose AnalyzeStmt
                                {
-                                       $$ = cat_str(3, make_str("vacuum"), $2, $3);
+                                       $$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
                                }
                ;
 
@@ -2318,7 +2312,11 @@ analyze_keyword:  ANALYZE                                        { $$ = make_str("analyze"); }
                ;
 
 opt_verbose:  VERBOSE                                  { $$ = make_str("verbose"); }
-               | /*EMPTY*/                             { $$ = EMPTY; }
+               | /*EMPTY*/                                             { $$ = EMPTY; }
+               ;
+
+opt_full:  FULL                                                        { $$ = make_str("full"); }
+               | /*EMPTY*/                                             { $$ = EMPTY; }
                ;
 
 opt_name_list:  '(' name_list ')'              { $$ = cat_str(3, make_str("("), $2, make_str(")")); }