</refsect1>
<refsect1 id="sql-createfunction-overloading">
<title>Overloading</title>
<para>
<productname>PostgreSQL</productname> allows function
<firstterm>overloading</firstterm>; that is, the same name can be
used for several different functions so long as they have distinct
input argument types. Whether or not you use it, this capability entails
security precautions when calling functions in databases where some users
mistrust other users; see <xref linkend="typeconv-func"/>.
</para>
<para>
Two functions are considered the same if they have the same names and
<emphasis>input</emphasis> argument types, ignoring any <literal>OUT</literal>
parameters. Thus for example these declarations conflict:
<programlisting>
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, out text) ...
</programlisting>
</para>
<para>
Functions that have different argument type lists will not be considered
to conflict at creation time, but if defaults are provided they might
conflict in use. For example, consider
<programlisting>
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, int default 42) ...
</programlisting>
A call <literal>foo(10)</literal> will fail due to the ambiguity about which
function should be called.
</para>
</refsect1>
<refsect1 id="sql-createfunction-notes">
<title>Notes</title>
<para>
The full <acronym>SQL</acronym> type syntax is allowed for
declaring a function's arguments and return value. However,
parenthesized type modifiers (e.g., the precision field for
type <type>numeric</type>) are discarded by <command>CREATE FUNCTION</command>.
Thus for example
<literal>CREATE FUNCTION foo (varchar(10)) ...</literal>
is exactly the same as
<literal>CREATE FUNCTION foo (varchar) ...</literal>.
</para>
<para>
When replacing an existing function with <command>CREATE OR REPLACE
FUNCTION</command>, there are restrictions on changing parameter names.
You cannot change the name already assigned to any input parameter
(although you can add names to parameters that had none before).
If there is more than one output parameter, you cannot change the
names of the output parameters, because that would change the
column names of the anonymous composite type that describes the
function's result. These restrictions are made to ensure that
existing calls of the function do not stop working when it is replaced.
</para>
<para>
If a function is declared <literal>STRICT</literal> with a <literal>VARIADIC</literal>
argument, the strictness check tests that the variadic array <emphasis>as
a whole</emphasis> is non-null. The function will still be called if the
array has null elements.
</para>
</refsect1>
<refsect1 id="sql-createfunction-examples">
<title>Examples</title>
<para>
Add two integers using an SQL function:
<programlisting>
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
</programlisting>
The same function written in a more SQL-conforming style, using argument
names and an unquoted body:
<programlisting>
CREATE FUNCTION add(a integer, b integer) RETURNS integer
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT
RETURN a + b;
</programlisting>
</para>
<para>
Increment an integer, making use of an argument name, in
<application>PL/pgSQL</application>:
<programlisting>
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
BEGIN
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
</programlisting>
</para>
<para>
Return a record containing multiple output parameters:
<programlisting>
CREATE FUNCTION dup(in int, out f1 int, out f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
</programlisting>
You can do the same thing