diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index fd911f57766..906d0c2ad7c 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -26,12 +26,12 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ option can be one of: - FULL - FREEZE - VERBOSE - ANALYZE - DISABLE_PAGE_SKIPPING - SKIP_LOCKED + FULL [ boolean ] + FREEZE [ boolean ] + VERBOSE [ boolean ] + ANALYZE [ boolean ] + DISABLE_PAGE_SKIPPING [ boolean ] + SKIP_LOCKED [ boolean ] and table_and_columns is: @@ -181,6 +181,20 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ boolean + + + Specifies whether the selected option should be turned on or off. + You can write TRUE, ON, or + 1 to enable the option, and FALSE, + OFF, or 0 to disable it. The + boolean value can also + be omitted, in which case TRUE is assumed. + + + + table_name diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index f0afeaf40c2..10df766f1ca 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -36,6 +36,7 @@ #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "commands/cluster.h" +#include "commands/defrem.h" #include "commands/vacuum.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -86,10 +87,14 @@ void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) { VacuumParams params; + bool verbose = false; + bool skip_locked = false; + bool analyze = false; + bool freeze = false; + bool full = false; + bool disable_page_skipping = false; ListCell *lc; - params.options = vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE; - /* Parse options list */ foreach(lc, vacstmt->options) { @@ -97,9 +102,9 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) /* Parse common options for VACUUM and ANALYZE */ if (strcmp(opt->defname, "verbose") == 0) - params.options |= VACOPT_VERBOSE; + verbose = defGetBoolean(opt); else if (strcmp(opt->defname, "skip_locked") == 0) - params.options |= VACOPT_SKIP_LOCKED; + skip_locked = defGetBoolean(opt); else if (!vacstmt->is_vacuumcmd) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -108,13 +113,13 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) /* Parse options available on VACUUM */ else if (strcmp(opt->defname, "analyze") == 0) - params.options |= VACOPT_ANALYZE; + analyze = defGetBoolean(opt); else if (strcmp(opt->defname, "freeze") == 0) - params.options |= VACOPT_FREEZE; + freeze = defGetBoolean(opt); else if (strcmp(opt->defname, "full") == 0) - params.options |= VACOPT_FULL; + full = defGetBoolean(opt); else if (strcmp(opt->defname, "disable_page_skipping") == 0) - params.options |= VACOPT_DISABLE_PAGE_SKIPPING; + disable_page_skipping = defGetBoolean(opt); else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -122,6 +127,16 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) parser_errposition(pstate, opt->location))); } + /* Set vacuum options */ + params.options = + (vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE) | + (verbose ? VACOPT_VERBOSE : 0) | + (skip_locked ? VACOPT_SKIP_LOCKED : 0) | + (analyze ? VACOPT_ANALYZE : 0) | + (freeze ? VACOPT_FREEZE : 0) | + (full ? VACOPT_FULL : 0) | + (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0); + /* sanity checks on options */ Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE)); Assert((params.options & VACOPT_VACUUM) || diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d711f9a7368..28f62de97e5 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -309,6 +309,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type vac_analyze_option_name %type vac_analyze_option_elem %type vac_analyze_option_list +%type vac_analyze_option_arg %type opt_or_replace opt_grant_grant_option opt_grant_admin_option opt_nowait opt_if_exists opt_with_data @@ -10543,9 +10544,9 @@ analyze_keyword: ; vac_analyze_option_elem: - vac_analyze_option_name + vac_analyze_option_name vac_analyze_option_arg { - $$ = makeDefElem($1, NULL, @1); + $$ = makeDefElem($1, $2, @1); } ; @@ -10554,6 +10555,11 @@ vac_analyze_option_name: | analyze_keyword { $$ = "analyze"; } ; +vac_analyze_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | /* EMPTY */ { $$ = NULL; } + ; + opt_analyze: analyze_keyword { $$ = true; } | /*EMPTY*/ { $$ = false; } diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index ab69a2c946d..d6d8fd02f5a 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3444,6 +3444,8 @@ psql_completion(const char *text, int start, int end) if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE", "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED"); + else if (TailMatches("FULL|FREEZE|ANALYZE|VERBOSE|DISABLE_PAGE_SKIPPING|SKIP_LOCKED")) + COMPLETE_WITH("ON", "OFF"); } else if (HeadMatches("VACUUM") && TailMatches("(")) /* "VACUUM (" should be caught above, so assume we want columns */