From 5e66a51c2eebaad4c0d78e3f776d74b2c5a0d1bc Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 16 Nov 2009 21:32:07 +0000 Subject: [PATCH] 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 --- doc/src/sgml/maintenance.sgml | 7 +-- doc/src/sgml/ref/vacuum.sgml | 15 +++++- src/backend/commands/analyze.c | 12 ++--- src/backend/commands/vacuum.c | 41 ++++++++------ src/backend/commands/vacuumlazy.c | 7 +-- src/backend/nodes/copyfuncs.c | 7 +-- src/backend/nodes/equalfuncs.c | 7 +-- src/backend/parser/gram.y | 81 +++++++++++++++++++++------- src/backend/postmaster/autovacuum.c | 11 ++-- src/backend/tcop/utility.c | 4 +- src/include/nodes/parsenodes.h | 21 +++++--- src/test/regress/expected/vacuum.out | 3 +- src/test/regress/sql/vacuum.sql | 4 +- 13 files changed, 146 insertions(+), 74 deletions(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 80b6365226..686a4e9d56 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -1,4 +1,4 @@ - + Routine Database Maintenance Tasks @@ -502,8 +502,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; only scans pages that have been modified since the last vacuum, but relfrozenxid can only be advanced when the whole table is scanned. The whole table is scanned when relfrozenxid is - more than vacuum_freeze_table_age transactions old, when the - VACUUM FREEZE command is used, or when all pages happen to + more than vacuum_freeze_table_age transactions old, when + VACUUM's FREEZE option is used, or when all pages + happen to require vacuuming to remove dead row versions. When VACUUM scans the whole table, after it's finished age(relfrozenxid) should be a little more than the vacuum_freeze_min_age setting diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index 205165e717..3b5d241703 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -1,5 +1,5 @@ @@ -21,6 +21,7 @@ PostgreSQL documentation +VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ table [ (column [, ...] ) ] ] VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ] VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ] @@ -63,6 +64,15 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ blocks. This form is much slower and requires an exclusive lock on each table while it is being processed. + + + 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 PostgreSQL 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. + @@ -127,6 +137,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ The name of a specific column to analyze. Defaults to all columns. + If a column list is specified, ANALYZE is implied. @@ -214,7 +225,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table in the regression database: -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 38cf57aba0..ab1fe9bf0e 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 bb1a2077ff..eeee7654e0 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 92fee334ff..50c96e948e 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 a9efce4053..b48909a3c5 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 d60d238be9..c69468ae7a 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 a61729135b..e80fffd3be 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 opt_lock lock_type cast_context +%type vacuum_option_list vacuum_option_elem %type 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 41bd37d72a..e4ab771b7f 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 025a03f19a..f0ef9d6406 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 2384e38ab7..b51f1d9892 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 1a578a0c9b..1a139d0377 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 368499ac4c..e1686971c9 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; -- GitLab