Tighten unit parsing in internal values
Interval values now generate an error when the user has multiple consecutive units or a unit without a value. Previously, it was possible to specify multiple units consecutively which is contrary to what the documentation allows, so it was possible to finish with confusing interval values. This is a follow-up of the work done in 165d581f146b. 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
This commit is contained in:
parent
165d581f14
commit
617f9b7d4b
@ -3278,6 +3278,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
{
|
||||
bool force_negative = false;
|
||||
bool is_before = false;
|
||||
bool parsing_unit_val = false;
|
||||
char *cp;
|
||||
int fmask = 0,
|
||||
tmask,
|
||||
@ -3336,6 +3337,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
itm_in->tm_usec > 0)
|
||||
itm_in->tm_usec = -itm_in->tm_usec;
|
||||
type = DTK_DAY;
|
||||
parsing_unit_val = false;
|
||||
break;
|
||||
|
||||
case DTK_TZ:
|
||||
@ -3373,6 +3375,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
* are reading right to left.
|
||||
*/
|
||||
type = DTK_DAY;
|
||||
parsing_unit_val = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3562,10 +3565,14 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
default:
|
||||
return DTERR_BAD_FORMAT;
|
||||
}
|
||||
parsing_unit_val = false;
|
||||
break;
|
||||
|
||||
case DTK_STRING:
|
||||
case DTK_SPECIAL:
|
||||
/* reject consecutive unhandled units */
|
||||
if (parsing_unit_val)
|
||||
return DTERR_BAD_FORMAT;
|
||||
type = DecodeUnits(i, field[i], &uval);
|
||||
if (type == IGNORE_DTF)
|
||||
continue;
|
||||
@ -3575,6 +3582,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
{
|
||||
case UNITS:
|
||||
type = uval;
|
||||
parsing_unit_val = true;
|
||||
break;
|
||||
|
||||
case AGO:
|
||||
@ -3607,6 +3615,10 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
if (fmask == 0)
|
||||
return DTERR_BAD_FORMAT;
|
||||
|
||||
/* reject if unit appeared and was never handled */
|
||||
if (parsing_unit_val)
|
||||
return DTERR_BAD_FORMAT;
|
||||
|
||||
/* finally, AGO negates everything */
|
||||
if (is_before)
|
||||
{
|
||||
|
@ -1796,3 +1796,12 @@ 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';
|
||||
^
|
||||
-- consecutive and dangling units are not allowed.
|
||||
SELECT INTERVAL 'hour 5 months';
|
||||
ERROR: invalid input syntax for type interval: "hour 5 months"
|
||||
LINE 1: SELECT INTERVAL 'hour 5 months';
|
||||
^
|
||||
SELECT INTERVAL '1 year months days 5 hours';
|
||||
ERROR: invalid input syntax for type interval: "1 year months days 5 hours"
|
||||
LINE 1: SELECT INTERVAL '1 year months days 5 hours';
|
||||
^
|
||||
|
@ -586,3 +586,7 @@ 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';
|
||||
|
||||
-- consecutive and dangling units are not allowed.
|
||||
SELECT INTERVAL 'hour 5 months';
|
||||
SELECT INTERVAL '1 year months days 5 hours';
|
||||
|
Loading…
x
Reference in New Issue
Block a user