Tighten handling of "ago" in interval values

This commit Restrict the unit "ago" to only appear at the end of the
interval.  According to the documentation, a direction can only be
defined at the end of an interval, but it was possible to define it in
the middle of the string or define it multiple times.

In spirit, this is similar to the error handling improvements done in
5b3c595355 or bcc704b524.

Author: Joseph Koshakow
Reviewed-by: Jacob Champion, Gurjeet Singh, Reid Thompson
Discussion: https://postgr.es/m/CAAvxfHd-yNO+XYnUxL=GaNZ1n+eE0V-oE0+-cC1jdjdU0KS3iw@mail.gmail.com
pull/140/head
Michael Paquier 2 years ago
parent 9a0ddc39c6
commit 165d581f14
  1. 7
      src/backend/utils/adt/datetime.c
  2. 9
      src/test/regress/expected/interval.out
  3. 4
      src/test/regress/sql/interval.sql

@ -3578,6 +3578,13 @@ 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;

@ -1787,3 +1787,12 @@ SELECT extract(epoch from interval '1000000000 days');
86400000000000.000000
(1 row)
-- "ago" can only appear once at the end of an 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';
^

@ -582,3 +582,7 @@ SELECT f1,
-- internal overflow test case
SELECT extract(epoch from interval '1000000000 days');
-- "ago" can only appear once at the end of an interval.
SELECT INTERVAL '42 days 2 seconds ago ago';
SELECT INTERVAL '2 minutes ago 5 days';

Loading…
Cancel
Save