Home Explore Blog CI



postgresql

13th chunk of `doc/src/sgml/trigger.sgml`
fb302a9ed2d937d7d5fabebbe99ebddae76c8efde5709a600000000100000b53
 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 actual operation if the
    command attempts to insert a null value into the column
    <structfield>x</structfield>. (So the trigger acts as a not-null constraint but
    doesn't abort the transaction.)
   </para>

   <para>
    First, the table definition:
<programlisting>
CREATE TABLE ttest (
    x integer
);
</programlisting>
   </para>

   <para>
    This is the source code of the trigger function:
<programlisting><![CDATA[
#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"       /* this is what you need to work with SPI */
#include "commands/trigger.h"   /* ... triggers ... */
#include "utils/rel.h"          /* ... and relations */

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(trigf);

Datum
trigf(PG_FUNCTION_ARGS)
{
    TriggerData *trigdata = (TriggerData *) fcinfo->context;
    TupleDesc   tupdesc;
    HeapTuple   rettuple;
    char       *when;
    bool        checknull = false;
    bool        isnull;
    int         ret, i;

    /* make sure it's called as a trigger at all */
    if (!CALLED_AS_TRIGGER(fcinfo))
        elog(ERROR, "trigf: not called by trigger manager");

    /* tuple to return to executor */
    if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
        rettuple = trigdata->tg_newtuple;
    else
        rettuple = trigdata->tg_trigtuple;

    /* check for null values */
    if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
        && TRIGGER_FIRED_BEFORE(trigdata->tg_event))
        checknull = true;

    if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
        when = "before";
    else
        when = "after ";

    tupdesc = trigdata->tg_relation->rd_att;

    /* connect to SPI manager */
    SPI_connect();

    /* get number of rows in table */
    ret = SPI_exec("SELECT count(*) FROM ttest", 0);

    if (ret < 0)
        elog(ERROR, "trigf (fired %s): SPI_exec returned %d", when, ret);

    /* count(*) returns int8, so be careful

Title: Trigger Function Example in C
Summary
This section provides a complete example of a trigger function written in C, which reports the number of rows in a table and prevents the insertion of null values into a specific column, and includes the table definition, trigger function source code, and explanations of how the function works with the SPI manager and handles different trigger events.