*tgnewtable;
} Trigger;
</programlisting>
where <structfield>tgname</structfield> is the trigger's name,
<structfield>tgnargs</structfield> is the number of arguments in
<structfield>tgargs</structfield>, and <structfield>tgargs</structfield> is an array of
pointers to the arguments specified in the <command>CREATE
TRIGGER</command> statement. The other members are for internal use
only.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tg_trigslot</structfield></term>
<listitem>
<para>
The slot containing <structfield>tg_trigtuple</structfield>,
or a <symbol>NULL</symbol> pointer if there is no such tuple.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tg_newslot</structfield></term>
<listitem>
<para>
The slot containing <structfield>tg_newtuple</structfield>,
or a <symbol>NULL</symbol> pointer if there is no such tuple.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tg_oldtable</structfield></term>
<listitem>
<para>
A pointer to a structure of type <structname>Tuplestorestate</structname>
containing zero or more rows in the format specified by
<structfield>tg_relation</structfield>, or a <symbol>NULL</symbol> pointer
if there is no <literal>OLD TABLE</literal> transition relation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tg_newtable</structfield></term>
<listitem>
<para>
A pointer to a structure of type <structname>Tuplestorestate</structname>
containing zero or more rows in the format specified by
<structfield>tg_relation</structfield>, or a <symbol>NULL</symbol> pointer
if there is no <literal>NEW TABLE</literal> transition relation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tg_updatedcols</structfield></term>
<listitem>
<para>
For <literal>UPDATE</literal> triggers, a bitmap set indicating the
columns that were updated by the triggering command. Generic trigger
functions can use this to optimize actions by not having to deal with
columns that were not changed.
</para>
<para>
As an example, to determine whether a column with attribute number
<varname>attnum</varname> (1-based) is a member of this bitmap set,
call <literal>bms_is_member(attnum -
FirstLowInvalidHeapAttributeNumber,
trigdata->tg_updatedcols))</literal>.
</para>
<para>
For triggers other than <literal>UPDATE</literal> triggers, this will
be <symbol>NULL</symbol>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
To allow queries issued through SPI to reference transition tables, see
<xref linkend="spi-spi-register-trigger-data"/>.
</para>
<para>
A trigger function must return either a
<structname>HeapTuple</structname> pointer or a <symbol>NULL</symbol> pointer
(<emphasis>not</emphasis> an SQL null value, that is, do not set <parameter>isNull</parameter> true).
Be careful to return either
<structfield>tg_trigtuple</structfield> or <structfield>tg_newtuple</structfield>,
as appropriate, if you don't want to modify the row being operated on.
</para>
</sect1>
<sect1 id="trigger-example">
<title>A Complete Trigger Example</title>
<para>
Here is a very simple example of a trigger function written in C.
(Examples of triggers written in procedural languages can be found
in the documentation of the procedural languages.)
</para>
<para>
The function <function>trigf</function> reports the number of rows in the
table <structname>ttest</structname> and skips the