From 7dfab04a8aad7aa5066d2625a649d407ed6b7a5f Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 2 Sep 2014 16:06:58 +0900 Subject: [PATCH] Support ALTER SYSTEM RESET command. This patch allows us to execute ALTER SYSTEM RESET command to remove the configuration entry from postgresql.auto.conf. Vik Fearing, reviewed by Amit Kapila and me. --- doc/src/sgml/ref/alter_system.sgml | 13 ++-- src/backend/parser/gram.y | 49 +++++++++----- src/backend/utils/misc/guc.c | 100 ++++++++++++++++++----------- src/bin/psql/tab-complete.c | 19 ++++-- 4 files changed, 117 insertions(+), 64 deletions(-) diff --git a/doc/src/sgml/ref/alter_system.sgml b/doc/src/sgml/ref/alter_system.sgml index 23c30efc8f..a6e32106e8 100644 --- a/doc/src/sgml/ref/alter_system.sgml +++ b/doc/src/sgml/ref/alter_system.sgml @@ -22,6 +22,9 @@ PostgreSQL documentation ALTER SYSTEM SET configuration_parameter { TO | = } { value | 'value' | DEFAULT } + +ALTER SYSTEM RESET configuration_parameter +ALTER SYSTEM RESET ALL @@ -30,10 +33,12 @@ ALTER SYSTEM SET configuration_parameter ALTER SYSTEM writes the configuration parameter - values to the postgresql.auto.conf file. With - DEFAULT, it removes a configuration entry from - postgresql.auto.conf file. The values will be - effective after reload of server configuration (SIGHUP) or in next + values to the postgresql.auto.conf file. + Setting the parameter to DEFAULT, or using the + RESET variant, removes the configuration entry from + postgresql.auto.conf file. Use RESET + ALL to clear all configuration entries. The values will + be effective after reload of server configuration (SIGHUP) or in next server start based on the type of configuration parameter modified. diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 2e9bbe232f..9d558a7b19 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -398,7 +398,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type insert_rest -%type generic_set set_rest set_rest_more SetResetClause FunctionSetResetClause +%type generic_set set_rest set_rest_more generic_reset reset_rest + SetResetClause FunctionSetResetClause %type TableElement TypedTableElement ConstraintElem TableFuncElement %type columnDef columnOptions @@ -1564,39 +1565,47 @@ NonReservedWord_or_Sconst: ; VariableResetStmt: - RESET var_name - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET; - n->name = $2; - $$ = (Node *) n; - } - | RESET TIME ZONE + RESET reset_rest { $$ = (Node *) $2; } + ; + +reset_rest: + generic_reset { $$ = $1; } + | TIME ZONE { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "timezone"; - $$ = (Node *) n; + $$ = n; } - | RESET TRANSACTION ISOLATION LEVEL + | TRANSACTION ISOLATION LEVEL { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "transaction_isolation"; - $$ = (Node *) n; + $$ = n; } - | RESET SESSION AUTHORIZATION + | SESSION AUTHORIZATION { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "session_authorization"; - $$ = (Node *) n; + $$ = n; } - | RESET ALL + ; + +generic_reset: + var_name + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; + n->name = $1; + $$ = n; + } + | ALL { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET_ALL; - $$ = (Node *) n; + $$ = n; } ; @@ -8442,7 +8451,7 @@ DropdbStmt: DROP DATABASE database_name /***************************************************************************** * - * ALTER SYSTEM SET + * ALTER SYSTEM * * This is used to change configuration parameters persistently. *****************************************************************************/ @@ -8454,6 +8463,12 @@ AlterSystemStmt: n->setstmt = $4; $$ = (Node *)n; } + | ALTER SYSTEM_P RESET generic_reset + { + AlterSystemStmt *n = makeNode(AlterSystemStmt); + n->setstmt = $4; + $$ = (Node *)n; + } ; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0e630fdbde..21f283bc4b 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -6691,6 +6691,8 @@ replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p, * This function takes all previous configuration parameters * set by ALTER SYSTEM command and the currently set ones * and write them all to the automatic configuration file. + * It just writes an empty file incase user wants to reset + * all the parameters. * * The configuration parameters are written to a temporary * file then renamed to the final name. @@ -6705,6 +6707,7 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) { char *name; char *value; + bool resetall = false; int Tmpfd = -1; FILE *infile; struct config_generic *record; @@ -6732,37 +6735,48 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) break; case VAR_SET_DEFAULT: + case VAR_RESET: value = NULL; break; + + case VAR_RESET_ALL: + value = NULL; + resetall = true; + break; + default: elog(ERROR, "unrecognized alter system stmt type: %d", altersysstmt->setstmt->kind); break; } - record = find_option(name, false, LOG); - if (record == NULL) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", name))); + /* If we're resetting everything, there's no need to validate anything */ + if (!resetall) + { + record = find_option(name, false, LOG); + if (record == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("unrecognized configuration parameter \"%s\"", name))); - /* - * Don't allow the parameters which can't be set in configuration - * files to be set in PG_AUTOCONF_FILENAME file. - */ - if ((record->context == PGC_INTERNAL) || - (record->flags & GUC_DISALLOW_IN_FILE) || - (record->flags & GUC_DISALLOW_IN_AUTO_FILE)) - ereport(ERROR, - (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), - errmsg("parameter \"%s\" cannot be changed", - name))); + /* + * Don't allow the parameters which can't be set in configuration + * files to be set in PG_AUTOCONF_FILENAME file. + */ + if ((record->context == PGC_INTERNAL) || + (record->flags & GUC_DISALLOW_IN_FILE) || + (record->flags & GUC_DISALLOW_IN_AUTO_FILE)) + ereport(ERROR, + (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), + errmsg("parameter \"%s\" cannot be changed", + name))); - if (!validate_conf_option(record, name, value, PGC_S_FILE, - ERROR, true, NULL, - &newextra)) - ereport(ERROR, - (errmsg("invalid value for parameter \"%s\": \"%s\"", name, value))); + if (!validate_conf_option(record, name, value, PGC_S_FILE, + ERROR, true, NULL, + &newextra)) + ereport(ERROR, + (errmsg("invalid value for parameter \"%s\": \"%s\"", name, value))); + } /* @@ -6794,26 +6808,34 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) PG_TRY(); { - if (stat(AutoConfFileName, &st) == 0) - { - /* open file PG_AUTOCONF_FILENAME */ - infile = AllocateFile(AutoConfFileName, "r"); - if (infile == NULL) - ereport(ERROR, - (errmsg("failed to open auto conf file \"%s\": %m ", - AutoConfFileName))); - - /* parse it */ - ParseConfigFp(infile, AutoConfFileName, 0, LOG, &head, &tail); - - FreeFile(infile); - } - /* - * replace with new value if the configuration parameter already - * exists OR add it as a new cofiguration parameter in the file. + * If we're going to reset everything, then don't open the file, don't + * parse it, and don't do anything with the configuration list. Just + * write out an empty file. */ - replace_auto_config_value(&head, &tail, AutoConfFileName, name, value); + if (!resetall) + { + if (stat(AutoConfFileName, &st) == 0) + { + /* open file PG_AUTOCONF_FILENAME */ + infile = AllocateFile(AutoConfFileName, "r"); + if (infile == NULL) + ereport(ERROR, + (errmsg("failed to open auto conf file \"%s\": %m ", + AutoConfFileName))); + + /* parse it */ + ParseConfigFp(infile, AutoConfFileName, 0, LOG, &head, &tail); + + FreeFile(infile); + } + + /* + * replace with new value if the configuration parameter already + * exists OR add it as a new cofiguration parameter in the file. + */ + replace_auto_config_value(&head, &tail, AutoConfFileName, name, value); + } /* Write and sync the new contents to the temporary file */ write_auto_conf_file(Tmpfd, AutoConfTmpFileName, &head); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index d09b4256d1..ca76856da9 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -545,7 +545,8 @@ static const SchemaQuery Query_for_list_of_matviews = { "SELECT name FROM "\ " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ " WHERE context != 'internal') ss "\ -" WHERE substring(name,1,%d)='%s'" +" WHERE substring(name,1,%d)='%s'"\ +" UNION ALL SELECT 'all' ss" #define Query_for_list_of_set_vars \ "SELECT name FROM "\ @@ -949,7 +950,7 @@ psql_completion(const char *text, int start, int end) {"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN", "EVENT TRIGGER", "EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION", "GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "MATERIALIZED VIEW", "OPERATOR", - "ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE", "SYSTEM SET", "TABLE", + "ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE", "SYSTEM", "TABLE", "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE", "USER", "USER MAPPING FOR", "VIEW", NULL}; @@ -1340,10 +1341,20 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_LIST(list_ALTER_SERVER); } - /* ALTER SYSTEM SET */ + /* ALTER SYSTEM SET, RESET, RESET ALL */ + else if (pg_strcasecmp(prev2_wd, "ALTER") == 0 && + pg_strcasecmp(prev_wd, "SYSTEM") == 0) + { + static const char *const list_ALTERSYSTEM[] = + {"SET", "RESET", NULL}; + + COMPLETE_WITH_LIST(list_ALTERSYSTEM); + } + /* ALTER SYSTEM SET|RESET */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && pg_strcasecmp(prev2_wd, "SYSTEM") == 0 && - pg_strcasecmp(prev_wd, "SET") == 0) + (pg_strcasecmp(prev_wd, "SET") == 0 || + pg_strcasecmp(prev_wd, "RESET") == 0)) COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars); /* ALTER VIEW */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&