diff options
| author | Tom Lane | 2020-03-14 18:42:22 +0000 |
|---|---|---|
| committer | Tom Lane | 2020-03-14 18:42:22 +0000 |
| commit | 4dbcb3f844eca4a401ce06aa2781bd9a9be433e9 (patch) | |
| tree | ccdb9c2c571f18b7b3589ebdae6fdc80d61dfbd6 /src/test | |
| parent | e83daa7e331e0718bb254ab685f2ed95df423554 (diff) | |
Restructure polymorphic-type resolution in funcapi.c.
resolve_polymorphic_tupdesc() and resolve_polymorphic_argtypes() failed to
cover the case of having to resolve anyarray given only an anyrange input.
The bug was masked if anyelement was also used (as either input or
output), which probably helps account for our not having noticed.
While looking at this I noticed that resolve_generic_type() would produce
the wrong answer if asked to make that same resolution. ISTM that
resolve_generic_type() is confusingly defined and overly complex, so
rather than fix it, let's just make funcapi.c do the specific lookups
it requires for itself.
With this change, resolve_generic_type() is not used anywhere, so remove
it in HEAD. In the back branches, leave it alone (complete with bug)
just in case any external code is using it.
While we're here, make some other refactoring adjustments in funcapi.c
with an eye to upcoming future expansion of the set of polymorphic types:
* Simplify quick-exit tests by adding an overall have_polymorphic_result
flag. This is about a wash now but will be a win when there are more
flags.
* Reduce duplication of code between resolve_polymorphic_tupdesc() and
resolve_polymorphic_argtypes().
* Don't bother to validate correct matching of anynonarray or anyenum;
the parser should have done that, and even if it didn't, just doing
"return false" here would lead to a very confusing, off-point error
message. (Really, "return false" in these two functions should only
occur if the call_expr isn't supplied or we can't obtain data type
info from it.)
* For the same reason, throw an elog rather than "return false" if
we fail to resolve a polymorphic type.
The bug's been there since we added anyrange, so back-patch to
all supported branches.
Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/rangetypes.out | 23 | ||||
| -rw-r--r-- | src/test/regress/sql/rangetypes.sql | 14 |
2 files changed, 28 insertions, 9 deletions
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index 220f2d96cbf..348235a15e9 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -1490,6 +1490,15 @@ select * from outparam_succeed(int4range(1,2)); [1,2) | foo (1 row) +create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray) + as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$ + language sql; +select * from outparam2_succeed(int4range(1,11)); + lu | ul +--------+-------- + {1,11} | {11,1} +(1 row) + create function inoutparam_succeed(out i anyelement, inout r anyrange) as $$ select upper($1), $1 $$ language sql; select * from inoutparam_succeed(int4range(1,2)); @@ -1498,12 +1507,14 @@ select * from inoutparam_succeed(int4range(1,2)); 2 | [1,2) (1 row) -create function table_succeed(i anyelement, r anyrange) returns table(i anyelement, r anyrange) - as $$ select $1, $2 $$ language sql; -select * from table_succeed(123, int4range(1,11)); - i | r ------+-------- - 123 | [1,11) +create function table_succeed(r anyrange) + returns table(l anyelement, u anyelement) + as $$ select lower($1), upper($1) $$ + language sql; +select * from table_succeed(int4range(1,11)); + l | u +---+---- + 1 | 11 (1 row) -- should fail diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql index 72d80bc9d46..85eaa9b34c6 100644 --- a/src/test/regress/sql/rangetypes.sql +++ b/src/test/regress/sql/rangetypes.sql @@ -517,15 +517,23 @@ create function outparam_succeed(i anyrange, out r anyrange, out t text) select * from outparam_succeed(int4range(1,2)); +create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray) + as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$ + language sql; + +select * from outparam2_succeed(int4range(1,11)); + create function inoutparam_succeed(out i anyelement, inout r anyrange) as $$ select upper($1), $1 $$ language sql; select * from inoutparam_succeed(int4range(1,2)); -create function table_succeed(i anyelement, r anyrange) returns table(i anyelement, r anyrange) - as $$ select $1, $2 $$ language sql; +create function table_succeed(r anyrange) + returns table(l anyelement, u anyelement) + as $$ select lower($1), upper($1) $$ + language sql; -select * from table_succeed(123, int4range(1,11)); +select * from table_succeed(int4range(1,11)); -- should fail create function outparam_fail(i anyelement, out r anyrange, out t text) |
