Re: Query generates infinite loop
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Corey Huinker <corey.huinker@gmail.com>
Cc: Jeff Janes <jeff.janes@gmail.com>,
Richard Wesley <richard@duckdblabs.com>,
PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2022-05-10T23:42:32Z
Lists: pgsql-bugs, pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Revert "Disallow infinite endpoints in generate_series() for timestamps."
- c0406fa768ed 11.16 landed
- 86a21803c7d8 10.21 landed
- 7f0754bc4c0a 13.7 landed
- 5045c795301d 12.11 landed
- 9b5797ca54f5 14.3 landed
- 29904f5f2fda 15.0 landed
-
Disallow infinite endpoints in generate_series() for timestamps.
- e34632947008 14.3 landed
- eafdf9de06e9 15.0 landed
- e7adbd282dbf 11.16 landed
- a1e4782a0bca 10.21 landed
- 8275ba773dfe 13.7 landed
- 33fe55c06b83 12.11 landed
Corey Huinker <corey.huinker@gmail.com> writes:
>> Less sure about that. ISTM the reason that the previous proposal failed
>> was that it introduced too much ambiguity about how to resolve
>> unknown-type arguments. Wouldn't the same problems arise here?
> By adding a different function, there is no prior behavior to worry about.
True, that's one less thing to worry about.
> So we should be safe with the following signatures doing the right thing,
> yes?:
> generate_finite_series(start timestamp, step interval, num_elements
> integer)
> generate_finite_series(start date, step integer, num_elements integer)
> generate_finite_series(start date, step interval year to month,
> num_elements integer)
No. You can experiment with it easily enough using stub functions:
regression=# create function generate_finite_series(start timestamp, step interval, num_elements
regression(# integer) returns timestamp as 'select $1' language sql;
CREATE FUNCTION
regression=# create function generate_finite_series(start date, step integer, num_elements integer) returns timestamp as 'select $1' language sql;
CREATE FUNCTION
regression=# create function generate_finite_series(start date, step interval year to month,
regression(# num_elements integer) returns timestamp as 'select $1' language sql;;
CREATE FUNCTION
regression=# select generate_finite_series(current_date, '1 day', 10);
ERROR: function generate_finite_series(date, unknown, integer) is not unique
LINE 1: select generate_finite_series(current_date, '1 day', 10);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
It's even worse if the first argument is also an unknown-type literal.
Sure, you could add explicit casts to force the choice of variant,
but then ease of use went out the window somewhere --- and IMO this
proposal is mostly about ease of use, since there's no fundamentally
new functionality.
It looks like you could make it work with just these three variants:
regression=# \df generate_finite_series
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------------------+-----------------------------+------------------------------------------------------------------------+------
public | generate_finite_series | timestamp without time zone | start date, step interval, num_elements integer | func
public | generate_finite_series | timestamp with time zone | start timestamp with time zone, step interval, num_elements integer | func
public | generate_finite_series | timestamp without time zone | start timestamp without time zone, step interval, num_elements integer | func
(3 rows)
I get non-error results with these:
regression=# select generate_finite_series(current_date, '1 day', 10);
generate_finite_series
------------------------
2022-05-10 00:00:00
(1 row)
regression=# select generate_finite_series('now', '1 day', 10);
generate_finite_series
-------------------------------
2022-05-10 19:35:33.773738-04
(1 row)
That shows that an unknown-type literal in the first argument will default
to timestamptz given these choices, which seems like a sane default.
BTW, you don't get to say "interval year to month" as a function argument,
or at least it won't do anything useful. If you want to restrict the
contents of the interval it'll have to be a runtime check inside the
function.
regards, tom lane