mleast(VARIADIC arr numeric[]) RETURNS numeric AS $$
SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
$$ LANGUAGE SQL;
SELECT mleast(10, -1, 5, 4.4);
mleast
--------
-1
(1 row)
</screen>
Effectively, all the actual arguments at or beyond the
<literal>VARIADIC</literal> position are gathered up into a one-dimensional
array, as if you had written
<screen>
SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work
</screen>
You can't actually write that, though — or at least, it will
not match this function definition. A parameter marked
<literal>VARIADIC</literal> matches one or more occurrences of its element
type, not of its own type.
</para>
<para>
Sometimes it is useful to be able to pass an already-constructed array
to a variadic function; this is particularly handy when one variadic
function wants to pass on its array parameter to another one. Also,
this is the only secure way to call a variadic function found in a schema
that permits untrusted users to create objects; see
<xref linkend="typeconv-func"/>. You can do this by
specifying <literal>VARIADIC</literal> in the call:
<screen>
SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
</screen>
This prevents expansion of the function's variadic parameter into its
element type, thereby allowing the array argument value to match
normally. <literal>VARIADIC</literal> can only be attached to the last
actual argument of a function call.
</para>
<para>
Specifying <literal>VARIADIC</literal> in the call is also the only way to
pass an empty array to a variadic function, for example:
<screen>
SELECT mleast(VARIADIC ARRAY[]::numeric[]);
</screen>
Simply writing <literal>SELECT mleast()</literal> does not work because a
variadic parameter must match at least one actual argument.
(You could define a second function also named <literal>mleast</literal>,
with no parameters, if you wanted to allow such calls.)
</para>
<para>
The array element parameters generated from a variadic parameter are
treated as not having any names of their own. This means it is not
possible to call a variadic function using named arguments (<xref
linkend="sql-syntax-calling-funcs"/>), except when you specify
<literal>VARIADIC</literal>. For example, this will work:
<screen>
SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]);
</screen>
but not these:
<screen>
SELECT mleast(arr => 10);
SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]);
</screen>
</para>
</sect2>
<sect2 id="xfunc-sql-parameter-defaults">
<title><acronym>SQL</acronym> Functions with Default Values for Arguments</title>
<indexterm>
<primary>function</primary>
<secondary>default values for arguments</secondary>
</indexterm>
<para>
Functions can be declared with default values for some or all input
arguments. The 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