diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 16 | ||||
-rw-r--r-- | doc/src/sgml/extend.sgml | 12 | ||||
-rw-r--r-- | doc/src/sgml/plpgsql.sgml | 9 | ||||
-rw-r--r-- | doc/src/sgml/ref/alter_function.sgml | 11 | ||||
-rw-r--r-- | doc/src/sgml/ref/comment.sgml | 11 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_function.sgml | 7 | ||||
-rw-r--r-- | doc/src/sgml/ref/drop_function.sgml | 11 | ||||
-rw-r--r-- | doc/src/sgml/typeconv.sgml | 14 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 136 |
9 files changed, 195 insertions, 32 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 76198b0f832..7accea0f76c 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.168 2008/07/14 00:51:45 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.169 2008/07/16 01:30:21 tgl Exp $ --> <!-- Documentation of the system catalogs, directed toward PostgreSQL developers --> @@ -3643,7 +3643,8 @@ <entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry> <entry> An array with the data types of the function arguments. This includes - only input arguments (including <literal>INOUT</literal> arguments), and thus represents + only input arguments (including <literal>INOUT</literal> and + <literal>VARIADIC</> arguments), and thus represents the call signature of the function </entry> </row> @@ -3654,8 +3655,9 @@ <entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry> <entry> An array with the data types of the function arguments. This includes - all arguments (including <literal>OUT</literal> and <literal>INOUT</literal> arguments); however, if all the - arguments are IN arguments, this field will be null. + all arguments (including <literal>OUT</literal> and + <literal>INOUT</literal> arguments); however, if all the + arguments are <literal>IN</literal> arguments, this field will be null. Note that subscripting is 1-based, whereas for historical reasons <structfield>proargtypes</> is subscripted from 0 </entry> @@ -3669,8 +3671,10 @@ An array with the modes of the function arguments, encoded as <literal>i</literal> for <literal>IN</> arguments, <literal>o</literal> for <literal>OUT</> arguments, - <literal>b</literal> for <literal>INOUT</> arguments. - If all the arguments are <literal>IN</literal> arguments, this field will be null. + <literal>b</literal> for <literal>INOUT</> arguments, + <literal>v</literal> for <literal>VARIADIC</> arguments. + If all the arguments are <literal>IN</literal> arguments, + this field will be null. Note that subscripts correspond to positions of <structfield>proallargtypes</> not <structfield>proargtypes</> </entry> diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml index e2805b41917..caeda7e75ca 100644 --- a/doc/src/sgml/extend.sgml +++ b/doc/src/sgml/extend.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.36 2007/08/31 21:33:48 momjian Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.37 2008/07/16 01:30:21 tgl Exp $ --> <chapter id="extend"> <title>Extending <acronym>SQL</acronym></title> @@ -254,6 +254,16 @@ is equivalent to declaring it as <literal>f(anyenum, anyenum)</>: both actual arguments have to be the same enum type. </para> + + <para> + A variadic function (one taking a variable number of arguments, as in + <xref linkend="xfunc-sql-variadic-functions">) can be + polymorphic: this is accomplished by declaring its last parameter as + <literal>VARIADIC</> <type>anyarray</>. For purposes of argument + matching and determining the actual result type, such a function behaves + the same as if you had written the appropriate number of + <type>anynonarray</> parameters. + </para> </sect2> </sect1> diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index cd1531999b7..42bd6048b68 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.131 2008/06/27 01:52:59 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.132 2008/07/16 01:30:21 tgl Exp $ --> <chapter id="plpgsql"> <title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title> @@ -122,6 +122,13 @@ </para> <para> + <application>PL/pgSQL</> functions can be declared to accept a variable + number of arguments by using the <literal>VARIADIC</> marker. This + works exactly the same way as for SQL functions, as discussed in + <xref linkend="xfunc-sql-variadic-functions">. + </para> + + <para> <application>PL/pgSQL</> functions can also be declared to accept and return the polymorphic types <type>anyelement</type>, <type>anyarray</type>, <type>anynonarray</type>, diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index bee2f6f4390..abedfe7d50b 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/alter_function.sgml,v 1.15 2007/09/03 18:46:29 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/alter_function.sgml,v 1.16 2008/07/16 01:30:21 tgl Exp $ PostgreSQL documentation --> @@ -81,13 +81,14 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: <listitem> <para> - The mode of an argument: either <literal>IN</>, <literal>OUT</>, - or <literal>INOUT</>. If omitted, the default is <literal>IN</>. + The mode of an argument: <literal>IN</>, <literal>OUT</>, + <literal>INOUT</>, or <literal>VARIADIC</>. + If omitted, the default is <literal>IN</>. Note that <command>ALTER FUNCTION</command> does not actually pay any attention to <literal>OUT</> arguments, since only the input arguments are needed to determine the function's identity. - So it is sufficient to list the <literal>IN</> and <literal>INOUT</> - arguments. + So it is sufficient to list the <literal>IN</>, <literal>INOUT</>, + and <literal>VARIADIC</> arguments. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml index c8993e915b8..2da64f87aca 100644 --- a/doc/src/sgml/ref/comment.sgml +++ b/doc/src/sgml/ref/comment.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/comment.sgml,v 1.36 2007/08/21 21:08:47 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/comment.sgml,v 1.37 2008/07/16 01:30:21 tgl Exp $ PostgreSQL documentation --> @@ -136,13 +136,14 @@ COMMENT ON <listitem> <para> - The mode of a function argument: either <literal>IN</>, <literal>OUT</>, - or <literal>INOUT</>. If omitted, the default is <literal>IN</>. + The mode of a function argument: <literal>IN</>, <literal>OUT</>, + <literal>INOUT</>, or <literal>VARIADIC</>. + If omitted, the default is <literal>IN</>. Note that <command>COMMENT ON FUNCTION</command> does not actually pay any attention to <literal>OUT</> arguments, since only the input arguments are needed to determine the function's identity. - So it is sufficient to list the <literal>IN</> and <literal>INOUT</> - arguments. + So it is sufficient to list the <literal>IN</>, <literal>INOUT</>, + and <literal>VARIADIC</> arguments. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index 8c542982d52..18b9bf7beea 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.78 2007/09/11 00:06:41 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.79 2008/07/16 01:30:21 tgl Exp $ --> <refentry id="SQL-CREATEFUNCTION"> @@ -101,8 +101,9 @@ CREATE [ OR REPLACE ] FUNCTION <listitem> <para> - The mode of an argument: either <literal>IN</>, <literal>OUT</>, - or <literal>INOUT</>. If omitted, the default is <literal>IN</>. + The mode of an argument: <literal>IN</>, <literal>OUT</>, + <literal>INOUT</>, or <literal>VARIADIC</>. + If omitted, the default is <literal>IN</>. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_function.sgml b/doc/src/sgml/ref/drop_function.sgml index bf39f5356dd..256cafe684f 100644 --- a/doc/src/sgml/ref/drop_function.sgml +++ b/doc/src/sgml/ref/drop_function.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/drop_function.sgml,v 1.33 2007/01/31 23:26:03 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/drop_function.sgml,v 1.34 2008/07/16 01:30:21 tgl Exp $ PostgreSQL documentation --> @@ -65,13 +65,14 @@ DROP FUNCTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ( <listitem> <para> - The mode of an argument: either <literal>IN</>, <literal>OUT</>, - or <literal>INOUT</>. If omitted, the default is <literal>IN</>. + The mode of an argument: <literal>IN</>, <literal>OUT</>, + <literal>INOUT</>, or <literal>VARIADIC</>. + If omitted, the default is <literal>IN</>. Note that <command>DROP FUNCTION</command> does not actually pay any attention to <literal>OUT</> arguments, since only the input arguments are needed to determine the function's identity. - So it is sufficient to list the <literal>IN</> and <literal>INOUT</> - arguments. + So it is sufficient to list the <literal>IN</>, <literal>INOUT</>, + and <literal>VARIADIC</> arguments. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index 451555cd022..4f04801210b 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.54 2008/07/11 07:02:43 petere Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.55 2008/07/16 01:30:21 tgl Exp $ --> <chapter Id="typeconv"> <title>Type Conversion</title> @@ -503,6 +503,18 @@ different argument types are considered on an equal footing regardless of search path position. </para> </step> +<step performance="optional"> +<para> +If a function is declared with a <literal>VARIADIC</> array parameter, and +the call does not use the <literal>VARIADIC</> keyword, then the function +is treated as if the array parameter were replaced by one or more occurrences +of its element type, as needed to match the call. After such expansion the +function might have effective argument types identical to some non-variadic +function. In that case the function appearing earlier in the search path is +used, or if the two functions are in the same schema, the non-variadic one is +selected. +</para> +</step> </substeps> </step> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index efee5d8d469..55ed719ec64 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.130 2007/11/10 20:14:36 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.131 2008/07/16 01:30:21 tgl Exp $ --> <sect1 id="xfunc"> <title>User-Defined Functions</title> @@ -495,7 +495,7 @@ SELECT getname(new_emp()); None (1 row) </screen> - </para> + </para> <para> Still another way to use a function that returns a composite type is to @@ -505,7 +505,7 @@ SELECT getname(new_emp()); </sect2> <sect2 id="xfunc-output-parameters"> - <title>Functions with Output Parameters</title> + <title><acronym>SQL</> Functions with Output Parameters</title> <indexterm> <primary>function</primary> @@ -578,9 +578,75 @@ DROP FUNCTION sum_n_product (int, int); <para> Parameters can be marked as <literal>IN</> (the default), - <literal>OUT</>, or <literal>INOUT</>. An <literal>INOUT</> + <literal>OUT</>, <literal>INOUT</>, or <literal>VARIADIC</>. + An <literal>INOUT</> parameter serves as both an input parameter (part of the calling argument list) and an output parameter (part of the result record type). + <literal>VARIADIC</> parameters are input parameters, but are treated + specially as described next. + </para> + </sect2> + + <sect2 id="xfunc-sql-variadic-functions"> + <title><acronym>SQL</> Functions with Variable Numbers of Arguments</title> + + <indexterm> + <primary>function</primary> + <secondary>variadic</secondary> + </indexterm> + + <indexterm> + <primary>variadic function</primary> + </indexterm> + + <para> + <acronym>SQL</acronym> functions can be declared to accept + variable numbers of arguments, so long as all the <quote>optional</> + arguments are of the same data type. The optional arguments will be + passed to the function as an array. The function is declared by + marking the last parameter as <literal>VARIADIC</>; this parameter + must be declared as being of an array type. For example: + +<screen> +CREATE FUNCTION mleast(VARIADIC 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</> 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</> 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. You can + do that by specifying <literal>VARIADIC</> 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</> can only be attached to the last + actual argument of a function call. </para> </sect2> @@ -795,7 +861,7 @@ DETAIL: A function returning a polymorphic type must have at least one polymorp For example: <screen> CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; +AS 'select $1, array[$1,$1]' LANGUAGE SQL; SELECT * FROM dup(22); f2 | f3 @@ -804,6 +870,38 @@ SELECT * FROM dup(22); (1 row) </screen> </para> + + <para> + Polymorphism can also be used with variadic functions. + For example: +<screen> +CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ + SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); +$$ LANGUAGE SQL; + +SELECT anyleast(10, -1, 5, 4); + anyleast +---------- + -1 +(1 row) + +SELECT anyleast('abc'::text, 'def'); + anyleast +---------- + abc +(1 row) + +CREATE FUNCTION concat(text, VARIADIC anyarray) RETURNS text AS $$ + SELECT array_to_string($2, $1); +$$ LANGUAGE SQL; + +SELECT concat('|', 1, 4, 2); + concat +-------- + 1|4|2 +(1 row) +</screen> + </para> </sect2> </sect1> @@ -853,6 +951,16 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... </para> <para> + Another possible conflict is between variadic and non-variadic functions. + For instance, it is possible to create both <literal>foo(numeric)</> and + <literal>foo(VARIADIC numeric[])</>. In this case it is unclear which one + should be matched to a call providing a single numeric argument, such as + <literal>foo(10.1)</>. The rule is that the function appearing + earlier in the search path is used, or if the two functions are in the + same schema, the non-variadic one is preferred. + </para> + + <para> When overloading C-language functions, there is an additional constraint: The C name of each function in the family of overloaded functions must be different from the C names of all @@ -2952,7 +3060,25 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray LANGUAGE C IMMUTABLE; </programlisting> </para> + + <para> + There is a variant of polymorphism that is only available to C-language + functions: they can be declared to take parameters of type + <literal>"any"</>. (Note that this type name must be double-quoted, + since it's also a SQL reserved word.) This works like + <type>anyelement</> except that it does not constrain different + <literal>"any"</> arguments to be the same type, nor do they help + determine the function's result type. A C-language function can also + declare its final parameter to be <literal>VARIADIC "any"</>. This will + match one or more actual arguments of any type (not necessarily the same + type). These arguments will <emphasis>not</> be gathered into an array + as happens with normal variadic functions; they will just be passed to + the function separately. The <function>PG_NARGS()</> macro and the + methods described above must be used to determine the number of actual + arguments and their types when using this feature. + </para> </sect2> + <sect2> <title>Shared Memory and LWLocks</title> |