21.2. トリガマネージャとの関係

この節はトリガ関数のインタフェースの低レベルな詳細について 説明します。この情報はトリガ関数を C で書く場合にのみ必要に なります。もしもっと高レベルな関数言語を使っている場合は これらの問題はすでに解決されています。

Note: ここで説明されるインタフェースはPostgres 7.1 以降に当てはまります。それ以前のバージョンでは TriggerData ポインタはグローバル変数 CurrentTriggerData の中で渡されていました。

関数がトリガマネージャから呼び出されるときは、通常のどのような パラメータに渡されるのではなく TriggerData 構造体を指す "コンテクスト" ポインタに渡されます。C 関数はトリガマネージャ から呼び出されたのかどうかをマクロ CALLED_AS_TRIGGER(fcinfo)を実行することでチェック することができ、下記のようになります。

        ((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
    
もしこれが TRUE を返す場合、fcinfo->context を TriggerData *型にキャストし、TriggerData 構造体を指すものを利用することは安全です。その関数は TriggerData 構造体やそれが指すどのようなデータも変えては いけません

構造体 TriggerData は src/include/commands/trigger.h の中で 定義されています。

typedef struct TriggerData
{
    NodeTag       type;
    TriggerEvent  tg_event;
    Relation      tg_relation;
    HeapTuple     tg_trigtuple;
    HeapTuple     tg_newtuple;
    Trigger      *tg_trigger;
} TriggerData;
    
そこではメンバは下記のように定義されています。

type

もしこれがトリガイベントである場合、常に T_TriggerDataです。

tg_event

その関数が呼び出されたイベントを説明します。 tg_eventを調べるためには下記の マクロを使うことができます。

TRIGGER_FIRED_BEFORE(tg_event)

トリガが BEFORE を発行した場合 TRUE を返します。

TRIGGER_FIRED_AFTER(tg_event)

トリガが AFTER を発行した場合 TRUE を返します。

TRIGGER_FIRED_FOR_ROW(event)

トリガが行レベルのイベントを発行した場合 TRUE を返します。

TRIGGER_FIRED_FOR_STATEMENT(event)

トリガがステートメントレベルのイベントを発行した場合 TRUE を返します。

TRIGGER_FIRED_BY_INSERT(event)

トリガが INSERT に発行された場合 TRUE を返します。

TRIGGER_FIRED_BY_DELETE(event)

トリガが DELETE に発行された場合 TRUE を返します。

TRIGGER_FIRED_BY_UPDATE(event)

トリガが UPDATE に発行された場合 TRUE を返します。

tg_relation

トリガされたリレーションを説明する構造体へのポインタです。 この構造体についての詳細は src/include/utils/rel.h を 見て下さい。最も興味深いのは tg_relation->rd_att (リレーションタプル の記述子)と tg_relation->rd_rel->relname (リレーション名。これは char* ではなく NameData です。もし名前のコピーが必要な場合は char* を得るために SPI_getrelname(tg_relation)を使って下さい。)です。

tg_trigtuple

トリガが発行されたタプルへのポインタです。これは(もし INSERT なら) 挿入された、(もし DELETE なら)削除された、(もし UPDATE なら) 更新されたタプルです。もし INSERT/DELETE の場合、タプルを 別のもの (INSERT) で置き換えるか演算子を飛ばしたくなければ、 これをエグゼキュータに返して下さい。

tg_newtuple

もしこれが INSERT か DELETE のためで UPDATE か NULL ならば、 タプルの新しいバージョンのためのポインタです。もし UPDATE だった場合でべつのタプルで置き換えるか演算を飛ばしたく なければ、これをエグゼキュータに返して下さい。

tg_trigger

src/include/utils/rel.h で定義された構造体 Trigger への ポインタです。

typedef struct Trigger
{
    Oid         tgoid;
    char       *tgname;
    Oid         tgfoid;
    FmgrInfo    tgfunc;
    int16       tgtype;
    bool        tgenabled;
    bool        tgisconstraint;
    bool        tgdeferrable;
    bool        tginitdeferred;
    int16       tgnargs;
    int16       tgattr[FUNC_MAX_ARGS];
    char      **tgargs;
} Trigger;
	
ここでは tgname がトリガの名前、tgnargs が tgargs の中の引数の数、 tgargs は CREATE TRIGGER 文で指定された引数へのポインタの配列 です。他のメンバは内部使用のみです。