default values are inserted whenever the function is
called with insufficiently many actual arguments. Since arguments
can only be omitted from the end of the actual argument list, all
parameters after a parameter with a default value have to have
default values as well. (Although the use of named argument notation
could allow this restriction to be relaxed, it's still enforced so that
positional argument notation works sensibly.) Whether or not you use it,
this capability creates a need for precautions when calling functions in
databases where some users mistrust other users; see
<xref linkend="typeconv-func"/>.
</para>
<para>
For example:
<screen>
CREATE FUNCTION foo(a int, b int DEFAULT 2, c int DEFAULT 3)
RETURNS int
LANGUAGE SQL
AS $$
SELECT $1 + $2 + $3;
$$;
SELECT foo(10, 20, 30);
foo
-----
60
(1 row)
SELECT foo(10, 20);
foo
-----
33
(1 row)
SELECT foo(10);
foo
-----
15
(1 row)
SELECT foo(); -- fails since there is no default for the first argument
ERROR: function foo() does not exist
</screen>
The <literal>=</literal> sign can also be used in place of the
key word <literal>DEFAULT</literal>.
</para>
</sect2>
<sect2 id="xfunc-sql-table-functions">
<title><acronym>SQL</acronym> Functions as Table Sources</title>
<para>
All SQL functions can be used in the <literal>FROM</literal> clause of a query,
but it is particularly useful for functions returning composite types.
If the function is defined to return a base type, the table function
produces a one-column table. If the function is defined to return
a composite type, the table function produces a column for each attribute
of the composite type.
</para>
<para>
Here is an example:
<screen>
CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe');
INSERT INTO foo VALUES (1, 2, 'Ed');
INSERT INTO foo VALUES (2, 1, 'Mary');
CREATE FUNCTION getfoo(int) RETURNS foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT *, upper(fooname) FROM getfoo(1) AS t1;
fooid | foosubid | fooname | upper
-------+----------+---------+-------
1 | 1 | Joe | JOE
(1 row)
</screen>
As the example shows, we can work with the columns of the function's
result just the same as if they were columns of a regular table.
</para>
<para>
Note that we only got one row out of the function. This is because
we did not use <literal>SETOF</literal>. That is described in the next section.
</para>
</sect2>
<sect2 id="xfunc-sql-functions-returning-set">
<title><acronym>SQL</acronym> Functions Returning Sets</title>
<indexterm>
<primary>function</primary>
<secondary>with SETOF</secondary>
</indexterm>
<para>
When an SQL function is declared as returning <literal>SETOF
<replaceable>sometype</replaceable></literal>, the function's final
query is executed to completion, and each row it
outputs is returned as an element of the result set.
</para>
<para>
This feature is normally used when calling the function in the <literal>FROM</literal>
clause. In this case each row returned by the function becomes
a row of the table seen by the query. For example, assume that
table <literal>foo</literal> has the same contents as above, and we say:
<programlisting>
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo(1) AS t1;
</programlisting>
Then we would get:
<screen>
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
(2 rows)
</screen>
</para>
<para>
It is also possible to return multiple rows with the columns defined by
output parameters, like this:
<programlisting>
CREATE TABLE tab (y int, z int);
INSERT INTO tab VALUES (1, 2),