proposal: new polymorphic types - commontype and commontypearray

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule
Hi,

the possibility to use polymorphic types is a specific interesting PostgreSQL feature. The polymorphic types allows to use almost all types, but when some type is selected, then this type is required strictly without possibility to use some implicit casting.

So if I have a fx(anyelement, anyelement), then I can call function fx with parameters (int, int), (numeric, numeric), but I cannot to use parameters (int, numeric). The strict design has sense, but for few important cases is too restrictive. We are not able to implement (with plpgsql) functions like coalesce, greatest, least where all numeric types can be used.

Alternative solution can be based on usage "any" type. But we can work with this type only from "C" extensions, and there is some performance penalization due dynamic casting inside function.

Four years ago I proposed implicit casting to common type of arguments with anyelement type.


My proposal was rejected, because it introduce compatibility issues.

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, ..

More, these types are independent on current polymorphic types - and can be used with current polymorphic types together to cover some new use cases.

CREATE OR REPLACE FUNCTION fx(anyelement, commontype, anyelement, commontype)
RETURNS commontype

or

CREATE OR REPLACE FUNCTION fx(anyelement, commontype, anyelement, commontype)
RETURNS anyelement

and commontype and anyelement types can be really independent.

Comments, notes?

Regards

Pavel



commontype-poc.patch (69K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Tom Lane-2
Pavel Stehule <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


so 26. 1. 2019 v 1:20 odesílatel Tom Lane <[hidden email]> napsal:
Pavel Stehule <[hidden email]> 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.

I still expect we can have a more polymorphic types like any***(N)

There are important questions

1. Has a sense to have more distinct polymorphic types with same be behave? - I see a benefit of this possibility - we can introduce anyelement2 .. AN2 and we can have a function

  fx(AN,AN, AN2,AN2) .. that means P2 and P4 should to have a same types like P1 and P3.

2. What are a strategy of choosing real type for polymorphic types? - now only equivalence is supported, but I can see more possibilities

  * common type - I did it
  * first win - often used in Oracle

The common type strategy is more important, because it is typical for some "pseudo" functions like coalesce, least, greatest, .. in Postgres - and extension's developers can design functions more compatible with core functionality.

first win can be interesting for me (like Orafce creator and maintainer). It can increase level of similarity implemented functions there, and reduce work when queries are ported to Postgres. But this is important for smaller group of PostgreSQL users.
 

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.

I implemented just minimal set of new polymorphic types, just for demonstration of my idea. Better coverage of other variants (where it has a sense) is not a problem. Now, mostly I am searching a design where can be a some agreement.
 

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 am open to any ideas. I don't like anyelement2, anyarray2 because

a) it is not verbose - and really different behave should not be signed by number
b) I can imagine very well more anyelementX types.

I don't think so length is too important factor (but I fully agree - shorter is better here). The polymorphic types are not too common.

I though about your proposed anyelementc, but the "c" is not much visible. Can we use snake notation?

commontype, commottype_array, commontype_nonarray ..
common_type, common_type_array, ...

I am not fully happy with "commontype", but I didn't find better




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.

Just I use original behave everywhere where I had not a stronger idea to use new polymorphic types there.

Regards

Pavel

                        regards, tom lane
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


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.

the convention "any-something" is joined with just currently implemented families of polymorphic types. I propose new family, so I think so it should not be named "any-xxxx"

Maybe we can use some form of typemod - but typemod is ignored for function parameters - so it can be much more significant change

a alternative, probably very simple, but less power solution can be some special flag for function parameters - at the end, it is similar to previous solution.

I can imagine

create or replace function fx(p1 anyelement use_common_type, p2 anyelement, ...)
create or replace function fx2(p1 int, p2 int, variadic p3 anyarray use_common_type)

or maybe

create or replace function fx(p1 anyelement, p2 anyelement ...) ... language plpgsql options (use_common_type = true)

or we can drop it - on other thread you propose supported functions - can be some function, that can preproces parameters - and can replace polymorphic types by real types.

Comments, notes?

Pavel




 
                        regards, tom lane
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Robert Haas
In reply to this post by Tom Lane-2
On Fri, Jan 25, 2019 at 7:21 PM Tom Lane <[hidden email]> wrote:
> Anyway I think the names need to be any-something.

To me, that seems unnecessarily rigid.  Not a bad idea if we can come
up with something that is otherwise acceptable.  But all of your
suggestions sound worse than Pavel's proposal, so...

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


po 28. 1. 2019 v 20:47 odesílatel Robert Haas <[hidden email]> napsal:
On Fri, Jan 25, 2019 at 7:21 PM Tom Lane <[hidden email]> wrote:
> Anyway I think the names need to be any-something.

To me, that seems unnecessarily rigid.  Not a bad idea if we can come
up with something that is otherwise acceptable.  But all of your
suggestions sound worse than Pavel's proposal, so...

I implemented commontypenonarray, and commontyperange types. Now, a SQL functions are supported too.

