Commit 7778ddc7 authored by Bruce Momjian's avatar Bruce Momjian

Allow 5+ digit years for non-ISO timestamp/date strings, where appropriate

Report from Haribabu Kommi
parent d41ab717
...@@ -1161,7 +1161,17 @@ DecodeDateTime(char **field, int *ftype, int nf, ...@@ -1161,7 +1161,17 @@ DecodeDateTime(char **field, int *ftype, int nf,
if (dterr < 0) if (dterr < 0)
return dterr; return dterr;
} }
else if (flen > 4) /*
* Is this a YMD or HMS specification, or a year number?
* YMD and HMS are required to be six digits or more, so
* if it is 5 digits, it is a year. If it is six or more
* more digits, we assume it is YMD or HMS unless no date
* and no time values have been specified. This forces
* 6+ digit years to be at the end of the string, or to use
* the ISO date specification.
*/
else if (flen >= 6 && (!(fmask & DTK_DATE_M) ||
!(fmask & DTK_TIME_M)))
{ {
dterr = DecodeNumberField(flen, field[i], fmask, dterr = DecodeNumberField(flen, field[i], fmask,
&tmask, tm, &tmask, tm,
...@@ -2647,29 +2657,20 @@ DecodeNumberField(int len, char *str, int fmask, ...@@ -2647,29 +2657,20 @@ DecodeNumberField(int len, char *str, int fmask,
/* No decimal point and no complete date yet? */ /* No decimal point and no complete date yet? */
else if ((fmask & DTK_DATE_M) != DTK_DATE_M) else if ((fmask & DTK_DATE_M) != DTK_DATE_M)
{ {
/* yyyymmdd? */ if (len >= 6)
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)
{ {
*tmask = DTK_DATE_M; *tmask = DTK_DATE_M;
tm->tm_mday = atoi(str + 4); /*
*(str + 4) = '\0'; * Start from end and consider first 2 as Day, next 2 as Month,
tm->tm_mon = atoi(str + 2); * and the rest as Year.
*(str + 2) = '\0'; */
tm->tm_year = atoi(str + 0); tm->tm_mday = atoi(str + (len - 2));
*is2digits = TRUE; *(str + (len - 2)) = '\0';
tm->tm_mon = atoi(str + (len - 4));
*(str + (len - 4)) = '\0';
tm->tm_year = atoi(str);
if ((len - 4) == 2)
*is2digits = TRUE;
return DTK_DATE; return DTK_DATE;
} }
...@@ -2686,7 +2687,7 @@ DecodeNumberField(int len, char *str, int fmask, ...@@ -2686,7 +2687,7 @@ DecodeNumberField(int len, char *str, int fmask,
*(str + 4) = '\0'; *(str + 4) = '\0';
tm->tm_min = atoi(str + 2); tm->tm_min = atoi(str + 2);
*(str + 2) = '\0'; *(str + 2) = '\0';
tm->tm_hour = atoi(str + 0); tm->tm_hour = atoi(str);
return DTK_TIME; return DTK_TIME;
} }
...@@ -2697,7 +2698,7 @@ DecodeNumberField(int len, char *str, int fmask, ...@@ -2697,7 +2698,7 @@ DecodeNumberField(int len, char *str, int fmask,
tm->tm_sec = 0; tm->tm_sec = 0;
tm->tm_min = atoi(str + 2); tm->tm_min = atoi(str + 2);
*(str + 2) = '\0'; *(str + 2) = '\0';
tm->tm_hour = atoi(str + 0); tm->tm_hour = atoi(str);
return DTK_TIME; return DTK_TIME;
} }
......
...@@ -1675,3 +1675,25 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') ...@@ -1675,3 +1675,25 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
| 2001 1 1 1 1 1 1 | 2001 1 1 1 1 1 1
(66 rows) (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 12 23:58:48 1000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 12 23:58:48 10000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 12 23:58:48 100000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(3, '10000 Mar 12 23:58:48 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100000312 23:58:48 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(4, '1000000312 23:58:48 IST');
--Verify data
SELECT * FROM TIMESTAMPTZ_TST ORDER BY a;
a | b
---+--------------------------------
1 | Wed Mar 12 13:58:48 1000 PST
2 | Sun Mar 12 14:58:48 10000 PDT
3 | Sun Mar 12 14:58:48 100000 PDT
3 | Sun Mar 12 14:58:48 10000 PDT
4 | Sun Mar 12 14:58:48 10000 PDT
4 | Sun Mar 12 14:58:48 100000 PDT
(6 rows)
--Cleanup
DROP TABLE TIMESTAMPTZ_TST;
...@@ -240,3 +240,17 @@ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID') ...@@ -240,3 +240,17 @@ 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') SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
FROM TIMESTAMPTZ_TBL; 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 12 23:58:48 1000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 12 23:58:48 10000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 12 23:58:48 100000 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(3, '10000 Mar 12 23:58:48 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100000312 23:58:48 IST');
INSERT INTO TIMESTAMPTZ_TST VALUES(4, '1000000312 23:58:48 IST');
--Verify data
SELECT * FROM TIMESTAMPTZ_TST ORDER BY a;
--Cleanup
DROP TABLE TIMESTAMPTZ_TST;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment