Re: polymorphic types - enforce casting to most common type automatically

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: polymorphic types - enforce casting to most common type automatically
Date: 2015-03-08 18:31:50
Message-ID: CAFj8pRCZVo_xoW0cfxt=mmgjXKBgr3Gm1VMGL_zx9wDRHmm6Cw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi

I am sending a proof concept. Current implementation is not suboptimal - I
wrote this code for demonstration of current issues, and checking possible
side effects of changes in this patch.

The basic problem is strong restrictive implementation of polymorphic types
- now these types doesn't allow any cast although it is possible. It can be
changed relatively simply I though (after we implemented variadic
functions).

CREATE OR REPLACE FUNCTION public.foo1(anyelement, anyelement)
RETURNS anyelement
LANGUAGE sql
AS $function$
SELECT $1 + $2;
$function$

CREATE OR REPLACE FUNCTION public.foo2(anyelement, anyelement)
RETURNS anyarray
LANGUAGE sql
AS $function$
SELECT ARRAY[$1, $2]
$function$

Now, polymorphic functions don't allow some natively expected calls:

postgres=# select foo1(1,1);
foo1
------
2
(1 row)

postgres=# select foo1(1,1.1);
ERROR: function foo1(integer, numeric) does not exist
LINE 1: select foo1(1,1.1);
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

postgres=# select foo2(1,1);
foo2
-------
{1,1}
(1 row)

postgres=# select foo2(1,1.1);
ERROR: function foo2(integer, numeric) does not exist
LINE 1: select foo2(1,1.1);
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

CREATE OR REPLACE FUNCTION public.foo3(VARIADIC anyarray)
RETURNS anyelement
LANGUAGE sql
AS $function$
SELECT min(v) FROM unnest($1) g(v)
$function$

postgres=# SELECT foo3(1,2,3);
foo3
------
1
(1 row)

postgres=# SELECT foo3(1,2,3.1);
ERROR: function foo3(integer, integer, numeric) does not exist
LINE 1: SELECT foo3(1,2,3.1);
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

Some our functions like COALESCE are not too restrictive and allow to use
types from same category.

postgres=# select coalesce(1,1.1);
coalesce
----------
1
(1 row)

With attached patch the polymorphic functions use same mechanism as our
buildin functions. It is applied on ANYARRAY, ANYELEMENT types only.

postgres=# select foo1(1,1.1), foo2(1,1.1), foo3(1.1,2,3.1);
foo1 | foo2 | foo3
------+---------+------
2.1 | {1,1.1} | 1.1
(1 row)

Comments, notices, ... ?

Regards

Pavel

2014-11-24 20:52 GMT+01:00 Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>:

> Hello
>
> now a functions with more than one polymorphic arguments are relative
> fragile due missing casting to most common type. Some our "functions" like
> "coalesce" can do it, so it is surprising for our users.
>
> our custom polymorphic function foo(anyelement, anyelement) working well
> for
>
> foo(10,20) or foo(10.1, 20.1), but not for foo(10, 20.1)
>
> I am thinking, so we can add a searching most common type stage without
> breaking to backing compatibility.
>
> What do you think about it?
>
> Regards
>
> Pavel
>

Attachment Content-Type Size
use-common-type-for-polymorphic-types.patch text/x-patch 17.2 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Dmitry Voronin 2015-03-08 19:14:27 New functions
Previous Message Tom Lane 2015-03-08 18:22:31 Re: Bootstrap DATA is a pita