]> granicus.if.org Git - postgresql/commitdiff
Measure epoch of timestamp-without-time-zone from local not UTC midnight.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Apr 2012 16:04:42 +0000 (12:04 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Apr 2012 16:04:42 +0000 (12:04 -0400)
This patch reverts commit 191ef2b407f065544ceed5700e42400857d9270f
and thereby restores the pre-7.3 behavior of EXTRACT(EPOCH FROM
timestamp-without-tz).  Per discussion, the more recent behavior was
misguided on a couple of grounds: it makes it hard to get a
non-timezone-aware epoch value for a timestamp, and it makes this one
case dependent on the value of the timezone GUC, which is incompatible
with having timestamp_part() labeled as immutable.

The other behavior is still available (in all releases) by explicitly
casting the timestamp to timestamp with time zone before applying EXTRACT.

This will need to be called out as an incompatible change in the 9.2
release notes.  Although having mutable behavior in a function marked
immutable is clearly a bug, we're not going to back-patch such a change.

doc/src/sgml/func.sgml
src/backend/utils/adt/timestamp.c

index 34fea16eeeeb58d2c76d1e028eadd3f46e834c3f..ae22ee5f7fae64873414b4a2c0b715d4f55c1e9a 100644 (file)
@@ -6684,8 +6684,10 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
       <term><literal>epoch</literal></term>
       <listitem>
        <para>
-        For <type>date</type> and <type>timestamp</type> values, the
+        For <type>timestamp with time zone</type> values, the
         number of seconds since 1970-01-01 00:00:00 UTC (can be negative);
+        for <type>date</type> and <type>timestamp</type> values, the
+        number of seconds since 1970-01-01 00:00:00 local time;
         for <type>interval</type> values, the total number
         of seconds in the interval
        </para>
index 9a7238be38d03d2de0a5850527930e8f66d72909..a3e1e94a2b22a253b1372f02230d783834ad9bdb 100644 (file)
@@ -4066,32 +4066,13 @@ timestamp_part(PG_FUNCTION_ARGS)
                switch (val)
                {
                        case DTK_EPOCH:
-                               {
-                                       int                     tz;
-                                       TimestampTz timestamptz;
-
-                                       /*
-                                        * convert to timestamptz to produce consistent results
-                                        */
-                                       if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                                errmsg("timestamp out of range")));
-
-                                       tz = DetermineTimeZoneOffset(tm, session_timezone);
-
-                                       if (tm2timestamp(tm, fsec, &tz, &timestamptz) != 0)
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                                errmsg("timestamp out of range")));
-
 #ifdef HAVE_INT64_TIMESTAMP
-                                       result = (timestamptz - SetEpochTimestamp()) / 1000000.0;
+                                       result = (timestamp - SetEpochTimestamp()) / 1000000.0;
 #else
-                                       result = timestamptz - SetEpochTimestamp();
+                                       result = timestamp - SetEpochTimestamp();
 #endif
                                        break;
-                               }
+
                        case DTK_DOW:
                        case DTK_ISODOW:
                                if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)