Re: range bug in resolve_generic_type?

From: Paul A Jungwirth <pj(at)illuminatedcomputing(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, Jeff Davis <pgsql(at)j-davis(dot)com>
Subject: Re: range bug in resolve_generic_type?
Date: 2019-08-31 13:35:48
Message-ID: CA+renyXLEqHdAAveH3eWXsSMo4Y1WPG_Hze5qud2vsXMXhgzpA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Aug 27, 2019 at 8:52 AM Paul A Jungwirth
<pj(at)illuminatedcomputing(dot)com> wrote:
>
> On Tue, Aug 27, 2019 at 8:23 AM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> > I seem to recall that we discussed this exact point during development
> > of the range feature, and concluded that this was the behavior we
> > wanted, ie, treat anyrange like a scalar for this purpose. Otherwise
> > there isn't any way to use a polymorphic function to build an array
> > of ranges

One more thing about this: The docs only say that elemOf(anyrange) =
anyelement and elemOf(anyarray) = anyelement. I already added
anymultirange to that page, so here is what I have (from my
forthcoming patch). It also includes anyrangearray. I thought it might
be useful here to clarify how we could support polymorphic
arrays-of-ranges going forward, while avoiding any contradictions:

<para>
Seven pseudo-types of special interest are <type>anyelement</type>,
<type>anyarray</type>, <type>anynonarray</type>, <type>anyenum</type>,
<type>anyrange</type>, <type>anymultirange</type>, and
<type>anyrangearray</type>.
which are collectively called <firstterm>polymorphic types</firstterm>.
Any function declared using these types is said to be
a <firstterm>polymorphic function</firstterm>. A polymorphic function can
operate on many different data types, with the specific data type(s)
being determined by the data types actually passed to it in a particular
call.
</para>

<para>
Polymorphic arguments and results are tied to each other and are resolved
to a specific data type when a query calling a polymorphic function is
parsed. Each position (either argument or return value) declared as
<type>anyelement</type> is allowed to have any specific actual
data type, but in any given call they must all be the
<emphasis>same</emphasis> actual type. Each
position declared as <type>anyarray</type> can have any array data type,
but similarly they must all be the same type. And similarly,
positions declared as <type>anyrange</type> must all be the same range
type. Likewise for <type>anymultirange</type> and
<type>anyrangearray</type>.
</para>

<para>
Furthermore, if there are
positions declared <type>anyarray</type> and others declared
<type>anyelement</type>, the actual array type in the
<type>anyarray</type> positions must be an array whose elements are
the same type appearing in the <type>anyelement</type> positions.
<type>anynonarray</type> is treated exactly the same as
<type>anyelement</type>,
but adds the additional constraint that the actual type must not be
an array type.
<type>anyenum</type> is treated exactly the same as
<type>anyelement</type>,
but adds the additional constraint that the actual type must
be an enum type.
</para>

<para>
Similarly, if there are positions declared <type>anyrange</type>
and others declared <type>anyelement</type>, the actual range type in
the <type>anyrange</type> positions must be a range whose subtype is
the same type appearing in the <type>anyelement</type> positions.
The types <type>anymultirange</type> and <type>anyrangearray</type> accept
a multirange or array of any range type, respectively.
If they appear along with an <type>anyrange</type> then they must be a
multirange/array of that range type.
If a function has both <type>anymultirange</type> and
<type>anyrangearray</type>, they must contain ranges of the same type,
even if there is no <type>anyrange</type> parameter.
</para>

<para>
Thus, when more than one argument position is declared with a polymorphic
type, the net effect is that only certain combinations of actual argument
types are allowed. For example, a function declared as
<literal>equal(anyelement, anyelement)</literal> will take any
two input values,
so long as they are of the same data type.
</para>

I hope that helps!

Yours,
Paul

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2019-08-31 18:27:55 Re: [HACKERS] Deadlock in XLogInsert at AIX
Previous Message Peter Geoghegan 2019-08-31 08:04:01 Re: [HACKERS] [WIP] Effective storage of duplicates in B-tree index.