summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/datatype.sgml7
-rw-r--r--doc/src/sgml/ref/set.sgml9
-rw-r--r--src/backend/commands/variable.c96
-rw-r--r--src/backend/utils/init/globals.c2
-rw-r--r--src/include/miscadmin.h9
-rw-r--r--src/test/regress/expected/horology.out6
6 files changed, 31 insertions, 98 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 07f0385d80d..dea5195786a 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -2419,8 +2419,11 @@ January 8 04:05:06 1999 PST
optional daylight-savings zone abbreviation, assumed to stand for one
hour ahead of the given offset. For example, if <literal>EST5EDT</>
were not already a recognized zone name, it would be accepted and would
- be functionally equivalent to United States East Coast time. When a
- daylight-savings zone name is present, it is assumed to be used
+ be functionally equivalent to United States East Coast time. In this
+ syntax, a zone abbreviation can be a string of letters, or an
+ arbitrary string surrounded by angle brackets (<literal>&lt;&gt;</>).
+ When a daylight-savings zone abbreviation is present,
+ it is assumed to be used
according to the same daylight-savings transition rules used in the
<literal>zoneinfo</> time zone database's <filename>posixrules</> entry.
In a standard <productname>PostgreSQL</productname> installation,
diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml
index d108dd4831c..6290c9de708 100644
--- a/doc/src/sgml/ref/set.sgml
+++ b/doc/src/sgml/ref/set.sgml
@@ -243,7 +243,16 @@ SELECT setseed(<replaceable>value</replaceable>);
</listitem>
</varlistentry>
</variablelist>
+ </para>
+ <para>
+ Timezone settings given as numbers or intervals are internally
+ translated to POSIX timezone syntax. For example, after
+ <literal>SET TIME ZONE -7</>, <command>SHOW TIME ZONE</> would
+ report <literal>&lt;-07&gt;+07</>.
+ </para>
+
+ <para>
See <xref linkend="datatype-timezones"> for more information
about time zones.
</para>
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index b6af6e7e253..e1ce6ff5b0a 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -243,34 +243,17 @@ assign_datestyle(const char *newval, void *extra)
* TIMEZONE
*/
-typedef struct
-{
- pg_tz *session_timezone;
- int CTimeZone;
- bool HasCTZSet;
-} timezone_extra;
-
/*
* check_timezone: GUC check_hook for timezone
*/
bool
check_timezone(char **newval, void **extra, GucSource source)
{
- timezone_extra myextra;
+ pg_tz *new_tz;
+ long gmtoffset;
char *endptr;
double hours;
- /*
- * 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
- * specified by logic below. To avoid leaking memory during failure
- * returns, we set up the struct contents in a local variable, and only
- * copy it to *extra at the end.
- */
- myextra.session_timezone = session_timezone;
- myextra.CTimeZone = CTimeZone;
- myextra.HasCTZSet = HasCTZSet;
-
if (pg_strncasecmp(*newval, "interval", 8) == 0)
{
/*
@@ -323,12 +306,11 @@ check_timezone(char **newval, void **extra, GucSource source)
/* Here we change from SQL to Unix sign convention */
#ifdef HAVE_INT64_TIMESTAMP
- myextra.CTimeZone = -(interval->time / USECS_PER_SEC);
+ gmtoffset = -(interval->time / USECS_PER_SEC);
#else
- myextra.CTimeZone = -interval->time;
+ gmtoffset = -interval->time;
#endif
- myextra.session_timezone = pg_tzset_offset(myextra.CTimeZone);
- myextra.HasCTZSet = true;
+ new_tz = pg_tzset_offset(gmtoffset);
pfree(interval);
}
@@ -341,17 +323,14 @@ check_timezone(char **newval, void **extra, GucSource source)
if (endptr != *newval && *endptr == '\0')
{
/* Here we change from SQL to Unix sign convention */
- myextra.CTimeZone = -hours * SECS_PER_HOUR;
- myextra.session_timezone = pg_tzset_offset(myextra.CTimeZone);
- myextra.HasCTZSet = true;
+ gmtoffset = -hours * SECS_PER_HOUR;
+ new_tz = pg_tzset_offset(gmtoffset);
}
else
{
/*
* Otherwise assume it is a timezone name, and try to load it.
*/
- pg_tz *new_tz;
-
new_tz = pg_tzset(*newval);
if (!new_tz)
@@ -367,40 +346,16 @@ check_timezone(char **newval, void **extra, GucSource source)
GUC_check_errdetail("PostgreSQL does not support leap seconds.");
return false;
}
-
- myextra.session_timezone = new_tz;
- myextra.HasCTZSet = false;
}
}
/*
- * Prepare the canonical string to return. GUC wants it malloc'd.
- *
- * Note: the result string should be something that we'd accept as input.
- * We use the numeric format for interval cases, because it's simpler to
- * reload. In the named-timezone case, *newval is already OK and need not
- * be changed; it might not have the canonical casing, but that's taken
- * care of by show_timezone.
- */
- if (myextra.HasCTZSet)
- {
- char *result = (char *) malloc(64);
-
- if (!result)
- return false;
- snprintf(result, 64, "%.5f",
- (double) (-myextra.CTimeZone) / (double) SECS_PER_HOUR);
- free(*newval);
- *newval = result;
- }
-
- /*
* Pass back data for assign_timezone to use
*/
- *extra = malloc(sizeof(timezone_extra));
+ *extra = malloc(sizeof(pg_tz *));
if (!*extra)
return false;
- memcpy(*extra, &myextra, sizeof(timezone_extra));
+ *((pg_tz **) *extra) = new_tz;
return true;
}
@@ -411,43 +366,19 @@ check_timezone(char **newval, void **extra, GucSource source)
void
assign_timezone(const char *newval, void *extra)
{
- timezone_extra *myextra = (timezone_extra *) extra;
-
- session_timezone = myextra->session_timezone;
- CTimeZone = myextra->CTimeZone;
- HasCTZSet = myextra->HasCTZSet;
+ session_timezone = *((pg_tz **) extra);
}
/*
* show_timezone: GUC show_hook for timezone
- *
- * We wouldn't need this, except that historically interval values have been
- * shown without an INTERVAL prefix, so the display format isn't what would
- * be accepted as input. Otherwise we could have check_timezone return the
- * preferred string to begin with.
*/
const char *
show_timezone(void)
{
const char *tzn;
- if (HasCTZSet)
- {
- Interval interval;
-
- interval.month = 0;
- interval.day = 0;
-#ifdef HAVE_INT64_TIMESTAMP
- interval.time = -(CTimeZone * USECS_PER_SEC);
-#else
- interval.time = -CTimeZone;
-#endif
-
- tzn = DatumGetCString(DirectFunctionCall1(interval_out,
- IntervalPGetDatum(&interval)));
- }
- else
- tzn = pg_get_timezone_name(session_timezone);
+ /* Always show the zone's canonical name */
+ tzn = pg_get_timezone_name(session_timezone);
if (tzn != NULL)
return tzn;
@@ -497,7 +428,7 @@ check_log_timezone(char **newval, void **extra, GucSource source)
*extra = malloc(sizeof(pg_tz *));
if (!*extra)
return false;
- memcpy(*extra, &new_tz, sizeof(pg_tz *));
+ *((pg_tz **) *extra) = new_tz;
return true;
}
@@ -519,6 +450,7 @@ show_log_timezone(void)
{
const char *tzn;
+ /* Always show the zone's canonical name */
tzn = pg_get_timezone_name(log_timezone);
if (tzn != NULL)
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 33efb3c3cca..e76704f3153 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -93,8 +93,6 @@ bool ExitOnAnyError = false;
int DateStyle = USE_ISO_DATES;
int DateOrder = DATEORDER_MDY;
int IntervalStyle = INTSTYLE_POSTGRES;
-bool HasCTZSet = false;
-int CTimeZone = 0;
bool enableFsync = true;
bool allowSystemTableMods = false;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 0aa540a08ef..98ca5539a4c 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -219,15 +219,6 @@ extern int DateOrder;
extern int IntervalStyle;
-/*
- * HasCTZSet is true if user has set timezone as a numeric offset from UTC.
- * If so, CTimeZone is the timezone offset in seconds (using the Unix-ish
- * sign convention, ie, positive offset is west of UTC, rather than the
- * SQL-ish convention that positive is east of UTC).
- */
-extern bool HasCTZSet;
-extern int CTimeZone;
-
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
extern bool enableFsync;
diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out
index 3ed9c8c1a09..87a695144ea 100644
--- a/src/test/regress/expected/horology.out
+++ b/src/test/regress/expected/horology.out
@@ -2941,9 +2941,9 @@ DETAIL: Value must be in the range -2147483648 to 2147483647.
SET TIME ZONE 'America/New_York';
SET TIME ZONE '-1.5';
SHOW TIME ZONE;
- TimeZone
-----------------------
- @ 1 hour 30 mins ago
+ TimeZone
+----------------
+ <-01:30>+01:30
(1 row)
SELECT '2012-12-12 12:00'::timestamptz;