37.1. Обзор поведения триггеров событий#

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-операций, которые пользователи могут выполнять.