aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/formatting.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-04-03 17:04:21 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-04-03 17:04:33 -0400
commit591e088dd5b357796e136c13dfcdb1f06fd7a3c2 (patch)
tree7fb2dd81ceece5c68645bb7e112b4f6ac224ebf2 /src/backend/utils/adt/formatting.c
parentf3c15cbe5065f8c4fb902af8f810a8061a802417 (diff)
downloadpostgresql-591e088dd5b357796e136c13dfcdb1f06fd7a3c2.tar.gz
postgresql-591e088dd5b357796e136c13dfcdb1f06fd7a3c2.zip
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
Diffstat (limited to 'src/backend/utils/adt/formatting.c')
-rw-r--r--src/backend/utils/adt/formatting.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 843b07d7d24..97a4544ffc6 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -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();