PGC_INTERNAL, PGC_S_OVERRIDE);
/* If we have no other source of client_encoding, use server encoding */
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
- PGC_BACKEND, PGC_S_DEFAULT);
+ PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
/* assign locale variables */
collate = NameStr(dbform->datcollate);
#include <ctype.h>
#include <unistd.h>
+#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/guc.h"
*tail;
char *cvc = NULL;
struct config_string *cvc_struct;
- const char *envvar;
int i;
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
stack->source = PGC_S_DEFAULT;
}
- /* Now we can re-apply the wired-in default */
+ /* Now we can re-apply the wired-in default (i.e., the boot_val) */
set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT,
GUC_ACTION_SET, true);
if (context == PGC_SIGHUP)
}
/*
- * Restore any variables determined by environment variables. This
- * is a no-op except in the case where one of these had been in the
- * config file and is now removed. PGC_S_ENV_VAR will override the
- * wired-in default we just applied, but cannot override any other source.
+ * Restore any variables determined by environment variables or
+ * dynamically-computed defaults. This is a no-op except in the case
+ * where one of these had been in the config file and is now removed.
*
- * Keep this list in sync with InitializeGUCOptions()!
- * PGPORT can be ignored, because it cannot be changed without restart.
- * We assume rlimit hasn't changed, either.
+ * In particular, we *must not* do this during the postmaster's
+ * initial loading of the file, since the timezone functions in
+ * particular should be run only after initialization is complete.
+ *
+ * XXX this is an unmaintainable crock, because we have to know how
+ * to set (or at least what to call to set) every variable that could
+ * potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
+ * However, there's no time to redesign it for 9.1.
*/
- envvar = getenv("PGDATESTYLE");
- if (envvar != NULL)
- set_config_option("datestyle", envvar, PGC_POSTMASTER,
- PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
- envvar = getenv("PGCLIENTENCODING");
- if (envvar != NULL)
- set_config_option("client_encoding", envvar, PGC_POSTMASTER,
- PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
+ if (context == PGC_SIGHUP)
+ {
+ InitializeGUCOptionsFromEnvironment();
+ pg_timezone_initialize();
+ pg_timezone_abbrev_initialize();
+ /* this selects SQL_ASCII in processes not connected to a database */
+ SetConfigOption("client_encoding", GetDatabaseEncodingName(),
+ PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
+ }
/* If we got here all the options checked out okay, so apply them. */
for (item = head; item; item = item->next)
const char *const GucSource_Names[] =
{
/* PGC_S_DEFAULT */ "default",
+ /* PGC_S_DYNAMIC_DEFAULT */ "default",
/* PGC_S_ENV_VAR */ "environment variable",
/* PGC_S_FILE */ "configuration file",
/* PGC_S_ARGV */ "command line",
static int guc_var_compare(const void *a, const void *b);
static int guc_name_compare(const char *namea, const char *nameb);
+static void InitializeGUCOptionsFromEnvironment(void);
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);
InitializeGUCOptions(void)
{
int i;
- char *env;
- long stack_rlimit;
/*
* Before log_line_prefix could possibly receive a nonempty setting, make
/*
* For historical reasons, some GUC parameters can receive defaults from
- * environment variables. Process those settings. NB: if you add or
- * remove anything here, see also ProcessConfigFile().
+ * environment variables. Process those settings.
*/
+ InitializeGUCOptionsFromEnvironment();
+}
+
+/*
+ * Assign any GUC values that can come from the server's environment.
+ *
+ * This is called from InitializeGUCOptions, and also from ProcessConfigFile
+ * to deal with the possibility that a setting has been removed from
+ * postgresql.conf and should now get a value from the environment.
+ * (The latter is a kludge that should probably go away someday; if so,
+ * fold this back into InitializeGUCOptions.)
+ */
+static void
+InitializeGUCOptionsFromEnvironment(void)
+{
+ char *env;
+ long stack_rlimit;
env = getenv("PGPORT");
if (env != NULL)
switch (pHolder->gen.source)
{
case PGC_S_DEFAULT:
+ case PGC_S_DYNAMIC_DEFAULT:
case PGC_S_ENV_VAR:
case PGC_S_FILE:
case PGC_S_ARGV:
*
* This is called after initial loading of postgresql.conf. If no
* timezone_abbreviations setting was found therein, select default.
+ * If a non-default value is already installed, nothing will happen.
*/
void
pg_timezone_abbrev_initialize(void)
{
- if (timezone_abbreviations_string == NULL)
- {
- SetConfigOption("timezone_abbreviations", "Default",
- PGC_POSTMASTER, PGC_S_DEFAULT);
- }
+ SetConfigOption("timezone_abbreviations", "Default",
+ PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
}
static const char *
*/
typedef enum
{
- PGC_S_DEFAULT, /* wired-in default */
+ PGC_S_DEFAULT, /* hard-wired default ("boot_val") */
+ PGC_S_DYNAMIC_DEFAULT, /* default computed during initialization */
PGC_S_ENV_VAR, /* postmaster environment variable */
PGC_S_FILE, /* postgresql.conf */
PGC_S_ARGV, /* postmaster command line */
* This is called after initial loading of postgresql.conf. If no TimeZone
* setting was found therein, we try to derive one from the environment.
* Likewise for log_timezone.
+ *
+ * Note: this is also called from ProcessConfigFile, to re-establish valid
+ * GUC settings if the GUCs have been reset to default following their
+ * removal from postgresql.conf.
*/
void
pg_timezone_initialize(void)
log_timezone = def_tz;
}
- /* Now, set the timezone GUC if it's not already set */
- if (GetConfigOption("timezone", false) == NULL)
- {
- /* Tell GUC about the value. Will redundantly call pg_tzset() */
+ /*
+ * Now, set the timezone and log_timezone GUCs if they're still default.
+ * (This will redundantly call pg_tzset().)
+ *
+ * We choose to label these values PGC_S_ENV_VAR, rather than
+ * PGC_S_DYNAMIC_DEFAULT which would be functionally equivalent, because
+ * they came either from getenv("TZ") or from libc behavior that's
+ * determined by process environment of some kind.
+ *
+ * Note: in the case where a setting has just been removed from
+ * postgresql.conf, this code will not do what you might expect, namely
+ * call select_default_timezone() and install that value as the setting.
+ * Rather, the previously active setting --- typically the one from
+ * postgresql.conf --- will be reinstalled, relabeled as PGC_S_ENV_VAR.
+ * If we did try to install the "correct" default value, the effect would
+ * be that each postmaster child would independently run an extremely
+ * expensive search of the timezone database, bringing the database to its
+ * knees for possibly multiple seconds. This is so unpleasant, and could
+ * so easily be triggered quite unintentionally, that it seems better to
+ * violate the principle of least astonishment.
+ */
+ if (GetConfigOptionResetString("timezone") == NULL)
SetConfigOption("timezone", pg_get_timezone_name(session_timezone),
PGC_POSTMASTER, PGC_S_ENV_VAR);
- }
- /* Likewise for log timezone */
- if (GetConfigOption("log_timezone", false) == NULL)
- {
- /* Tell GUC about the value. Will redundantly call pg_tzset() */
+ if (GetConfigOptionResetString("log_timezone") == NULL)
SetConfigOption("log_timezone", pg_get_timezone_name(log_timezone),
PGC_POSTMASTER, PGC_S_ENV_VAR);
- }
}