Pavel Stehule <pavel.steh...@gmail.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