doesn't have to be saved until end of statement.
</para>
<para>
If a trigger function executes SQL commands then these
commands might fire triggers again. This is known as cascading
triggers. There is no direct limitation on the number of cascade
levels. It is possible for cascades to cause a recursive invocation
of the same trigger; for example, an <command>INSERT</command>
trigger might execute a command that inserts an additional row
into the same table, causing the <command>INSERT</command> trigger
to be fired again. It is the trigger programmer's responsibility
to avoid infinite recursion in such scenarios.
</para>
<para>
If a foreign key constraint specifies referential actions (that
is, cascading updates or deletes), those actions are performed via
ordinary SQL <command>UPDATE</command> or <command>DELETE</command>
commands on the referencing table.
In particular, any triggers that exist on the referencing table
will be fired for those changes. If such a trigger modifies or
blocks the effect of one of these commands, the end result could
be to break referential integrity. It is the trigger programmer's
responsibility to avoid that.
</para>
<para>
<indexterm>
<primary>trigger</primary>
<secondary>arguments for trigger functions</secondary>
</indexterm>
When a trigger is being defined, arguments can be specified for
it. The purpose of including arguments in the
trigger definition is to allow different triggers with similar
requirements to call the same function. As an example, there
could be a generalized trigger function that takes as its
arguments two column names and puts the current user in one and
the current time stamp in the other. Properly written, this
trigger function would be independent of the specific table it is
triggering on. So the same function could be used for
<command>INSERT</command> events on any table with suitable
columns, to automatically track creation of records in a
transaction table for example. It could also be used to track
last-update events if defined as an <command>UPDATE</command>
trigger.
</para>
<para>
Each programming language that supports triggers has its own method
for making the trigger input data available to the trigger function.
This input data includes the type of trigger event (e.g.,
<command>INSERT</command> or <command>UPDATE</command>) as well as any
arguments that were listed in <command>CREATE TRIGGER</command>.
For a row-level trigger, the input data also includes the
<varname>NEW</varname> row for <command>INSERT</command> and
<command>UPDATE</command> triggers, and/or the <varname>OLD</varname> row
for <command>UPDATE</command> and <command>DELETE</command> triggers.
</para>
<para>
By default, statement-level triggers do not have any way to examine the
individual row(s) modified by the statement. But an <literal>AFTER
STATEMENT</literal> trigger can request that <firstterm>transition tables</firstterm>
be created to make the sets of affected rows available to the trigger.
<literal>AFTER ROW</literal> triggers can also request transition tables, so
that they can see the total changes in the table as well as the change in
the individual row they are currently being fired for. The method for
examining the transition tables again depends on the programming language
that is being used, but the typical approach is to make the transition
tables act like read-only temporary tables that can be accessed by SQL
commands issued within the trigger function.
</para>
</sect1>
<sect1 id="trigger-datachanges">
<title>Visibility of Data Changes</title>
<para>
If you execute SQL commands in your trigger function, and these
commands access the table that the trigger is for, then
you need to be