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.
This commit is contained in:
Fujii Masao 2014-09-02 16:06:58 +09:00
parent 01b6976c13
commit bd3b7a9eef
4 changed files with 117 additions and 64 deletions

View File

@ -22,6 +22,9 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER SYSTEM SET <replaceable class="PARAMETER">configuration_parameter</replaceable> { TO | = } { <replaceable class="PARAMETER">value</replaceable> | '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT }
ALTER SYSTEM RESET <replaceable class="PARAMETER">configuration_parameter</replaceable>
ALTER SYSTEM RESET ALL
</synopsis>
</refsynopsisdiv>
@ -30,10 +33,12 @@ ALTER SYSTEM SET <replaceable class="PARAMETER">configuration_parameter</replace
<para>
<command>ALTER SYSTEM</command> writes the configuration parameter
values to the <filename>postgresql.auto.conf</filename> file. With
<literal>DEFAULT</literal>, it removes a configuration entry from
<filename>postgresql.auto.conf</filename> file. The values will be
effective after reload of server configuration (SIGHUP) or in next
values to the <filename>postgresql.auto.conf</filename> file.
Setting the parameter to <literal>DEFAULT</literal>, or using the
<command>RESET</command> variant, removes the configuration entry from
<filename>postgresql.auto.conf</filename> file. Use <literal>RESET
ALL</literal> 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.
</para>

View File

@ -411,7 +411,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <istmt> insert_rest
%type <vsetstmt> generic_set set_rest set_rest_more SetResetClause FunctionSetResetClause
%type <vsetstmt> generic_set set_rest set_rest_more generic_reset reset_rest
SetResetClause FunctionSetResetClause
%type <node> TableElement TypedTableElement ConstraintElem TableFuncElement
%type <node> columnDef columnOptions
@ -1579,39 +1580,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;
}
;
@ -8494,7 +8503,7 @@ DropdbStmt: DROP DATABASE database_name
/*****************************************************************************
*
* ALTER SYSTEM SET
* ALTER SYSTEM
*
* This is used to change configuration parameters persistently.
*****************************************************************************/
@ -8506,6 +8515,12 @@ AlterSystemStmt:
n->setstmt = $4;
$$ = (Node *)n;
}
| ALTER SYSTEM_P RESET generic_reset
{
AlterSystemStmt *n = makeNode(AlterSystemStmt);
n->setstmt = $4;
$$ = (Node *)n;
}
;

View File

@ -6696,6 +6696,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.
@ -6710,6 +6712,7 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
{
char *name;
char *value;
bool resetall = false;
int Tmpfd = -1;
FILE *infile;
struct config_generic *record;
@ -6737,37 +6740,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)));
}
/*
@ -6799,26 +6813,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);

View File

@ -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 "\
@ -963,7 +964,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};
@ -1328,10 +1329,20 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST(list_ALTER_SERVER);
}
/* ALTER SYSTEM SET <name> */
/* 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 <name> */
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 <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&