1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

Fix portability issues in datetime parsing.

datetime.c's parsing logic has assumed that strtod() will accept
a string that looks like ".", which it does in glibc, but not on
some less-common platforms such as AIX.  The result of this was
that datetime fields like "123." would be accepted on some platforms
but not others; which is a sufficiently odd case that it's not that
surprising we've heard no field complaints.  But commit e39f99046
extended that assumption to new places, and happened to add a test
case that exposed the platform dependency.  Remove this dependency
by special-casing situations without any digits after the decimal
point.

(Again, this is in part a pre-existing bug but I don't feel a
compulsion to back-patch.)

Also, rearrange e39f99046's changes in formatting.c to avoid a
Coverity complaint that we were copying an uninitialized field.

Discussion: https://postgr.es/m/1592893.1648969747@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2022-04-03 17:04:21 -04:00
parent f3c15cbe50
commit 591e088dd5
4 changed files with 132 additions and 36 deletions

View File

@ -4134,11 +4134,13 @@ timestamp_to_char(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
COPY_tm(tm, &tt);
thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
tm->tm_wday = (thisdate + 1) % 7;
tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;
/* calculate wday and yday, because timestamp2tm doesn't */
thisdate = date2j(tt.tm_year, tt.tm_mon, tt.tm_mday);
tt.tm_wday = (thisdate + 1) % 7;
tt.tm_yday = thisdate - date2j(tt.tm_year, 1, 1) + 1;
COPY_tm(tm, &tt);
if (!(res = datetime_to_char_body(&tmtc, fmt, false, PG_GET_COLLATION())))
PG_RETURN_NULL();
@ -4168,11 +4170,13 @@ timestamptz_to_char(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
COPY_tm(tm, &tt);
thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
tm->tm_wday = (thisdate + 1) % 7;
tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;
/* calculate wday and yday, because timestamp2tm doesn't */
thisdate = date2j(tt.tm_year, tt.tm_mon, tt.tm_mday);
tt.tm_wday = (thisdate + 1) % 7;
tt.tm_yday = thisdate - date2j(tt.tm_year, 1, 1) + 1;
COPY_tm(tm, &tt);
if (!(res = datetime_to_char_body(&tmtc, fmt, false, PG_GET_COLLATION())))
PG_RETURN_NULL();