mirror of
https://github.com/postgres/postgres.git
synced 2025-12-01 12:18:01 +03:00
Switch over to using the src/timezone functions for formatting timestamps
displayed in the postmaster log. This avoids Windows-specific problems with localized time zone names that are in the wrong encoding, and generally seems like a good idea to forestall other potential platform-dependent issues. To preserve the existing behavior that all backends will log in the same time zone, create a new GUC variable log_timezone that can only be changed on a system-wide basis, and reference log-related calculations to that zone instead of the TimeZone variable. This fixes the issue reported by Hiroshi Saito that timestamps printed by xlog.c startup could be improperly localized on Windows. We still need a simpler patch for that problem in the back branches, however.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.134 2007/07/06 04:15:58 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.135 2007/08/04 01:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -360,7 +360,7 @@ date2timestamptz(DateADT dateVal)
|
||||
tm->tm_hour = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
|
||||
@@ -2239,7 +2239,7 @@ time_timetz(PG_FUNCTION_ARGS)
|
||||
|
||||
GetCurrentDateTime(tm);
|
||||
time2tm(time, tm, &fsec);
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.181 2007/06/12 15:58:32 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.182 2007/08/04 01:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1325,7 +1325,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
if (fmask & DTK_M(DTZMOD))
|
||||
return DTERR_BAD_FORMAT;
|
||||
|
||||
*tzp = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
*tzp = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1361,7 +1361,7 @@ DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp)
|
||||
after_isdst;
|
||||
int res;
|
||||
|
||||
if (tzp == global_timezone && HasCTZSet)
|
||||
if (tzp == session_timezone && HasCTZSet)
|
||||
{
|
||||
tm->tm_isdst = 0; /* for lack of a better idea */
|
||||
return CTimeZone;
|
||||
@@ -2033,7 +2033,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
tmp->tm_hour = tm->tm_hour;
|
||||
tmp->tm_min = tm->tm_min;
|
||||
tmp->tm_sec = tm->tm_sec;
|
||||
*tzp = DetermineTimeZoneOffset(tmp, global_timezone);
|
||||
*tzp = DetermineTimeZoneOffset(tmp, session_timezone);
|
||||
tm->tm_isdst = tmp->tm_isdst;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* formatting.c
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.130 2007/06/29 01:51:35 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.131 2007/08/04 01:26:53 tgl Exp $
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1999-2007, PostgreSQL Global Development Group
|
||||
@@ -3286,7 +3286,7 @@ to_timestamp(PG_FUNCTION_ARGS)
|
||||
|
||||
do_to_timestamp(date_txt, fmt, &tm, &fsec);
|
||||
|
||||
tz = DetermineTimeZoneOffset(&tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(&tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
|
||||
ereport(ERROR,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.150 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.151 2007/08/04 01:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -112,7 +112,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn)
|
||||
time -= CTimeZone;
|
||||
|
||||
if (!HasCTZSet && tzp != NULL)
|
||||
tx = pg_localtime(&time, global_timezone);
|
||||
tx = pg_localtime(&time, session_timezone);
|
||||
else
|
||||
tx = pg_gmtime(&time);
|
||||
|
||||
@@ -474,7 +474,7 @@ timestamp_abstime(PG_FUNCTION_ARGS)
|
||||
result = NOEND_ABSTIME;
|
||||
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
|
||||
{
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
result = tm2abstime(tm, tz);
|
||||
}
|
||||
else
|
||||
@@ -1591,7 +1591,7 @@ timeofday(PG_FUNCTION_ARGS)
|
||||
gettimeofday(&tp, NULL);
|
||||
tt = (pg_time_t) tp.tv_sec;
|
||||
pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
|
||||
pg_localtime(&tt, global_timezone));
|
||||
pg_localtime(&tt, session_timezone));
|
||||
snprintf(buf, sizeof(buf), templ, tp.tv_usec);
|
||||
|
||||
len = VARHDRSZ + strlen(buf);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.180 2007/07/18 03:13:13 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.181 2007/08/04 01:26:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1494,7 +1494,7 @@ recalc_t:
|
||||
if ((Timestamp) utime == dt)
|
||||
{
|
||||
struct pg_tm *tx = pg_localtime(&utime,
|
||||
attimezone ? attimezone : global_timezone);
|
||||
attimezone ? attimezone : session_timezone);
|
||||
|
||||
tm->tm_year = tx->tm_year + 1900;
|
||||
tm->tm_mon = tx->tm_mon + 1;
|
||||
@@ -2675,7 +2675,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
|
||||
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
||||
tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
|
||||
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0)
|
||||
ereport(ERROR,
|
||||
@@ -2699,7 +2699,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
|
||||
julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day;
|
||||
j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
||||
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0)
|
||||
ereport(ERROR,
|
||||
@@ -3546,7 +3546,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
if (redotz)
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
|
||||
ereport(ERROR,
|
||||
@@ -4010,7 +4010,7 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0)
|
||||
ereport(ERROR,
|
||||
@@ -4549,7 +4549,7 @@ timestamp2timestamptz(Timestamp timestamp)
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
|
||||
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
|
||||
ereport(ERROR,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.191 2007/08/02 23:39:44 adunstan Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.192 2007/08/04 01:26:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1495,33 +1495,18 @@ log_line_prefix(StringInfo buf)
|
||||
break;
|
||||
case 'm':
|
||||
{
|
||||
/*
|
||||
* Note: for %m, %t, and %s we deliberately use the C
|
||||
* library's strftime/localtime, and not the equivalent
|
||||
* functions from src/timezone. This ensures that all
|
||||
* backends will report log entries in the same timezone,
|
||||
* namely whatever C-library setting they inherit from the
|
||||
* postmaster. If we used src/timezone then local
|
||||
* settings of the TimeZone GUC variable would confuse the
|
||||
* log.
|
||||
*/
|
||||
time_t stamp_time;
|
||||
struct timeval tv;
|
||||
pg_time_t stamp_time;
|
||||
char strfbuf[128],
|
||||
msbuf[8];
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
stamp_time = tv.tv_sec;
|
||||
stamp_time = (pg_time_t) tv.tv_sec;
|
||||
|
||||
strftime(strfbuf, sizeof(strfbuf),
|
||||
/* leave room for milliseconds... */
|
||||
/* Win32 timezone names are too long so don't print them */
|
||||
#ifndef WIN32
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
#else
|
||||
"%Y-%m-%d %H:%M:%S ",
|
||||
#endif
|
||||
localtime(&stamp_time));
|
||||
pg_strftime(strfbuf, sizeof(strfbuf),
|
||||
/* leave room for milliseconds... */
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
pg_localtime(&stamp_time, log_timezone));
|
||||
|
||||
/* 'paste' milliseconds into place... */
|
||||
sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));
|
||||
@@ -1532,32 +1517,23 @@ log_line_prefix(StringInfo buf)
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
time_t stamp_time = time(NULL);
|
||||
pg_time_t stamp_time = (pg_time_t) time(NULL);
|
||||
char strfbuf[128];
|
||||
|
||||
strftime(strfbuf, sizeof(strfbuf),
|
||||
/* Win32 timezone names are too long so don't print them */
|
||||
#ifndef WIN32
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
#else
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
#endif
|
||||
localtime(&stamp_time));
|
||||
pg_strftime(strfbuf, sizeof(strfbuf),
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
pg_localtime(&stamp_time, log_timezone));
|
||||
appendStringInfoString(buf, strfbuf);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
{
|
||||
pg_time_t stamp_time = (pg_time_t) MyStartTime;
|
||||
char strfbuf[128];
|
||||
|
||||
strftime(strfbuf, sizeof(strfbuf),
|
||||
/* Win32 timezone names are too long so don't print them */
|
||||
#ifndef WIN32
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
#else
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
#endif
|
||||
localtime(&MyStartTime));
|
||||
pg_strftime(strfbuf, sizeof(strfbuf),
|
||||
"%Y-%m-%d %H:%M:%S %Z",
|
||||
pg_localtime(&stamp_time, log_timezone));
|
||||
appendStringInfoString(buf, strfbuf);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.408 2007/08/01 22:45:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.409 2007/08/04 01:26:54 tgl Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
@@ -255,6 +255,7 @@ static char *server_encoding_string;
|
||||
static char *server_version_string;
|
||||
static int server_version_num;
|
||||
static char *timezone_string;
|
||||
static char *log_timezone_string;
|
||||
static char *timezone_abbreviations_string;
|
||||
static char *XactIsoLevel_string;
|
||||
static char *data_directory;
|
||||
@@ -1984,6 +1985,14 @@ static struct config_string ConfigureNamesString[] =
|
||||
"", NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
{"log_timezone", PGC_SIGHUP, LOGGING_WHAT,
|
||||
gettext_noop("Sets the time zone to use in log messages."),
|
||||
NULL
|
||||
},
|
||||
&log_timezone_string,
|
||||
"UNKNOWN", assign_log_timezone, show_log_timezone
|
||||
},
|
||||
|
||||
{
|
||||
{"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
|
||||
|
||||
@@ -347,6 +347,8 @@
|
||||
#log_temp_files = -1 # Log temporary files equal or larger
|
||||
# than specified number of kilobytes.
|
||||
# -1 disables; 0 logs all temp files
|
||||
#log_timezone = unknown # actually, defaults to TZ
|
||||
# environment setting
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# RUNTIME STATISTICS
|
||||
|
||||
Reference in New Issue
Block a user