postgres.git / summary / log / commit / refs
commit 33fe55c06b83ea428429f5d522e474fbbe4ab655
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed Apr 20 22:08:15 2022 +0000
First released in: master (reverted before release), REL_10_STABLE (reverted before release), REL_11_STABLE (reverted before release), REL_12_STABLE (reverted before release), REL_13_STABLE (reverted before release), REL_14_STABLE (reverted before release)
Reverted by: 86a21803c7d8 (in 10.21), c0406fa768ed (in 11.16), 5045c795301d (in 12.11), 7f0754bc4c0a (in 13.7), 9b5797ca54f5 (in 14.3), 29904f5f2fda (in 15.0)
Disallow infinite endpoints in generate_series() for timestamps.
Such cases will lead to infinite loops, so they're of no practical
value. The numeric variant of generate_series() already threw error
for this, so borrow its message wording.
Per report from Richard Wesley. Back-patch to all supported branches.
Discussion: https://postgr.es/m/91B44E7B-68D5-448F-95C8-B4B3B0F5DEAF@duckdblabs.com
src/backend/utils/adt/timestamp.c | 28 ++++++++++++++++++
src/test/regress/expected/timestamp.out | 49 +++++++++++++++++++++++++++++++
src/test/regress/expected/timestamptz.out | 49 +++++++++++++++++++++++++++++++
src/test/regress/sql/timestamp.sql | 15 ++++++++++
src/test/regress/sql/timestamptz.sql | 15 ++++++++++
5 files changed, 156 insertions(+)
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 3e7c77ee48f..a6161198f8e 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -5392,6 +5392,20 @@ generate_series_timestamp(PG_FUNCTION_ARGS)
MemoryContext oldcontext;
Interval interval_zero;
+ /* Reject infinities in start and stop values */
+ if (TIMESTAMP_IS_NOBEGIN(start) ||
+ TIMESTAMP_IS_NOEND(start))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("start value cannot be infinity")));
+ if (TIMESTAMP_IS_NOBEGIN(finish) ||
+ TIMESTAMP_IS_NOEND(finish))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("stop value cannot be infinity")));
+
+ /* Interval doesn't (currently) have infinity, so nothing to check */
+
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
@@ -5473,6 +5487,20 @@ generate_series_timestamptz(PG_FUNCTION_ARGS)
MemoryContext oldcontext;
Interval interval_zero;
+ /* Reject infinities in start and stop values */
+ if (TIMESTAMP_IS_NOBEGIN(start) ||
+ TIMESTAMP_IS_NOEND(start))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("start value cannot be infinity")));
+ if (TIMESTAMP_IS_NOBEGIN(finish) ||
+ TIMESTAMP_IS_NOEND(finish))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("stop value cannot be infinity")));
+
+ /* Interval doesn't (currently) have infinity, so nothing to check */
+
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out
index 3025d8431e0..d6f7a91ffd8 100644
--- a/src/test/regress/expected/timestamp.out
+++ b/src/test/regress/expected/timestamp.out
@@ -1731,3 +1731,52 @@ SELECT make_timestamp(2014,12,28,6,30,45.887);
Sun Dec 28 06:30:45.887 2014
(1 row)
+-- generate_series for timestamp
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '1 hour'::interval);
+ generate_series
+--------------------------
+ Wed Jan 01 00:00:00 2020
+ Wed Jan 01 01:00:00 2020
+ Wed Jan 01 02:00:00 2020
+ Wed Jan 01 03:00:00 2020
+ Wed Jan 01 04:00:00 2020
+ Wed Jan 01 05:00:00 2020
+ Wed Jan 01 06:00:00 2020
+ Wed Jan 01 07:00:00 2020
+ Wed Jan 01 08:00:00 2020
+ Wed Jan 01 09:00:00 2020
+ Wed Jan 01 10:00:00 2020
+ Wed Jan 01 11:00:00 2020
+ Wed Jan 01 12:00:00 2020
+ Wed Jan 01 13:00:00 2020
+ Wed Jan 01 14:00:00 2020
+ Wed Jan 01 15:00:00 2020
+ Wed Jan 01 16:00:00 2020
+ Wed Jan 01 17:00:00 2020
+ Wed Jan 01 18:00:00 2020
+ Wed Jan 01 19:00:00 2020
+ Wed Jan 01 20:00:00 2020
+ Wed Jan 01 21:00:00 2020
+ Wed Jan 01 22:00:00 2020
+ Wed Jan 01 23:00:00 2020
+ Thu Jan 02 00:00:00 2020
+ Thu Jan 02 01:00:00 2020
+ Thu Jan 02 02:00:00 2020
+ Thu Jan 02 03:00:00 2020
+(28 rows)
+
+-- errors
+select * from generate_series('-infinity'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '1 hour'::interval);
+ERROR: start value cannot be infinity
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ 'infinity'::timestamp,
+ '1 hour'::interval);
+ERROR: stop value cannot be infinity
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '0 hour'::interval);
+ERROR: step size cannot equal zero
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index 78d9e398979..8a905aba8d4 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -2091,6 +2091,55 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT');
(1 row)
RESET TimeZone;
+-- generate_series for timestamptz
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '1 hour'::interval);
+ generate_series
+------------------------------
+ Wed Jan 01 00:00:00 2020 PST
+ Wed Jan 01 01:00:00 2020 PST
+ Wed Jan 01 02:00:00 2020 PST
+ Wed Jan 01 03:00:00 2020 PST
+ Wed Jan 01 04:00:00 2020 PST
+ Wed Jan 01 05:00:00 2020 PST
+ Wed Jan 01 06:00:00 2020 PST
+ Wed Jan 01 07:00:00 2020 PST
+ Wed Jan 01 08:00:00 2020 PST
+ Wed Jan 01 09:00:00 2020 PST
+ Wed Jan 01 10:00:00 2020 PST
+ Wed Jan 01 11:00:00 2020 PST
+ Wed Jan 01 12:00:00 2020 PST
+ Wed Jan 01 13:00:00 2020 PST
+ Wed Jan 01 14:00:00 2020 PST
+ Wed Jan 01 15:00:00 2020 PST
+ Wed Jan 01 16:00:00 2020 PST
+ Wed Jan 01 17:00:00 2020 PST
+ Wed Jan 01 18:00:00 2020 PST
+ Wed Jan 01 19:00:00 2020 PST
+ Wed Jan 01 20:00:00 2020 PST
+ Wed Jan 01 21:00:00 2020 PST
+ Wed Jan 01 22:00:00 2020 PST
+ Wed Jan 01 23:00:00 2020 PST
+ Thu Jan 02 00:00:00 2020 PST
+ Thu Jan 02 01:00:00 2020 PST
+ Thu Jan 02 02:00:00 2020 PST
+ Thu Jan 02 03:00:00 2020 PST
+(28 rows)
+
+-- errors
+select * from generate_series('-infinity'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '1 hour'::interval);
+ERROR: start value cannot be infinity
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ 'infinity'::timestamptz,
+ '1 hour'::interval);
+ERROR: stop value cannot be infinity
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '0 hour'::interval);
+ERROR: step size cannot equal zero
--
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
-- These tests rely on the knowledge that MSK (Europe/Moscow standard time)
diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql
index 55380c59e77..947dbfc3259 100644
--- a/src/test/regress/sql/timestamp.sql
+++ b/src/test/regress/sql/timestamp.sql
@@ -239,3 +239,18 @@ SELECT i,
-- timestamp numeric fields constructor
SELECT make_timestamp(2014,12,28,6,30,45.887);
+
+-- generate_series for timestamp
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '1 hour'::interval);
+-- errors
+select * from generate_series('-infinity'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '1 hour'::interval);
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ 'infinity'::timestamp,
+ '1 hour'::interval);
+select * from generate_series('2020-01-01 00:00'::timestamp,
+ '2020-01-02 03:00'::timestamp,
+ '0 hour'::interval);
diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql
index a93bec5b4a0..e67d33fb5fd 100644
--- a/src/test/regress/sql/timestamptz.sql
+++ b/src/test/regress/sql/timestamptz.sql
@@ -334,6 +334,21 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT');
RESET TimeZone;
+-- generate_series for timestamptz
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '1 hour'::interval);
+-- errors
+select * from generate_series('-infinity'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '1 hour'::interval);
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ 'infinity'::timestamptz,
+ '1 hour'::interval);
+select * from generate_series('2020-01-01 00:00'::timestamptz,
+ '2020-01-02 03:00'::timestamptz,
+ '0 hour'::interval);
+
--
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
-- These tests rely on the knowledge that MSK (Europe/Moscow standard time)
[parent: 481a99811a41]