Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8275ba7

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 f583633 commit 8275ba7

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
@@ -5426,6 +5426,20 @@ generate_series_timestamp(PG_FUNCTION_ARGS)
54265426
MemoryContext oldcontext;
54275427
Interval interval_zero;
54285428

5429+
/* Reject infinities in start and stop values */
5430+
if (TIMESTAMP_IS_NOBEGIN(start) ||
5431+
TIMESTAMP_IS_NOEND(start))
5432+
ereport(ERROR,
5433+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5434+
errmsg("start value cannot be infinity")));
5435+
if (TIMESTAMP_IS_NOBEGIN(finish) ||
5436+
TIMESTAMP_IS_NOEND(finish))
5437+
ereport(ERROR,
5438+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5439+
errmsg("stop value cannot be infinity")));
5440+
5441+
/* Interval doesn't (currently) have infinity, so nothing to check */
5442+
54295443
/* create a function context for cross-call persistence */
54305444
funcctx = SRF_FIRSTCALL_INIT();
54315445

@@ -5506,6 +5520,20 @@ generate_series_timestamptz(PG_FUNCTION_ARGS)
55065520
MemoryContext oldcontext;
55075521
Interval interval_zero;
55085522

5523+
/* Reject infinities in start and stop values */
5524+
if (TIMESTAMP_IS_NOBEGIN(start) ||
5525+
TIMESTAMP_IS_NOEND(start))
5526+
ereport(ERROR,
5527+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5528+
errmsg("start value cannot be infinity")));
5529+
if (TIMESTAMP_IS_NOBEGIN(finish) ||
5530+
TIMESTAMP_IS_NOEND(finish))
5531+
ereport(ERROR,
5532+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5533+
errmsg("stop value cannot be infinity")));
5534+
5535+
/* Interval doesn't (currently) have infinity, so nothing to check */
5536+
55095537
/* create a function context for cross-call persistence */
55105538
funcctx = SRF_FIRSTCALL_INIT();
55115539

src/test/regress/expected/timestamp.out

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

1749+
-- generate_series for timestamp
1750+
select * from generate_series('2020-01-01 00:00'::timestamp,
1751+
'2020-01-02 03:00'::timestamp,
1752+
'1 hour'::interval);
1753+
generate_series
1754+
--------------------------
1755+
Wed Jan 01 00:00:00 2020
1756+
Wed Jan 01 01:00:00 2020
1757+
Wed Jan 01 02:00:00 2020
1758+
Wed Jan 01 03:00:00 2020
1759+
Wed Jan 01 04:00:00 2020
1760+
Wed Jan 01 05:00:00 2020
1761+
Wed Jan 01 06:00:00 2020
1762+
Wed Jan 01 07:00:00 2020
1763+
Wed Jan 01 08:00:00 2020
1764+
Wed Jan 01 09:00:00 2020
1765+
Wed Jan 01 10:00:00 2020
1766+
Wed Jan 01 11:00:00 2020
1767+
Wed Jan 01 12:00:00 2020
1768+
Wed Jan 01 13:00:00 2020
1769+
Wed Jan 01 14:00:00 2020
1770+
Wed Jan 01 15:00:00 2020
1771+
Wed Jan 01 16:00:00 2020
1772+
Wed Jan 01 17:00:00 2020
1773+
Wed Jan 01 18:00:00 2020
1774+
Wed Jan 01 19:00:00 2020
1775+
Wed Jan 01 20:00:00 2020
1776+
Wed Jan 01 21:00:00 2020
1777+
Wed Jan 01 22:00:00 2020
1778+
Wed Jan 01 23:00:00 2020
1779+
Thu Jan 02 00:00:00 2020
1780+
Thu Jan 02 01:00:00 2020
1781+
Thu Jan 02 02:00:00 2020
1782+
Thu Jan 02 03:00:00 2020
1783+
(28 rows)
1784+
1785+
-- errors
1786+
select * from generate_series('-infinity'::timestamp,
1787+
'2020-01-02 03:00'::timestamp,
1788+
'1 hour'::interval);
1789+
ERROR: start value cannot be infinity
1790+
select * from generate_series('2020-01-01 00:00'::timestamp,
1791+
'infinity'::timestamp,
1792+
'1 hour'::interval);
1793+
ERROR: stop value cannot be infinity
1794+
select * from generate_series('2020-01-01 00:00'::timestamp,
1795+
'2020-01-02 03:00'::timestamp,
1796+
'0 hour'::interval);
1797+
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
@@ -2106,6 +2106,55 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT');
21062106
(1 row)
21072107