The naming is same - I had not a better idea. But it can be changed without any problems, if somebody come with some more acceptable.

I don't think so the name is too important. The polymorphic types are important, interesting for extension's developers what is small group of Postgres users. 

And personally, I think so commontype and commontypearray are good enough for not native speakers like me. But I am opened any variant - I think so this functionality is interesting
and partially coverage one gap in our implementation of polymorphic types.

Regards

Pavel



--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

polymorphics-commontype-20190130.patch (92K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


st 30. 1. 2019 v 17:00 odesílatel Pavel Stehule <[hidden email]> napsal:


po 28. 1. 2019 v 20:47 odesílatel Robert Haas <[hidden email]> napsal:
On Fri, Jan 25, 2019 at 7:21 PM Tom Lane <[hidden email]> wrote:
> Anyway I think the names need to be any-something.

To me, that seems unnecessarily rigid.  Not a bad idea if we can come
up with something that is otherwise acceptable.  But all of your
suggestions sound worse than Pavel's proposal, so...

I implemented commontypenonarray, and commontyperange types. Now, a SQL functions are supported too.

The naming is same - I had not a better idea. But it can be changed without any problems, if somebody come with some more acceptable.

I don't think so the name is too important. The polymorphic types are important, interesting for extension's developers what is small group of Postgres users. 

And personally, I think so commontype and commontypearray are good enough for not native speakers like me. But I am opened any variant - I think so this functionality is interesting
and partially coverage one gap in our implementation of polymorphic types.

maybe "supertype". It is one char shorter .. somewhere is term "supperclass, ..."

In Czech language this term is short, "nadtyp", but probably it is not acceptable :)



Regards

Pavel



--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Michael Paquier-2
On Wed, Jan 30, 2019 at 05:08:03PM +0100, Pavel Stehule wrote:
> maybe "supertype". It is one char shorter .. somewhere is term
> "supperclass, ..."
>
> In Czech language this term is short, "nadtyp", but probably it is not
> acceptable :)

Moved to next CF.
--
Michael

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: proposal: new polymorphic types - commontype and commontypearray

David Steele
On 2/4/19 4:21 AM, Michael Paquier wrote:
> On Wed, Jan 30, 2019 at 05:08:03PM +0100, Pavel Stehule wrote:
>> maybe "supertype". It is one char shorter .. somewhere is term
>> "supperclass, ..."
>>
>> In Czech language this term is short, "nadtyp", but probably it is not
>> acceptable :)
>
> Moved to next CF.

This thread has been very quiet for a month.  I agree with Andres [1]
that we should push this to PG13.

--
-David
[hidden email]

[1]
https://www.postgresql.org/message-id/raw/20190214203752.t4hl574k6jlu4t25%40alap3.anarazel.de 


Reply | Threaded
Open this post in threaded view
|

Re: Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


út 5. 3. 2019 v 14:38 odesílatel David Steele <[hidden email]> napsal:
On 2/4/19 4:21 AM, Michael Paquier wrote:
> On Wed, Jan 30, 2019 at 05:08:03PM +0100, Pavel Stehule wrote:
>> maybe "supertype". It is one char shorter .. somewhere is term
>> "supperclass, ..."
>>
>> In Czech language this term is short, "nadtyp", but probably it is not
>> acceptable :)
>
> Moved to next CF.

This thread has been very quiet for a month.  I agree with Andres [1]
that we should push this to PG13.

ok

Pavel


--
-David
[hidden email]

[1]
https://www.postgresql.org/message-id/raw/20190214203752.t4hl574k6jlu4t25%40alap3.anarazel.de

Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Tom Lane-2
In reply to this post by David Steele
David Steele <[hidden email]> writes:
> This thread has been very quiet for a month.  I agree with Andres [1]
> that we should push this to PG13.

I think the main thing it's blocked on is disagreement on what the
type name should be, which is kind of a silly thing to get blocked on,
but nonetheless it's important ...

                        regards, tom lane

Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


út 5. 3. 2019 v 15:35 odesílatel Tom Lane <[hidden email]> napsal:
David Steele <[hidden email]> writes:
> This thread has been very quiet for a month.  I agree with Andres [1]
> that we should push this to PG13.

I think the main thing it's blocked on is disagreement on what the
type name should be, which is kind of a silly thing to get blocked on,
but nonetheless it's important ...

I sent some others possible names, but probably this mail was forgotten

What about "ctype" like shortcut for common type? carraytype, cnonarraytype?

Regards

Pavel

                        regards, tom lane
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule
Hi

út 5. 3. 2019 v 18:37 odesílatel Pavel Stehule <[hidden email]> napsal:


út 5. 3. 2019 v 15:35 odesílatel Tom Lane <[hidden email]> napsal:
David Steele <[hidden email]> writes:
> This thread has been very quiet for a month.  I agree with Andres [1]
> that we should push this to PG13.

I think the main thing it's blocked on is disagreement on what the
type name should be, which is kind of a silly thing to get blocked on,
but nonetheless it's important ...

I sent some others possible names, but probably this mail was forgotten

What about "ctype" like shortcut for common type? carraytype, cnonarraytype?

rebase for PostgreSQL 13

Regards

Pavel


Regards

Pavel

                        regards, tom lane

common-type-20190524.patch (92K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Greg Stark
In reply to this post by Pavel Stehule
The proposals I see above are "commontype", "supertype", "anycommontype", and various abbreviations of those. I would humbly add "compatibletype".

Fwiw I kind of like commontype.

Alternately an argument could be made that length and typing convenience isn't really a factor here since database users never have to type these types. The only place they get written is when defining polymorphic functions which is a pretty uncommon operation.

In which case a very explicit "anycompatibletype" may be better.

On Tue., Mar. 5, 2019, 12:38 p.m. Pavel Stehule, <[hidden email]> wrote:


út 5. 3. 2019 v 15:35 odesílatel Tom Lane <[hidden email]> napsal:
David Steele <[hidden email]> writes:
> This thread has been very quiet for a month.  I agree with Andres [1]
> that we should push this to PG13.

I think the main thing it's blocked on is disagreement on what the
type name should be, which is kind of a silly thing to get blocked on,
but nonetheless it's important ...

I sent some others possible names, but probably this mail was forgotten

What about "ctype" like shortcut for common type? carraytype, cnonarraytype?

Regards

Pavel

                        regards, tom lane
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Tom Lane-2
Greg Stark <[hidden email]> writes:
> The proposals I see above are "commontype", "supertype", "anycommontype",
> and various abbreviations of those. I would humbly add "compatibletype".
> Fwiw I kind of like commontype.
> Alternately an argument could be made that length and typing convenience
> isn't really a factor here since database users never have to type these
> types. The only place they get written is when defining polymorphic
> functions which is a pretty uncommon operation.
> In which case a very explicit "anycompatibletype" may be better.

I could go with "anycompatibletype".  That would lead us to needing
related names like "anycompatiblearraytype", which is getting annoyingly
long, but you might be right that people wouldn't have to type it that
often.

Also, given the precedent of "anyarray" and "anyrange", it might be
okay to make these just "anycompatible" and "anycompatiblearray".

[ wanders away wondering if psql can tab-complete type names in
function definitions ... ]

                        regards, tom lane


Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule


čt 13. 6. 2019 v 2:37 odesílatel Tom Lane <[hidden email]> napsal:
Greg Stark <[hidden email]> writes:
> The proposals I see above are "commontype", "supertype", "anycommontype",
> and various abbreviations of those. I would humbly add "compatibletype".
> Fwiw I kind of like commontype.
> Alternately an argument could be made that length and typing convenience
> isn't really a factor here since database users never have to type these
> types. The only place they get written is when defining polymorphic
> functions which is a pretty uncommon operation.
> In which case a very explicit "anycompatibletype" may be better.

I could go with "anycompatibletype".  That would lead us to needing
related names like "anycompatiblearraytype", which is getting annoyingly
long, but you might be right that people wouldn't have to type it that
often.

Also, given the precedent of "anyarray" and "anyrange", it might be
okay to make these just "anycompatible" and "anycompatiblearray".

I like anycompatible and anycompatiblearray.

I'll update the patch

Regards

Pavel


[ wanders away wondering if psql can tab-complete type names in
function definitions ... ]

                        regards, tom lane
Reply | Threaded
Open this post in threaded view
|

Re: proposal: new polymorphic types - commontype and commontypearray

Pavel Stehule
Hi

pá 14. 6. 2019 v 6:09 odesílatel Pavel Stehule <[hidden email]> napsal:


čt 13. 6. 2019 v 2:37 odesílatel Tom Lane <[hidden email]> napsal:
Greg Stark <[hidden email]> writes:
> The proposals I see above are "commontype", "supertype", "anycommontype",
> and various abbreviations of those. I would humbly add "compatibletype".
> Fwiw I kind of like commontype.
> Alternately an argument could be made that length and typing convenience
> isn't really a factor here since database users never have to type these
> types. The only place they get written is when defining polymorphic
> functions which is a pretty uncommon operation.
> In which case a very explicit "anycompatibletype" may be better.

I could go with "anycompatibletype".  That would lead us to needing
related names like "anycompatiblearraytype", which is getting annoyingly
long, but you might be right that people wouldn't have to type it that
often.

Also, given the precedent of "anyarray" and "anyrange", it might be
okay to make these just "anycompatible" and "anycompatiblearray".

I like anycompatible and anycompatiblearray.

I'll update the patch

and here it is

Regards

Pavel
 

Regards

Pavel


[ wanders away wondering if psql can tab-complete type names in
function definitions ... ]

                        regards, tom lane

anycompatible-types-20190617.patch (94K) Download Attachment