or equal to <varname>tg_nargs</varname>)
result in a null value.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
A trigger function must return either <symbol>NULL</symbol> or a
record/row value having exactly the structure of the table the
trigger was fired for.
</para>
<para>
Row-level triggers fired <literal>BEFORE</literal> can return null to signal the
trigger manager to skip the rest of the operation for this row
(i.e., subsequent triggers are not fired, and the
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> does not occur
for this row). If a nonnull
value is returned then the operation proceeds with that row value.
Returning a row value different from the original value
of <varname>NEW</varname> alters the row that will be inserted or
updated. Thus, if the trigger function wants the triggering
action to succeed normally without altering the row
value, <varname>NEW</varname> (or a value equal thereto) has to be
returned. To alter the row to be stored, it is possible to
replace single values directly in <varname>NEW</varname> and return the
modified <varname>NEW</varname>, or to build a complete new record/row to
return. In the case of a before-trigger
on <command>DELETE</command>, the returned value has no direct
effect, but it has to be nonnull to allow the trigger action to
proceed. Note that <varname>NEW</varname> is null
in <command>DELETE</command> triggers, so returning that is
usually not sensible. The usual idiom in <command>DELETE</command>
triggers is to return <varname>OLD</varname>.
</para>
<para>
<literal>INSTEAD OF</literal> triggers (which are always row-level triggers,
and may only be used on views) can return null to signal that they did
not perform any updates, and that the rest of the operation for this
row should be skipped (i.e., subsequent triggers are not fired, and the
row is not counted in the rows-affected status for the surrounding
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>).
Otherwise a nonnull value should be returned, to signal
that the trigger performed the requested operation. For
<command>INSERT</command> and <command>UPDATE</command> operations, the return value
should be <varname>NEW</varname>, which the trigger function may modify to
support <command>INSERT RETURNING</command> and <command>UPDATE RETURNING</command>
(this will also affect the row value passed to any subsequent triggers,
or passed to a special <varname>EXCLUDED</varname> alias reference within
an <command>INSERT</command> statement with an <literal>ON CONFLICT DO
UPDATE</literal> clause). For <command>DELETE</command> operations, the return
value should be <varname>OLD</varname>.
</para>
<para>
The return value of a row-level trigger
fired <literal>AFTER</literal> or a statement-level trigger
fired <literal>BEFORE</literal> or <literal>AFTER</literal> is
always ignored; it might as well be null. However, any of these types of
triggers might still abort the entire operation by raising an error.
</para>
<para>
<xref linkend="plpgsql-trigger-example"/> shows an example of a
trigger function in <application>PL/pgSQL</application>.
</para>
<example id="plpgsql-trigger-example">
<title>A <application>PL/pgSQL</application> Trigger Function</title>
<para>
This example trigger ensures that any time a row is inserted or updated
in the table, the current user name and time are stamped into the
row. And it checks that an employee's name is given and that the
salary is a positive value.
</para>
<programlisting>
CREATE TABLE emp (
empname text,
salary integer,
last_date timestamp,
last_user text
);
CREATE FUNCTION