Simplify handling of the timezone GUC by making initdb choose the default.
We were doing some amazingly complicated things in order to avoid running the very expensive identify_system_timezone() procedure during GUC initialization. But there is an obvious fix for that, which is to do it once during initdb and have initdb install the system-specific default into postgresql.conf, as it already does for most other GUC variables that need system-environment-dependent defaults. This means that the timezone (and log_timezone) settings no longer have any magic behavior in the server. Per discussion.
This commit is contained in:
parent
a7801b62f2
commit
ca4af308c3
|
@ -3915,9 +3915,10 @@ FROM pg_stat_activity;
|
||||||
Sets the time zone used for timestamps written in the server log.
|
Sets the time zone used for timestamps written in the server log.
|
||||||
Unlike <xref linkend="guc-timezone">, this value is cluster-wide,
|
Unlike <xref linkend="guc-timezone">, this value is cluster-wide,
|
||||||
so that all sessions will report timestamps consistently.
|
so that all sessions will report timestamps consistently.
|
||||||
If not explicitly set, the server initializes this variable to the
|
The built-in default is <literal>GMT</>, but that is typically
|
||||||
time zone specified by its system environment. See <xref
|
overridden in <filename>postgresql.conf</>; <application>initdb</>
|
||||||
linkend="datatype-timezones"> for more information.
|
will install a setting there corresponding to its system environment.
|
||||||
|
See <xref linkend="datatype-timezones"> for more information.
|
||||||
This parameter can only be set in the <filename>postgresql.conf</>
|
This parameter can only be set in the <filename>postgresql.conf</>
|
||||||
file or on the server command line.
|
file or on the server command line.
|
||||||
</para>
|
</para>
|
||||||
|
@ -4963,9 +4964,10 @@ SET XML OPTION { DOCUMENT | CONTENT };
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Sets the time zone for displaying and interpreting time stamps.
|
Sets the time zone for displaying and interpreting time stamps.
|
||||||
If not explicitly set, the server initializes this variable to the
|
The built-in default is <literal>GMT</>, but that is typically
|
||||||
time zone specified by its system environment. See <xref
|
overridden in <filename>postgresql.conf</>; <application>initdb</>
|
||||||
linkend="datatype-timezones"> for more information.
|
will install a setting there corresponding to its system environment.
|
||||||
|
See <xref linkend="datatype-timezones"> for more information.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -2286,7 +2286,7 @@ January 8 04:05:06 1999 PST
|
||||||
but continue to be prone to arbitrary changes, particularly with
|
but continue to be prone to arbitrary changes, particularly with
|
||||||
respect to daylight-savings rules.
|
respect to daylight-savings rules.
|
||||||
<productname>PostgreSQL</productname> uses the widely-used
|
<productname>PostgreSQL</productname> uses the widely-used
|
||||||
<literal>zoneinfo</> time zone database for information about
|
<literal>zoneinfo</> (Olson) time zone database for information about
|
||||||
historical time zone rules. For times in the future, the assumption
|
historical time zone rules. For times in the future, the assumption
|
||||||
is that the latest known rules for a given time zone will
|
is that the latest known rules for a given time zone will
|
||||||
continue to be observed indefinitely far into the future.
|
continue to be observed indefinitely far into the future.
|
||||||
|
@ -2432,26 +2432,9 @@ January 8 04:05:06 1999 PST
|
||||||
The <xref linkend="guc-timezone"> configuration parameter can
|
The <xref linkend="guc-timezone"> configuration parameter can
|
||||||
be set in the file <filename>postgresql.conf</>, or in any of the
|
be set in the file <filename>postgresql.conf</>, or in any of the
|
||||||
other standard ways described in <xref linkend="runtime-config">.
|
other standard ways described in <xref linkend="runtime-config">.
|
||||||
There are also several special ways to set it:
|
There are also some special ways to set it:
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
If <varname>timezone</> is not specified in
|
|
||||||
<filename>postgresql.conf</> or as a server command-line option,
|
|
||||||
the server attempts to use the value of the <envar>TZ</envar>
|
|
||||||
environment variable as the default time zone. If <envar>TZ</envar>
|
|
||||||
is not defined or is not any of the time zone names known to
|
|
||||||
<productname>PostgreSQL</productname>, the server attempts to
|
|
||||||
determine the operating system's default time zone by checking the
|
|
||||||
behavior of the C library function <literal>localtime()</>. The
|
|
||||||
default time zone is selected as the closest match among
|
|
||||||
<productname>PostgreSQL</productname>'s known time zones.
|
|
||||||
(These rules are also used to choose the default value of
|
|
||||||
<xref linkend="guc-log-timezone">, if not specified.)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The <acronym>SQL</acronym> command <command>SET TIME ZONE</command>
|
The <acronym>SQL</acronym> command <command>SET TIME ZONE</command>
|
||||||
|
|
|
@ -239,9 +239,7 @@ SELECT setseed(<replaceable>value</replaceable>);
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Set the time zone to your local time zone (that is, the
|
Set the time zone to your local time zone (that is, the
|
||||||
server's default value of <varname>timezone</>; if this
|
server's default value of <varname>timezone</>).
|
||||||
has not been explicitly set anywhere, it will be the zone that
|
|
||||||
the server's operating system defaults to).
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -333,10 +333,6 @@ AuxiliaryProcessMain(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (!SelectConfigFiles(userDoption, progname))
|
if (!SelectConfigFiles(userDoption, progname))
|
||||||
proc_exit(1);
|
proc_exit(1);
|
||||||
/* If timezone is not set, determine what the OS uses */
|
|
||||||
pg_timezone_initialize();
|
|
||||||
/* If timezone_abbreviations is not set, select default */
|
|
||||||
pg_timezone_abbrev_initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate we have been given a reasonable-looking DataDir */
|
/* Validate we have been given a reasonable-looking DataDir */
|
||||||
|
|
|
@ -259,23 +259,6 @@ check_timezone(char **newval, void **extra, GucSource source)
|
||||||
char *endptr;
|
char *endptr;
|
||||||
double hours;
|
double hours;
|
||||||
|
|
||||||
if (*newval == NULL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The boot_val given for TimeZone in guc.c is NULL. When we see this
|
|
||||||
* we just do nothing. If this isn't overridden from the config file
|
|
||||||
* then pg_timezone_initialize() will eventually select a default
|
|
||||||
* value from the environment. This hack has two purposes: to avoid
|
|
||||||
* wasting cycles loading values that might soon be overridden from
|
|
||||||
* the config file, and to avoid trying to read the timezone files
|
|
||||||
* during InitializeGUCOptions(). The latter doesn't work in an
|
|
||||||
* EXEC_BACKEND subprocess because my_exec_path hasn't been set yet
|
|
||||||
* and so we can't locate PGSHAREDIR.
|
|
||||||
*/
|
|
||||||
Assert(source == PGC_S_DEFAULT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the "extra" struct that will be passed to assign_timezone.
|
* Initialize the "extra" struct that will be passed to assign_timezone.
|
||||||
* We don't want to change any of the three global variables except as
|
* We don't want to change any of the three global variables except as
|
||||||
|
@ -374,7 +357,7 @@ check_timezone(char **newval, void **extra, GucSource source)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tz_acceptable(new_tz))
|
if (!pg_tz_acceptable(new_tz))
|
||||||
{
|
{
|
||||||
GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
|
GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
|
||||||
*newval);
|
*newval);
|
||||||
|
@ -427,10 +410,6 @@ assign_timezone(const char *newval, void *extra)
|
||||||
{
|
{
|
||||||
timezone_extra *myextra = (timezone_extra *) extra;
|
timezone_extra *myextra = (timezone_extra *) extra;
|
||||||
|
|
||||||
/* Do nothing for the boot_val default of NULL */
|
|
||||||
if (!myextra)
|
|
||||||
return;
|
|
||||||
|
|
||||||
session_timezone = myextra->session_timezone;
|
session_timezone = myextra->session_timezone;
|
||||||
CTimeZone = myextra->CTimeZone;
|
CTimeZone = myextra->CTimeZone;
|
||||||
HasCTZSet = myextra->HasCTZSet;
|
HasCTZSet = myextra->HasCTZSet;
|
||||||
|
@ -490,20 +469,8 @@ check_log_timezone(char **newval, void **extra, GucSource source)
|
||||||
{
|
{
|
||||||
pg_tz *new_tz;
|
pg_tz *new_tz;
|
||||||
|
|
||||||
if (*newval == NULL)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* The boot_val given for log_timezone in guc.c is NULL. When we see
|
* Assume it is a timezone name, and try to load it.
|
||||||
* this we just do nothing. If this isn't overridden from the config
|
|
||||||
* file then pg_timezone_initialize() will eventually select a default
|
|
||||||
* value from the environment.
|
|
||||||
*/
|
|
||||||
Assert(source == PGC_S_DEFAULT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Otherwise assume it is a timezone name, and try to load it.
|
|
||||||
*/
|
*/
|
||||||
new_tz = pg_tzset(*newval);
|
new_tz = pg_tzset(*newval);
|
||||||
|
|
||||||
|
@ -513,7 +480,7 @@ check_log_timezone(char **newval, void **extra, GucSource source)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tz_acceptable(new_tz))
|
if (!pg_tz_acceptable(new_tz))
|
||||||
{
|
{
|
||||||
GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
|
GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
|
||||||
*newval);
|
*newval);
|
||||||
|
@ -538,10 +505,6 @@ check_log_timezone(char **newval, void **extra, GucSource source)
|
||||||
void
|
void
|
||||||
assign_log_timezone(const char *newval, void *extra)
|
assign_log_timezone(const char *newval, void *extra)
|
||||||
{
|
{
|
||||||
/* Do nothing for the boot_val default of NULL */
|
|
||||||
if (!extra)
|
|
||||||
return;
|
|
||||||
|
|
||||||
log_timezone = *((pg_tz **) extra);
|
log_timezone = *((pg_tz **) extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -795,21 +795,6 @@ PostmasterMain(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
CreateDataDirLockFile(true);
|
CreateDataDirLockFile(true);
|
||||||
|
|
||||||
/*
|
|
||||||
* If timezone is not set, determine what the OS uses. (In theory this
|
|
||||||
* should be done during GUC initialization, but because it can take as
|
|
||||||
* much as several seconds, we delay it until after we've created the
|
|
||||||
* postmaster.pid file. This prevents problems with boot scripts that
|
|
||||||
* expect the pidfile to appear quickly. Also, we avoid problems with
|
|
||||||
* trying to locate the timezone files too early in initialization.)
|
|
||||||
*/
|
|
||||||
pg_timezone_initialize();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Likewise, init timezone_abbreviations if not already set.
|
|
||||||
*/
|
|
||||||
pg_timezone_abbrev_initialize();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize SSL library, if specified.
|
* Initialize SSL library, if specified.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3537,10 +3537,6 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||||
{
|
{
|
||||||
if (!SelectConfigFiles(userDoption, progname))
|
if (!SelectConfigFiles(userDoption, progname))
|
||||||
proc_exit(1);
|
proc_exit(1);
|
||||||
/* If timezone is not set, determine what the OS uses */
|
|
||||||
pg_timezone_initialize();
|
|
||||||
/* If timezone_abbreviations is not set, select default */
|
|
||||||
pg_timezone_abbrev_initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1805,24 +1805,20 @@ setup_formatted_log_time(void)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
pg_time_t stamp_time;
|
pg_time_t stamp_time;
|
||||||
pg_tz *tz;
|
|
||||||
char msbuf[8];
|
char msbuf[8];
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
stamp_time = (pg_time_t) tv.tv_sec;
|
stamp_time = (pg_time_t) tv.tv_sec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normally we print log timestamps in log_timezone, but during startup we
|
* Note: we expect that guc.c will ensure that log_timezone is set up
|
||||||
* could get here before that's set. If so, fall back to gmt_timezone
|
* (at least with a minimal GMT value) before Log_line_prefix can become
|
||||||
* (which guc.c ensures is set up before Log_line_prefix can become
|
* nonempty or CSV mode can be selected.
|
||||||
* nonempty).
|
|
||||||
*/
|
*/
|
||||||
tz = log_timezone ? log_timezone : gmt_timezone;
|
|
||||||
|
|
||||||
pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
|
pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
|
||||||
/* leave room for milliseconds... */
|
/* leave room for milliseconds... */
|
||||||
"%Y-%m-%d %H:%M:%S %Z",
|
"%Y-%m-%d %H:%M:%S %Z",
|
||||||
pg_localtime(&stamp_time, tz));
|
pg_localtime(&stamp_time, log_timezone));
|
||||||
|
|
||||||
/* 'paste' milliseconds into place... */
|
/* 'paste' milliseconds into place... */
|
||||||
sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));
|
sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));
|
||||||
|
@ -1836,19 +1832,15 @@ static void
|
||||||
setup_formatted_start_time(void)
|
setup_formatted_start_time(void)
|
||||||
{
|
{
|
||||||
pg_time_t stamp_time = (pg_time_t) MyStartTime;
|
pg_time_t stamp_time = (pg_time_t) MyStartTime;
|
||||||
pg_tz *tz;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normally we print log timestamps in log_timezone, but during startup we
|
* Note: we expect that guc.c will ensure that log_timezone is set up
|
||||||
* could get here before that's set. If so, fall back to gmt_timezone
|
* (at least with a minimal GMT value) before Log_line_prefix can become
|
||||||
* (which guc.c ensures is set up before Log_line_prefix can become
|
* nonempty or CSV mode can be selected.
|
||||||
* nonempty).
|
|
||||||
*/
|
*/
|
||||||
tz = log_timezone ? log_timezone : gmt_timezone;
|
|
||||||
|
|
||||||
pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
|
pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
|
||||||
"%Y-%m-%d %H:%M:%S %Z",
|
"%Y-%m-%d %H:%M:%S %Z",
|
||||||
pg_localtime(&stamp_time, tz));
|
pg_localtime(&stamp_time, log_timezone));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1947,14 +1939,11 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
|
||||||
case 't':
|
case 't':
|
||||||
{
|
{
|
||||||
pg_time_t stamp_time = (pg_time_t) time(NULL);
|
pg_time_t stamp_time = (pg_time_t) time(NULL);
|
||||||
pg_tz *tz;
|
|
||||||
char strfbuf[128];
|
char strfbuf[128];
|
||||||
|
|
||||||
tz = log_timezone ? log_timezone : gmt_timezone;
|
|
||||||
|
|
||||||
pg_strftime(strfbuf, sizeof(strfbuf),
|
pg_strftime(strfbuf, sizeof(strfbuf),
|
||||||
"%Y-%m-%d %H:%M:%S %Z",
|
"%Y-%m-%d %H:%M:%S %Z",
|
||||||
pg_localtime(&stamp_time, tz));
|
pg_localtime(&stamp_time, log_timezone));
|
||||||
appendStringInfoString(buf, strfbuf);
|
appendStringInfoString(buf, strfbuf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -292,7 +292,6 @@ ProcessConfigFile(GucContext context)
|
||||||
if (context == PGC_SIGHUP)
|
if (context == PGC_SIGHUP)
|
||||||
{
|
{
|
||||||
InitializeGUCOptionsFromEnvironment();
|
InitializeGUCOptionsFromEnvironment();
|
||||||
pg_timezone_initialize();
|
|
||||||
pg_timezone_abbrev_initialize();
|
pg_timezone_abbrev_initialize();
|
||||||
/* this selects SQL_ASCII in processes not connected to a database */
|
/* this selects SQL_ASCII in processes not connected to a database */
|
||||||
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
|
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
|
||||||
|
|
|
@ -187,6 +187,7 @@ static bool check_log_stats(bool *newval, void **extra, GucSource source);
|
||||||
static bool check_canonical_path(char **newval, void **extra, GucSource source);
|
static bool check_canonical_path(char **newval, void **extra, GucSource source);
|
||||||
static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source);
|
static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source);
|
||||||
static void assign_timezone_abbreviations(const char *newval, void *extra);
|
static void assign_timezone_abbreviations(const char *newval, void *extra);
|
||||||
|
static void pg_timezone_abbrev_initialize(void);
|
||||||
static const char *show_archive_command(void);
|
static const char *show_archive_command(void);
|
||||||
static void assign_tcp_keepalives_idle(int newval, void *extra);
|
static void assign_tcp_keepalives_idle(int newval, void *extra);
|
||||||
static void assign_tcp_keepalives_interval(int newval, void *extra);
|
static void assign_tcp_keepalives_interval(int newval, void *extra);
|
||||||
|
@ -2547,7 +2548,7 @@ static struct config_string ConfigureNamesString[] =
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
&log_timezone_string,
|
&log_timezone_string,
|
||||||
NULL,
|
"GMT",
|
||||||
check_log_timezone, assign_log_timezone, show_log_timezone
|
check_log_timezone, assign_log_timezone, show_log_timezone
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2827,7 +2828,7 @@ static struct config_string ConfigureNamesString[] =
|
||||||
GUC_REPORT
|
GUC_REPORT
|
||||||
},
|
},
|
||||||
&timezone_string,
|
&timezone_string,
|
||||||
NULL,
|
"GMT",
|
||||||
check_timezone, assign_timezone, show_timezone
|
check_timezone, assign_timezone, show_timezone
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3817,7 +3818,7 @@ InitializeGUCOptions(void)
|
||||||
* Before log_line_prefix could possibly receive a nonempty setting, make
|
* Before log_line_prefix could possibly receive a nonempty setting, make
|
||||||
* sure that timezone processing is minimally alive (see elog.c).
|
* sure that timezone processing is minimally alive (see elog.c).
|
||||||
*/
|
*/
|
||||||
pg_timezone_pre_initialize();
|
pg_timezone_initialize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build sorted array of all GUC variables.
|
* Build sorted array of all GUC variables.
|
||||||
|
@ -4114,6 +4115,15 @@ SelectConfigFiles(const char *userDoption, const char *progname)
|
||||||
*/
|
*/
|
||||||
SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If timezone_abbreviations wasn't set in the configuration file, install
|
||||||
|
* the default value. We do it this way because we can't safely install
|
||||||
|
* a "real" value until my_exec_path is set, which may not have happened
|
||||||
|
* when InitializeGUCOptions runs, so the bootstrap default value cannot
|
||||||
|
* be the real desired default.
|
||||||
|
*/
|
||||||
|
pg_timezone_abbrev_initialize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out where pg_hba.conf is, and make sure the path is absolute.
|
* Figure out where pg_hba.conf is, and make sure the path is absolute.
|
||||||
*/
|
*/
|
||||||
|
@ -8444,8 +8454,11 @@ assign_timezone_abbreviations(const char *newval, void *extra)
|
||||||
* This is called after initial loading of postgresql.conf. If no
|
* This is called after initial loading of postgresql.conf. If no
|
||||||
* timezone_abbreviations setting was found therein, select default.
|
* timezone_abbreviations setting was found therein, select default.
|
||||||
* If a non-default value is already installed, nothing will happen.
|
* If a non-default value is already installed, nothing will happen.
|
||||||
|
*
|
||||||
|
* This can also be called from ProcessConfigFile to establish the default
|
||||||
|
* value after a postgresql.conf entry for it is removed.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
pg_timezone_abbrev_initialize(void)
|
pg_timezone_abbrev_initialize(void)
|
||||||
{
|
{
|
||||||
SetConfigOption("timezone_abbreviations", "Default",
|
SetConfigOption("timezone_abbreviations", "Default",
|
||||||
|
|
|
@ -406,7 +406,7 @@
|
||||||
#log_temp_files = -1 # log temporary files equal or larger
|
#log_temp_files = -1 # log temporary files equal or larger
|
||||||
# than the specified size in kilobytes;
|
# than the specified size in kilobytes;
|
||||||
# -1 disables, 0 logs all temp files
|
# -1 disables, 0 logs all temp files
|
||||||
#log_timezone = '(defaults to server environment setting)'
|
#log_timezone = 'GMT'
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
@ -486,7 +486,7 @@
|
||||||
|
|
||||||
#datestyle = 'iso, mdy'
|
#datestyle = 'iso, mdy'
|
||||||
#intervalstyle = 'postgres'
|
#intervalstyle = 'postgres'
|
||||||
#timezone = '(defaults to server environment setting)'
|
#timezone = 'GMT'
|
||||||
#timezone_abbreviations = 'Default' # Select the set of available time zone
|
#timezone_abbreviations = 'Default' # Select the set of available time zone
|
||||||
# abbreviations. Currently, there are
|
# abbreviations. Currently, there are
|
||||||
# Default
|
# Default
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/encnames.c
|
/encnames.c
|
||||||
/pqsignal.c
|
/pqsignal.c
|
||||||
|
/localtime.c
|
||||||
|
|
||||||
/initdb
|
/initdb
|
||||||
|
|
|
@ -16,9 +16,9 @@ subdir = src/bin/initdb
|
||||||
top_builddir = ../../..
|
top_builddir = ../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
|
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(CPPFLAGS)
|
||||||
|
|
||||||
OBJS= initdb.o encnames.o pqsignal.o $(WIN32RES)
|
OBJS= initdb.o findtimezone.o localtime.o encnames.o pqsignal.o $(WIN32RES)
|
||||||
|
|
||||||
all: initdb
|
all: initdb
|
||||||
|
|
||||||
|
@ -35,6 +35,11 @@ encnames.c: % : $(top_srcdir)/src/backend/utils/mb/%
|
||||||
pqsignal.c: % : $(top_srcdir)/src/interfaces/libpq/%
|
pqsignal.c: % : $(top_srcdir)/src/interfaces/libpq/%
|
||||||
rm -f $@ && $(LN_S) $< .
|
rm -f $@ && $(LN_S) $< .
|
||||||
|
|
||||||
|
# Likewise, pull in localtime.c from src/timezones
|
||||||
|
|
||||||
|
localtime.c: % : $(top_srcdir)/src/timezone/%
|
||||||
|
rm -f $@ && $(LN_S) $< .
|
||||||
|
|
||||||
install: all installdirs
|
install: all installdirs
|
||||||
$(INSTALL_PROGRAM) initdb$(X) '$(DESTDIR)$(bindir)/initdb$(X)'
|
$(INSTALL_PROGRAM) initdb$(X) '$(DESTDIR)$(bindir)/initdb$(X)'
|
||||||
|
|
||||||
|
@ -45,7 +50,7 @@ uninstall:
|
||||||
rm -f '$(DESTDIR)$(bindir)/initdb$(X)'
|
rm -f '$(DESTDIR)$(bindir)/initdb$(X)'
|
||||||
|
|
||||||
clean distclean maintainer-clean:
|
clean distclean maintainer-clean:
|
||||||
rm -f initdb$(X) $(OBJS) encnames.c pqsignal.c
|
rm -f initdb$(X) $(OBJS) encnames.c pqsignal.c localtime.c
|
||||||
|
|
||||||
|
|
||||||
# ensure that changes in datadir propagate into object file
|
# ensure that changes in datadir propagate into object file
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -61,6 +61,9 @@
|
||||||
#include "getopt_long.h"
|
#include "getopt_long.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
|
/* Ideally this would be in a .h file, but it hardly seems worth the trouble */
|
||||||
|
extern const char *select_default_timezone(const char *share_path);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* these values are passed in by makefile defines
|
* these values are passed in by makefile defines
|
||||||
|
@ -947,8 +950,9 @@ static void
|
||||||
setup_config(void)
|
setup_config(void)
|
||||||
{
|
{
|
||||||
char **conflines;
|
char **conflines;
|
||||||
char repltok[100];
|
char repltok[TZ_STRLEN_MAX + 100];
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
|
const char *default_timezone;
|
||||||
|
|
||||||
fputs(_("creating configuration files ... "), stdout);
|
fputs(_("creating configuration files ... "), stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -1011,6 +1015,17 @@ setup_config(void)
|
||||||
"#default_text_search_config = 'pg_catalog.simple'",
|
"#default_text_search_config = 'pg_catalog.simple'",
|
||||||
repltok);
|
repltok);
|
||||||
|
|
||||||
|
default_timezone = select_default_timezone(share_path);
|
||||||
|
if (default_timezone)
|
||||||
|
{
|
||||||
|
snprintf(repltok, sizeof(repltok), "timezone = '%s'",
|
||||||
|
escape_quotes(default_timezone));
|
||||||
|
conflines = replace_token(conflines, "#timezone = 'GMT'", repltok);
|
||||||
|
snprintf(repltok, sizeof(repltok), "log_timezone = '%s'",
|
||||||
|
escape_quotes(default_timezone));
|
||||||
|
conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
|
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
|
||||||
|
|
||||||
writefile(path, conflines);
|
writefile(path, conflines);
|
||||||
|
@ -2796,14 +2811,6 @@ main(int argc, char *argv[])
|
||||||
sprintf(pgdenv, "PGDATA=%s", pg_data);
|
sprintf(pgdenv, "PGDATA=%s", pg_data);
|
||||||
putenv(pgdenv);
|
putenv(pgdenv);
|
||||||
|
|
||||||
/*
|
|
||||||
* Also ensure that TZ is set, so that we don't waste time identifying the
|
|
||||||
* system timezone each of the many times we start a standalone backend.
|
|
||||||
* It's okay to use a hard-wired value here because nothing done during
|
|
||||||
* initdb cares about the timezone setting.
|
|
||||||
*/
|
|
||||||
putenv("TZ=GMT");
|
|
||||||
|
|
||||||
if ((ret = find_other_exec(argv[0], "postgres", PG_BACKEND_VERSIONSTR,
|
if ((ret = find_other_exec(argv[0], "postgres", PG_BACKEND_VERSIONSTR,
|
||||||
backend_exec)) < 0)
|
backend_exec)) < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,11 @@ struct pg_tm
|
||||||
typedef struct pg_tz pg_tz;
|
typedef struct pg_tz pg_tz;
|
||||||
typedef struct pg_tzenum pg_tzenum;
|
typedef struct pg_tzenum pg_tzenum;
|
||||||
|
|
||||||
|
/* Maximum length of a timezone name (not including trailing null) */
|
||||||
|
#define TZ_STRLEN_MAX 255
|
||||||
|
|
||||||
|
/* these functions are in localtime.c */
|
||||||
|
|
||||||
extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz);
|
extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz);
|
||||||
extern struct pg_tm *pg_gmtime(const pg_time_t *timep);
|
extern struct pg_tm *pg_gmtime(const pg_time_t *timep);
|
||||||
extern int pg_next_dst_boundary(const pg_time_t *timep,
|
extern int pg_next_dst_boundary(const pg_time_t *timep,
|
||||||
|
@ -52,22 +57,20 @@ extern int pg_next_dst_boundary(const pg_time_t *timep,
|
||||||
extern size_t pg_strftime(char *s, size_t max, const char *format,
|
extern size_t pg_strftime(char *s, size_t max, const char *format,
|
||||||
const struct pg_tm * tm);
|
const struct pg_tm * tm);
|
||||||
|
|
||||||
extern void pg_timezone_pre_initialize(void);
|
|
||||||
extern void pg_timezone_initialize(void);
|
|
||||||
extern pg_tz *pg_tzset(const char *tzname);
|
|
||||||
extern bool tz_acceptable(pg_tz *tz);
|
|
||||||
extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff);
|
extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff);
|
||||||
extern const char *pg_get_timezone_name(pg_tz *tz);
|
extern const char *pg_get_timezone_name(pg_tz *tz);
|
||||||
|
extern bool pg_tz_acceptable(pg_tz *tz);
|
||||||
|
|
||||||
|
/* these functions and variables are in pgtz.c */
|
||||||
|
|
||||||
|
extern pg_tz *session_timezone;
|
||||||
|
extern pg_tz *log_timezone;
|
||||||
|
|
||||||
|
extern void pg_timezone_initialize(void);
|
||||||
|
extern pg_tz *pg_tzset(const char *tzname);
|
||||||
|
|
||||||
extern pg_tzenum *pg_tzenumerate_start(void);
|
extern pg_tzenum *pg_tzenumerate_start(void);
|
||||||
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
|
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
|
||||||
extern void pg_tzenumerate_end(pg_tzenum *dir);
|
extern void pg_tzenumerate_end(pg_tzenum *dir);
|
||||||
|
|
||||||
extern pg_tz *session_timezone;
|
|
||||||
extern pg_tz *log_timezone;
|
|
||||||
extern pg_tz *gmt_timezone;
|
|
||||||
|
|
||||||
/* Maximum length of a timezone name (not including trailing null) */
|
|
||||||
#define TZ_STRLEN_MAX 255
|
|
||||||
|
|
||||||
#endif /* _PGTIME_H */
|
#endif /* _PGTIME_H */
|
||||||
|
|
|
@ -333,8 +333,6 @@ extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *va
|
||||||
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
|
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
|
||||||
extern ArrayType *GUCArrayReset(ArrayType *array);
|
extern ArrayType *GUCArrayReset(ArrayType *array);
|
||||||
|
|
||||||
extern void pg_timezone_abbrev_initialize(void);
|
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
extern void write_nondefault_variables(GucContext context);
|
extern void write_nondefault_variables(GucContext context);
|
||||||
extern void read_nondefault_variables(void);
|
extern void read_nondefault_variables(void);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "datatype/timestamp.h"
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include "pgtz.h"
|
#include "pgtz.h"
|
||||||
#include "tzfile.h"
|
#include "tzfile.h"
|
||||||
|
@ -734,6 +735,7 @@ tzparse(const char *name, struct state * sp, int lastditch)
|
||||||
* can't assume pg_open_tzfile() is sane yet, and we don't care about
|
* can't assume pg_open_tzfile() is sane yet, and we don't care about
|
||||||
* leap seconds anyway.
|
* leap seconds anyway.
|
||||||
*/
|
*/
|
||||||
|
sp->goback = sp->goahead = FALSE;
|
||||||
load_result = -1;
|
load_result = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1476,3 +1478,29 @@ pg_get_timezone_name(pg_tz *tz)
|
||||||
return tz->TZname;
|
return tz->TZname;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether timezone is acceptable.
|
||||||
|
*
|
||||||
|
* What we are doing here is checking for leap-second-aware timekeeping.
|
||||||
|
* We need to reject such TZ settings because they'll wreak havoc with our
|
||||||
|
* date/time arithmetic.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
pg_tz_acceptable(pg_tz *tz)
|
||||||
|
{
|
||||||
|
struct pg_tm *tt;
|
||||||
|
pg_time_t time2000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To detect leap-second timekeeping, run pg_localtime for what should be
|
||||||
|
* GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
|
||||||
|
* other result has to be due to leap seconds.
|
||||||
|
*/
|
||||||
|
time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
|
||||||
|
tt = pg_localtime(&time2000, tz);
|
||||||
|
if (!tt || tt->tm_sec != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
1265
src/timezone/pgtz.c
1265
src/timezone/pgtz.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue