Re: proposal: new polymorphic types - commontype and commontypearray

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: proposal: new polymorphic types - commontype and commontypearray
Date: 2019-01-26 00:20:55
Message-ID: 18109.1548462055@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> writes:
> Four years ago I proposed implicit casting to common type of arguments with
> anyelement type.
> https://www.postgresql.org/message-id/CAFj8pRCZVo_xoW0cfxt%3DmmgjXKBgr3Gm1VMGL_zx9wDRHmm6Cw%40mail.gmail.com
> My proposal was rejected, because it introduce compatibility issues.

Yup.

> Now I have a solution that doesn't break anything. With two new polymorphic
> types: commontype and commontypearray we can write functions like coalesce,
> greatest, ..

I think this is a good idea at its core, but I don't like the specifics
too much.

I agree with the basic idea of introducing a second, independent set of
polymorphic-type variables. Way back when we first discussed polymorphic
types, we thought maybe we should invent anyelement2 and anyarray2, and
perhaps even more pairs, to allow polymorphic functions to deal with two
or more base types. We didn't do that for lack of convincing examples of
the need for it, but I expected some would emerge; I'm rather astonished
that we've gotten by for so many years without adding a second set.
So where I think we should go with this is to solve that need while
we're at it.

However, this proposal doesn't do so, because it omits "commonrange".
I'm prepared to believe that we don't need "commonenum"; that would
presumably have the semantics of "resolve the common type and then
it must be an enum". And that seems pretty useless, because there
are no type resolution rules that would let us choose one enum out of
a set. (I suppose somebody might create implicit casts between some
enum types, but it doesn't seem very likely.) I also suspect that
we could get away without "commonnonarray". Anynonarray is really
just a hack that we invented to avoid ambiguity around the ||
operator, and an equivalent need would likely not come up for this
second set of types. (I could be wrong though; I'm not sure right
now whether array_agg's use of anynonarray rather than anyelement
is essential or just randomness.) But neither of those arguments
apply to commonrange; in fact it's highly likely that somebody would
want to have "myfunc(commontype, commontype) returns commonrange"
as a customized range constructor that can deal with slightly
different input types.

My second problem with this proposal is that it simply ignores
the naming precedent of the existing polymorphic types. We have
a convention that polymorphic types are named "any-something",
and I do not think we should just toss that overboard. Moreover,
if we do end up needing "commonnonarray" or "commonenum", those
names are ugly, typo-prone, and unreasonably long.

We could do worse than to call these types anyelement2, anyarray2,
anyrange2 and just document that their resolution rule depends
on finding a common type rather than identical base types.
I suppose that's not too pretty --- it reminds one of Oracle finally
getting varchar semantics right with varchar2 :-(. Another idea
is anyelementc, anyarrayc, anyrangec ("c" for "common") but that's
not pretty either. Anyway I think the names need to be any-something.

I haven't particularly studied the patch code, but I will note that
this sort of change seems pretty dumb:

@@ -953,7 +953,7 @@ make_scalar_array_op(ParseState *pstate, List *opname,
* enforce_generic_type_consistency may or may not have replaced a
* polymorphic type with a real one.
*/
- if (IsPolymorphicType(declared_arg_types[1]))
+ if (IsPolymorphicTypeAny(declared_arg_types[1]))
{
/* assume the actual array type is OK */
res_atypeId = atypeId;

Why would we want to reject the new poly types here? Or just about
anyplace else that tests IsPolymorphicType? The argument-type resolution
functions themselves need to distinguish the two groups of types,
at least for some purposes, but it's very hard to believe anyplace
else should do so.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Chapman Flack 2019-01-26 00:37:48 Re: PostgreSQL vs SQL/XML Standards
Previous Message Bruce Momjian 2019-01-26 00:01:53 Re: How does the planner determine plan_rows ?