37.1. Обзор поведения триггеров событий#
37.1. Обзор поведения триггеров событий #
Событийный триггер срабатывает каждый раз, когда происходит событие, с которым он связан, в базе данных, в которой он определен. В настоящее время поддерживаются только следующие события: ddl_command_start
, ddl_command_end
, table_rewrite
и sql_drop
. Поддержка дополнительных событий может быть добавлена в будущих версиях.
Событие ddl_command_start
происходит непосредственно перед выполнением команды CREATE
, ALTER
, DROP
, SECURITY LABEL
, COMMENT
, GRANT
или REVOKE
. Перед срабатыванием триггера события не выполняется проверка наличия или отсутствия затронутого объекта.
Однако, существует исключение: данное событие не происходит для команд DDL, направленных на общие объекты - базы данных, роли и табличные пространства имен, а также для команд, направленных на сами триггеры событий. Механизм триггеров событий не поддерживает эти типы объектов.
Событие ddl_command_start
также происходит непосредственно перед выполнением команды SELECT INTO
, так как она эквивалентна команде CREATE TABLE AS
.
Событие ddl_command_end
происходит сразу после выполнения этого же набора команд. Чтобы получить более подробную информацию о операциях DDL, которые произошли, используйте функцию, возвращающую набор значений pg_event_trigger_ddl_commands()
из кода триггера события ddl_command_end
(см. Раздел 9.29). Обратите внимание, что триггер срабатывает после выполнения действий (но перед коммитом транзакции), поэтому системные каталоги можно читать уже измененными.
Событие sql_drop
происходит непосредственно перед срабатыванием триггера ddl_command_end
для любой операции, удаляющей объекты базы данных. Чтобы получить список удаленных объектов, используйте множественно возвращающую функцию pg_event_trigger_dropped_objects()
из кода триггера события sql_drop
(см. Раздел 9.29). Обратите внимание, что триггер выполняется после удаления объектов из системных каталогов, поэтому невозможно получить информацию о них.
Событие table_rewrite
происходит непосредственно перед тем, как таблица будет переписана в результате некоторых действий команд ALTER TABLE
и ALTER TYPE
. Хотя другие управляющие операторы, такие как CLUSTER
и VACUUM
, также могут переписывать таблицу, событие table_rewrite
ими не вызывается. Чтобы найти OID таблицы, которая была переписана, используйте функцию pg_event_trigger_table_rewrite_oid()
(см. Раздел 9.29). Чтобы узнать причину(ы) переписывания, используйте функцию pg_event_trigger_table_rewrite_reason()
.
Триггеры событий (как и другие функции) не могут быть выполнены в аннулированной транзакции. Таким образом, если команда DDL завершается с ошибкой, триггеры ddl_command_end
не будут выполнены. Напротив, если триггер ddl_command_start
завершается с ошибкой, дальнейшие триггеры событий не будут запущены, и попытка выполнить саму команду не будет предпринята. Аналогично, если триггер ddl_command_end
завершается с ошибкой, эффекты оператора DDL будут отменены, как и в любом другом случае, когда транзакция прерывается.
Для полного списка команд, поддерживаемых механизмом триггеров событий, см. Раздел 37.2.
Создание триггеров событий выполняется с помощью команды CREATE EVENT TRIGGER.
Для создания триггера событий необходимо сначала создать функцию с особым типом возвращаемого значения event_trigger
. Эта функция не обязана (и не может) возвращать значение; тип возвращаемого значения служит только сигналом о том, что функция должна быть вызвана как триггер событий.
Если для определенного события определено более одного триггера, они будут запускаться в алфавитном порядке по имени триггера.
Определение триггера также может указывать условие WHEN
,
чтобы, например, триггер ddl_command_start
мог быть запущен только для определенных команд, которые пользователь хочет перехватить. Обычное использование таких триггеров - ограничение диапазона DDL-операций, которые пользователи могут выполнять.