resolved
to specific data types when a query calling a polymorphic function is
parsed. When there is more than one polymorphic argument, the actual
data types of the input values must match up as described below. If the
function's result type is polymorphic, or it has output parameters of
polymorphic types, the types of those results are deduced from the
actual types of the polymorphic inputs as described below.
</para>
<para>
For the <quote>simple</quote> family of polymorphic types, the
matching and deduction rules work like this:
</para>
<para>
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>.
</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> or <type>anyarray</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 and the same as the element type
of the <type>anyarray</type> positions.
If there are positions declared <type>anymultirange</type>,
their actual multirange type must contain ranges matching parameters declared
<type>anyrange</type> and base elements matching parameters declared
<type>anyelement</type> and <type>anyarray</type>.
</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>
<para>
When the return value of a function is declared as a polymorphic type,
there must be at least one argument position that is also polymorphic,
and the actual data type(s) supplied for the polymorphic arguments
determine the actual
result type for that call. For example, if there were not already
an array subscripting mechanism, one could define a function that
implements subscripting as <literal>subscript(anyarray, integer)
returns anyelement</literal>. This declaration constrains the actual first
argument to be an array type, and allows the parser to infer the correct
result type from the actual first argument's type. Another example
is that a function declared as <literal>f(anyarray) returns anyenum</literal>
will only accept arrays of enum types.
</para>
<para>
In most cases, the parser can infer the actual data type for a
polymorphic result type from arguments that are of a different
polymorphic type in the same family; for example <type>anyarray</type>
can be deduced from <type>anyelement</type>