Interaction with the Trigger Manager

PostgreSQL 7.3.4 Documentation
Prev | Chapter 16. Triggers | Next

# 16.2. Interaction with the Trigger Manager

This section describes the low-level details of the interface to a trigger function. This information is only needed when writing a trigger function in C. If you are using a higher-level function language then these details are handled for you.

> Note: The interface described here applies for PostgreSQL 7.1 and later. Earlier versions passed the `TriggerData` pointer in a global variable CurrentTriggerData.

When a function is called by the trigger manager, it is not passed any normal parameters, but it is passed a "context" pointer pointing to a `TriggerData` structure. C functions can check whether they were called from the trigger manager or not by executing the macro CALLED_AS_TRIGGER(fcinfo), which expands to

    ((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))

If this returns true, then it is safe to cast fcinfo->context to type TriggerData * and make use of the pointed-to `TriggerData` structure. The function must not alter the `TriggerData` structure or any of the data it points to.

`struct TriggerData` is defined in `commands/trigger.h`:

    typedef struct TriggerData
    {
        NodeTag       type;
        TriggerEvent  tg_event;
        Relation      tg_relation;
        HeapTuple     tg_trigtuple;
        HeapTuple     tg_newtuple;
        Trigger      *tg_trigger;
    } TriggerData;

where the members are defined as follows:

`type`

  Always T_TriggerData if this is a trigger event.

`tg_event`

  describes the event for which the function is called. You may use the following macros to examine tg_event:

  TRIGGER_FIRED_BEFORE(tg_event)

    returns TRUE if trigger fired BEFORE.

  TRIGGER_FIRED_AFTER(tg_event)

    Returns TRUE if trigger fired AFTER.

  TRIGGER_FIRED_FOR_ROW(event)

    Returns TRUE if trigger fired for a ROW-level event.

  TRIGGER_FIRED_FOR_STATEMENT(event)

    Returns TRUE if trigger fired for STATEMENT-level event.

  TRIGGER_FIRED_BY_INSERT(event)

    Returns TRUE if trigger fired by INSERT.

  TRIGGER_FIRED_BY_DELETE(event)

    Returns TRUE if trigger fired by DELETE.

  TRIGGER_FIRED_BY_UPDATE(event)

    Returns TRUE if trigger fired by UPDATE.

`tg_relation`

  is a pointer to structure describing the triggered relation. Look at `utils/rel.h` for details about this structure. The most interesting things are tg_relation->rd_att (descriptor of the relation tuples) and tg_relation->rd_rel->relname (relation's name. This is not `char*`, but `NameData`. Use SPI_getrelname(tg_relation) to get `char*` if you need a copy of the name).

`tg_trigtuple`

  is a pointer to the tuple for which the trigger is fired. This is the tuple being inserted (if INSERT), deleted (if DELETE) or updated (if UPDATE). If INSERT/DELETE then this is what you are to return to Executor if you don't want to replace tuple with another one (INSERT) or skip the operation.

`tg_newtuple`

  is a pointer to the new version of tuple if UPDATE and `NULL` if this is for an INSERT or a DELETE. This is what you are to return to Executor if UPDATE and you don't want to replace this tuple with another one or skip the operation.

`tg_trigger`

  is pointer to structure `Trigger` defined in `utils/rel.h`:

      typedef struct Trigger
      {
          Oid         tgoid;
          char       *tgname;
          Oid         tgfoid;
          int16       tgtype;
          bool        tgenabled;
          bool        tgisconstraint;
          Oid         tgconstrrelid;
          bool        tgdeferrable;
          bool        tginitdeferred;
          int16       tgnargs;
          int16       tgattr[FUNC_MAX_ARGS];
          char      **tgargs;
      } Trigger;

  where `tgname` is the trigger's name, `tgnargs` is number of arguments in `tgargs`, `tgargs` is an array of pointers to the arguments specified in the CREATE TRIGGER statement. Other members are for internal use only.

Prev | Home | Next
Triggers | Up | Visibility of Data Changes