diff options
author | John Naylor <john.naylor@postgresql.org> | 2021-07-22 17:34:19 -0400 |
---|---|---|
committer | John Naylor <john.naylor@postgresql.org> | 2021-07-22 17:36:26 -0400 |
commit | 81322fc409743f9ef169cb7bd89b0d0113a0aaa1 (patch) | |
tree | 68bf4263e5080d1804a1fcea85c8a6457b903c19 | |
parent | b1c1b7af573bbc9fe9039c82ffb7d3a3c378fe4a (diff) | |
download | postgresql-81322fc409743f9ef169cb7bd89b0d0113a0aaa1.tar.gz postgresql-81322fc409743f9ef169cb7bd89b0d0113a0aaa1.zip |
Fix division by zero error in date_bin
Bauyrzhan Sakhariyev, via Github
Backpatch to v14
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 10 | ||||
-rw-r--r-- | src/test/regress/expected/timestamp.out | 3 | ||||
-rw-r--r-- | src/test/regress/expected/timestamptz.out | 3 | ||||
-rw-r--r-- | src/test/regress/sql/timestamp.sql | 3 | ||||
-rw-r--r-- | src/test/regress/sql/timestamptz.sql | 3 |
5 files changed, 22 insertions, 0 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 79761f809c8..ea847576cd2 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -3843,6 +3843,11 @@ timestamp_bin(PG_FUNCTION_ARGS) stride_usecs = stride->day * USECS_PER_DAY + stride->time; + if (stride_usecs == 0) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("stride cannot equal zero"))); + tm_diff = timestamp - origin; tm_delta = tm_diff - tm_diff % stride_usecs; @@ -4021,6 +4026,11 @@ timestamptz_bin(PG_FUNCTION_ARGS) stride_usecs = stride->day * USECS_PER_DAY + stride->time; + if (stride_usecs == 0) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("stride cannot equal 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 6fdca6b295c..7a2cbd9b3f0 100644 --- a/src/test/regress/expected/timestamp.out +++ b/src/test/regress/expected/timestamp.out @@ -704,6 +704,9 @@ SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp ERROR: timestamps cannot be binned into intervals containing months or years SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01'); 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 -- 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 421ef2578ac..be6ead0fb50 100644 --- a/src/test/regress/expected/timestamptz.out +++ b/src/test/regress/expected/timestamptz.out @@ -748,6 +748,9 @@ SELECT date_bin('5 months'::interval, timestamp with time zone '2020-02-01 01:01 ERROR: timestamps cannot be binned into intervals containing months or years SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00'); 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 -- 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 2841d2f2af4..7307a240927 100644 --- a/src/test/regress/sql/timestamp.sql +++ b/src/test/regress/sql/timestamp.sql @@ -263,6 +263,9 @@ SELECT date_bin('5 min'::interval, timestamp '2020-02-01 01:01:01', timestamp '2 SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01'); SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01'); +-- disallow zero intervals +SELECT date_bin('0 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 17ced99efca..3642d8c143c 100644 --- a/src/test/regress/sql/timestamptz.sql +++ b/src/test/regress/sql/timestamptz.sql @@ -238,6 +238,9 @@ SELECT date_bin('5 min'::interval, timestamptz '2020-02-01 01:01:01+00', timesta SELECT date_bin('5 months'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00'); SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00'); +-- 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'); + -- Test casting within a BETWEEN qualifier SELECT d1 - timestamp with time zone '1997-01-02' AS diff FROM TIMESTAMPTZ_TBL |