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

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

  1. Introduce "anycompatible" family of polymorphic types.

  2. Refactor our checks for valid function and aggregate signatures.

  3. Rearrange pseudotypes.c to get rid of duplicative code.