]> granicus.if.org Git - postgresql/commitdiff
Fix DecodeDateTime to allow timezone to appear before year. This had
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Jun 2007 15:58:32 +0000 (15:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Jun 2007 15:58:32 +0000 (15:58 +0000)
historically worked in some but not all cases, but as of 8.2 it failed for all
timezone formats.  Fix, and add regression test cases to catch future
regressions in this area.  Per gripe from Adam Witney.

src/backend/utils/adt/datetime.c
src/test/regress/expected/timestamptz.out
src/test/regress/sql/timestamptz.sql

index b5cc2461589c98b1a8aeb64db0666a059e6a09e1..ddd4fa6167decd219221ee046abaf17a1d1050a0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.180 2007/05/29 04:58:43 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.181 2007/06/12 15:58:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -721,11 +721,17 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                }
                                /***
                                 * Already have a date? Then this might be a time zone name
-                                * with embedded punctuation (e.g. "America/New_York") or
-                                * run-together time with trailing time zone (e.g. hhmmss-zz).
+                                * with embedded punctuation (e.g. "America/New_York") or a
+                                * run-together time with trailing time zone (e.g. hhmmss-zz).
                                 * - thomas 2001-12-25
+                                *
+                                * We consider it a time zone if we already have month & day.
+                                * This is to allow the form "mmm dd hhmmss tz year", which
+                                * we've historically accepted.
                                 ***/
-                               else if ((fmask & DTK_DATE_M) == DTK_DATE_M || ptype != 0)
+                               else if (ptype != 0 ||
+                                                ((fmask & (DTK_M(MONTH) | DTK_M(DAY))) ==
+                                                 (DTK_M(MONTH) | DTK_M(DAY))))
                                {
                                        /* No time zone accepted? Then quit... */
                                        if (tzp == NULL)
index 3f117ec0842cc0e933c6eedccf2f3a858e937b7b..e6213a5d9b7b9e6e3091bbb40f5b086122a74491 100644 (file)
@@ -153,6 +153,38 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097');
 ERROR:  time zone displacement out of range: "Feb 16 17:32:01 -0097"
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC');
 ERROR:  timestamp out of range: "Feb 16 17:32:01 5097 BC"
+-- Alternate field order that we've historically supported (sort of)
+-- with regular and POSIXy timezone specs
+SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz;
+         timestamptz          
+------------------------------
+ Wed Jul 11 07:51:14 2001 PDT
+(1 row)
+
+SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz;
+         timestamptz          
+------------------------------
+ Tue Jul 10 23:51:14 2001 PDT
+(1 row)
+
+SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz;
+         timestamptz          
+------------------------------
+ Wed Jul 11 07:51:14 2001 PDT
+(1 row)
+
+SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz;
+         timestamptz          
+------------------------------
+ Wed Jul 11 00:51:14 2001 PDT
+(1 row)
+
+SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz;
+         timestamptz          
+------------------------------
+ Wed Jul 11 06:51:14 2001 PDT
+(1 row)
+
 SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL; 
  64 |               d1                
 ----+---------------------------------
@@ -724,7 +756,7 @@ SELECT '' AS "54", d1 as timestamptz,
    date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
    date_part( 'dow', d1) AS dow
    FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
- 54 |            timestamptz          | isoyear | week | dow 
+ 54 |           timestamptz           | isoyear | week | dow 
 ----+---------------------------------+---------+------+-----
     | Wed Dec 31 16:00:00 1969 PST    |    1970 |    1 |   3
     | Mon Feb 10 17:32:01 1997 PST    |    1997 |    7 |   1
index 73c5bde5f37ec933a11c9a46400e9fd37ffa8917..6cac1a33c74b56be5cb0d9fee8af2fe6e515c6cb 100644 (file)
@@ -127,6 +127,14 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC');
 
+-- Alternate field order that we've historically supported (sort of)
+-- with regular and POSIXy timezone specs
+SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz;
+SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz;
+SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz;
+SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz;
+SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz;
+
 SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL; 
 
 -- Demonstrate functions and operators