]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/misc/guc.c
Remove all the special-case code for INT64_IS_BUSTED, per decision that
[postgresql] / src / backend / utils / misc / guc.c
index a9e78f733a4dc8e3abdea50f22d6c0fbd6f3dfb2..38d577f87bb9a892a8908bc8f7d3dcc2eafe02bb 100644 (file)
@@ -6,11 +6,11 @@
  * See src/backend/utils/misc/README for more information.
  *
  *
- * Copyright (c) 2000-2009, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2010, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.501 2009/04/07 22:22:19 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.532 2010/01/07 04:53:35 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
 #include "commands/trigger.h"
 #include "funcapi.h"
 #include "libpq/auth.h"
+#include "libpq/be-fsstubs.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
 #include "optimizer/cost.h"
 #include "optimizer/geqo.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
-#include "parser/gramparse.h"
 #include "parser/parse_expr.h"
-#include "parser/parse_relation.h"
 #include "parser/parse_type.h"
+#include "parser/parser.h"
 #include "parser/scansup.h"
 #include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
 #include "postmaster/walwriter.h"
-#include "regex/regex.h"
 #include "storage/bufmgr.h"
 #include "storage/fd.h"
 #include "tcop/tcopprot.h"
 #include "tsearch/ts_cache.h"
 #include "utils/builtins.h"
+#include "utils/bytea.h"
 #include "utils/guc_tables.h"
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
@@ -87,7 +87,8 @@
 #endif
 
 /* upper limit for GUC variables measured in kilobytes of memory */
-#if SIZEOF_SIZE_T > 4
+/* note that various places assume the byte size fits in a "long" variable */
+#if SIZEOF_SIZE_T > 4 && SIZEOF_LONG > 4
 #define MAX_KILOBYTES  INT_MAX
 #else
 #define MAX_KILOBYTES  (INT_MAX / 1024)
@@ -114,6 +115,9 @@ extern char *default_tablespace;
 extern char *temp_tablespaces;
 extern bool synchronize_seqscans;
 extern bool fullPageWrites;
+extern int     vacuum_defer_cleanup_age;
+
+int    trace_recovery_messages = LOG;
 
 #ifdef TRACE_SORT
 extern bool trace_sort;
@@ -139,7 +143,7 @@ static const char *assign_log_destination(const char *value,
 static int     syslog_facility = LOG_LOCAL0;
 
 static bool assign_syslog_facility(int newval,
-                                   bool doit, GucSource source);
+                                          bool doit, GucSource source);
 static const char *assign_syslog_ident(const char *ident,
                                        bool doit, GucSource source);
 #endif
@@ -151,6 +155,7 @@ static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
 static const char *assign_custom_variable_classes(const char *newval, bool doit,
                                                           GucSource source);
 static bool assign_debug_assertions(bool newval, bool doit, GucSource source);
+static bool assign_bonjour(bool newval, bool doit, GucSource source);
 static bool assign_ssl(bool newval, bool doit, GucSource source);
 static bool assign_stage_log_stats(bool newval, bool doit, GucSource source);
 static bool assign_log_stats(bool newval, bool doit, GucSource source);
@@ -168,10 +173,11 @@ static bool assign_maxconnections(int newval, bool doit, GucSource source);
 static bool assign_autovacuum_max_workers(int newval, bool doit, GucSource source);
 static bool assign_effective_io_concurrency(int newval, bool doit, GucSource source);
 static const char *assign_pgstat_temp_directory(const char *newval, bool doit, GucSource source);
+static const char *assign_application_name(const char *newval, bool doit, GucSource source);
 
-static char *config_enum_get_options(struct config_enum *record, 
-                                                                        const char *prefix, const char *suffix,
-                                                                        const char *separator);
+static char *config_enum_get_options(struct config_enum * record,
+                                               const char *prefix, const char *suffix,
+                                               const char *separator);
 
 
 /*
@@ -180,6 +186,12 @@ static char *config_enum_get_options(struct config_enum *record,
  * NOTE! Option values may not contain double quotes!
  */
 
+static const struct config_enum_entry bytea_output_options[] = {
+       {"escape", BYTEA_OUTPUT_ESCAPE, false},
+       {"hex", BYTEA_OUTPUT_HEX, false},
+       {NULL, 0, false}
+};
+
 /*
  * We have different sets for client and server message level options because
  * they sort slightly different (see "log" level)
@@ -241,13 +253,6 @@ static const struct config_enum_entry log_statement_options[] = {
        {NULL, 0, false}
 };
 
-static const struct config_enum_entry regex_flavor_options[] = {
-    {"advanced", REG_ADVANCED, false},
-    {"extended", REG_EXTENDED, false},
-    {"basic", REG_BASIC, false},
-    {NULL, 0, false}
-};
-
 static const struct config_enum_entry isolation_level_options[] = {
        {"serializable", XACT_SERIALIZABLE, false},
        {"repeatable read", XACT_REPEATABLE_READ, false},
@@ -377,6 +382,10 @@ char          *external_pid_file;
 
 char      *pgstat_temp_directory;
 
+char      *default_do_language;
+
+char      *application_name;
+
 int                    tcp_keepalives_idle;
 int                    tcp_keepalives_interval;
 int                    tcp_keepalives_count;
@@ -450,6 +459,7 @@ const char *const GucSource_Names[] =
         /* PGC_S_ARGV */ "command line",
         /* PGC_S_DATABASE */ "database",
         /* PGC_S_USER */ "user",
+        /* PGC_S_DATABASE_USER */ "database user",
         /* PGC_S_CLIENT */ "client",
         /* PGC_S_OVERRIDE */ "override",
         /* PGC_S_INTERACTIVE */ "interactive",
@@ -674,6 +684,14 @@ static struct config_bool ConfigureNamesBool[] =
                &session_auth_is_superuser,
                false, NULL, NULL
        },
