Re: proposal: new polymorphic types - commontype and commontypearray
Pavel Stehule <pavel.stehule@gmail.com>
From: Pavel Stehule <pavel.stehule@gmail.com>
To: Dmitry Dolgov <9erthalion6@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, Greg Stark <stark@mit.edu>,
David Steele <david@pgmasters.net>, Robert Haas <robertmhaas@gmail.com>,
PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2019-11-27T13:54:55Z
Lists: pgsql-hackers
Attachments
- anycompatible-types-20191127.patch (text/x-patch) patch
po 25. 11. 2019 v 14:35 odesílatel Dmitry Dolgov <9erthalion6@gmail.com>
napsal:
> > On Mon, Jun 17, 2019 at 05:31:40AM +0200, Pavel Stehule wrote:
> >
> > > I like anycompatible and anycompatiblearray.
> > >
> > > I'll update the patch
> > >
> >
> > and here it is
>
> Thanks for the patch! I've reviewed it a bit, and have a few small
> commentaries:
>
> * There are few traces of copy paste in comments
>
> +static Oid
> +select_common_type_from_vector(int nargs, Oid *typeids, bool noerror)
> ...
> + /*
> + * Nope, so set up for the full algorithm. Note that at this
> point, lc
> + * points to the first list item with type different from pexpr's;
> we need
> + * not re-examine any items the previous loop advanced over.
> + */
>
> Seems like it was taken from select_common_type, but in
> select_common_type_from_vector there is no `lc`, since it doesn't
> accept a list.
>
fixed
>
> * I guess it's would be beneficial to update also commentaries for
> check_generic_type_consistency and enforce_generic_type_consistency
>
> * The argument consistency rules are:
> *
> * 1) All arguments declared ANYELEMENT must have the same datatype.
> * ...
>
> Since they do not reflect the current state of things in this patch.
>
I add rules 8 and 9 about ANYCOMPATIBLE types
> * I've noticed that there is a small difference in how anyelement and
> anycompatible behave, namely anycompatible do not handle unknowns:
>
> =# select 'aaa'::anyelement;
> anyelement
> ------------
> aaa
>
> =# select 'aaa'::anycompatible;
> ERROR: 42846: cannot cast type unknown to anycompatible
> LINE 1: select 'aaa'::anycompatible;
> ^
> LOCATION: transformTypeCast, parse_expr.c:2823
>
>
It happens due to unknowns being filtered out quite early in
> check_generic_type_consistency and similar. By itself this difference it
> not a
> problem, but it causes different error messages in functions:
>
> -- this function accepts anycompatible
> =# select test_anycompatible('aaa');
> ERROR: 42883: function test_anycompatible(unknown) does not exist
> LINE 1: select test_anycompatible('aaa');
> ^
> HINT: No function matches the given name and argument types. You
> might need to add explicit type casts.
> LOCATION: ParseFuncOrColumn, parse_func.c:627
>
> -- this function accepts anyelement
> =# select test_anyelement('aaa');
> ERROR: 42804: could not determine polymorphic type because input
> has type unknown
> LOCATION: enforce_generic_type_consistency, parse_coerce.c:2177
>
fixed
> Although of course it's not that serious.
>
> * I'm also curious about the following situation:
>
> =# create function test_both(a anycompatible) returns
> anycompatible as $$
> begin
> return a;
> end$$ language plpgsql;
> CREATE FUNCTION
>
> =# create function test_both(a anyelement) returns anyelement as $$
> begin
> return a;
> end$$ language plpgsql;
> CREATE FUNCTION
>
> =# select test_both('aaa'::text);
> ERROR: 42725: function test_both(text) is not unique
> LINE 1: select test_both('aaa'::text);
> ^
> HINT: Could not choose a best candidate function. You might need
> to add explicit type casts.
> LOCATION: ParseFuncOrColumn, parse_func.c:568
>
> =# select test_both('aaa'::anyelement);
> ERROR: 42804: could not determine polymorphic type because input
> has type unknown
> LOCATION: enforce_generic_type_consistency, parse_coerce.c:2177
>
fixed
> Is it possible somehow to invoke any of these functions?
>
unfortunately - it's not possible - the construct 'aaa'::"polymorphic type"
doesn't create a value of this type - result type is a text type, and then
it doesn't help in this situation.
It is similar if you create fx(anyelement) and fx(anyarray) - and you
cannot to call fx(anyelement) by fx(1::anyelement)
> Other than that the functionality looks pretty solid. It may look obvious,
> but
> I've also tested performance in different use cases for anycompatible,
> looks
> the same as for anyelement.
>
Thank you for review, I am sending fixed patch
Regards
Pavel
Commits
-
Introduce "anycompatible" family of polymorphic types.
- 24e2885ee304 13.0 landed
-
Refactor our checks for valid function and aggregate signatures.
- e6c178b5b73a 13.0 landed
-
Rearrange pseudotypes.c to get rid of duplicative code.
- 87c9c2571c81 13.0 landed