any number of array parameters, and it returns a corresponding number of
columns, as if <literal>UNNEST</literal>
(<xref linkend="functions-array"/>) had been called on each parameter
separately and combined using the <literal>ROWS FROM</literal> construct.
</para>
<synopsis>
UNNEST( <replaceable>array_expression</replaceable> <optional>, ... </optional> ) <optional>WITH ORDINALITY</optional> <optional><optional>AS</optional> <replaceable>table_alias</replaceable> <optional>(<replaceable>column_alias</replaceable> <optional>, ... </optional>)</optional></optional>
</synopsis>
<para>
If no <replaceable>table_alias</replaceable> is specified, the function
name is used as the table name; in the case of a <literal>ROWS FROM()</literal>
construct, the first function's name is used.
</para>
<para>
If column aliases are not supplied, then for a function returning a base
data type, the column name is also the same as the function name. For a
function returning a composite type, the result columns get the names
of the individual attributes of the type.
</para>
<para>
Some examples:
<programlisting>
CREATE TABLE foo (fooid int, foosubid int, fooname text);
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo(1) AS t1;
SELECT * FROM foo
WHERE foosubid IN (
SELECT foosubid
FROM getfoo(foo.fooid) z
WHERE z.fooid = foo.fooid
);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
SELECT * FROM vw_getfoo;
</programlisting>
</para>
<para>
In some cases it is useful to define table functions that can
return different column sets depending on how they are invoked.
To support this, the table function can be declared as returning
the pseudo-type <type>record</type> with no <literal>OUT</literal>
parameters. When such a function is used in
a query, the expected row structure must be specified in the
query itself, so that the system can know how to parse and plan
the query. This syntax looks like:
</para>
<synopsis>
<replaceable>function_call</replaceable> <optional>AS</optional> <replaceable>alias</replaceable> (<replaceable>column_definition</replaceable> <optional>, ... </optional>)
<replaceable>function_call</replaceable> AS <optional><replaceable>alias</replaceable></optional> (<replaceable>column_definition</replaceable> <optional>, ... </optional>)
ROWS FROM( ... <replaceable>function_call</replaceable> AS (<replaceable>column_definition</replaceable> <optional>, ... </optional>) <optional>, ... </optional> )
</synopsis>
<para>
When not using the <literal>ROWS FROM()</literal> syntax,
the <replaceable>column_definition</replaceable> list replaces the column
alias list that could otherwise be attached to the <literal>FROM</literal>
item; the names in the column definitions serve as column aliases.
When using the <literal>ROWS FROM()</literal> syntax,
a <replaceable>column_definition</replaceable> list can be attached to
each member function separately; or if there is only one member function
and no <literal>WITH ORDINALITY</literal> clause,
a <replaceable>column_definition</replaceable> list can be written in
place of a column alias list following <literal>ROWS FROM()</literal>.
</para>
<para>
Consider this example:
<programlisting>
SELECT *
FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';
</programlisting>
The <xref linkend="contrib-dblink-function"/> function
(part of the <xref linkend="dblink"/> module) executes
a remote query. It is declared to return
<type>record</type> since it might be used for any kind of query.
The actual column set must