Provide a parenthesized-options syntax for VACUUM, analogous to that recently
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Nov 2009 21:32:07 +0000 (21:32 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Nov 2009 21:32:07 +0000 (21:32 +0000)
adopted for EXPLAIN.  This will allow additional options to be implemented
in future without having to make them fully-reserved keywords.  The old syntax
remains available for existing options, however.

Itagaki Takahiro

13 files changed:
doc/src/sgml/maintenance.sgml
doc/src/sgml/ref/vacuum.sgml
src/backend/commands/analyze.c
src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/postmaster/autovacuum.c
src/backend/tcop/utility.c
src/include/nodes/parsenodes.h
src/test/regress/expected/vacuum.out
src/test/regress/sql/vacuum.sql

index 80b6365226b8377b4678f924f9ad8fc921751958..686a4e9d56d9c445746518c8173d23c348439183 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.96 2009/08/07 20:54:31 alvherre Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.97 2009/11/16 21:32:06 tgl Exp $ -->
 
 <chapter id="maintenance">
  <title>Routine Database Maintenance Tasks</title>
@@ -502,8 +502,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database;
     only scans pages that have been modified since the last vacuum, but
     <structfield>relfrozenxid</> can only be advanced when the whole table is
     scanned. The whole table is scanned when <structfield>relfrozenxid</> is
-    more than <varname>vacuum_freeze_table_age</> transactions old, when the
-    <command>VACUUM FREEZE</> command is used, or when all pages happen to
+    more than <varname>vacuum_freeze_table_age</> transactions old, when
+    <command>VACUUM</>'s <literal>FREEZE</> option is used, or when all pages
+    happen to
     require vacuuming to remove dead row versions. When <command>VACUUM</>
     scans the whole table, after it's finished <literal>age(relfrozenxid)</>
     should be a little more than the <varname>vacuum_freeze_min_age</> setting
index 205165e7176338053558a00a266d4f3a7c05a287..3b5d241703da75a9ee232ca6172cc5b020d4a857 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.55 2009/03/24 20:17:08 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.56 2009/11/16 21:32:06 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -21,6 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
+VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
 VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
 VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
 </synopsis>
@@ -63,6 +64,15 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
    blocks.  This form is much slower and requires an exclusive lock on each
    table while it is being processed.
   </para>
+
+  <para>
+   When the option list is surrounded by parentheses, the options can be
+   written in any order.  Without parentheses, options must be specified
+   in exactly the order shown above.
+   Prior to <productname>PostgreSQL</productname> 8.5, the unparenthesized
+   syntax was the only one supported.  It is expected that all new options
+   will be supported only in the parenthesized syntax.
+  </para>
  </refsect1>
 
  <refsect1>
@@ -127,6 +137,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
     <listitem>
      <para>
       The name of a specific column to analyze. Defaults to all columns.
+      If a column list is specified, <literal>ANALYZE</> is implied.
      </para>
     </listitem>
    </varlistentry>
@@ -214,7 +225,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
    table in the regression database:
 
 <programlisting>
-regression=# VACUUM VERBOSE ANALYZE onek;
+regression=# VACUUM (VERBOSE, ANALYZE) onek;
 INFO:  vacuuming "public.onek"
 INFO:  index "onek_unique1" now contains 1000 tuples in 14 pages
 DETAIL:  3000 index tuples were removed.
index 38cf57aba08a022f8623b9d1ca7594d7c04f94c6..ab1fe9bf0eba9d73a2ee4ca60101c628158e1b65 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.141 2009/08/12 18:23:49 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.142 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -135,7 +135,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
        Oid                     save_userid;
        bool            save_secdefcxt;
 
-       if (vacstmt->verbose)
+       if (vacstmt->options & VACOPT_VERBOSE)
                elevel = INFO;
        else
                elevel = DEBUG2;
@@ -173,7 +173,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
                  (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
        {
                /* No need for a WARNING if we already complained during VACUUM */
-               if (!vacstmt->vacuum)
+               if (!(vacstmt->options & VACOPT_VACUUM))
                {
                        if (onerel->rd_rel->relisshared)
                                ereport(WARNING,
@@ -199,7 +199,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
        if (onerel->rd_rel->relkind != RELKIND_RELATION)
        {
                /* No need for a WARNING if we already complained during VACUUM */
-               if (!vacstmt->vacuum)
+               if (!(vacstmt->options & VACOPT_VACUUM))
                        ereport(WARNING,
                                        (errmsg("skipping \"%s\" --- cannot analyze indexes, views, or special system tables",
                                                        RelationGetRelationName(onerel))));
@@ -475,7 +475,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
         * VACUUM ANALYZE, don't overwrite the accurate count already inserted by
         * VACUUM.
         */
-       if (!vacstmt->vacuum)
+       if (!(vacstmt->options & VACOPT_VACUUM))
        {
                for (ind = 0; ind < nindexes; ind++)
                {
@@ -493,7 +493,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
 cleanup:
 
        /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
-       if (!vacstmt->vacuum)
+       if (!(vacstmt->options & VACOPT_VACUUM))
        {
                for (ind = 0; ind < nindexes; ind++)
                {
index bb1a2077ffa9aed063d50d3ad2966216d64feb73..eeee7654e0e47aad0594f1850dad4265dcdf465c 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.395 2009/11/10 18:00:06 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.396 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -289,14 +289,22 @@ void
 vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
           BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
 {
-       const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE";
+       const char *stmttype;
        volatile MemoryContext anl_context = NULL;
        volatile bool all_rels,
                                in_outer_xact,
                                use_own_xacts;
        List       *relations;
 
-       if (vacstmt->verbose)
+       /* sanity checks on options */
+       Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));
+       Assert((vacstmt->options & VACOPT_VACUUM) ||
+                  !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE)));
+       Assert((vacstmt->options & VACOPT_ANALYZE) || vacstmt->va_cols == NIL);
+
+       stmttype = (vacstmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
+
+       if (vacstmt->options & VACOPT_VERBOSE)
                elevel = INFO;
        else
                elevel = DEBUG2;
@@ -315,7 +323,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
         *
         * ANALYZE (without VACUUM) can run either way.
         */
-       if (vacstmt->vacuum)
+       if (vacstmt->options & VACOPT_VACUUM)
        {
                PreventTransactionChain(isTopLevel, stmttype);
                in_outer_xact = false;
@@ -327,7 +335,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
         * Send info about dead objects to the statistics collector, unless we are
         * in autovacuum --- autovacuum.c does this for itself.
         */
-       if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
+       if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
                pgstat_vacuum_stat();
 
        /*
@@ -378,11 +386,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
         * transaction block, and also in an autovacuum worker, use own
         * transactions so we can release locks sooner.
         */
-       if (vacstmt->vacuum)
+       if (vacstmt->options & VACOPT_VACUUM)
                use_own_xacts = true;
        else
        {
-               Assert(vacstmt->analyze);
+               Assert(vacstmt->options & VACOPT_ANALYZE);
                if (IsAutoVacuumWorkerProcess())
                        use_own_xacts = true;
                else if (in_outer_xact)
@@ -438,11 +446,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
                        Oid                     relid = lfirst_oid(cur);
                        bool            scanned_all = false;
 
-                       if (vacstmt->vacuum)
+                       if (vacstmt->options & VACOPT_VACUUM)
                                vacuum_rel(relid, vacstmt, do_toast, for_wraparound,
                                                   &scanned_all);
 
-                       if (vacstmt->analyze)
+                       if (vacstmt->options & VACOPT_ANALYZE)
                        {
                                MemoryContext old_context = NULL;
 
@@ -502,7 +510,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
                StartTransactionCommand();
        }
 
-       if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
+       if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
        {
                /*
                 * Update pg_database.datfrozenxid, and truncate pg_clog if possible.
@@ -1034,7 +1042,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
         */
        PushActiveSnapshot(GetTransactionSnapshot());
 
-       if (!vacstmt->full)
+       if (!(vacstmt->options & VACOPT_FULL))
        {
                /*
                 * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
@@ -1074,7 +1082,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
         * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
         * way, we can be sure that no other backend is vacuuming the same table.
         */
-       lmode = vacstmt->full ? AccessExclusiveLock : ShareUpdateExclusiveLock;
+       lmode = (vacstmt->options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
 
        /*
         * Open the relation and get the appropriate lock on it.
@@ -1186,7 +1194,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
        /*
         * Do the actual work --- either FULL or "lazy" vacuum
         */
-       if (vacstmt->full)
+       if (vacstmt->options & VACOPT_FULL)
                heldoff = full_vacuum_rel(onerel, vacstmt);
        else
                heldoff = lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
@@ -1331,8 +1339,11 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
                                                vacrelstats->hasindex, FreezeLimit);
 
        /* report results to the stats collector, too */
-       pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
-                                                true, vacstmt->analyze, vacrelstats->rel_tuples);
+       pgstat_report_vacuum(RelationGetRelid(onerel),
+                                                onerel->rd_rel->relisshared,
+                                                true,
+                                                (vacstmt->options & VACOPT_ANALYZE) != 0,
+                                                vacrelstats->rel_tuples);
 
        return heldoff;
 }
index 92fee334ff4030c91461567cb2ca7193814023bf..50c96e948ead142b8a7ebe200559d9ec909943e2 100644 (file)
@@ -29,7 +29,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.123 2009/11/10 18:00:06 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.124 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -164,7 +164,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration > 0)
                starttime = GetCurrentTimestamp();
 
-       if (vacstmt->verbose)
+       if (vacstmt->options & VACOPT_VERBOSE)
                elevel = INFO;
        else
                elevel = DEBUG2;
@@ -236,7 +236,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
        pgstat_report_vacuum(RelationGetRelid(onerel),
                                                 onerel->rd_rel->relisshared,
                                                 vacrelstats->scanned_all,
-                                                vacstmt->analyze, vacrelstats->rel_tuples);
+                                                (vacstmt->options & VACOPT_ANALYZE) != 0,
+                                                vacrelstats->rel_tuples);
 
        /* and log the action if appropriate */
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
index a9efce40532a8a92ba5ef9c7a91be932ad8f60c3..b48909a3c5ad783f5157d2bdc5ed0aa237cd5853 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.450 2009/10/28 14:55:38 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.451 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2957,10 +2957,7 @@ _copyVacuumStmt(VacuumStmt *from)
 {
        VacuumStmt *newnode = makeNode(VacuumStmt);
 
-       COPY_SCALAR_FIELD(vacuum);
-       COPY_SCALAR_FIELD(full);
-       COPY_SCALAR_FIELD(analyze);
-       COPY_SCALAR_FIELD(verbose);
+       COPY_SCALAR_FIELD(options);
        COPY_SCALAR_FIELD(freeze_min_age);
        COPY_SCALAR_FIELD(freeze_table_age);
        COPY_NODE_FIELD(relation);
index d60d238be93e2f33ea8a078922a3472da3d7be3b..c69468ae7aab9bea04e0be884794c3d364029234 100644 (file)
@@ -22,7 +22,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.372 2009/10/28 14:55:38 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.373 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1483,10 +1483,7 @@ _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b)
 static bool
 _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
 {
-       COMPARE_SCALAR_FIELD(vacuum);
-       COMPARE_SCALAR_FIELD(full);
-       COMPARE_SCALAR_FIELD(analyze);
-       COMPARE_SCALAR_FIELD(verbose);
+       COMPARE_SCALAR_FIELD(options);
        COMPARE_SCALAR_FIELD(freeze_min_age);
        COMPARE_SCALAR_FIELD(freeze_table_age);
        COMPARE_NODE_FIELD(relation);
index a61729135bd70dd40309ed1361b7b6242cb80c61..e80fffd3bed105b19b20058dcba1e828de2958be 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.692 2009/11/11 20:31:26 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.693 2009/11/16 21:32:06 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -229,6 +229,7 @@ static TypeName *TableFuncTypeName(List *columns);
                                transaction_mode_item
 
 %type <ival>   opt_lock lock_type cast_context
+%type <ival>   vacuum_option_list vacuum_option_elem
 %type <boolean>        opt_force opt_or_replace
                                opt_grant_grant_option opt_grant_admin_option
                                opt_nowait opt_if_exists opt_with_data
@@ -6625,12 +6626,13 @@ cluster_index_specification:
 VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = true;
-                                       n->analyze = false;
-                                       n->full = $2;
+                                       n->options = VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose = $4;
                                        n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6638,12 +6640,13 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                        | VACUUM opt_full opt_freeze opt_verbose qualified_name
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = true;
-                                       n->analyze = false;
-                                       n->full = $2;
+                                       n->options = VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose = $4;
                                        n->relation = $5;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6651,25 +6654,64 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                        | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
                                {
                                        VacuumStmt *n = (VacuumStmt *) $5;
-                                       n->vacuum = true;
-                                       n->full = $2;
+                                       n->options |= VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose |= $4;
                                        $$ = (Node *)n;
                                }
+                       | VACUUM '(' vacuum_option_list ')'
+                               {
+                                       VacuumStmt *n = makeNode(VacuumStmt);
+                                       n->options = VACOPT_VACUUM | $3;
+                                       if (n->options & VACOPT_FREEZE)
+                                               n->freeze_min_age = n->freeze_table_age = 0;
+                                       else
+                                               n->freeze_min_age = n->freeze_table_age = -1;
+                                       n->relation = NULL;
+                                       n->va_cols = NIL;
+                                       $$ = (Node *) n;
+                               }
+                       | VACUUM '(' vacuum_option_list ')' qualified_name opt_name_list
+                               {
+                                       VacuumStmt *n = makeNode(VacuumStmt);
+                                       n->options = VACOPT_VACUUM | $3;
+                                       if (n->options & VACOPT_FREEZE)
+                                               n->freeze_min_age = n->freeze_table_age = 0;
+                                       else
+                                               n->freeze_min_age = n->freeze_table_age = -1;
+                                       n->relation = $5;
+                                       n->va_cols = $6;
+                                       if (n->va_cols != NIL)  /* implies analyze */
+                                               n->options |= VACOPT_ANALYZE;
+                                       $$ = (Node *) n;
+                               }
+               ;
+
+vacuum_option_list:
+                       vacuum_option_elem                                                              { $$ = $1; }
+                       | vacuum_option_list ',' vacuum_option_elem             { $$ = $1 | $3; }
+               ;
+
+vacuum_option_elem:
+                       analyze_keyword         { $$ = VACOPT_ANALYZE; }
+                       | VERBOSE                       { $$ = VACOPT_VERBOSE; }
+                       | FREEZE                        { $$ = VACOPT_FREEZE; }
+                       | FULL                          { $$ = VACOPT_FULL; }
                ;
 
 AnalyzeStmt:
                        analyze_keyword opt_verbose
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = false;
-                                       n->analyze = true;
-                                       n->full = false;
+                                       n->options = VACOPT_ANALYZE;
+                                       if ($2)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = -1;
                                        n->freeze_table_age = -1;
-                                       n->verbose = $2;
                                        n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6677,12 +6719,11 @@ AnalyzeStmt:
                        | analyze_keyword opt_verbose qualified_name opt_name_list
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = false;
-                                       n->analyze = true;
-                                       n->full = false;
+                                       n->options = VACOPT_ANALYZE;
+                                       if ($2)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = -1;
                                        n->freeze_table_age = -1;
-                                       n->verbose = $2;
                                        n->relation = $3;
                                        n->va_cols = $4;
                                        $$ = (Node *)n;
index 41bd37d72a655fdd062f428cd1e8ca5c45563e9b..e4ab771b7f6ccebf88d0997587c1641d279c8a62 100644 (file)
@@ -55,7 +55,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.104 2009/08/31 19:40:59 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.105 2009/11/16 21:32:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2640,12 +2640,13 @@ autovacuum_do_vac_analyze(autovac_table *tab,
        MemSet(&vacstmt, 0, sizeof(vacstmt));
 
        vacstmt.type = T_VacuumStmt;
-       vacstmt.vacuum = tab->at_dovacuum;
-       vacstmt.full = false;
-       vacstmt.analyze = tab->at_doanalyze;
+       vacstmt.options = 0;
+       if (tab->at_dovacuum)
+               vacstmt.options |= VACOPT_VACUUM;
+       if (tab->at_doanalyze)
+               vacstmt.options |= VACOPT_ANALYZE;
        vacstmt.freeze_min_age = tab->at_freeze_min_age;
        vacstmt.freeze_table_age = tab->at_freeze_table_age;
-       vacstmt.verbose = false;
        vacstmt.relation = NULL;        /* not used since we pass a relid */
        vacstmt.va_cols = NIL;
 
index 025a03f19a931a5e1e9736626bd670675c0cf4eb..f0ef9d6406fc6f35435aab0179eb4dad58f63389 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.316 2009/10/26 02:26:40 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.317 2009/11/16 21:32:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1815,7 +1815,7 @@ CreateCommandTag(Node *parsetree)
                        break;
 
                case T_VacuumStmt:
-                       if (((VacuumStmt *) parsetree)->vacuum)
+                       if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
                                tag = "VACUUM";
                        else
                                tag = "ANALYZE";
index 2384e38ab7db90cb628c409947edff9c1a47ddaf..b51f1d9892f6c51f222cc9e30e0dc5ad6547e749 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.414 2009/11/13 23:44:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.415 2009/11/16 21:32:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2209,16 +2209,25 @@ typedef struct ClusterStmt
  *             Vacuum and Analyze Statements
  *
  * Even though these are nominally two statements, it's convenient to use
- * just one node type for both.
+ * just one node type for both.  Note that at least one of VACOPT_VACUUM
+ * and VACOPT_ANALYZE must be set in options.  VACOPT_FREEZE is an internal
+ * convenience for the grammar and is not examined at runtime --- the
+ * freeze_min_age and freeze_table_age fields are what matter.
  * ----------------------
  */
+typedef enum VacuumOption
+{
+       VACOPT_VACUUM           = 1 << 0,       /* do VACUUM */
+       VACOPT_ANALYZE          = 1 << 1,       /* do ANALYZE */
+       VACOPT_VERBOSE          = 1 << 2,       /* print progress info */
+       VACOPT_FREEZE           = 1 << 3,       /* FREEZE option */
+       VACOPT_FULL                     = 1 << 4        /* FULL (non-concurrent) vacuum */
+} VacuumOption;
+
 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 */
+       int                     options;                /* OR of VacuumOption flags */
        int                     freeze_min_age; /* min freeze age, or -1 to use default */
        int                     freeze_table_age;               /* age at which to scan whole table */
        RangeVar   *relation;           /* single table to process, or NULL */
index 1a578a0c9b5c1c42dcd6298ad5f489401eb554e1..1a139d03773e920f0889fa72459888a978729db3 100644 (file)
@@ -49,11 +49,12 @@ SELECT count(*) FROM vactst;
 (1 row)
 
 DELETE FROM vactst WHERE i != 0;
-VACUUM FULL vactst;
+VACUUM (FULL) vactst;
 DELETE FROM vactst;
 SELECT * FROM vactst;
  i 
 ---
 (0 rows)
 
+VACUUM (FULL, FREEZE) vactst;
 DROP TABLE vactst;
index 368499ac4c676c2acd6cd2c82eccb03b00f6b914..e1686971c967427971cb5382f2b6a2b3b7c119f8 100644 (file)
@@ -35,8 +35,10 @@ INSERT INTO vactst SELECT * FROM vactst;
 INSERT INTO vactst VALUES (0);
 SELECT count(*) FROM vactst;
 DELETE FROM vactst WHERE i != 0;
-VACUUM FULL vactst;
+VACUUM (FULL) vactst;
 DELETE FROM vactst;
 SELECT * FROM vactst;
 
+VACUUM (FULL, FREEZE) vactst;
+
 DROP TABLE vactst;