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

40.4. 完全なイベントトリガの例 #

<title>A Complete Event Trigger Example</title>

Here is a very simple example of an event trigger function written in C. (Examples of triggers written in procedural languages can be found in the documentation of the procedural languages.) C言語で作成したイベントトリガ関数に関するとても簡単な例をここに示します(手続き言語で作成したトリガの例は、その手続き言語の文書に記載されています)。

The function <function>noddl</function> raises an exception each time it is called. The event trigger definition associated the function with the <literal>ddl_command_start</literal> event. The effect is that all DDL commands (with the exceptions mentioned in <xref linkend="event-trigger-definition"/>) are prevented from running. noddl関数は、呼ばれるたびに例外を発生させます。 このイベントトリガは、この関数とddl_command_startイベントを関連づけます。 そのため、(40.1で言及した例外はありますが例外を含む)すべてのDDLコマンドは、実行できません。

This is the source code of the trigger function: 以下がトリガ関数のソースコードです。

#include "postgres.h"
#include "commands/event_trigger.h"


PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(noddl);

Datum
noddl(PG_FUNCTION_ARGS)
{
    EventTriggerData *trigdata;


    if (!CALLED_AS_EVENT_TRIGGER(fcinfo))  /* internal error */

    if (!CALLED_AS_EVENT_TRIGGER(fcinfo))  /* 内部エラー */
        elog(ERROR, "not fired by event trigger manager");

    trigdata = (EventTriggerData *) fcinfo->context;

    ereport(ERROR,
            (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
             errmsg("command \"%s\" denied",
                    GetCommandTagName(trigdata->tag))));

    PG_RETURN_NULL();
}

After you have compiled the source code (see <xref linkend="dfunc"/>), declare the function and the triggers: ソースコードをコンパイル(38.10.5を参照してください)した後に、以下の様に関数とトリガを宣言します。

CREATE FUNCTION noddl() RETURNS event_trigger
    AS 'noddl' LANGUAGE C;

CREATE EVENT TRIGGER noddl ON ddl_command_start
    EXECUTE FUNCTION noddl();

Now you can test the operation of the trigger: これで、トリガの操作を確認することができます。

=# \dy
                     List of event triggers
 Name  |       Event       | Owner | Enabled | Function | Tags
-------+-------------------+-------+---------+----------+------
 noddl | ddl_command_start | dim   | enabled | noddl    |
(1 row)

=# CREATE TABLE foo(id serial);
ERROR:  command "CREATE TABLE" denied

In this situation, in order to be able to run some DDL commands when you need to do so, you have to either drop the event trigger or disable it. It can be convenient to disable the trigger for only the duration of a transaction: この状況では、DDLコマンドを必要なときに実行できるようにするには、このイベントトリガを削除するか、無効化しなければなりません。 以下のように、トランザクションの期間中だけトリガを無効化するのが、便利かもしれません。

BEGIN;
ALTER EVENT TRIGGER noddl DISABLE;
CREATE TABLE foo (id serial);
ALTER EVENT TRIGGER noddl ENABLE;
COMMIT;

(Recall that DDL commands on event triggers themselves are not affected by event triggers.) (イベントトリガ自体が関係するDDLコマンドは、イベントトリガの影響を受けないことを思い出してください。)