aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Naylor <john.naylor@postgresql.org>2021-07-28 11:22:58 -0400
committerJohn Naylor <john.naylor@postgresql.org>2021-07-28 12:10:12 -0400
commit3ba70d4e152372fd8ab90ed0887ee08d505ef306 (patch)
tree0a9f052ccd6bf9a23b55442e512c4c5b19e0699c /src
parented1884a2fedeffd2e6902451a9d41f4b3f6e859f (diff)
downloadpostgresql-3ba70d4e152372fd8ab90ed0887ee08d505ef306.tar.gz
postgresql-3ba70d4e152372fd8ab90ed0887ee08d505ef306.zip
Disallow negative strides in date_bin()
It's not clear what the semantics of negative strides would be, so throw an error instead. Per report from Bauyrzhan Sakhariyev Reviewed-by: Tom Lane, Michael Paquier Discussion: https://www.postgresql.org/message-id/CAKpL73vZmLuFVuwF26FJ%2BNk11PVHhAnQRoREFcA03x7znRoFvA%40mail.gmail.com Backpatch to v14
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/timestamp.c8
-rw-r--r--src/test/regress/expected/timestamp.out5
-rw-r--r--src/test/regress/expected/timestamptz.out5
-rw-r--r--src/test/regress/sql/timestamp.sql3
-rw-r--r--src/test/regress/sql/timestamptz.sql3
5 files changed, 18 insertions, 6 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index ea847576cd2..1c0bf0aa5c8 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -3843,10 +3843,10 @@ timestamp_bin(PG_FUNCTION_ARGS)
stride_usecs = stride->day * USECS_PER_DAY + stride->time;
- if (stride_usecs == 0)
+ if (stride_usecs <= 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("stride cannot equal zero")));
+ errmsg("stride must be greater than zero")));
tm_diff = timestamp - origin;
tm_delta = tm_diff - tm_diff % stride_usecs;
@@ -4026,10 +4026,10 @@ timestamptz_bin(PG_FUNCTION_ARGS)
stride_usecs = stride->day * USECS_PER_DAY + stride->time;
- if (stride_usecs == 0)
+ if (stride_usecs <= 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("stride cannot equal zero")));
+ errmsg("stride must be greater than zero")));
tm_diff = timestamp - origin;
tm_delta = tm_diff - tm_diff % stride_usecs;
diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out
index 7a2cbd9b3f0..1a2d48cae96 100644
--- a/src/test/regress/expected/timestamp.out
+++ b/src/test/regress/expected/timestamp.out
@@ -706,7 +706,10 @@ SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp
ERROR: timestamps cannot be binned into intervals containing months or years
-- disallow zero intervals
SELECT date_bin('0 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00');
-ERROR: stride cannot equal zero
+ERROR: stride must be greater than zero
+-- disallow negative intervals
+SELECT date_bin('-2 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00');
+ERROR: stride must be greater than zero
-- Test casting within a BETWEEN qualifier
SELECT d1 - timestamp without time zone '1997-01-02' AS diff
FROM TIMESTAMP_TBL
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index be6ead0fb50..990c4eddf13 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -750,7 +750,10 @@ SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01
ERROR: timestamps cannot be binned into intervals containing months or years
-- disallow zero intervals
SELECT date_bin('0 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00');
-ERROR: stride cannot equal zero
+ERROR: stride must be greater than zero
+-- disallow negative intervals
+SELECT date_bin('-2 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00');
+ERROR: stride must be greater than zero
-- Test casting within a BETWEEN qualifier
SELECT d1 - timestamp with time zone '1997-01-02' AS diff
FROM TIMESTAMPTZ_TBL
diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql
index 7307a240927..e011e779ea2 100644
--- a/src/test/regress/sql/timestamp.sql
+++ b/src/test/regress/sql/timestamp.sql
@@ -266,6 +266,9 @@ SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp
-- disallow zero intervals
SELECT date_bin('0 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00');
+-- disallow negative intervals
+SELECT date_bin('-2 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00');
+
-- Test casting within a BETWEEN qualifier
SELECT d1 - timestamp without time zone '1997-01-02' AS diff
FROM TIMESTAMP_TBL
diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql
index 3642d8c143c..b18821de53b 100644
--- a/src/test/regress/sql/timestamptz.sql
+++ b/src/test/regress/sql/timestamptz.sql
@@ -241,6 +241,9 @@ SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01
-- disallow zero intervals
SELECT date_bin('0 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00');
+-- disallow negative intervals
+SELECT date_bin('-2 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00');
+
-- Test casting within a BETWEEN qualifier
SELECT d1 - timestamp with time zone '1997-01-02' AS diff
FROM TIMESTAMPTZ_TBL