バージョンごとのドキュメント一覧

37.3. Cによるトリガ関数の作成 #

<title>Writing Trigger Functions in C</title>

This section describes the low-level details of the interface to a trigger function. This information is only needed when writing trigger functions in C. If you are using a higher-level language then these details are handled for you. In most cases you should consider using a procedural language before writing your triggers in C. The documentation of each procedural language explains how to write a trigger in that language. 本節ではトリガ関数とのインタフェースについて低レベルな詳細を説明します。 この情報はC言語でトリガ関数を作成する時にのみ必要です。 高レベルな言語で作成すれば、こうした詳細は代わりに扱ってもらえます。 たいていの場合、Cでトリガを作成する前に手続き言語を使用することを検討すべきです。 各手続き言語の文書で、その言語を使用したトリガの作成方法を説明します。

Trigger functions must use the <quote>version 1</quote> function manager interface. トリガ関数はversion 1関数マネージャインタフェースを使わなくてはいけません。

When a function is called by the trigger manager, it is not passed any normal arguments, but it is passed a <quote>context</quote> pointer pointing to a <structname>TriggerData</structname> structure. C functions can check whether they were called from the trigger manager or not by executing the macro: 関数がトリガマネージャから呼び出される時は、通常の引数が渡されるのではなく、TriggerData構造体を指すcontextポインタが渡されます。 C関数は、トリガマネージャから呼び出されたのかどうかを以下のマクロを実行することで検査することができます。

CALLED_AS_TRIGGER(fcinfo)

which expands to: これは以下に展開されます。

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

If this returns true, then it is safe to cast <literal>fcinfo-&gt;context</literal> to type <literal>TriggerData *</literal> and make use of the pointed-to <structname>TriggerData</structname> structure. The function must <emphasis>not</emphasis> alter the <structname>TriggerData</structname> structure or any of the data it points to. もしこれが真を返す場合、fcinfo->contextTriggerData *型にキャストし、指されたTriggerData構造体を使用することは安全です。 その関数は、TriggerData構造体やそれが指すどのようなデータも変更してはいけません

<structname>struct TriggerData</structname> is defined in <filename>commands/trigger.h</filename>: struct TriggerDatacommands/trigger.hの中で定義されています。

typedef struct TriggerData
{
    NodeTag          type;
    TriggerEvent     tg_event;
    Relation         tg_relation;
    HeapTuple        tg_trigtuple;
    HeapTuple        tg_newtuple;
    Trigger         *tg_trigger;
    TupleTableSlot  *tg_trigslot;
    TupleTableSlot  *tg_newslot;
    Tuplestorestate *tg_oldtable;
    Tuplestorestate *tg_newtable;
    const Bitmapset *tg_updatedcols;
} TriggerData;

where the members are defined as follows: メンバは下記のように定義されています。

type

Always <literal>T_TriggerData</literal>. 常にT_TriggerDataです。

tg_event

Describes the event for which the function is called. You can use the following macros to examine <literal>tg_event</literal>: その関数が呼び出されたイベントを記述します。 tg_eventを調べるためには下記のマクロを使うことができます。

TRIGGER_FIRED_BEFORE(tg_event)

Returns true if the trigger fired before the operation. トリガが操作の前に(before)発行された場合真を返します。

TRIGGER_FIRED_AFTER(tg_event)

Returns true if the trigger fired after the operation. トリガが操作の後に(after)発行された場合真を返します。

TRIGGER_FIRED_INSTEAD(tg_event)

Returns true if the trigger fired instead of the operation. トリガがINSTEAD OFで発行された場合真を返します。

TRIGGER_FIRED_FOR_ROW(tg_event)

Returns true if the trigger fired for a row-level event. トリガが行レベルのイベントで発行された場合真を返します。

TRIGGER_FIRED_FOR_STATEMENT(tg_event)

Returns true if the trigger fired for a statement-level event. トリガが文レベルのイベントで発行された場合真を返します。

TRIGGER_FIRED_BY_INSERT(tg_event)

Returns true if the trigger was fired by an <command>INSERT</command> command. トリガがINSERTコマンドで発行された場合真を返します。

TRIGGER_FIRED_BY_UPDATE(tg_event)

Returns true if the trigger was fired by an <command>UPDATE</command> command. トリガがUPDATEコマンドで発行された場合真を返します。

TRIGGER_FIRED_BY_DELETE(tg_event)

Returns true if the trigger was fired by a <command>DELETE</command> command. トリガがDELETEコマンドで発行された場合真を返します。

TRIGGER_FIRED_BY_TRUNCATE(tg_event)

Returns true if the trigger was fired by a <command>TRUNCATE</command> command. トリガがTRUNCATEコマンドで発行された場合真を返します。

tg_relation

