aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/datetime.c16
-rw-r--r--src/test/regress/expected/interval.out28
-rw-r--r--src/test/regress/sql/interval.sql5
3 files changed, 43 insertions, 6 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 452eb8532dd..a3be406b684 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -2877,19 +2877,18 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
case DTK_TZ:
/*
- * Timezone is a token with a leading sign character and at
+ * Timezone means a token with a leading sign character and at
* least one digit; there could be ':', '.', '-' embedded in
* it as well.
*/
Assert(*field[i] == '-' || *field[i] == '+');
/*
- * Try for hh:mm or hh:mm:ss. If not, fall through to
- * DTK_NUMBER case, which can handle signed float numbers and
- * signed year-month values.
+ * Check for signed hh:mm or hh:mm:ss. If so, process exactly
+ * like DTK_TIME case above, plus handling the sign.
*/
if (strchr(field[i] + 1, ':') != NULL &&
- DecodeTime(field[i] + 1, fmask, INTERVAL_FULL_RANGE,
+ DecodeTime(field[i] + 1, fmask, range,
&tmask, tm, fsec) == 0)
{
if (*field[i] == '-')
@@ -2907,9 +2906,14 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
* are reading right to left.
*/
type = DTK_DAY;
- tmask = DTK_M(TZ);
break;
}
+
+ /*
+ * Otherwise, fall through to DTK_NUMBER case, which can
+ * handle signed float numbers and signed year-month values.
+ */
+
/* FALL THROUGH */
case DTK_DATE:
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out
index e7e21813332..3bf221187bc 100644
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -545,6 +545,30 @@ SELECT interval '1 2:03:04' minute to second;
1 day 02:03:04
(1 row)
+SELECT interval '1 +2:03' minute to second;
+ interval
+----------------
+ 1 day 00:02:03
+(1 row)
+
+SELECT interval '1 +2:03:04' minute to second;
+ interval
+----------------
+ 1 day 02:03:04
+(1 row)
+
+SELECT interval '1 -2:03' minute to second;
+ interval
+-----------------
+ 1 day -00:02:03
+(1 row)
+
+SELECT interval '1 -2:03:04' minute to second;
+ interval
+-----------------
+ 1 day -02:03:04
+(1 row)
+
SELECT interval '123 11' day to hour; -- ok
interval
-------------------
@@ -559,6 +583,10 @@ SELECT interval '123 11'; -- not ok, too ambiguous
ERROR: invalid input syntax for type interval: "123 11"
LINE 1: SELECT interval '123 11';
^
+SELECT interval '123 2:03 -2:04'; -- not ok, redundant hh:mm fields
+ERROR: invalid input syntax for type interval: "123 2:03 -2:04"
+LINE 1: SELECT interval '123 2:03 -2:04';
+ ^
-- test syntaxes for restricted precision
SELECT interval(0) '1 day 01:23:45.6789';
interval
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql
index 9da2dc63e87..f1da4c29117 100644
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -165,9 +165,14 @@ SELECT interval '1 2:03:04' hour to second;
SELECT interval '1 2' minute to second;
SELECT interval '1 2:03' minute to second;
SELECT interval '1 2:03:04' minute to second;
+SELECT interval '1 +2:03' minute to second;
+SELECT interval '1 +2:03:04' minute to second;
+SELECT interval '1 -2:03' minute to second;
+SELECT interval '1 -2:03:04' minute to second;
SELECT interval '123 11' day to hour; -- ok
SELECT interval '123 11' day; -- not ok
SELECT interval '123 11'; -- not ok, too ambiguous
+SELECT interval '123 2:03 -2:04'; -- not ok, redundant hh:mm fields
-- test syntaxes for restricted precision
SELECT interval(0) '1 day 01:23:45.6789';