From 6271c5fcca30de0982b4b6073b49c1cea6c7391b Mon Sep 17 00:00:00 2001 From: Joseph Koshakow Date: Sun, 9 Jul 2023 13:17:08 -0400 Subject: [PATCH 2/3] Fix Interval 'ago' parsing This commit Restrict the unit "ago" to only appear at the end of the interval. According to the docs [0], this is the only valid place to put it, but we allowed it multiple times at any point in the input. [0] https://www.postgresql.org/docs/15/datatype-datetime.html#DATATYPE-INTERVAL-INPUT --- src/backend/utils/adt/datetime.c | 6 ++++++ src/test/regress/expected/interval.out | 9 +++++++++ src/test/regress/sql/interval.sql | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 2a5dddc43f..9d09381328 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -3578,6 +3578,12 @@ DecodeInterval(char **field, int *ftype, int nf, int range, break; case AGO: + /* + * 'ago' is only allowed to appear at the end of the + * interval. + */ + if (i != nf - 1) + return DTERR_BAD_FORMAT; is_before = true; type = uval; break; diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out index 28b71d9681..42062f947f 100644 --- a/src/test/regress/expected/interval.out +++ b/src/test/regress/expected/interval.out @@ -1787,3 +1787,12 @@ SELECT extract(epoch from interval '1000000000 days'); 86400000000000.000000 (1 row) +-- test that ago can only appear once at the end of the interval. +SELECT INTERVAL '42 days 2 seconds ago ago'; +ERROR: invalid input syntax for type interval: "42 days 2 seconds ago ago" +LINE 1: SELECT INTERVAL '42 days 2 seconds ago ago'; + ^ +SELECT INTERVAL '2 minutes ago 5 days'; +ERROR: invalid input syntax for type interval: "2 minutes ago 5 days" +LINE 1: SELECT INTERVAL '2 minutes ago 5 days'; + ^ diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql index 56feda1a3d..8fd2e7f41e 100644 --- a/src/test/regress/sql/interval.sql +++ b/src/test/regress/sql/interval.sql @@ -582,3 +582,7 @@ SELECT f1, -- internal overflow test case SELECT extract(epoch from interval '1000000000 days'); + +-- test that ago can only appear once at the end of the interval. +SELECT INTERVAL '42 days 2 seconds ago ago'; +SELECT INTERVAL '2 minutes ago 5 days'; -- 2.34.1