Перейти к основному содержимому

Пример триггера события

примечание

Эта страница переведена при помощи нейросети GigaChat.

Вот очень простой пример функции триггера событий, написанной на языке C. (Примеры триггеров, написанных на процедурных языках, можно найти в документации к этим языкам.)

Функция noddl вызывает исключение каждый раз при ее вызове. Определение триггера события связывает функцию с событием ddl_command_start. Эффект заключается в том, что все команды DDL (за исключением упомянутых в разделе «Обзор поведения триггеров событий») не могут быть выполнены.

Исходный код функции триггера:

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


PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(noddl);

Datum
noddl(PG_FUNCTION_ARGS)
{
EventTriggerData *trigdata;

if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
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();
}

После того, как скомпилировали исходный код (см. раздел «Компиляция и компоновка динамически загружаемых функций»), объявите функцию и триггеры:

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

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

Теперь можно протестировать работу триггера:

=# \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

В такой ситуации, чтобы иметь возможность выполнять некоторые DDL-команды в нужный момент, нужно либо отказаться от триггера событий, либо отключить его. Может быть удобно отключать триггер только на время транзакции:

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

(Помните, что команды DDL для триггеров событий сами по себе не затрагиваются триггерами событий.)