Re: proposal: new polymorphic types - commontype and commontypearray - Mailing list pgsql-hackers

From Pavel Stehule
Subject Re: proposal: new polymorphic types - commontype and commontypearray
Date
Msg-id CAFj8pRCEVYv_y3sUtPAL1TZxdN4+GtKqXkquSKWH6TrPe3e94g@mail.gmail.com
Whole thread Raw
In response to Re: proposal: new polymorphic types - commontype and commontypearray  (Dmitry Dolgov <9erthalion6@gmail.com>)
Responses Re: proposal: new polymorphic types - commontype and commontypearray  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers


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
Attachment

pgsql-hackers by date:

Previous
From: Konstantin Knizhnik
Date:
Subject: Re: How to prohibit parallel scan through tableam?
Next
From: Tomas Vondra
Date:
Subject: Re: pglz performance