Триггер события срабатывает всякий раз, когда в базе данных, в которой он определён, происходит связанное с ним событие. В настоящий момент поддерживаются следующие события: login, ddl_command_start, ddl_command_end, table_rewrite и sql_drop. Поддержка дополнительных событий может быть добавлена в будущих выпусках.
Событие login происходит, когда аутентифицированный пользователь входит в систему. Любые ошибки в процедуре триггера для этого события могут помешать успешному входу в систему. Таких ошибок можно избежать, задав для параметра event_triggers значение false в строке подключения или файле конфигурации. Кроме того, можно перезапустить сервер в однопользовательском режиме (поскольку триггеры событий в этом режиме отключены). За дополнительными сведениями об однопользовательском режиме обратитесь к справке по postgres. Событийный триггер login также срабатывает на резервных серверах. Во избежание проблем с подключением к серверам, работающие на них триггеры login не должны ничего записывать в базу данных. Кроме того, рекомендуется избегать длительных запросов в событийных триггерах login. Обратите внимание, что отмена подключения в psql не отменит текущий триггер login.
Пример использования триггера события login приведён в Разделе 38.5.
Событие ddl_command_start происходит непосредственно перед выполнением команды DDL. В данном контексте командами DDL считаются:
CREATE
ALTER
DROP
COMMENT
GRANT
IMPORT FOREIGN SCHEMA
REINDEX
REFRESH MATERIALIZED VIEW
REVOKE
SECURITY LABEL
Событие ddl_command_start также происходит перед выполнением команды SELECT INTO, так как она равнозначна CREATE TABLE AS.
В качестве исключения это событие не срабатывает для команд DDL, направленных на общие объекты:
базы данных
роли (определения ролей и членство в ролях)
табличные пространства
права на параметры
ALTER SYSTEM
Оно также не срабатывает для команд, направленных на сами триггеры событий.
Проверка существования целевого объекта до срабатывания событийного триггера не выполняется.
Событие ddl_command_end происходит непосредственно после выполнения того же набора команд, что и для ddl_command_start. Чтобы получить дополнительную информацию об операциях DDL, повлёкших произошедшее событие, вызовите функцию pg_event_trigger_ddl_commands(), возвращающую множество, из кода обработчика события ddl_command_end (см. Раздел 9.30). Заметьте, что этот триггер срабатывает после того, как эти действия имели место (но до фиксации транзакции), так что в системных каталогах можно увидеть уже изменённое состояние.
Событие sql_drop происходит непосредственно перед событием ddl_command_end для любой операции, которая удаляет объекты базы данных. Обратите внимание, что кроме очевидных команд DROP некоторые команды ALTER также могут вызывать событие sql_drop.
Для получения списка удалённых объектов используйте возвращающую набор строк функцию pg_event_trigger_dropped_objects() в триггере события sql_drop (см. Раздел 9.30). Обратите внимание, что триггер выполняется после удаления объектов из таблиц системного каталога, поэтому их невозможно больше увидеть.
Событие table_rewrite происходит непосредственно перед тем, как таблица будет перезаписана в результате определённых действий команд ALTER TABLE и ALTER TYPE. Хотя перезапись таблицы может быть вызвана и другими управляющими операторами, в частности CLUSTER и VACUUM, событие table_rewrite для них не вызывается. Найти OID таблицы, которая была перезаписана, можно с помощью функции pg_event_trigger_table_rewrite_oid(). Чтобы узнать причину (причины) перезаписи, используйте функцию pg_event_trigger_table_rewrite_reason() (см. Раздел 9.30).
Триггеры событий (как и прочие функции) не могут выполняться в прерванной транзакции. Поэтому, если команда DDL завершается ошибкой, соответствующие триггеры ddl_command_end не сработают. И наоборот, если триггер ddl_command_end завершился с ошибкой, последующие триггеры событий не сработают, так же как и сама команда не будет выполняться. Похожим образом, если триггер ddl_command_end завершится ошибкой, действие команды DDL будет отменено, как это происходит при возникновении ошибки внутри транзакции.
Для создания триггера события используется команда CREATE EVENT TRIGGER. Предварительно нужно создать функцию, со специальным возвращаемым типом event_trigger. Данная функция не обязана возвращать значение (и может не возвращать). Возвращаемый тип служит лишь указанием на то, что функция будет вызываться из триггера события.
Если есть несколько триггеров на одно и то же событие, то они будут вызываться в алфавитном порядке по имени триггера.
В определении триггера можно использовать условие WHEN, чтобы, например, триггер ddl_command_start срабатывал только для отдельных команд, которые нужно перехватить. Триггеры событий часто используются для ограничения диапазона DDL-команд, доступных пользователям.