21082108
RESET TimeZone;
2109+
-- generate_series for timestamptz
2110+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2111+
'2020-01-02 03:00'::timestamptz,
2112+
'1 hour'::interval);
2113+
generate_series
2114+
------------------------------
2115+
Wed Jan 01 00:00:00 2020 PST
2116+
Wed Jan 01 01:00:00 2020 PST
2117+
Wed Jan 01 02:00:00 2020 PST
2118+
Wed Jan 01 03:00:00 2020 PST
2119+
Wed Jan 01 04:00:00 2020 PST
2120+
Wed Jan 01 05:00:00 2020 PST
2121+
Wed Jan 01 06:00:00 2020 PST
2122+
Wed Jan 01 07:00:00 2020 PST
2123+
Wed Jan 01 08:00:00 2020 PST
2124+
Wed Jan 01 09:00:00 2020 PST
2125+
Wed Jan 01 10:00:00 2020 PST
2126+
Wed Jan 01 11:00:00 2020 PST
2127+
Wed Jan 01 12:00:00 2020 PST
2128+
Wed Jan 01 13:00:00 2020 PST
2129+
Wed Jan 01 14:00:00 2020 PST
2130+
Wed Jan 01 15:00:00 2020 PST
2131+
Wed Jan 01 16:00:00 2020 PST
2132+
Wed Jan 01 17:00:00 2020 PST
2133+
Wed Jan 01 18:00:00 2020 PST
2134+
Wed Jan 01 19:00:00 2020 PST
2135+
Wed Jan 01 20:00:00 2020 PST
2136+
Wed Jan 01 21:00:00 2020 PST
2137+
Wed Jan 01 22:00:00 2020 PST
2138+
Wed Jan 01 23:00:00 2020 PST
2139+
Thu Jan 02 00:00:00 2020 PST
2140+
Thu Jan 02 01:00:00 2020 PST
2141+
Thu Jan 02 02:00:00 2020 PST
2142+
Thu Jan 02 03:00:00 2020 PST
2143+
(28 rows)
2144+
2145+
-- errors
2146+
select * from generate_series('-infinity'::timestamptz,
2147+
'2020-01-02 03:00'::timestamptz,
2148+
'1 hour'::interval);
2149+
ERROR: start value cannot be infinity
2150+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2151+
'infinity'::timestamptz,
2152+
'1 hour'::interval);
2153+
ERROR: stop value cannot be infinity
2154+
select * from generate_series('2020-01-01 00:00'::timestamptz,
2155+
'2020-01-02 03:00'::timestamptz,
2156+
'0 hour'::interval);
2157+
ERROR: step size cannot equal zero
21092158
--
21102159
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
21112160
-- 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
@@ -247,3 +247,18 @@ SELECT i,
247247

248248
-- timestamp numeric fields constructor
249249
SELECT make_timestamp(2014,12,28,6,30,45.887);
250+
251+
-- generate_series for timestamp
252+
select * from generate_series('2020-01-01 00:00'::timestamp,
253+
'2020-01-02 03:00'::timestamp,
254+
'1 hour'::interval);
255+
-- errors
256+
select * from generate_series('-infinity'::timestamp,
257+
'2020-01-02 03:00'::timestamp,
258+
'1 hour'::interval);
259+
select * from generate_series('2020-01-01 00:00'::timestamp,
260+
'infinity'::timestamp,
261+
'1 hour'::interval);
262+
select * from generate_series('2020-01-01 00:00'::timestamp,
263+
'2020-01-02 03:00'::timestamp,
264+
'0 hour'::interval);

src/test/regress/sql/timestamptz.sql

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

343343
RESET TimeZone;
344344

345+
-- generate_series for timestamptz
346+
select * from generate_series('2020-01-01 00:00'::timestamptz,
347+
'2020-01-02 03:00'::timestamptz,
348+
'1 hour'::interval);
349+
-- errors
350+
select * from generate_series('-infinity'::timestamptz,
351+
'2020-01-02 03:00'::timestamptz,
352+
'1 hour'::interval);
353+
select * from generate_series('2020-01-01 00:00'::timestamptz,
354+
'infinity'::timestamptz,
355+
'1 hour'::interval);
356+
select * from generate_series('2020-01-01 00:00'::timestamptz,
357+
'2020-01-02 03:00'::timestamptz,
358+
'0 hour'::interval);
359+
345360
--
346361
-- Test behavior with a dynamic (time-varying) timezone abbreviation.
347362
-- These tests rely on the knowledge that MSK (Europe/Moscow standard time)

0 commit comments

Comments
 (0)