a composite type's name.
(Since every table has an associated composite type of the same name,
it actually does not matter in <productname>PostgreSQL</productname> whether you
write <literal>%ROWTYPE</literal> or not. But the form with
<literal>%ROWTYPE</literal> is more portable.)
</para>
<para>
As with <literal>%TYPE</literal>, <literal>%ROWTYPE</literal> can be
followed by array decoration to declare a variable that holds an array
of the referenced composite type.
</para>
<para>
Parameters to a function can be
composite types (complete table rows). In that case, the
corresponding identifier <literal>$<replaceable>n</replaceable></literal> will be a row variable, and fields can
be selected from it, for example <literal>$1.user_id</literal>.
</para>
<para>
Here is an example of using composite types. <structname>table1</structname>
and <structname>table2</structname> are existing tables having at least the
mentioned fields:
<programlisting>
CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$
DECLARE
t2_row table2%ROWTYPE;
BEGIN
SELECT * INTO t2_row FROM table2 WHERE ... ;
RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
END;
$$ LANGUAGE plpgsql;
SELECT merge_fields(t.*) FROM table1 t WHERE ... ;
</programlisting>
</para>
</sect2>
<sect2 id="plpgsql-declaration-records">
<title>Record Types</title>
<synopsis>
<replaceable>name</replaceable> RECORD;
</synopsis>
<para>
Record variables are similar to row-type variables, but they have no
predefined structure. They take on the actual row structure of the
row they are assigned during a <command>SELECT</command> or <command>FOR</command> command. The substructure
of a record variable can change each time it is assigned to.
A consequence of this is that until a record variable is first assigned
to, it has no substructure, and any attempt to access a
field in it will draw a run-time error.
</para>
<para>
Note that <literal>RECORD</literal> is not a true data type, only a placeholder.
One should also realize that when a <application>PL/pgSQL</application>
function is declared to return type <type>record</type>, this is not quite the
same concept as a record variable, even though such a function might
use a record variable to hold its result. In both cases the actual row
structure is unknown when the function is written, but for a function
returning <type>record</type> the actual structure is determined when the
calling query is parsed, whereas a record variable can change its row
structure on-the-fly.
</para>
</sect2>
<sect2 id="plpgsql-declaration-collation">
<title>Collation of <application>PL/pgSQL</application> Variables</title>
<indexterm>
<primary>collation</primary>
<secondary>in PL/pgSQL</secondary>
</indexterm>
<para>
When a <application>PL/pgSQL</application> function has one or more
parameters of collatable data types, a collation is identified for each
function call depending on the collations assigned to the actual
arguments, as described in <xref linkend="collation"/>. If a collation is
successfully identified (i.e., there are no conflicts of implicit
collations among the arguments) then all the collatable parameters are
treated as having that collation implicitly. This will affect the
behavior of collation-sensitive operations within the function.
For example, consider
<programlisting>
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
RETURN a < b;
END;
$$ LANGUAGE plpgsql;
SELECT less_than(text_field_1, text_field_2) FROM table1;
SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1;
</programlisting>
The first use of <function>less_than</function> will use the common collation
of <structfield>text_field_1</structfield> and <structfield>text_field_2</structfield>