+       {
+               {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
+                       gettext_noop("Enables advertising the server via Bonjour."),
+                       NULL
+               },
+               &enable_bonjour,
+               false, assign_bonjour, NULL
+       },
        {
                {"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
                        gettext_noop("Enables SSL connections."),
@@ -727,7 +745,7 @@ static struct config_bool ConfigureNamesBool[] =
                true, NULL, NULL
        },
        {
-               {"silent_mode", PGC_POSTMASTER, LOGGING_WHEN,
+               {"silent_mode", PGC_POSTMASTER, LOGGING_WHERE,
                        gettext_noop("Runs the server silently."),
                        gettext_noop("If this parameter is set, the server will automatically run in the "
                                 "background and any controlling terminals are dissociated.")
@@ -1038,14 +1056,6 @@ static struct config_bool ConfigureNamesBool[] =
                &XactReadOnly,
                false, assign_transaction_read_only, NULL
        },
-       {
-               {"add_missing_from", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
-                       gettext_noop("Automatically adds missing table references to FROM clauses."),
-                       NULL
-               },
-               &add_missing_from,
-               false, NULL, NULL
-       },
        {
                {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
                        gettext_noop("Check function bodies during CREATE FUNCTION."),
@@ -1200,6 +1210,17 @@ static struct config_bool ConfigureNamesBool[] =
                false, NULL, NULL
        },
 
+       {
+               {"recovery_connections", PGC_POSTMASTER, WAL_SETTINGS,
+                       gettext_noop("During recovery, allows connections and queries. "
+                                                " During normal running, causes additional info to be written"
+                                                " to WAL to enable hot standby mode on WAL standby nodes."),
+                       NULL
+               },
+               &XLogRequestRecoveryConnections,
+               true, NULL, NULL
+       },
+
        {
                {"allow_system_table_mods", PGC_POSTMASTER, DEVELOPER_OPTIONS,
                        gettext_noop("Allows modifications of the structure of system tables."),
@@ -1221,6 +1242,16 @@ static struct config_bool ConfigureNamesBool[] =
                false, NULL, NULL
        },
 
+       {
+               {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS,
+                       gettext_noop("Enables backward compatibility mode for privilege checks on large objects"),
+                       gettext_noop("Skips privilege checks when reading or modifying large objects, "
+                                                "for compatibility with PostgreSQL releases prior to 8.5.")
+               },
+               &lo_compat_privileges,
+               false, NULL, NULL
+       },
+
        /* End-of-list marker */
        {
                {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL
@@ -1316,7 +1347,7 @@ static struct config_int ConfigureNamesInt[] =
        {
                /* This is PGC_SIGHUP so all backends have the same value. */
                {"deadlock_timeout", PGC_SIGHUP, LOCK_MANAGEMENT,
-                       gettext_noop("Sets the time to wait on a lock before checking for deadlock, in milliseconds."),
+                       gettext_noop("Sets the time to wait on a lock before checking for deadlock."),
                        NULL,
                        GUC_UNIT_MS
                },
@@ -1328,9 +1359,11 @@ static struct config_int ConfigureNamesInt[] =
         * Note: MaxBackends is limited to INT_MAX/4 because some places compute
         * 4*MaxBackends without any overflow check.  This check is made in
         * assign_maxconnections, since MaxBackends is computed as MaxConnections
-        * plus autovacuum_max_workers.
+        * plus autovacuum_max_workers plus one (for the autovacuum launcher).
         *
         * Likewise we have to limit NBuffers to INT_MAX/2.
+        *
+        * See also CheckRequiredParameterValues() if this parameter changes
         */
        {
                {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
@@ -1341,6 +1374,15 @@ static struct config_int ConfigureNamesInt[] =
                100, 1, INT_MAX / 4, assign_maxconnections, NULL
        },
 
+       {
+               {"max_standby_delay", PGC_SIGHUP, WAL_SETTINGS,
+                       gettext_noop("Sets the maximum delay to avoid conflict processing on Hot Standby servers."),
+                       NULL
+               },
+               &MaxStandbyDelay,
+               30, -1, INT_MAX, NULL, NULL
+       },
+
        {
                {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
                        gettext_noop("Sets the number of connection slots reserved for superusers."),
@@ -1406,7 +1448,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM,
-                       gettext_noop("Sets the maximum memory to be used for maintenance operations, in kilobytes."),
+                       gettext_noop("Sets the maximum memory to be used for maintenance operations."),
                        gettext_noop("This includes operations such as VACUUM and CREATE INDEX."),
                        GUC_UNIT_KB
                },
@@ -1498,13 +1540,16 @@ static struct config_int ConfigureNamesInt[] =
                1000, 25, INT_MAX, NULL, NULL
        },
 
+       /*
+        * See also CheckRequiredParameterValues() if this parameter changes
+        */
        {
                {"max_prepared_transactions", PGC_POSTMASTER, RESOURCES,
                        gettext_noop("Sets the maximum number of simultaneously prepared transactions."),
                        NULL
                },
                &max_prepared_xacts,
-               5, 0, INT_MAX, NULL, NULL
+               0, 0, INT_MAX / 4, NULL, NULL
        },
 
 #ifdef LOCK_DEBUG
@@ -1530,7 +1575,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
-                       gettext_noop("Sets the maximum duration of any statement, in milliseconds."),
+                       gettext_noop("Sets the maximum allowed duration of any statement."),
                        gettext_noop("A value of 0 turns off the timeout."),
                        GUC_UNIT_MS
                },
@@ -1556,6 +1601,18 @@ static struct config_int ConfigureNamesInt[] =
                150000000, 0, 2000000000, NULL, NULL
        },
 
+       {
+               {"vacuum_defer_cleanup_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
+                       gettext_noop("Age by which VACUUM and HOT cleanup should be deferred, if any."),
+                       NULL
+               },
+               &vacuum_defer_cleanup_age,
+               0, 0, 1000000, NULL, NULL
+       },
+
+       /*
+        * See also CheckRequiredParameterValues() if this parameter changes
+        */
        {
                {"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
                        gettext_noop("Sets the maximum number of locks per transaction."),
@@ -1569,7 +1626,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"authentication_timeout", PGC_SIGHUP, CONN_AUTH_SECURITY,
-                       gettext_noop("Sets the maximum allowed time to complete client authentication, in seconds."),
+                       gettext_noop("Sets the maximum allowed time to complete client authentication."),
                        NULL,
                        GUC_UNIT_S
                },
@@ -1599,7 +1656,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS,
-                       gettext_noop("Sets the maximum time between automatic WAL checkpoints, in seconds."),
+                       gettext_noop("Sets the maximum time between automatic WAL checkpoints."),
                        NULL,
                        GUC_UNIT_S
                },
@@ -1632,7 +1689,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS,
-                       gettext_noop("WAL writer sleep time between WAL flushes, in milliseconds."),
+                       gettext_noop("WAL writer sleep time between WAL flushes."),
                        NULL,
                        GUC_UNIT_MS
                },
@@ -1668,13 +1725,13 @@ static struct config_int ConfigureNamesInt[] =
                                                 "(FLT_DIG or DBL_DIG as appropriate).")
                },
                &extra_float_digits,
-               0, -15, 2, NULL, NULL
+               0, -15, 3, NULL, NULL
        },
 
        {
                {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
-                       gettext_noop("Sets the minimum execution time (in milliseconds) above "
-                                                "which statements will be logged."),
+                       gettext_noop("Sets the minimum execution time above which "
+                                                "statements will be logged."),
                        gettext_noop("Zero prints all queries. -1 turns this feature off."),
                        GUC_UNIT_MS
                },
@@ -1684,7 +1741,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT,
-                       gettext_noop("Sets the minimum execution in milliseconds above which "
+                       gettext_noop("Sets the minimum execution time above which "
                                                 "autovacuum actions will be logged."),
                        gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."),
                        GUC_UNIT_MS
@@ -1695,7 +1752,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"bgwriter_delay", PGC_SIGHUP, RESOURCES,
-                       gettext_noop("Background writer sleep time between rounds, in milliseconds."),
+                       gettext_noop("Background writer sleep time between rounds."),
                        NULL,
                        GUC_UNIT_MS
                },
@@ -1715,11 +1772,11 @@ static struct config_int ConfigureNamesInt[] =
        {
                {"effective_io_concurrency",
 #ifdef USE_PREFETCH
-               PGC_USERSET,
+                       PGC_USERSET,
 #else
-               PGC_INTERNAL,
+                       PGC_INTERNAL,
 #endif
-               RESOURCES,
+                       RESOURCES,
                        gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."),
                        gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array.")
                },
@@ -1794,9 +1851,9 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"segment_size", PGC_INTERNAL, PRESET_OPTIONS,
-                   gettext_noop("Shows the number of pages per disk file."),
-                   NULL,
-                   GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+                       gettext_noop("Shows the number of pages per disk file."),
+                       NULL,
+                       GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
                },
                &segment_size,
                RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE, NULL, NULL
@@ -1819,15 +1876,15 @@ static struct config_int ConfigureNamesInt[] =
                        GUC_UNIT_XBLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
                },
                &wal_segment_size,
-               (XLOG_SEG_SIZE / XLOG_BLCKSZ), 
-               (XLOG_SEG_SIZE / XLOG_BLCKSZ), 
+               (XLOG_SEG_SIZE / XLOG_BLCKSZ),
+               (XLOG_SEG_SIZE / XLOG_BLCKSZ),
                (XLOG_SEG_SIZE / XLOG_BLCKSZ),
                NULL, NULL
        },
 
        {
                {"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
-                       gettext_noop("Time to sleep between autovacuum runs, in seconds."),
+                       gettext_noop("Time to sleep between autovacuum runs."),
                        NULL,
                        GUC_UNIT_S
                },
@@ -1857,6 +1914,7 @@ static struct config_int ConfigureNamesInt[] =
                        NULL
                },
                &autovacuum_freeze_max_age,
+               /* see pg_resetxlog if you change the upper-limit value */
                200000000, 100000000, 2000000000, NULL, NULL
        },
        {
@@ -1871,7 +1929,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
-                       gettext_noop("Seconds between issuing TCP keepalives."),
+                       gettext_noop("Time between issuing TCP keepalives."),
                        gettext_noop("A value of 0 uses the system default."),
                        GUC_UNIT_S
                },
@@ -1881,7 +1939,7 @@ static struct config_int ConfigureNamesInt[] =
 
        {
                {"tcp_keepalives_interval", PGC_USERSET, CLIENT_CONN_OTHER,
-                       gettext_noop("Seconds between TCP keepalive retransmits."),
+                       gettext_noop("Time between TCP keepalive retransmits."),
                        gettext_noop("A value of 0 uses the system default."),
                        GUC_UNIT_S
                },
@@ -2026,6 +2084,14 @@ static struct config_real ConfigureNamesReal[] =
                DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
                MAX_GEQO_SELECTION_BIAS, NULL, NULL
        },
+       {
+               {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO,
+                       gettext_noop("GEQO: seed for random path selection."),
+                       NULL
+               },
+               &Geqo_seed,
+               0.0, 0.0, 1.0, NULL, NULL
+       },
 
        {
                {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES,
@@ -2183,7 +2249,7 @@ static struct config_string ConfigureNamesString[] =
 
        {
                {"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
-                       gettext_noop("Sets the Bonjour broadcast service name."),
+                       gettext_noop("Sets the Bonjour service name."),
                        NULL
                },
                &bonjour_name,
@@ -2305,7 +2371,7 @@ static struct config_string ConfigureNamesString[] =
                {"role", PGC_USERSET, UNGROUPED,
                        gettext_noop("Sets the current role."),
                        NULL,
-                       GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+                       GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
                },
                &role_string,
                "none", assign_role, show_role
@@ -2316,7 +2382,7 @@ static struct config_string ConfigureNamesString[] =
                {"session_authorization", PGC_USERSET, UNGROUPED,
                        gettext_noop("Sets the session user name."),
                        NULL,
-                       GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+                       GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
                },
                &session_authorization_string,
                NULL, assign_session_authorization, show_session_authorization
@@ -2514,6 +2580,25 @@ static struct config_string ConfigureNamesString[] =
        },
 #endif   /* USE_SSL */
 
+       {
+               {"default_do_language", PGC_USERSET, CLIENT_CONN_STATEMENT,
+                       gettext_noop("Sets the language used in DO statement if LANGUAGE is not specified."),
+                       NULL
+               },
+               &default_do_language,
+               "plpgsql", NULL, NULL
+       },
+
+       {
+               {"application_name", PGC_USERSET, LOGGING,
+                gettext_noop("Sets the application name to be reported in statistics and logs."),
+                NULL,
+                GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE
+               },
+               &application_name,
+               "", assign_application_name, NULL
+       },
+
        /* End-of-list marker */
        {
                {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
@@ -2532,6 +2617,15 @@ static struct config_enum ConfigureNamesEnum[] =
                BACKSLASH_QUOTE_SAFE_ENCODING, backslash_quote_options, NULL, NULL
        },
 
+       {
+               {"bytea_output", PGC_USERSET, CLIENT_CONN_STATEMENT,
+                       gettext_noop("Sets the output format for bytea."),
+                       NULL
+               },
+               &bytea_output,
+               BYTEA_OUTPUT_HEX, bytea_output_options, NULL, NULL
+       },
+
        {
                {"client_min_messages", PGC_USERSET, LOGGING_WHEN,
                        gettext_noop("Sets the message levels that are sent to the client."),
@@ -2562,7 +2656,7 @@ static struct config_enum ConfigureNamesEnum[] =
                XACT_READ_COMMITTED, isolation_level_options, NULL, NULL
        },
 
-       {
+       {
                {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
                        gettext_noop("Sets the display format for interval values."),
                        NULL,
@@ -2621,15 +2715,6 @@ static struct config_enum ConfigureNamesEnum[] =
        },
 #endif
 
-       {
-               {"regex_flavor", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
-                       gettext_noop("Sets the regular expression \"flavor\"."),
-                       NULL
-               },
-               &regex_flavor,
-               REG_ADVANCED, regex_flavor_options, NULL, NULL
-       },
-
        {
                {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
                        gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
@@ -2640,6 +2725,16 @@ static struct config_enum ConfigureNamesEnum[] =
                assign_session_replication_role, NULL
        },
 
+       {
+               {"trace_recovery_messages", PGC_SUSET, LOGGING_WHEN,
+                       gettext_noop("Sets the message levels that are logged during recovery."),
+                       gettext_noop("Each level includes all the levels that follow it. The later"
+                                                " the level, the fewer messages are sent.")
+               },
+               &trace_recovery_messages,
+               DEBUG1, server_message_level_options, NULL, NULL
+       },
+
        {
                {"track_functions", PGC_SUSET, STATS_COLLECTOR,
                        gettext_noop("Collects function-level statistics on database activity."),
@@ -2655,7 +2750,7 @@ static struct config_enum ConfigureNamesEnum[] =
                        NULL
                },
                &sync_method,
-               DEFAULT_SYNC_METHOD, sync_method_options, 
+               DEFAULT_SYNC_METHOD, sync_method_options,
                assign_xlog_sync_method, NULL
        },
 
@@ -2722,7 +2817,7 @@ static int        GUCNestLevel = 0;       /* 1 when in main transaction */
 
 static int     guc_var_compare(const void *a, const void *b);
 static int     guc_name_compare(const char *namea, const char *nameb);
-static void InitializeOneGUCOption(struct config_generic *gconf);
+static void InitializeOneGUCOption(struct config_generic * gconf);
 static void push_old_value(struct config_generic * gconf, GucAction action);
 static void ReportGUCOption(struct config_generic * record);
 static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
@@ -2853,7 +2948,7 @@ set_stack_value(struct config_generic * gconf, union config_var_value * val)
                                                         *((struct config_string *) gconf)->variable);
                        break;
                case PGC_ENUM:
-                       val->enumval = 
+                       val->enumval =
                                *((struct config_enum *) gconf)->variable;
                        break;
        }
@@ -3290,7 +3385,7 @@ InitializeGUCOptions(void)
  * Initialize one GUC option variable to its compiled-in default.
  */
 static void
-InitializeOneGUCOption(struct config_generic *gconf)
+InitializeOneGUCOption(struct config_generic * gconf)
 {
        gconf->status = 0;
        gconf->reset_source = PGC_S_DEFAULT;
@@ -3302,100 +3397,100 @@ InitializeOneGUCOption(struct config_generic *gconf)
        switch (gconf->vartype)
        {
                case PGC_BOOL:
-               {
-                       struct config_bool *conf = (struct config_bool *) gconf;
-
-                       if (conf->assign_hook)
-                               if (!(*conf->assign_hook) (conf->boot_val, true,
-                                                                                  PGC_S_DEFAULT))
-                                       elog(FATAL, "failed to initialize %s to %d",
-                                                conf->gen.name, (int) conf->boot_val);
-                       *conf->variable = conf->reset_val = conf->boot_val;
-                       break;
-               }
-               case PGC_INT:
-               {
-                       struct config_int *conf = (struct config_int *) gconf;
-
-                       Assert(conf->boot_val >= conf->min);
-                       Assert(conf->boot_val <= conf->max);
-                       if (conf->assign_hook)
-                               if (!(*conf->assign_hook) (conf->boot_val, true,
-                                                                                  PGC_S_DEFAULT))
-                                       elog(FATAL, "failed to initialize %s to %d",
-                                                conf->gen.name, conf->boot_val);
-                       *conf->variable = conf->reset_val = conf->boot_val;
-                       break;
-               }
-               case PGC_REAL:
-               {
-                       struct config_real *conf = (struct config_real *) gconf;
-
-                       Assert(conf->boot_val >= conf->min);
-                       Assert(conf->boot_val <= conf->max);
-                       if (conf->assign_hook)
-                               if (!(*conf->assign_hook) (conf->boot_val, true,
-                                                                                  PGC_S_DEFAULT))
-                                       elog(FATAL, "failed to initialize %s to %g",
-                                                conf->gen.name, conf->boot_val);
-                       *conf->variable = conf->reset_val = conf->boot_val;
-                       break;
-               }
-               case PGC_STRING:
-               {
-                       struct config_string *conf = (struct config_string *) gconf;
-                       char       *str;
-
-                       *conf->variable = NULL;
-                       conf->reset_val = NULL;
-
-                       if (conf->boot_val == NULL)
                        {
-                               /* leave the value NULL, do not call assign hook */
+                               struct config_bool *conf = (struct config_bool *) gconf;
+
+                               if (conf->assign_hook)
+                                       if (!(*conf->assign_hook) (conf->boot_val, true,
+                                                                                          PGC_S_DEFAULT))
+                                               elog(FATAL, "failed to initialize %s to %d",
+                                                        conf->gen.name, (int) conf->boot_val);
+                               *conf->variable = conf->reset_val = conf->boot_val;
                                break;
                        }
+               case PGC_INT:
+                       {
+                               struct config_int *conf = (struct config_int *) gconf;
 
-                       str = guc_strdup(FATAL, conf->boot_val);
-                       conf->reset_val = str;
+                               Assert(conf->boot_val >= conf->min);
+                               Assert(conf->boot_val <= conf->max);
+                               if (conf->assign_hook)
+                                       if (!(*conf->assign_hook) (conf->boot_val, true,
+                                                                                          PGC_S_DEFAULT))
+                                               elog(FATAL, "failed to initialize %s to %d",
+                                                        conf->gen.name, conf->boot_val);
+                               *conf->variable = conf->reset_val = conf->boot_val;
+                               break;
+                       }
+               case PGC_REAL:
+                       {
+                               struct config_real *conf = (struct config_real *) gconf;
 
-                       if (conf->assign_hook)
+                               Assert(conf->boot_val >= conf->min);
+                               Assert(conf->boot_val <= conf->max);
+                               if (conf->assign_hook)
+                                       if (!(*conf->assign_hook) (conf->boot_val, true,
+                                                                                          PGC_S_DEFAULT))
+                                               elog(FATAL, "failed to initialize %s to %g",
+                                                        conf->gen.name, conf->boot_val);
+                               *conf->variable = conf->reset_val = conf->boot_val;
+                               break;
+                       }
+               case PGC_STRING:
                        {
-                               const char *newstr;
+                               struct config_string *conf = (struct config_string *) gconf;
+                               char       *str;
 
-                               newstr = (*conf->assign_hook) (str, true,
-                                                                                          PGC_S_DEFAULT);
-                               if (newstr == NULL)
+                               *conf->variable = NULL;
+                               conf->reset_val = NULL;
+
+                               if (conf->boot_val == NULL)
                                {
-                                       elog(FATAL, "failed to initialize %s to \"%s\"",
-                                                conf->gen.name, str);
+                                       /* leave the value NULL, do not call assign hook */
+                                       break;
                                }
-                               else if (newstr != str)
+
+                               str = guc_strdup(FATAL, conf->boot_val);
+                               conf->reset_val = str;
+
+                               if (conf->assign_hook)
                                {
-                                       free(str);
+                                       const char *newstr;
 
-                                       /*
-                                        * See notes in set_config_option about casting
-                                        */
-                                       str = (char *) newstr;
-                                       conf->reset_val = str;
+                                       newstr = (*conf->assign_hook) (str, true,
+                                                                                                  PGC_S_DEFAULT);
+                                       if (newstr == NULL)
+                                       {
+                                               elog(FATAL, "failed to initialize %s to \"%s\"",
+                                                        conf->gen.name, str);
+                                       }
+                                       else if (newstr != str)
+                                       {
+                                               free(str);
+
+                                               /*
+                                                * See notes in set_config_option about casting
+                                                */
+                                               str = (char *) newstr;
+                                               conf->reset_val = str;
+                                       }
                                }
+                               *conf->variable = str;
+                               break;
                        }
-                       *conf->variable = str;
-                       break;
-               }
                case PGC_ENUM:
-               {
-                       struct config_enum *conf = (struct config_enum *) gconf;
-
-                       if (conf->assign_hook)
-                               if (!(*conf->assign_hook) (conf->boot_val, true,
-                                                                                  PGC_S_DEFAULT))
-                                       elog(FATAL, "failed to initialize %s to %s",
-                                                conf->gen.name, 
-                                                config_enum_lookup_by_value(conf, conf->boot_val));
-                       *conf->variable = conf->reset_val = conf->boot_val;
-                       break;
-               }
+                       {
+                               struct config_enum *conf = (struct config_enum *) gconf;
+
+                               if (conf->assign_hook)
+                                       if (!(*conf->assign_hook) (conf->boot_val, true,
+                                                                                          PGC_S_DEFAULT))
+                                               elog(FATAL, "failed to initialize %s to %s",
+                                                        conf->gen.name,
+                                                 config_enum_lookup_by_value(conf, conf->boot_val));
+                               *conf->variable = conf->reset_val = conf->boot_val;
+                               break;
+                       }
        }
 }
 
@@ -4009,13 +4104,13 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
                                        case PGC_ENUM:
                                                {
                                                        struct config_enum *conf = (struct config_enum *) gconf;
-                                                       int newval = newvalue.enumval;
+                                                       int                     newval = newvalue.enumval;
 
                                                        if (*conf->variable != newval)
                                                        {
                                                                if (conf->assign_hook)
                                                                        if (!(*conf->assign_hook) (newval,
-                                                                                                                          true, PGC_S_OVERRIDE))
+                                                                                                          true, PGC_S_OVERRIDE))
                                                                                elog(LOG, "failed to commit %s as %s",
                                                                                         conf->gen.name,
                                                                                         config_enum_lookup_by_value(conf, newval));
@@ -4145,10 +4240,6 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
                /*
                 * Note: the multiple-switch coding technique here is a bit tedious,
                 * but seems necessary to avoid intermediate-value overflows.
-                *
-                * If INT64_IS_BUSTED (ie, it's really int32) we will fail to detect
-                * overflow due to units conversion, but there are few enough such
-                * machines that it does not seem worth trying to be smarter.
                 */
                if (flags & GUC_UNIT_MEMORY)
                {
@@ -4351,7 +4442,7 @@ parse_real(const char *value, double *result)
  * allocated for modification.
  */
 const char *
-config_enum_lookup_by_value(struct config_enum *record, int val)
+config_enum_lookup_by_value(struct config_enum * record, int val)
 {
        const struct config_enum_entry *entry;
 
@@ -4363,7 +4454,7 @@ config_enum_lookup_by_value(struct config_enum *record, int val)
 
        elog(ERROR, "could not find enum option %d for %s",
                 val, record->gen.name);
-       return NULL;            /* silence compiler */
+       return NULL;                            /* silence compiler */
 }
 
 
@@ -4374,7 +4465,7 @@ config_enum_lookup_by_value(struct config_enum *record, int val)
  * true. If it's not found, return FALSE and retval is set to 0.
  */
 bool
-config_enum_lookup_by_name(struct config_enum *record, const char *value,
+config_enum_lookup_by_name(struct config_enum * record, const char *value,
                                                   int *retval)
 {
        const struct config_enum_entry *entry;
@@ -4400,16 +4491,16 @@ config_enum_lookup_by_name(struct config_enum *record, const char *value,
  * If suffix is non-NULL, it is added to the end of the string.
  */
 static char *
-config_enum_get_options(struct config_enum *record, const char *prefix,
+config_enum_get_options(struct config_enum * record, const char *prefix,
                                                const char *suffix, const char *separator)
 {
        const struct config_enum_entry *entry;
-       StringInfoData  retstr;
+       StringInfoData retstr;
        int                     seplen;
 
        initStringInfo(&retstr);
        appendStringInfoString(&retstr, prefix);
-       
+
        seplen = strlen(separator);
        for (entry = record->options; entry && entry->name; entry++)
        {
@@ -4421,11 +4512,11 @@ config_enum_get_options(struct config_enum *record, const char *prefix,
        }
 
        /*
-        * All the entries may have been hidden, leaving the string empty
-        * if no prefix was given. This indicates a broken GUC setup, since
-        * there is no use for an enum without any values, so we just check
-        * to make sure we don't write to invalid memory instead of actually
-        * trying to do something smart with it.
+        * All the entries may have been hidden, leaving the string empty if no
+        * prefix was given. This indicates a broken GUC setup, since there is no
+        * use for an enum without any values, so we just check to make sure we
+        * don't write to invalid memory instead of actually trying to do
+        * something smart with it.
         */
        if (retstr.len >= seplen)
        {
@@ -4511,7 +4602,8 @@ set_config_option(const char *name, const char *value,
                 */
                elevel = IsUnderPostmaster ? DEBUG3 : LOG;
        }
-       else if (source == PGC_S_DATABASE || source == PGC_S_USER)
+       else if (source == PGC_S_DATABASE || source == PGC_S_USER ||
+                        source == PGC_S_DATABASE_USER)
                elevel = WARNING;
        else
                elevel = ERROR;
@@ -4565,18 +4657,16 @@ set_config_option(const char *name, const char *value,
                                if (changeVal && !is_newvalue_equal(record, value))
                                        ereport(elevel,
                                                        (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-                                                        errmsg("attempted change of parameter \"%s\" ignored",
-                                                                       name),
-                                                        errdetail("This parameter cannot be changed after server start.")));
+                                          errmsg("parameter \"%s\" cannot be changed without restarting the server",
+                                                         name)));
                                return true;
                        }
                        if (context != PGC_POSTMASTER)
                        {
                                ereport(elevel,
                                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-                                                errmsg("attempted change of parameter \"%s\" ignored",
-                                                               name),
-                                                errdetail("This parameter cannot be changed after server start.")));
+                                          errmsg("parameter \"%s\" cannot be changed without restarting the server",
+                                                         name)));
                                return false;
                        }
                        break;
@@ -4611,7 +4701,8 @@ set_config_option(const char *name, const char *value,
                                if (IsUnderPostmaster)
                                        return true;
                        }
-                       else if (context != PGC_BACKEND && context != PGC_POSTMASTER)
+                       else if (context != PGC_POSTMASTER && context != PGC_BACKEND &&
+                                        source != PGC_S_CLIENT)
                        {
                                ereport(elevel,
                                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
@@ -4635,6 +4726,48 @@ set_config_option(const char *name, const char *value,
                        break;
        }
 
+       /*
+        * Disallow changing GUC_NOT_WHILE_SEC_REST values if we are inside a
+        * security restriction context.  We can reject this regardless of
+        * the GUC context or source, mainly because sources that it might be
+        * reasonable to override for won't be seen while inside a function.
+        *
+        * Note: variables marked GUC_NOT_WHILE_SEC_REST should usually be marked
+        * GUC_NO_RESET_ALL as well, because ResetAllOptions() doesn't check this.
+        * An exception might be made if the reset value is assumed to be "safe".
+        *
+        * Note: this flag is currently used for "session_authorization" and
+        * "role".  We need to prohibit changing these inside a local userid
+        * context because when we exit it, GUC won't be notified, leaving things
+        * out of sync.  (This could be fixed by forcing a new GUC nesting level,
+        * but that would change behavior in possibly-undesirable ways.)  Also,
+        * we prohibit changing these in a security-restricted operation because
+        * otherwise RESET could be used to regain the session user's privileges.
+        */
+       if (record->flags & GUC_NOT_WHILE_SEC_REST)
+       {
+               if (InLocalUserIdChange())
+               {
+                       /*
+                        * Phrasing of this error message is historical, but it's the
+                        * most common case.
+                        */
+                       ereport(elevel,
+                                       (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                        errmsg("cannot set parameter \"%s\" within security-definer function",
+                                                       name)));
+                       return false;
+               }
+               if (InSecurityRestrictedOperation())
+               {
+                       ereport(elevel,
+                                       (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                        errmsg("cannot set parameter \"%s\" within security-restricted operation",
+                                                       name)));
+                       return false;
+               }
+       }
+
        /*
         * Should we set reset/stacked values?  (If so, the behavior is not
         * transactional.)      This is done either when we get a default value from
@@ -5004,16 +5137,16 @@ set_config_option(const char *name, const char *value,
                                {
                                        if (!config_enum_lookup_by_name(conf, value, &newval))
                                        {
-                                               char *hintmsg;
-                                          
-                                               hintmsg = config_enum_get_options(conf,
-                                                                                                                 "Available values: ",
+                                               char       *hintmsg;
+
+                                               hintmsg = config_enum_get_options(conf,
+                                                                                                               "Available values: ",
                                                                                                                  ".", ", ");
 
                                                ereport(elevel,
                                                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                                                errmsg("invalid value for parameter \"%s\": \"%s\"",
-                                                                               name, value),
+                                                errmsg("invalid value for parameter \"%s\": \"%s\"",
+                                                               name, value),
                                                                 hintmsg ? errhint("%s", _(hintmsg)) : 0));
 
                                                if (hintmsg)
@@ -5038,9 +5171,9 @@ set_config_option(const char *name, const char *value,
                                        {
                                                ereport(elevel,
                                                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                                                errmsg("invalid value for parameter \"%s\": \"%s\"",
-                                                                               name, 
-                                                                               config_enum_lookup_by_value(conf, newval))));
+                                                errmsg("invalid value for parameter \"%s\": \"%s\"",
+                                                               name,
+                                                               config_enum_lookup_by_value(conf, newval))));
                                                return false;
                                        }
 
@@ -5088,8 +5221,8 @@ set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
        int                     elevel;
 
        /*
-        * To avoid cluttering the log, only the postmaster bleats loudly
-        * about problems with the config file.
+        * To avoid cluttering the log, only the postmaster bleats loudly about
+        * problems with the config file.
         */
        elevel = IsUnderPostmaster ? DEBUG3 : LOG;
 
@@ -5127,11 +5260,15 @@ SetConfigOption(const char *name, const char *value,
  * Fetch the current value of the option `name'. If the option doesn't exist,
  * throw an ereport and don't return.
  *
+ * If restrict_superuser is true, we also enforce that only superusers can
+ * see GUC_SUPERUSER_ONLY variables.  This should only be passed as true
+ * in user-driven calls.
+ *
  * The string is *not* allocated for modification and is really only
  * valid until the next call to configuration related functions.
  */
 const char *
-GetConfigOption(const char *name)
+GetConfigOption(const char *name, bool restrict_superuser)
 {
        struct config_generic *record;
        static char buffer[256];
@@ -5141,7 +5278,9 @@ GetConfigOption(const char *name)
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_OBJECT),
                           errmsg("unrecognized configuration parameter \"%s\"", name)));
-       if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
+       if (restrict_superuser &&
+               (record->flags & GUC_SUPERUSER_ONLY) &&
+               !superuser())
                ereport(ERROR,
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                 errmsg("must be superuser to examine \"%s\"", name)));
@@ -5166,7 +5305,7 @@ GetConfigOption(const char *name)
 
                case PGC_ENUM:
                        return config_enum_lookup_by_value((struct config_enum *) record,
-                                                                                       *((struct config_enum *) record)->variable);
+                                                                *((struct config_enum *) record)->variable);
        }
        return NULL;
 }
@@ -5214,27 +5353,11 @@ GetConfigOptionResetString(const char *name)
 
                case PGC_ENUM:
                        return config_enum_lookup_by_value((struct config_enum *) record,
-                                                                                   ((struct config_enum *) record)->reset_val);
+                                                                ((struct config_enum *) record)->reset_val);
        }
        return NULL;
 }
 
-/*
- * Detect whether the given configuration option can only be set by
- * a superuser.
- */
-bool
-IsSuperuserConfigOption(const char *name)
-{
-       struct config_generic *record;
-
-       record = find_option(name, false, ERROR);
-       /* On an unrecognized name, don't error, just return false. */
-       if (record == NULL)
-               return false;
-       return (record->context == PGC_SUSET);
-}
-
 
 /*
  * GUC_complaint_elevel
@@ -5244,7 +5367,7 @@ IsSuperuserConfigOption(const char *name)
  * report (in addition to the generic "invalid value for option FOO" that
  * guc.c will provide).  Note that the result might be ERROR or a lower
  * level, so the caller must be prepared for control to return from ereport,
- * or not.  If control does return, return false/NULL from the hook function.
+ * or not.     If control does return, return false/NULL from the hook function.
  *
  * At some point it'd be nice to replace this with a mechanism that allows
  * the custom message to become the DETAIL line of guc.c's generic message.
@@ -5266,9 +5389,9 @@ GUC_complaint_elevel(GucSource source)
        {
                /*
                 * If we're a postmaster child, this is probably "undo" during
-                * transaction abort, so we don't want to clutter the log.  There's
-                * a small chance of a real problem with an OVERRIDE setting,
-                * though, so suppressing the message entirely wouldn't be desirable.
+                * transaction abort, so we don't want to clutter the log.  There's a
+                * small chance of a real problem with an OVERRIDE setting, though, so
+                * suppressing the message entirely wouldn't be desirable.
                 */
                elevel = IsUnderPostmaster ? DEBUG5 : LOG;
        }
@@ -5324,25 +5447,25 @@ flatten_set_variable_args(const char *name, List *args)
 
        /*
         * Each list member may be a plain A_Const node, or an A_Const within a
-        * TypeCast; the latter case is supported only for ConstInterval
-        * arguments (for SET TIME ZONE).
+        * TypeCast; the latter case is supported only for ConstInterval arguments
+        * (for SET TIME ZONE).
         */
        foreach(l, args)
        {
-               Node       *arg = (Node *) lfirst(l);
+               Node       *arg = (Node *) lfirst(l);
                char       *val;
-               TypeName   *typename = NULL;
-               A_Const    *con;
+               TypeName   *typeName = NULL;
+               A_Const    *con;
 
                if (l != list_head(args))
                        appendStringInfo(&buf, ", ");
 
                if (IsA(arg, TypeCast))
                {
-                       TypeCast *tc = (TypeCast *) arg;
+                       TypeCast   *tc = (TypeCast *) arg;
 
                        arg = tc->arg;
-                       typename = tc->typename;
+                       typeName = tc->typeName;
                }
 
                if (!IsA(arg, A_Const))
@@ -5360,7 +5483,7 @@ flatten_set_variable_args(const char *name, List *args)
                                break;
                        case T_String:
                                val = strVal(&con->val);
-                               if (typename != NULL)
+                               if (typeName != NULL)
                                {
                                        /*
                                         * Must be a ConstInterval argument for TIME ZONE. Coerce
@@ -5372,7 +5495,7 @@ flatten_set_variable_args(const char *name, List *args)
                                        Datum           interval;
                                        char       *intervalout;
 
-                                       typoid = typenameTypeId(NULL, typename, &typmod);
+                                       typoid = typenameTypeId(NULL, typeName, &typmod);
                                        Assert(typoid == INTERVALOID);
 
                                        interval =
@@ -5597,11 +5720,11 @@ init_custom_variable(const char *name,
        struct config_generic *gen;
 
        /*
-        * Only allow custom PGC_POSTMASTER variables to be created during
-        * shared library preload; any later than that, we can't ensure that
-        * the value doesn't change after startup.  This is a fatal elog if it
-        * happens; just erroring out isn't safe because we don't know what
-        * the calling loadable module might already have hooked into.
+        * Only allow custom PGC_POSTMASTER variables to be created during shared
+        * library preload; any later than that, we can't ensure that the value
+        * doesn't change after startup.  This is a fatal elog if it happens; just
+        * erroring out isn't safe because we don't know what the calling loadable
+        * module might already have hooked into.
         */
        if (context == PGC_POSTMASTER &&
                !process_shared_preload_libraries_in_progress)
@@ -5632,7 +5755,7 @@ define_custom_variable(struct config_generic * variable)
        const char **nameAddr = &name;
        const char *value;
        struct config_string *pHolder;
-       GucContext phcontext;
+       GucContext      phcontext;
        struct config_generic **res;
 
        /*
@@ -5679,9 +5802,9 @@ define_custom_variable(struct config_generic * variable)
        *res = variable;
 
        /*
-        * Infer context for assignment based on source of existing value.
-        * We can't tell this with exact accuracy, but we can at least do
-        * something reasonable in typical cases.
+        * Infer context for assignment based on source of existing value. We
+        * can't tell this with exact accuracy, but we can at least do something
+        * reasonable in typical cases.
         */
        switch (pHolder->gen.source)
        {
@@ -5689,10 +5812,11 @@ define_custom_variable(struct config_generic * variable)
                case PGC_S_ENV_VAR:
                case PGC_S_FILE:
                case PGC_S_ARGV:
+
                        /*
-                        * If we got past the check in init_custom_variable, we can
-                        * safely assume that any existing value for a PGC_POSTMASTER
-                        * variable was set in postmaster context.
+                        * If we got past the check in init_custom_variable, we can safely
+                        * assume that any existing value for a PGC_POSTMASTER variable
+                        * was set in postmaster context.
                         */
                        if (variable->context == PGC_POSTMASTER)
                                phcontext = PGC_POSTMASTER;
@@ -5701,6 +5825,7 @@ define_custom_variable(struct config_generic * variable)
                        break;
                case PGC_S_DATABASE:
                case PGC_S_USER:
+               case PGC_S_DATABASE_USER:
                case PGC_S_CLIENT:
                case PGC_S_SESSION:
                default:
@@ -5852,7 +5977,7 @@ DefineCustomEnumVariable(const char *name,
                                                 const char *long_desc,
                                                 int *valueAddr,
                                                 int bootValue,
-                                                const struct config_enum_entry *options,
+                                                const struct config_enum_entry * options,
                                                 GucContext context,
                                                 int flags,
                                                 GucEnumAssignHook assign_hook,
@@ -5977,7 +6102,8 @@ ShowAllGUCConfig(DestReceiver *dest)
        int                     i;
        TupOutputState *tstate;
        TupleDesc       tupdesc;
-       char       *values[3];
+       Datum       values[3];
+       bool            isnull[3] = { false, false, false };
 
        /* need a tuple descriptor representing three TEXT columns */
        tupdesc = CreateTemplateTupleDesc(3, false);
@@ -5988,29 +6114,46 @@ ShowAllGUCConfig(DestReceiver *dest)
        TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
                                           TEXTOID, -1, 0);
 
-
        /* prepare for projection of tuples */
        tstate = begin_tup_output_tupdesc(dest, tupdesc);
 
        for (i = 0; i < num_guc_variables; i++)
        {
                struct config_generic *conf = guc_variables[i];
+               char   *setting;
 
                if ((conf->flags & GUC_NO_SHOW_ALL) ||
                        ((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
                        continue;
 
                /* assign to the values array */
-               values[0] = (char *) conf->name;
-               values[1] = _ShowOption(conf, true);
-               values[2] = (char *) conf->short_desc;
+               values[0] = PointerGetDatum(cstring_to_text(conf->name));
+
+               setting = _ShowOption(conf, true);
+               if (setting)
+               {
+                       values[1] = PointerGetDatum(cstring_to_text(setting));
+                       isnull[1] = false;
+               }
+               else
+               {
+                       values[1] = PointerGetDatum(NULL);
+                       isnull[1] = true;
+               }
+
+               values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
 
                /* send it to dest */
-               do_tup_output(tstate, values);
+               do_tup_output(tstate, values, isnull);
 
                /* clean up */
-               if (values[1] != NULL)
-                       pfree(values[1]);
+               pfree(DatumGetPointer(values[0]));
+               if (setting)
+               {
+                       pfree(setting);
+                       pfree(DatumGetPointer(values[1]));
+               }
+               pfree(DatumGetPointer(values[2]));
        }
 
        end_tup_output(tstate);
@@ -6165,13 +6308,13 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
                                /* enumvals */
                                values[11] = NULL;
 
-                               /* boot_val */
-                               snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
-                               values[12] = pstrdup(buffer);
+                               /* boot_val */
+                               snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
+                               values[12] = pstrdup(buffer);
 
-                               /* reset_val */
-                               snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
-                               values[13] = pstrdup(buffer);
+                               /* reset_val */
+                               snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
+                               values[13] = pstrdup(buffer);
                        }
                        break;
 
@@ -6190,19 +6333,19 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
                                /* enumvals */
                                values[11] = NULL;
 
-                               /* boot_val */
-                               snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
-                               values[12] = pstrdup(buffer);
+                               /* boot_val */
+                               snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
+                               values[12] = pstrdup(buffer);
 
-                               /* reset_val */
-                               snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
-                               values[13] = pstrdup(buffer);
+                               /* reset_val */
+                               snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
+                               values[13] = pstrdup(buffer);
                        }
                        break;
 
                case PGC_STRING:
                        {
-                               struct config_string *lconf = (struct config_string *) conf;
+                               struct config_string *lconf = (struct config_string *) conf;
 
                                /* min_val */
                                values[9] = NULL;
@@ -6213,15 +6356,15 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
                                /* enumvals */
                                values[11] = NULL;
 
-                               /* boot_val */
-                               if (lconf->boot_val == NULL)
-                                       values[12] = NULL;
+                               /* boot_val */
+                               if (lconf->boot_val == NULL)
+                                       values[12] = NULL;
                                else
                                        values[12] = pstrdup(lconf->boot_val);
 
-                               /* reset_val */
-                               if (lconf->reset_val == NULL)
-                                       values[13] = NULL;
+                               /* reset_val */
+                               if (lconf->reset_val == NULL)
+                                       values[13] = NULL;
                                else
                                        values[13] = pstrdup(lconf->reset_val);
                        }
@@ -6229,7 +6372,7 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
 
                case PGC_ENUM:
                        {
-                               struct config_enum *lconf = (struct config_enum *) conf;
+                               struct config_enum *lconf = (struct config_enum *) conf;
 
                                /* min_val */
                                values[9] = NULL;
@@ -6238,17 +6381,21 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
                                values[10] = NULL;
 
                                /* enumvals */
-                               /* NOTE! enumvals with double quotes in them are not supported! */
+
+                               /*
+                                * NOTE! enumvals with double quotes in them are not
+                                * supported!
+                                */
                                values[11] = config_enum_get_options((struct config_enum *) conf,
                                                                                                         "{\"", "\"}", "\",\"");
 
-                               /* boot_val */
+                               /* boot_val */
                                values[12] = pstrdup(config_enum_lookup_by_value(lconf,
-                                                                                                                                lconf->boot_val));
+                                                                                                                  lconf->boot_val));
 
-                               /* reset_val */
+                               /* reset_val */
                                values[13] = pstrdup(config_enum_lookup_by_value(lconf,
-                                                                                                                                lconf->reset_val));
+                                                                                                                 lconf->reset_val));
                        }
                        break;
 
@@ -6267,18 +6414,18 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
                                /* enumvals */
                                values[11] = NULL;
 
-                               /* boot_val */
-                               values[12] = NULL;
+                               /* boot_val */
+                               values[12] = NULL;
 
-                               /* reset_val */
-                               values[13] = NULL;
+                               /* reset_val */
+                               values[13] = NULL;
                        }
                        break;
        }
 
-       /* 
-        * If the setting came from a config file, set the source location.
-        * For security reasons, we don't show source file/line number for
+       /*
+        * If the setting came from a config file, set the source location. For
+        * security reasons, we don't show source file/line number for
         * non-superusers.
         */
        if (conf->source == PGC_S_FILE && superuser())
@@ -6379,10 +6526,10 @@ show_all_settings(PG_FUNCTION_ARGS)
                                                   TEXTOID, -1, 0);
                TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
                                                   TEXTARRAYOID, -1, 0);
-               TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
-                                                  TEXTOID, -1, 0);
-               TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
-                                                  TEXTOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
+                                                  TEXTOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
+                                                  TEXTOID, -1, 0);
                TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile",
                                                   TEXTOID, -1, 0);
                TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
@@ -6476,10 +6623,7 @@ _ShowOption(struct config_generic * record, bool use_units)
                                {
                                        /*
                                         * Use int64 arithmetic to avoid overflows in units
-                                        * conversion.  If INT64_IS_BUSTED we might overflow
-                                        * anyway and print bogus answers, but there are few
-                                        * enough such machines that it doesn't seem worth
-                                        * trying harder.
+                                        * conversion.
                                         */
                                        int64           result = *conf->variable;
                                        const char *unit;
@@ -6592,7 +6736,7 @@ _ShowOption(struct config_generic * record, bool use_units)
                        {
                                struct config_enum *conf = (struct config_enum *) record;
 
-                               if(conf->show_hook)
+                               if (conf->show_hook)
                                        val = (*conf->show_hook) ();
                                else
                                        val = config_enum_lookup_by_value(conf, *conf->variable);
@@ -6681,7 +6825,7 @@ is_newvalue_equal(struct config_generic * record, const char *newvalue)
  *             variable source, integer
  */
 static void
-write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
+write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
 {
        if (gconf->source == PGC_S_DEFAULT)
                return;
@@ -6692,49 +6836,49 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
        switch (gconf->vartype)
        {
                case PGC_BOOL:
-               {
-                       struct config_bool *conf = (struct config_bool *) gconf;
+                       {
+                               struct config_bool *conf = (struct config_bool *) gconf;
 
-                       if (*conf->variable)
-                               fprintf(fp, "true");
-                       else
-                               fprintf(fp, "false");
-               }
-               break;
+                               if (*conf->variable)
+                                       fprintf(fp, "true");
+                               else
+                                       fprintf(fp, "false");
+                       }
+                       break;
 
                case PGC_INT:
-               {
-                       struct config_int *conf = (struct config_int *) gconf;
+                       {
+                               struct config_int *conf = (struct config_int *) gconf;
 
-                       fprintf(fp, "%d", *conf->variable);
-               }
-               break;
+                               fprintf(fp, "%d", *conf->variable);
+                       }
+                       break;
 
                case PGC_REAL:
-               {
-                       struct config_real *conf = (struct config_real *) gconf;
+                       {
+                               struct config_real *conf = (struct config_real *) gconf;
 
-                       /* Could lose precision here? */
-                       fprintf(fp, "%f", *conf->variable);
-               }
-               break;
+                               /* Could lose precision here? */
+                               fprintf(fp, "%f", *conf->variable);
+                       }
+                       break;
 
                case PGC_STRING:
-               {
-                       struct config_string *conf = (struct config_string *) gconf;
+                       {
+                               struct config_string *conf = (struct config_string *) gconf;
 
-                       fprintf(fp, "%s", *conf->variable);
-               }
-               break;
+                               fprintf(fp, "%s", *conf->variable);
+                       }
+                       break;
 
                case PGC_ENUM:
-               {
-                       struct config_enum *conf = (struct config_enum *) gconf;
-                                               
-                       fprintf(fp, "%s",
-                                       config_enum_lookup_by_value(conf, *conf->variable));
-               }
-               break;
+                       {
+                               struct config_enum *conf = (struct config_enum *) gconf;
+
+                               fprintf(fp, "%s",
+                                               config_enum_lookup_by_value(conf, *conf->variable));
+                       }
+                       break;
        }
 
        fputc(0, fp);
@@ -7157,7 +7301,7 @@ assign_log_destination(const char *value, bool doit, GucSource source)
                list_free(elemlist);
                ereport(GUC_complaint_elevel(source),
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                       errmsg("invalid list syntax for parameter \"log_destination\"")));
+                  errmsg("invalid list syntax for parameter \"log_destination\"")));
                return NULL;
        }
 
@@ -7335,6 +7479,21 @@ assign_debug_assertions(bool newval, bool doit, GucSource source)
        return true;
 }
 
+static bool
+assign_bonjour(bool newval, bool doit, GucSource source)
+{
+#ifndef USE_BONJOUR
+       if (newval)
+       {
+               ereport(GUC_complaint_elevel(source),
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("Bonjour is not supported by this build")));
+               return false;
+       }
+#endif
+       return true;
+}
+
 static bool
 assign_ssl(bool newval, bool doit, GucSource source)
 {
@@ -7396,6 +7555,18 @@ assign_transaction_read_only(bool newval, bool doit, GucSource source)
                if (source != PGC_S_OVERRIDE)
                        return false;
        }
+
+       /* Can't go to r/w mode while recovery is still active */
+       if (newval == false && XactReadOnly && RecoveryInProgress())
+       {
+               ereport(GUC_complaint_elevel(source),
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("cannot set transaction read-write mode during recovery")));
+               /* source == PGC_S_OVERRIDE means do it anyway, eg at xact abort */
+               if (source != PGC_S_OVERRIDE)
+                       return false;
+       }
+
        return true;
 }
 
@@ -7537,11 +7708,11 @@ show_tcp_keepalives_count(void)
 static bool
 assign_maxconnections(int newval, bool doit, GucSource source)
 {
-       if (newval + autovacuum_max_workers > INT_MAX / 4)
+       if (newval + autovacuum_max_workers + 1 > INT_MAX / 4)
                return false;
 
        if (doit)
-               MaxBackends = newval + autovacuum_max_workers;
+               MaxBackends = newval + autovacuum_max_workers + 1;
 
        return true;
 }
@@ -7549,11 +7720,11 @@ assign_maxconnections(int newval, bool doit, GucSource source)
 static bool
 assign_autovacuum_max_workers(int newval, bool doit, GucSource source)
 {
-       if (newval + MaxConnections > INT_MAX / 4)
+       if (MaxConnections + newval + 1 > INT_MAX / 4)
                return false;
 
        if (doit)
-               MaxBackends = newval + MaxConnections;
+               MaxBackends = MaxConnections + newval + 1;
 
        return true;
 }
@@ -7573,11 +7744,11 @@ assign_effective_io_concurrency(int newval, bool doit, GucSource source)
         *
         * drives |   I/O requests
         * -------+----------------
-        *      1 |   1
-        *      2 |   2/1 + 2/2 = 3
-        *      3 |   3/1 + 3/2 + 3/3 = 5 1/2
-        *      4 |   4/1 + 4/2 + 4/3 + 4/4 = 8 1/3
-        *      n |   n * H(n)
+        *              1 |   1
+        *              2 |   2/1 + 2/2 = 3
+        *              3 |   3/1 + 3/2 + 3/3 = 5 1/2
+        *              4 |   4/1 + 4/2 + 4/3 + 4/4 = 8 1/3
+        *              n |   n * H(n)
         *
         * This is called the "coupon collector problem" and H(n) is called the
         * harmonic series.  This could be approximated by n * ln(n), but for
@@ -7610,7 +7781,7 @@ assign_effective_io_concurrency(int newval, bool doit, GucSource source)
                return false;
 #else
        return true;
-#endif /* USE_PREFETCH */
+#endif   /* USE_PREFETCH */
 }
 
 static const char *
@@ -7618,19 +7789,52 @@ assign_pgstat_temp_directory(const char *newval, bool doit, GucSource source)
 {
        if (doit)
        {
+               char       *canon_val = guc_strdup(ERROR, newval);
+               char       *tname;
+               char       *fname;
+
+               canonicalize_path(canon_val);
+
+               tname = guc_malloc(ERROR, strlen(canon_val) + 12);              /* /pgstat.tmp */
+               sprintf(tname, "%s/pgstat.tmp", canon_val);
+               fname = guc_malloc(ERROR, strlen(canon_val) + 13);              /* /pgstat.stat */
+               sprintf(fname, "%s/pgstat.stat", canon_val);
+
                if (pgstat_stat_tmpname)
                        free(pgstat_stat_tmpname);
+               pgstat_stat_tmpname = tname;
                if (pgstat_stat_filename)
                        free(pgstat_stat_filename);
+               pgstat_stat_filename = fname;
 
-               pgstat_stat_tmpname = guc_malloc(FATAL, strlen(newval) + 12);  /* /pgstat.tmp */
-               pgstat_stat_filename = guc_malloc(FATAL, strlen(newval) + 13); /* /pgstat.stat */
-
-               sprintf(pgstat_stat_tmpname, "%s/pgstat.tmp", newval);
-               sprintf(pgstat_stat_filename, "%s/pgstat.stat", newval);
+               return canon_val;
        }
+       else
+               return newval;
+}
 
-       return newval;
+static const char *
+assign_application_name(const char *newval, bool doit, GucSource source)
+{
+       if (doit)
+       {
+               /* Only allow clean ASCII chars in the application name */
+               char       *repval = guc_strdup(ERROR, newval);
+               char       *p;
+
+               for (p = repval; *p; p++)
+               {
+                       if (*p < 32 || *p > 126)
+                               *p = '?';
+               }
+
+               /* Update the pg_stat_activity view */
+               pgstat_report_appname(repval);
+
+               return repval;
+       }
+       else
+               return newval;
 }
 
 #include "guc-file.c"