aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-11-16 21:32:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-11-16 21:32:07 +0000
commit5e66a51c2eebaad4c0d78e3f776d74b2c5a0d1bc (patch)
treecda9e19e07b87dfbd4ca411ad8cc1b496348536d
parent49ed392cd8721226c73b6bfe09e976acd72ef4de (diff)
downloadpostgresql-5e66a51c2eebaad4c0d78e3f776d74b2c5a0d1bc.tar.gz
postgresql-5e66a51c2eebaad4c0d78e3f776d74b2c5a0d1bc.zip
Provide a parenthesized-options syntax for VACUUM, analogous to that recently
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
-rw-r--r--doc/src/sgml/maintenance.sgml7
-rw-r--r--doc/src/sgml/ref/vacuum.sgml15
-rw-r--r--src/backend/commands/analyze.c12
-rw-r--r--src/backend/commands/vacuum.c41
-rw-r--r--src/backend/commands/vacuumlazy.c7
-rw-r--r--src/backend/nodes/copyfuncs.c7
-rw-r--r--src/backend/nodes/equalfuncs.c7
-rw-r--r--src/backend/parser/gram.y81
-rw-r--r--src/backend/postmaster/autovacuum.c11
-rw-r--r--src/backend/tcop/utility.c4
-rw-r--r--src/include/nodes/parsenodes.h21
-rw-r--r--src/test/regress/expected/vacuum.out3
-rw-r--r--src/test/regress/sql/vacuum.sql4
13 files changed, 146 insertions, 74 deletions
diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index 80b6365226b..686a4e9d56d 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -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
diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml
index 205165e7176..3b5d241703d 100644
--- a/doc/src/sgml/ref/vacuum.sgml
+++ b/doc/src/sgml/ref/vacuum.sgml
@@ -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.
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 38cf57aba08..ab1fe9bf0eb 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -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++)
{
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index bb1a2077ffa..eeee7654e0e 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -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;
}
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 92fee334ff4..50c96e948ea 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -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)
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index a9efce40532..b48909a3c5a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $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);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index d60d238be93..c69468ae7aa 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -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);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a61729135bd..e80fffd3bed 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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;
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 41bd37d72a6..e4ab771b7f6 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -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;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 025a03f19a9..f0ef9d6406f 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -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";
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2384e38ab7d..b51f1d9892f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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 */
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index 1a578a0c9b5..1a139d03773 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -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;
diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql
index 368499ac4c6..e1686971c96 100644
--- a/src/test/regress/sql/vacuum.sql
+++ b/src/test/regress/sql/vacuum.sql
@@ -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;