From 591e088dd5b357796e136c13dfcdb1f06fd7a3c2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 3 Apr 2022 17:04:21 -0400 Subject: 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 --- src/test/regress/expected/interval.out | 35 ++++++++++++++++++++++++++++++++++ src/test/regress/sql/interval.sql | 8 ++++++++ 2 files changed, 43 insertions(+) (limited to 'src/test') diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out index 86c8d4bc990..03f77c01dcf 100644 --- a/src/test/regress/expected/interval.out +++ b/src/test/regress/expected/interval.out @@ -908,6 +908,41 @@ select interval 'P0002' AS "year only", 2 years | 2 years 10 mons | 2 years 10 mons 15 days | 2 years 00:00:01 | 2 years 10 mons 00:00:01 | 2 years 10 mons 15 days 00:00:01 | 10:00:00 | 10:30:00 (1 row) +-- Check handling of fractional fields in ISO8601 format. +select interval 'P1Y0M3DT4H5M6S'; + interval +------------------------ + 1 year 3 days 04:05:06 +(1 row) + +select interval 'P1.0Y0M3DT4H5M6S'; + interval +------------------------ + 1 year 3 days 04:05:06 +(1 row) + +select interval 'P1.1Y0M3DT4H5M6S'; + interval +------------------------------ + 1 year 1 mon 3 days 04:05:06 +(1 row) + +select interval 'P1.Y0M3DT4H5M6S'; + interval +------------------------ + 1 year 3 days 04:05:06 +(1 row) + +select interval 'P.1Y0M3DT4H5M6S'; + interval +----------------------- + 1 mon 3 days 04:05:06 +(1 row) + +select interval 'P.Y0M3DT4H5M6S'; -- error +ERROR: invalid input syntax for type interval: "P.Y0M3DT4H5M6S" +LINE 1: select interval 'P.Y0M3DT4H5M6S'; + ^ -- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. SET IntervalStyle to postgres_verbose; select interval '-10 mons -3 days +03:55:06.70'; diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql index f05055e03a9..97d33a13236 100644 --- a/src/test/regress/sql/interval.sql +++ b/src/test/regress/sql/interval.sql @@ -312,6 +312,14 @@ select interval 'P0002' AS "year only", interval 'PT10' AS "hour only", interval 'PT10:30' AS "hour minute"; +-- Check handling of fractional fields in ISO8601 format. +select interval 'P1Y0M3DT4H5M6S'; +select interval 'P1.0Y0M3DT4H5M6S'; +select interval 'P1.1Y0M3DT4H5M6S'; +select interval 'P1.Y0M3DT4H5M6S'; +select interval 'P.1Y0M3DT4H5M6S'; +select interval 'P.Y0M3DT4H5M6S'; -- error + -- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. SET IntervalStyle to postgres_verbose; select interval '-10 mons -3 days +03:55:06.70'; -- cgit v1.2.3