Support ALTER SYSTEM RESET command.
authorFujii Masao <fujii@postgresql.org>
Tue, 2 Sep 2014 07:06:58 +0000 (16:06 +0900)
committerFujii Masao <fujii@postgresql.org>
Tue, 2 Sep 2014 07:06:58 +0000 (16:06 +0900)
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
src/backend/parser/gram.y
src/backend/utils/misc/guc.c
src/bin/psql/tab-complete.c

index 23c30efc8f853df9eb4652e45836df200ef95bfb..a6e32106e80206b2c58ac546092c083c3a40d319 100644 (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>
 
index 6f4d6455df69d2e31ea3c76c1bb38c577eb77e0d..b46dd7b008caf407aa29606ee3e2cd094e3f4d4f 100644 (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
+           RESET reset_rest                        { $$ = (Node *) $2; }
+       ;
+
+reset_rest:
+           generic_reset                           { $$ = $1; }
+           | TIME ZONE
                {
                    VariableSetStmt *n = makeNode(VariableSetStmt);
                    n->kind = VAR_RESET;
-                   n->name = $2;
-                   $$ = (Node *) n;
+                   n->name = "timezone";
+                   $$ = n;
                }
-           | RESET TIME ZONE
+           | TRANSACTION ISOLATION LEVEL
                {
                    VariableSetStmt *n = makeNode(VariableSetStmt);
                    n->kind = VAR_RESET;
-                   n->name = "timezone";
-                   $$ = (Node *) n;
+                   n->name = "transaction_isolation";
+                   $$ = n;
                }
-           | RESET TRANSACTION ISOLATION LEVEL
+           | SESSION AUTHORIZATION
                {
                    VariableSetStmt *n = makeNode(VariableSetStmt);
                    n->kind = VAR_RESET;
-                   n->name = "transaction_isolation";
-                   $$ = (Node *) n;
+                   n->name = "session_authorization";
+                   $$ = n;
                }
-           | RESET SESSION AUTHORIZATION
+       ;
+
+generic_reset:
+           var_name
                {
                    VariableSetStmt *n = makeNode(VariableSetStmt);
                    n->kind = VAR_RESET;
-                   n->name = "session_authorization";
-                   $$ = (Node *) n;
+                   n->name = $1;
+                   $$ = n;
                }
-           | RESET ALL
+           | 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;
+               }
        ;
 
 
index 8c57803afe2694bdc0bfe0913c9a0d6fe9a4b4c0..af667f54ada520db97d45b8929458dba0c6c96d2 100644 (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)));
-
-   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)));
+       /*
+        * 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)));
+   }
 
 
    /*
@@ -6799,26 +6813,34 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
 
    PG_TRY();
    {
-       if (stat(AutoConfFileName, &st) == 0)
+       /*
+        * 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.
+        */
+       if (!resetall)
        {
-           /* open file PG_AUTOCONF_FILENAME */
-           infile = AllocateFile(AutoConfFileName, "r");
-           if (infile == NULL)
-               ereport(ERROR,
-                       (errmsg("failed to open auto conf file \"%s\": %m ",
-                               AutoConfFileName)));
+           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);
+               /* parse it */
+               ParseConfigFp(infile, AutoConfFileName, 0, LOG, &head, &tail);
 
-           FreeFile(infile);
-       }
+               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);
+           /*
+            * 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);
index 76b2b04c1acd3186657a93a039a9c41b9cefe36e..8288b41f0a5ebbebe6c33b288fcf77bd9043d90e 100644 (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 &&