mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Allow 5+ digit years for non-ISO timestamp/date strings, where appropriate
Report from Haribabu Kommi
This commit is contained in:
@ -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,28 +2657,19 @@ 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;
|
*tmask = DTK_DATE_M;
|
||||||
|
/*
|
||||||
tm->tm_mday = atoi(str + 6);
|
* Start from end and consider first 2 as Day, next 2 as Month,
|
||||||
*(str + 6) = '\0';
|
* and the rest as Year.
|
||||||
tm->tm_mon = atoi(str + 4);
|
*/
|
||||||
*(str + 4) = '\0';
|
tm->tm_mday = atoi(str + (len - 2));
|
||||||
tm->tm_year = atoi(str + 0);
|
*(str + (len - 2)) = '\0';
|
||||||
|
tm->tm_mon = atoi(str + (len - 4));
|
||||||
return DTK_DATE;
|
*(str + (len - 4)) = '\0';
|
||||||
}
|
tm->tm_year = atoi(str);
|
||||||
/* yymmdd? */
|
if ((len - 4) == 2)
|
||||||
else 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;
|
*is2digits = TRUE;
|
||||||
|
|
||||||
return DTK_DATE;
|
return DTK_DATE;
|
||||||
@ -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,
|
|||||||
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')
|
|||||||
| 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')
|
|||||||
|
|
||||||
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;
|
||||||
|
Reference in New Issue
Block a user