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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy