Skip to content

Commit 33fe55c

Browse files
committed
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
1 parent 481a998 commit 33fe55c

File tree

5 files changed

+156
-0
lines changed

5 files changed

+156
-0
lines changed

src/backend/utils/adt/timestamp.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5392,6 +5392,20 @@ generate_series_timestamp(PG_FUNCTION_ARGS)
53925392
MemoryContext oldcontext;
53935393
Interval interval_zero;
53945394

5395+
/* Reject infinities in start and stop values */
5396+
if (TIMESTAMP_IS_NOBEGIN(start) ||
5397+
TIMESTAMP_IS_NOEND(start))
5398+
ereport(ERROR,
5399+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5400+
errmsg("start value cannot be infinity")));
5401+
if (TIMESTAMP_IS_NOBEGIN(finish) ||
5402+
TIMESTAMP_IS_NOEND(finish))
5403+
ereport(ERROR,
5404+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5405+
errmsg("stop value cannot be infinity")));
5406+
5407+
/* Interval doesn't (currently) have infinity, so nothing to check */
5408+
53955409
/* create a function context for cross-call persistence */
53965410
funcctx = SRF_FIRSTCALL_INIT();
53975411

@@ -5473,6 +5487,20 @@ generate_series_timestamptz(PG_FUNCTION_ARGS)
54735487
MemoryContext oldcontext;
54745488
Interval interval_zero;
54755489

5490+
/* Reject infinities in start and stop values */
5491+
if (TIMESTAMP_IS_NOBEGIN(start) ||
5492+
TIMESTAMP_IS_NOEND(start))
5493+
ereport(ERROR,
5494+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5495+
errmsg("start value cannot be infinity")));
5496+
if (TIMESTAMP_IS_NOBEGIN(finish) ||
5497+
TIMESTAMP_IS_NOEND(finish))
5498+
ereport(ERROR,
5499+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5500+
errmsg("stop value cannot be infinity")));
5501+
5502+
/* Interval doesn't (currently) have infinity, so nothing to check */
5503+
54765504
/* create a function context for cross-call persistence */
54775505
funcctx = SRF_FIRSTCALL_INIT();
54785506

src/test/regress/expected/timestamp.out

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,3 +1731,52 @@ SELECT make_timestamp(2014,12,28,6,30,45.887);
17311731
Sun Dec 28 06:30:45.887 2014
17321732
(1 row)
17331733

1734+
-- generate_series for timestamp
1735+
select * from generate_series('2020-01-01 00:00'::timestamp,
1736+
'2020-01-02 03:00'::timestamp,
1737+
'1 hour'::interval);
1738+
generate_series
1739+
--------------------------
1740+
Wed Jan 01 00:00:00 2020
1741+
Wed Jan 01 01:00:00 2020
1742+
Wed Jan 01 02:00:00 2020
1743+
Wed Jan 01 03:00:00 2020
1744+
Wed Jan 01 04:00:00 2020
1745+
Wed Jan 01 05:00:00 2020
1746+
Wed Jan 01 06:00:00 2020
1747+
Wed Jan 01 07:00:00 2020
1748+
Wed Jan 01 08:00:00 2020
1749+
Wed Jan 01 09:00:00 2020
1750+
Wed Jan 01 10:00:00 2020
1751+
Wed Jan 01 11:00:00 2020
1752+
Wed Jan 01 12:00:00 2020
1753+
Wed Jan 01 13:00:00 2020
1754+
Wed Jan 01 14:00:00 2020
1755+
Wed Jan 01 15:00:00 2020
1756+
Wed Jan 01 16:00:00 2020
1757+
Wed Jan 01 17:00:00 2020
1758+
Wed Jan 01 18:00:00 2020
1759+
Wed Jan 01 19:00:00 2020
1760+
Wed Jan 01 20:00:00 2020
1761+
Wed Jan 01 21:00:00 2020
1762+
Wed Jan 01 22:00:00 2020
1763+
Wed Jan 01 23:00:00 2020
1764+
Thu Jan 02 00:00:00 2020
1765+
Thu Jan 02 01:00:00 2020
1766+
Thu Jan 02 02:00:00 2020
1767+
Thu Jan 02 03:00:00 2020
1768+
(28 rows)
1769+
1770+
-- errors
1771+
select * from generate_series('-infinity'::timestamp,
1772+
'2020-01-02 03:00'::timestamp,
1773+
'1 hour'::interval);
1774+
ERROR: start value cannot be infinity
1775+
select * from generate_series('2020-01-01 00:00'::timestamp,
1776+
'infinity'::timestamp,
1777+
'1 hour'::interval);
1778+
ERROR: stop value cannot be infinity
1779+
select * from generate_series('2020-01-01 00:00'::timestamp,
1780+
'2020-01-02 03:00'::timestamp,
1781+
'0 hour'::interval);
1782+
ERROR: step size cannot equal zero

