Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 617f9b7

Browse files
committed
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 165d581. 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
1 parent 165d581 commit 617f9b7

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

src/backend/utils/adt/datetime.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
32783278
{
32793279
bool force_negative = false;
32803280
bool is_before = false;
3281+
bool parsing_unit_val = false;
32813282
char *cp;
32823283
int fmask = 0,
32833284
tmask,
@@ -3336,6 +3337,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
33363337
itm_in->tm_usec > 0)
33373338
itm_in->tm_usec = -itm_in->tm_usec;
33383339
type = DTK_DAY;
3340+
parsing_unit_val = false;
33393341
break;
33403342

33413343
case DTK_TZ:
@@ -3373,6 +3375,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
33733375
* are reading right to left.
33743376
*/
33753377
type = DTK_DAY;
3378+
parsing_unit_val = false;
33763379
break;
33773380
}
33783381

@@ -3562,10 +3565,14 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
35623565
default:
35633566
return DTERR_BAD_FORMAT;
35643567
}
3568+
parsing_unit_val = false;
35653569
break;
35663570

35673571
case DTK_STRING:
35683572
case DTK_SPECIAL:
3573+
/* reject consecutive unhandled units */
3574+
if (parsing_unit_val)
3575+
return DTERR_BAD_FORMAT;
35693576
type = DecodeUnits(i, field[i], &uval);
35703577
if (type == IGNORE_DTF)
35713578
continue;
@@ -3575,6 +3582,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
35753582
{
35763583
case UNITS:
35773584
type = uval;
3585+
parsing_unit_val = true;
35783586
break;
35793587

35803588
case AGO:
@@ -3607,6 +3615,10 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
36073615
if (fmask == 0)
36083616
return DTERR_BAD_FORMAT;
36093617

3618+
/* reject if unit appeared and was never handled */
3619+
if (parsing_unit_val)
3620+
return DTERR_BAD_FORMAT;
3621+
36103622
/* finally, AGO negates everything */
36113623
if (is_before)
36123624
{

src/test/regress/expected/interval.out

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,3 +1796,12 @@ SELECT INTERVAL '2 minutes ago 5 days';
17961796
ERROR: invalid input syntax for type interval: "2 minutes ago 5 days"
17971797
LINE 1: SELECT INTERVAL '2 minutes ago 5 days';
17981798
^
1799+
-- consecutive and dangling units are not allowed.
1800+
SELECT INTERVAL 'hour 5 months';
1801+
ERROR: invalid input syntax for type interval: "hour 5 months"
1802+
LINE 1: SELECT INTERVAL 'hour 5 months';
1803+
^
1804+
SELECT INTERVAL '1 year months days 5 hours';
1805+
ERROR: invalid input syntax for type interval: "1 year months days 5 hours"
1806+
LINE 1: SELECT INTERVAL '1 year months days 5 hours';
1807+
^

src/test/regress/sql/interval.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,3 +586,7 @@ SELECT extract(epoch from interval '1000000000 days');
586586
-- "ago" can only appear once at the end of an interval.
587587
SELECT INTERVAL '42 days 2 seconds ago ago';
588588
SELECT INTERVAL '2 minutes ago 5 days';
589+
590+
-- consecutive and dangling units are not allowed.
591+
SELECT INTERVAL 'hour 5 months';
592+
SELECT INTERVAL '1 year months days 5 hours';

0 commit comments

Comments
 (0)