EXECUTE FUNCTION process_emp_audit();
CREATE TRIGGER emp_audit_upd
AFTER UPDATE ON emp
REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
CREATE TRIGGER emp_audit_del
AFTER DELETE ON emp
REFERENCING OLD TABLE AS old_table
FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
</programlisting>
</example>
</sect2>
<sect2 id="plpgsql-event-trigger">
<title>Triggers on Events</title>
<para>
<application>PL/pgSQL</application> can be used to define
<link linkend="event-triggers">event triggers</link>.
<productname>PostgreSQL</productname> requires that a function that
is to be called as an event trigger must be declared as a function with
no arguments and a return type of <literal>event_trigger</literal>.
</para>
<para>
When a <application>PL/pgSQL</application> function is called as an
event trigger, several special variables are created automatically
in the top-level block. They are:
<variablelist>
<varlistentry id="plpgsql-event-trigger-tg-event">
<term><varname>TG_EVENT</varname> <type>text</type></term>
<listitem>
<para>
event the trigger is fired for.
</para>
</listitem>
</varlistentry>
<varlistentry id="plpgsql-event-trigger-tg-tag">
<term><varname>TG_TAG</varname> <type>text</type></term>
<listitem>
<para>
command tag for which the trigger is fired.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
<xref linkend="plpgsql-event-trigger-example"/> shows an example of an
event trigger function in <application>PL/pgSQL</application>.
</para>
<example id="plpgsql-event-trigger-example">
<title>A <application>PL/pgSQL</application> Event Trigger Function</title>
<para>
This example trigger simply raises a <literal>NOTICE</literal> message
each time a supported command is executed.
</para>
<programlisting>
CREATE OR REPLACE FUNCTION snitch() RETURNS event_trigger AS $$
BEGIN
RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="plpgsql-implementation">
<title><application>PL/pgSQL</application> under the Hood</title>
<para>
This section discusses some implementation details that are
frequently important for <application>PL/pgSQL</application> users to know.
</para>
<sect2 id="plpgsql-var-subst">
<title>Variable Substitution</title>
<para>
SQL statements and expressions within a <application>PL/pgSQL</application> function
can refer to variables and parameters of the function. Behind the scenes,
<application>PL/pgSQL</application> substitutes query parameters for such references.
Query parameters will only be substituted in places where they are
syntactically permissible. As an extreme case, consider
this example of poor programming style:
<programlisting>
INSERT INTO foo (foo) VALUES (foo(foo));
</programlisting>
The first occurrence of <literal>foo</literal> must syntactically be a table
name, so it will not be substituted, even if the function has a variable
named <literal>foo</literal>. The second occurrence must be the name of a
column of that table, so it will not be substituted either. Likewise
the third occurrence must be a function name, so it also will not be
substituted for. Only the last occurrence is a candidate to be a
reference to a variable of the <application>PL/pgSQL</application>
function.
</para>
<para>
Another way to understand this is that variable substitution can only
insert data values into an SQL command; it cannot dynamically change which
database objects are referenced by the command. (If you want to do
that, you must build a command string