visible
outside the function. Hence, the result is labeled <literal>one</literal>
instead of <literal>result</literal>.
</para>
<para>
It is almost as easy to define <acronym>SQL</acronym> functions
that take base types as arguments:
<screen>
CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$
SELECT x + y;
$$ LANGUAGE SQL;
SELECT add_em(1, 2) AS answer;
answer
--------
3
</screen>
</para>
<para>
Alternatively, we could dispense with names for the arguments and
use numbers:
<screen>
CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$
SELECT $1 + $2;
$$ LANGUAGE SQL;
SELECT add_em(1, 2) AS answer;
answer
--------
3
</screen>
</para>
<para>
Here is a more useful function, which might be used to debit a
bank account:
<programlisting>
CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
UPDATE bank
SET balance = balance - debit
WHERE accountno = tf1.accountno;
SELECT 1;
$$ LANGUAGE SQL;
</programlisting>
A user could execute this function to debit account 17 by $100.00 as
follows:
<programlisting>
SELECT tf1(17, 100.0);
</programlisting>
</para>
<para>
In this example, we chose the name <literal>accountno</literal> for the first
argument, but this is the same as the name of a column in the
<literal>bank</literal> table. Within the <command>UPDATE</command> command,
<literal>accountno</literal> refers to the column <literal>bank.accountno</literal>,
so <literal>tf1.accountno</literal> must be used to refer to the argument.
We could of course avoid this by using a different name for the argument.
</para>
<para>
In practice one would probably like a more useful result from the
function than a constant 1, so a more likely definition
is:
<programlisting>
CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
UPDATE bank
SET balance = balance - debit
WHERE accountno = tf1.accountno;
SELECT balance FROM bank WHERE accountno = tf1.accountno;
$$ LANGUAGE SQL;
</programlisting>
which adjusts the balance and returns the new balance.
The same thing could be done in one command using <literal>RETURNING</literal>:
<programlisting>
CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
UPDATE bank
SET balance = balance - debit
WHERE accountno = tf1.accountno
RETURNING balance;
$$ LANGUAGE SQL;
</programlisting>
</para>
<para>
If the final <literal>SELECT</literal> or <literal>RETURNING</literal>
clause in an <acronym>SQL</acronym> function does not return exactly
the function's declared result
type, <productname>PostgreSQL</productname> will automatically cast
the value to the required type, if that is possible with an implicit
or assignment cast. Otherwise, you must write an explicit cast.
For example, suppose we wanted the
previous <function>add_em</function> function to return
type <type>float8</type> instead. It's sufficient to write
<programlisting>
CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$
SELECT $1 + $2;
$$ LANGUAGE SQL;
</programlisting>
since the <type>integer</type> sum can be implicitly cast
to <type>float8</type>.
(See <xref linkend="typeconv"/> or <xref linkend="sql-createcast"/>
for more about casts.)
</para>
</sect2>
<sect2 id="xfunc-sql-composite-functions">
<title><acronym>SQL</acronym> Functions on Composite Types</title>
<para>
When writing functions with arguments of composite types, we must not
only specify which argument we want but also the desired attribute
(field) of that argument. For example, suppose that
<type>emp</type> is a table containing employee data, and therefore
also the name of the composite type of each row of the