Chapter 13. Triggers

Table of Contents
トリガーの生成
トリガーマネージャとの関係
データ変更時の可視性

Postgres has various client interfaces such as Perl, Tcl, Python and C, as well as two Procedural Languages (PL). It is also possible to call C functions as trigger actions. Note that STATEMENT-level trigger events are not supported in the current version. You can currently specify BEFORE or AFTER on INSERT, DELETE or UPDATE of a tuple as a trigger event.

Postgres は 2 つの 手続き言語 ( PL )の他、Perl、Tcl、Python、 C といった各種のインタフェースを持っています。またトリガーアクショ ンとして C の関数を呼ぶこともできます。現バージョンでは、STATEMENT レベルのトリガーイベントはサポートされていませんので注意して下さい。 現在はタプルの INSERT、DELETE、UPDATEの前( BEFORE )または後( AFTER )をトリガーイベントとして指定できます。

トリガーの生成

If a trigger event occurs, the trigger manager (called by the Executor) initializes the global structure TriggerData *CurrentTriggerData (described below) and calls the trigger function to handle the event.

トリガーイベントが発生すると、(エグゼキュータによって呼び出され る)トリガーマネージャは(後述の)大域構造体 TriggerData *CurrentTriggerData を初期化し、そのイベントを扱うト リガー関数を呼び出します。

The trigger function must be created before the trigger is created as a function taking no arguments and returns opaque.

トリガーが生成される前に、トリガー関数は、引数をとらない、 opaque 型を返す関数として作成されていなければなりません。

The syntax for creating triggers is as follows:

   CREATE TRIGGER <trigger name> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
       ON <relation name> FOR EACH <ROW|STATEMENT>
       EXECUTE PROCEDURE <procedure name> (<function args>);

トリガーを生成するための構文は次の通りです。

   CREATE TRIGGER <トリガー名> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
       ON <リレーション名> FOR EACH <ROW|STATEMENT>
       EXECUTE PROCEDURE <プロシージャ名> (<関数の引数>);

The name of the trigger is used if you ever have to delete the trigger. It is used as an argument to the DROP TRIGGER command.

トリガー名は、トリガーを削除する必要になった時にも使われます。 DROP TRIGGER コマンドの引数として使われます。

The next word determines whether the function is called before or after the event.

次の単語は、関数がイベントが発生する前に呼ばれるのか後に呼ばれ るのかを決定します。

The next element of the command determines on what event(s) will trigger the function. Multiple events can be specified separated by OR.

次の要素は、どのコマンドのイベント(複数可)で関数を呼び出すか を決定します。複数のイベントを OR で区切って指定できます。

The relation name determines which table the event applies to.

リレーション名はどのテーブルにイベントを適用するかを決定します。

The FOR EACH statement determines whether the trigger is fired for each affected row or before (or after) the entire statement has completed.

FOR EACH 文はトリガーを行が影響を受ける度に発行するか、文全体が 終了する前(または後)に発行するかを決定します。

The procedure name is the C function called.

プロシージャ名は呼び出される C の関数を示します。

The args are passed to the function in the CurrentTriggerData structure. The purpose of passing arguments to the function is to allow different triggers with similar requirements to call the same function.

関数の引数は、関数に CurrentTriggerData 構造体の中に格納され て渡されます。引数を関数に渡す目的は、同一関数の呼び出しによ って要求仕様が似ている異なるトリガーを扱えるようにすることで す。

Also, function may be used for triggering different relations (these functions are named as "general trigger functions").

また、関数は異なるリレーションのトリガーに使うこともできます。 (こういった関数は "汎用トリガー関数" と呼ばれます。)

As example of using both features above, there could be a general function that takes as its arguments two field names and puts the current user in one and the current timestamp in the other. This allows triggers to be written on INSERT events to automatically track creation of records in a transaction table for example. It could also be used as a "last updated" function if used in an UPDATE event.

上記の両機能を使う例として、片方に現在のユーザを、もう片方に現 時刻を格納した 2 つのフィールドの名前を引数としてとる汎用関数が あります。例えば、この関数を INSERT イベント時に使用すれば、ト ランザクションテーブル内のレコードの作成を検出して、自動的に書 き込みを行なわせることができます。または、UPDATE イベント時に使 用すれば、"最終更新" 機能を行なわせることもできます。

Trigger functions return HeapTuple to the calling Executor. This is ignored for triggers fired after an INSERT, DELETE or UPDATE operation but it allows BEFORE triggers to: - return NULL to skip the operation for the current tuple (and so the tuple will not be inserted/updated/deleted); - return a pointer to another tuple (INSERT and UPDATE only) which will be inserted (as the new version of the updated tuple if UPDATE) instead of original tuple.

トリガー関数は呼び出したエグゼキュータに HeapTuple を返します。 これは INSERT、DELETE、UPDATE の後に発行されるトリガー( AFTER ) では無視されますが、BEFORE のトリガーでは、以下を行なうことがで きます。 - NULL を返して、現タプルへの操作をとばします。(そして、このタ プルの挿入、更新、削除は行なわれなくなります。) - 本来のタプルではなく他のタプルのポインタを返して、それを( UPDATE の場合は更新されたタプルの新しいバージョンとして)挿入 させます。( INSERT と UPDATE のみ)

Note, that there is no initialization performed by the CREATE TRIGGER handler. This will be changed in the future. Also, if more than one trigger is defined for the same event on the same relation, the order of trigger firing is unpredictable. This may be changed in the future.

CREATE TRIGGER ハンドラによって初期化は行なわれないことに注意 して下さい。このことは今後変更する予定です。また、同一リレーシ ョンの同一イベントに対して複数トリガーが定義された場合は、トリ ガーの発行順は予測できません。これも今後変更されるかもしれませ ん。

If a trigger function executes SQL-queries (using SPI) then these queries may fire triggers again. This is known as cascading triggers. There is no explicit limitation on the number of cascade levels.

トリガー関数が( SPI を使用して)SQL 問い合わせを処理する場合、こ れらの問い合わせがトリガーを再度発行することがあります。これはカス ケードされたトリガーと呼ばれます。カスケードの段数に明確な制限はあ りません。

If a trigger is fired by INSERT and inserts a new tuple in the same relation then this trigger will be fired again. Currently, there is nothing provided for synchronization (etc) of these cases but this may change. At the moment, there is function funny_dup17() in the regress tests which uses some techniques to stop recursion (cascading) on itself...

INSERT によって発行されたトリガーが同じリレーションに新しいタプル を挿入する場合、このトリガーが再度発行されます。現状、この場合の 同期(などの)機能は提供されていませんが、これも変更される可能性 があります。現段階では、レグレッションテストの中に、自身への再帰 (カスケーディング)を停止させるための数個のテクニックを使用した funny_dup17() という関数があります。