Revert "Disallow infinite endpoints in generate_series() for timestamps."
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 May 2022 15:02:36 +0000 (11:02 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 May 2022 15:40:40 +0000 (11:40 -0400)
This reverts commit eafdf9de06e9b60168f5e47cedcfceecdc6d4b5f
and its back-branch counterparts.  Corey Huinker pointed out that
we'd discussed this exact change back in 2016 and rejected it,
on the grounds that there's at least one usage pattern with LIMIT
where an infinite endpoint can usefully be used.  Perhaps that
argument needs to be re-litigated, but there's no time left before
our back-branch releases.  To keep our options open, restore the
status quo ante; if we do end up deciding to change things, waiting
one more quarter won't hurt anything.

Rather than just doing a straight revert, I added a new test case
demonstrating the usage with LIMIT.  That'll at least remind us of
the issue if we forget again.

Discussion: https://postgr.es/m/3603504.1652068977@sss.pgh.pa.us
Discussion: https://postgr.es/m/CADkLM=dzw0Pvdqp5yWKxMd+VmNkAMhG=4ku7GnCZxebWnzmz3Q@mail.gmail.com

src/backend/utils/adt/timestamp.c
src/test/regress/expected/timestamp.out
src/test/regress/expected/timestamptz.out
src/test/regress/sql/timestamp.sql
src/test/regress/sql/timestamptz.sql

index 93c10e1ae41a89f4fe28807f8778967b4d55e2b9..552b631ba784e04a6f608b9c8406475e7930785d 100644 (file)
@@ -5778,20 +5778,6 @@ 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();
 
@@ -5872,20 +5858,6 @@ 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();
 
index d5ca6b76a439344618f69eed9ce3caab2b5a1416..79f81809558ecbbbc5e65b5a96a35a5a32da2897 100644 (file)
@@ -2055,15 +2055,26 @@ select * from generate_series('2020-01-01 00:00'::timestamp,
  Thu Jan 02 03:00:00 2020
 (28 rows)
 
+-- the LIMIT should allow this to terminate in a reasonable amount of time
+-- (but that unfortunately doesn't work yet for SELECT * FROM ...)
+select generate_series('2022-01-01 00:00'::timestamp,
+                       'infinity'::timestamp,
+                       '1 month'::interval) limit 10;
+     generate_series      
+--------------------------
+ Sat Jan 01 00:00:00 2022
+ Tue Feb 01 00:00:00 2022
+ Tue Mar 01 00:00:00 2022
+ Fri Apr 01 00:00:00 2022
+ Sun May 01 00:00:00 2022
+ Wed Jun 01 00:00:00 2022
+ Fri Jul 01 00:00:00 2022
+ Mon Aug 01 00:00:00 2022
+ Thu Sep 01 00:00:00 2022
+ Sat Oct 01 00:00:00 2022
+(10 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);
index 4a29484ec3630a7f3b7aa26487e3f902f2de200b..eba84191d367d02fdb686b511954af0668fd0e42 100644 (file)
@@ -2398,15 +2398,26 @@ select * from generate_series('2020-01-01 00:00'::timestamptz,
  Thu Jan 02 03:00:00 2020 PST
 (28 rows)
 
+-- the LIMIT should allow this to terminate in a reasonable amount of time
+-- (but that unfortunately doesn't work yet for SELECT * FROM ...)
+select generate_series('2022-01-01 00:00'::timestamptz,
+                       'infinity'::timestamptz,
+                       '1 month'::interval) limit 10;
+       generate_series        
+------------------------------
+ Sat Jan 01 00:00:00 2022 PST
+ Tue Feb 01 00:00:00 2022 PST
+ Tue Mar 01 00:00:00 2022 PST
+ Fri Apr 01 00:00:00 2022 PDT
+ Sun May 01 00:00:00 2022 PDT
+ Wed Jun 01 00:00:00 2022 PDT
+ Fri Jul 01 00:00:00 2022 PDT
+ Mon Aug 01 00:00:00 2022 PDT
+ Thu Sep 01 00:00:00 2022 PDT
+ Sat Oct 01 00:00:00 2022 PDT
+(10 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);
index 0778e5d7c0c686a78212decd8d8a2ed001c31393..ebc969f36cf6e5f88b2e160b7dc345c478adce58 100644 (file)
@@ -375,13 +375,12 @@ select make_timestamp(0, 7, 15, 12, 30, 15);
 select * from generate_series('2020-01-01 00:00'::timestamp,
                               '2020-01-02 03:00'::timestamp,
                               '1 hour'::interval);
+-- the LIMIT should allow this to terminate in a reasonable amount of time
+-- (but that unfortunately doesn't work yet for SELECT * FROM ...)
+select generate_series('2022-01-01 00:00'::timestamp,
+                       'infinity'::timestamp,
+                       '1 month'::interval) limit 10;
 -- 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);
index c1643de0f1d237d2dd70a73d63d56d51705e1a38..a107abc5a4c2012dfe591c6e909e7c66ccf05e1a 100644 (file)
@@ -436,13 +436,12 @@ RESET TimeZone;
 select * from generate_series('2020-01-01 00:00'::timestamptz,
                               '2020-01-02 03:00'::timestamptz,
                               '1 hour'::interval);
+-- the LIMIT should allow this to terminate in a reasonable amount of time
+-- (but that unfortunately doesn't work yet for SELECT * FROM ...)
+select generate_series('2022-01-01 00:00'::timestamptz,
+                       'infinity'::timestamptz,
+                       '1 month'::interval) limit 10;
 -- 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);