src/test/regress/expected/timestamptz.out

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,55 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT');
20912091
(1 row)
20922092

20932093
RESET TimeZone;
2094+
-- generate_series for timestamptz
2095+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2096+
'2020-01-02 03:00'::timestamptz,
2097+
'1 hour'::interval);
2098+
generate_series
2099+
------------------------------
2100+
Wed Jan 01 00:00:00 2020 PST
2101+
Wed Jan 01 01:00:00 2020 PST
2102+
Wed Jan 01 02:00:00 2020 PST
2103+
Wed Jan 01 03:00:00 2020 PST
2104+
Wed Jan 01 04:00:00 2020 PST
2105+
Wed Jan 01 05:00:00 2020 PST
2106+
Wed Jan 01 06:00:00 2020 PST
2107+
Wed Jan 01 07:00:00 2020 PST
2108+
Wed Jan 01 08:00:00 2020 PST
2109+
Wed Jan 01 09:00:00 2020 PST
2110+
Wed Jan 01 10:00:00 2020 PST
2111+
Wed Jan 01 11:00:00 2020 PST
2112+
Wed Jan 01 12:00:00 2020 PST
2113+
Wed Jan 01 13:00:00 2020 PST
2114+
Wed Jan 01 14:00:00 2020 PST
2115+
Wed Jan 01 15:00:00 2020 PST
2116+
Wed Jan 01 16:00:00 2020 PST
2117+
Wed Jan 01 17:00:00 2020 PST
2118+
Wed Jan 01 18:00:00 2020 PST
2119+
Wed Jan 01 19:00:00 2020 PST
2120+
Wed Jan 01 20:00:00 2020 PST
2121+
Wed Jan 01 21:00:00 2020 PST
2122+
Wed Jan 01 22:00:00 2020 PST
2123+
Wed Jan 01 23:00:00 2020 PST
2124+
Thu Jan 02 00:00:00 2020 PST
2125+
Thu Jan 02 01:00:00 2020 PST
2126+
Thu Jan 02 02:00:00 2020 PST
2127+
Thu Jan 02 03:00:00 2020 PST
2128+
(28 rows)
2129+
2130+
-- errors
2131+
select * from generate_series('-infinity'::timestamptz,
2132+
'2020-01-02 03:00'::timestamptz,
2133+
'1 hour'::interval);
2134+
ERROR: start value cannot be infinity
2135+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2136+
'infinity'::timestamptz,
2137+
'1 hour'::interval);
2138+
ERROR: stop value cannot be infinity
2139+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2140+
'2020-01-02 03:00'::timestamptz,
2141+
'0 hour'::interval);
2142+
ERROR: step size cannot equal zero
20942143
--
20952144
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
20962145
-- These tests rely on the knowledge that MSK (Europe/Moscow standard time)

src/test/regress/sql/timestamp.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,18 @@ SELECT i,
239239

240240
-- timestamp numeric fields constructor
241241
SELECT make_timestamp(2014,12,28,6,30,45.887);
242+
243+
-- generate_series for timestamp
244+
select * from generate_series('2020-01-01 00:00'::timestamp,
245+
'2020-01-02 03:00'::timestamp,
246+
'1 hour'::interval);
247+
-- errors
248+
select * from generate_series('-infinity'::timestamp,
249+
'2020-01-02 03:00'::timestamp,
250+
'1 hour'::interval);
251+
select * from generate_series('2020-01-01 00:00'::timestamp,
252+
'infinity'::timestamp,
253+
'1 hour'::interval);
254+
select * from generate_series('2020-01-01 00:00'::timestamp,
255+
'2020-01-02 03:00'::timestamp,
256+
'0 hour'::interval);

src/test/regress/sql/timestamptz.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,21 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT');
334334

335335
RESET TimeZone;
336336

337+
-- generate_series for timestamptz
338+
select * from generate_series('2020-01-01 00:00'::timestamptz,
339+
'2020-01-02 03:00'::timestamptz,
340+
'1 hour'::interval);
341+
-- errors
342+
select * from generate_series('-infinity'::timestamptz,
343+
'2020-01-02 03:00'::timestamptz,
344+
'1 hour'::interval);
345+
select * from generate_series('2020-01-01 00:00'::timestamptz,
346+
'infinity'::timestamptz,
347+
'1 hour'::interval);
348+
select * from generate_series('2020-01-01 00:00'::timestamptz,
349+
'2020-01-02 03:00'::timestamptz,
350+
'0 hour'::interval);
351+
337352
--
338353
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
339354
-- These tests rely on the knowledge that MSK (Europe/Moscow standard time)

0 commit comments

Comments
 (0)