Remove CTimeZone/HasCTZSet, root and branch.
authorTom Lane
Fri, 1 Nov 2013 17:57:31 +0000 (13:57 -0400)
committerTom Lane
Fri, 1 Nov 2013 17:57:31 +0000 (13:57 -0400)
These variables no longer have any useful purpose, since there's no reason
to special-case brute force timezones now that we have a valid
session_timezone setting for them.  Remove the variables, and remove the
SET/SHOW TIME ZONE code that deals with them.

The user-visible impact of this is that SHOW TIME ZONE will now show a
POSIX-style zone specification, in the form "<+-offset>-+offset", rather
than an interval value when a brute-force zone has been set.  While perhaps
less intuitive, this is a better definition than before because it's
actually possible to give that string back to SET TIME ZONE and get the
same behavior, unlike what used to happen.

We did not previously mention the angle-bracket syntax when describing
POSIX timezone specifications; add some documentation so that people
can figure out what these strings do.  (There's still quite a lot of
undocumented functionality there, but anybody who really cares can
go read the POSIX spec to find out about it.  In practice most people
seem to prefer Olsen-style city names anyway.)

doc/src/sgml/datatype.sgml
doc/src/sgml/ref/set.sgml
src/backend/commands/variable.c
src/backend/utils/init/globals.c
src/include/miscadmin.h
src/test/regress/expected/horology.out

index 07f0385d80d4eeb4f568e43efbf387f4791a3a56..dea5195786a45ff18bb3d327d35ccb7c5b4cb050 100644 (file)
@@ -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 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 (<>).
+        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
         zoneinfo time zone database's posixrules entry.
         In a standard PostgreSQL installation,
index d108dd4831c56757ccabd394406c2ec976a0fa6b..6290c9de70852cb6cb502b9e4804e456fe7c9973 100644 (file)
@@ -243,7 +243,16 @@ SELECT setseed(value);
          
         
        
+      
 
+      
+       Timezone settings given as numbers or intervals are internally
+       translated to POSIX timezone syntax.  For example, after
+       SET TIME ZONE -7, SHOW TIME ZONE would
+       report <-07>+07.
+      
+
+      
        See  for more information
        about time zones.
       
index b6af6e7e2531300a6ccb887465fc3a26a982eb56..e1ce6ff5b0a45ab008a358933fd3298b460310ec 100644 (file)
@@ -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)
index 33efb3c3cca933f69aa16286aa8c0e68d67bb754..e76704f315334e9be0f3cae5af06de41d0e5829b 100644 (file)
@@ -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;
index 0aa540a08ef8e53db4e1aa339df27a20c4de66b6..98ca5539a4ca7e1a7f2ee0cf544f5eecdbce4be1 100644 (file)
@@ -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;
index 3ed9c8c1a095e939ef8cdd1c050fac307a96cdc5..87a695144eaf4f2ea1457dabefb8074e2182a5a9 100644 (file)
@@ -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;