diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 7a08b92..a508ef9 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -1161,7 +1161,11 @@ DecodeDateTime(char **field, int *ftype, int nf, if (dterr < 0) return dterr; } - else if (flen > 4) + /* + * should call DecodeNumberField only when anyone Date or + * Time field is not yet found. + */ + else if (flen > 4 && (!(fmask & DTK_DATE_M) || !(fmask & DTK_TIME_M))) { dterr = DecodeNumberField(flen, field[i], fmask, &tmask, tm, @@ -2647,29 +2651,20 @@ DecodeNumberField(int len, char *str, int fmask, /* No decimal point and no complete date yet? */ else if ((fmask & DTK_DATE_M) != DTK_DATE_M) { - /* yyyymmdd? */ - if (len == 8) - { - *tmask = DTK_DATE_M; - - tm->tm_mday = atoi(str + 6); - *(str + 6) = '\0'; - tm->tm_mon = atoi(str + 4); - *(str + 4) = '\0'; - tm->tm_year = atoi(str + 0); - - return DTK_DATE; - } - /* yymmdd? */ - else if (len == 6) + if (len >= 6) { *tmask = DTK_DATE_M; - tm->tm_mday = atoi(str + 4); - *(str + 4) = '\0'; - tm->tm_mon = atoi(str + 2); - *(str + 2) = '\0'; - tm->tm_year = atoi(str + 0); - *is2digits = TRUE; + /* + * Start from end and consider first 2 as Day next 2 as Month and rest + * as Year field. + */ + tm->tm_mday = atoi(str + (len-2)); + *(str + (len-2)) = '\0'; + tm->tm_mon = atoi(str + (len-4)); + *(str + (len-4)) = '\0'; + tm->tm_year = atoi(str+0); + if ((len-4) == 2) + *is2digits = TRUE; return DTK_DATE; } diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out index 6581b5e..84361df 100644 --- a/src/test/regress/expected/timestamptz.out +++ b/src/test/regress/expected/timestamptz.out @@ -1675,3 +1675,21 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') | 2001 1 1 1 1 1 1 (66 rows) +CREATE TABLE TIMESTAMPTZ_TST (a int , b timestamptz); +-- Test year field value with len > 4 +INSERT INTO TIMESTAMPTZ_TST VALUES(1, 'Sat Mar 11 23:58:48 1000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 11 23:58:48 10000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 11 23:58:48 100000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100011010 10:10:10 IST'); +--Verify data +SELECT * FROM TIMESTAMPTZ_TST ORDER BY a; + a | b +---+-------------------------------- + 1 | Tue Mar 11 13:58:48 1000 PST + 2 | Sat Mar 11 13:58:48 10000 PST + 3 | Sat Mar 11 13:58:48 100000 PST + 4 | Wed Oct 10 01:10:10 10001 PDT +(4 rows) + +--Cleanup +DROP TABLE TIMESTAMPTZ_TST; diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql index 863b286..27f96dd 100644 --- a/src/test/regress/sql/timestamptz.sql +++ b/src/test/regress/sql/timestamptz.sql @@ -240,3 +240,15 @@ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID') SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') FROM TIMESTAMPTZ_TBL; + +CREATE TABLE TIMESTAMPTZ_TST (a int , b timestamptz); + +-- Test year field value with len > 4 +INSERT INTO TIMESTAMPTZ_TST VALUES(1, 'Sat Mar 11 23:58:48 1000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 11 23:58:48 10000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 11 23:58:48 100000 IST'); +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100011010 10:10:10 IST'); +--Verify data +SELECT * FROM TIMESTAMPTZ_TST ORDER BY a; +--Cleanup +DROP TABLE TIMESTAMPTZ_TST;