A pointer to a structure describing the relation that the trigger fired for. Look at <filename>utils/rel.h</filename> for details about this structure. The most interesting things are <literal>tg_relation-&gt;rd_att</literal> (descriptor of the relation tuples) and <literal>tg_relation-&gt;rd_rel-&gt;relname</literal> (relation name; the type is not <type>char*</type> but <type>NameData</type>; use <literal>SPI_getrelname(tg_relation)</literal> to get a <type>char*</type> if you need a copy of the name). トリガの発行元のリレーションを記述する構造体へのポインタです。 この構造体についての詳細は、utils/rel.hを参照してください。 最も興味深いのは、tg_relation->rd_att(リレーションタプルの記述子)とtg_relation->rd_rel->relnameです(リレーション名、これはchar*ではなくNameDataです。 名前のコピーが必要な場合は、char*を得るためにSPI_getrelname(tg_relation)を使用してください)。

tg_trigtuple

A pointer to the row for which the trigger was fired. This is the row being inserted, updated, or deleted. If this trigger was fired for an <command>INSERT</command> or <command>DELETE</command> then this is what you should return from the function if you don't want to replace the row with a different one (in the case of <command>INSERT</command>) or skip the operation. For triggers on foreign tables, values of system columns herein are unspecified. トリガが発行された行へのポインタです。 これは挿入される、削除される、あるいは更新される行です。 もしINSERT/DELETEでこのトリガが発行された時、この行を別のもので置き換えたくない(INSERTの場合)場合や、その操作を飛ばしたくない場合は、これをこの関数から返してください。 外部テーブルのトリガに対しては、システム列の値はここでは指定されません。

tg_newtuple

A pointer to the new version of the row, if the trigger was fired for an <command>UPDATE</command>, and <symbol>NULL</symbol> if it is for an <command>INSERT</command> or a <command>DELETE</command>. This is what you have to return from the function if the event is an <command>UPDATE</command> and you don't want to replace this row by a different one or skip the operation. For triggers on foreign tables, values of system columns herein are unspecified. トリガがUPDATEで発行された場合は、行の新しいバージョンへのポインタです。 INSERTもしくはDELETEの場合は、NULLです。 UPDATEイベントの時、この行を別のもので置き換えたくない場合や操作を飛ばしたくない場合は、これをこの関数から返してください。 外部テーブルのトリガに対しては、システム列の値はここでは指定されません。

tg_trigger

A pointer to a structure of type <structname>Trigger</structname>, defined in <filename>utils/reltrigger.h</filename>: 以下のようにutils/reltrigger.hで定義された、Trigger構造体へのポインタです。

typedef struct Trigger
{
    Oid         tgoid;
    char       *tgname;
    Oid         tgfoid;
    int16       tgtype;
    char        tgenabled;
    bool        tgisinternal;
    bool        tgisclone;
    Oid         tgconstrrelid;
    Oid         tgconstrindid;
    Oid         tgconstraint;
    bool        tgdeferrable;
    bool        tginitdeferred;
    int16       tgnargs;
    int16       tgnattr;
    int16      *tgattr;
    char      **tgargs;
    char       *tgqual;
    char       *tgoldtable;
    char       *tgnewtable;
} Trigger;

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. ここで、tgnameがトリガの名前、tgnargstgargs内の引数の数、tgargsCREATE TRIGGER文で指定された引数へのポインタの配列です。 他のメンバは内部でのみ使用されます。

tg_trigslot

The slot containing <structfield>tg_trigtuple</structfield>, or a <symbol>NULL</symbol> pointer if there is no such tuple. tg_trigtupleを含むスロット、またはタプルが存在しない場合はNULLポインタです。

tg_newslot

The slot containing <structfield>tg_newtuple</structfield>, or a <symbol>NULL</symbol> pointer if there is no such tuple. tg_newtupleを含むスロット、またはタプルが存在しない場合はNULLポインタです。

tg_oldtable

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. tg_relationで指定するフォーマットの0以上の行を含むTuplestorestate型の構造体へのポインタです。 OLD TABLE遷移リレーションが存在しない場合はNULLポインタです。

tg_newtable

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. tg_relationで指定するフォーマットの0以上の行を含むTuplestorestate型の構造体へのポインタです。 NEW TABLE遷移リレーションが存在しない場合はNULLポインタです。

tg_updatedcols

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. UPDATEトリガに対しては、トリガコマンドにより更新された列を示すビットマップ集合です。 汎用のトリガ関数はこれを使って、変更されていない列を扱わないことで動作を最適化できます。

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>. 例として、属性番号attnum(1始まり)の列がこのビットマップ集合のメンバであるかどうか判定するために、bms_is_member(attnum - FirstLowInvalidHeapAttributeNumber, trigdata->tg_updatedcols))を呼び出します。

For triggers other than <literal>UPDATE</literal> triggers, this will be <symbol>NULL</symbol>. UPDATEトリガ以外のトリガに対しては、これはNULLになります。

To allow queries issued through SPI to reference transition tables, see <xref linkend="spi-spi-register-trigger-data"/>. SPIを使って遷移テーブルを参照するクエリを発行する方法については、SPI_register_trigger_dataを参照してください。

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. トリガ関数はHeapTupleポインタもしくはNULLポインタ(SQLのNULLではありません。 したがって、isNullは真にはなりません)のどちらかを返さなければなりません。 操作対象の行を変更したくない場合は、注意して、tg_trigtupletg_newtupleの適切な方を返してください。