git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 165d581)
Tighten unit parsing in internal values
2023年8月28日 05:27:17 +0000 (14:27 +0900)
2023年8月28日 05:27:17 +0000 (14:27 +0900)
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


diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 178b3f47803a2b0801eb766d7e6fe62aab60eb82..267dfd37b2e8b9bc63797c69b9ca2e45e6bfde61 100644 (file)
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -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)
{
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out
index 01d43b58687c3c49f51c6c1a44f60aafdaaeae3f..c0ca8e041b1631d152ff450aa75a35fb3d1c95b5 100644 (file)
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -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';
+ ^
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql
index fb1ef3049048516aee383dd5602442e4ae332d47..038fc508d0c039a9bb9b16405d45b20e61ad52cf 100644 (file)
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -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';
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /