Событийный триггер срабатывает при возникновении события, с которым он связан, в той базе данных, где он определен. В настоящее время поддерживаются только события
login,
ddl_command_start,
ddl_command_end,
table_rewrite
и sql_drop.
Поддержка дополнительных событий может быть добавлена в будущих версиях.
Событие login возникает при входе аутентифицированного пользователя в систему. Наличие ошибок в процедуре триггера для данного события может сделать невозможным успешный вход в систему. Подобные ошибки можно обойти путем установки параметра event_triggers в значение false
либо в строке подключения, либо в конфигурационном файле. В качестве альтернативы систему можно
перезапустить в однопользовательском режиме (так как в этом режиме событийные триггеры
отключены). См. postgres справочную
страницу для получения подробных сведений об использовании однопользовательского режима.
Событие login также будет срабатывать на резервных серверах.
Чтобы предотвратить потерю доступа к серверам, такие триггеры должны избегать
записи в базу данных при выполнении на резервном сервере.
Кроме того, рекомендуется избегать длительных запросов в
login событийных триггерах. Обратите внимание, что, например,
прерывание соединения в psql не приведет к отмене выполняемой операции login триггера.
Событие ddl_command_start событие происходит непосредственно перед выполнением команды CREATE, ALTER, DROP,
SECURITY LABEL,
COMMENT, GRANT или REVOKE
команды. Перед срабатыванием событийного триггера проверка существования целевого объекта не выполняется. Однако в качестве исключения данное событие не возникает при выполнении команд DDL для общих объектов (shared objects) — баз данных, ролей и табличных пространств
— а также для команд, относящихся к самим событийным триггерам. Механизм событийных триггеров не поддерживает указанные типы объектов.
ddl_command_start также происходит непосредственно перед выполнением команды
SELECT INTO , так как она эквивалентна команде
CREATE TABLE AS.
Событие ddl_command_end происходит сразу после выполнения того же набора команд. Для получения подробных сведений о выполненных операциях DDL
следует использовать функцию
pg_event_trigger_ddl_commands() из
ddl_command_end кода событийного триггера (см.
Раздел 2.6.30). Следует отметить, что событийный триггер срабатывает после выполнения действий (но до фиксации транзакции), поэтому системные каталоги считываются как уже измененные.
Событие sql_drop событие происходит непосредственно перед
ddl_command_end событийный триггер для любой операции, удаляющей объекты базы данных. Для получения списка удаленных объектов используется функция, возвращающая набор строк, pg_event_trigger_dropped_objects() из
sql_drop кода событийного триггера (см.
Раздел 2.6.30). Следует учитывать, что триггер выполняется после удаления объектов из системных каталогов, поэтому их поиск более невозможен.
Событие table_rewrite событие происходит непосредственно перед перезаписью таблицы в результате выполнения команд ALTER TABLE и
ALTER TYPE. Несмотря на то, что для перезаписи таблицы могут использоваться и другие операторы, такие как CLUSTER и VACUUM,
the table_rewrite данное событие ими не инициируется.
Для получения OID перезаписанной таблицы используется функция
pg_event_trigger_table_rewrite_oid() (см.
Раздел 2.6.30). Для выяснения причин перезаписи следует использовать функцию
pg_event_trigger_table_rewrite_reason().
Событийные триггеры (как и другие функции) не могут быть выполнены в прерванной транзакции. Таким образом, если выполнение команды DDL завершается ошибкой, любые связанные с ней
ddl_command_end событийные триггеры не будут выполнены. И наоборот,
если ddl_command_start событийный триггер завершается ошибкой, последующие событийные триггеры не вызываются и попытка выполнения самой команды не предпринимается. Аналогично, если ddl_command_end событийный триггер завершается с ошибкой, результаты выполнения команды DDL будут отменены, как и в любом другом случае прерывания текущей транзакции.
Полный список команд, поддерживаемых механизмом событийных триггеров, приведен в Раздел 5.3.2.
Событийные триггеры создаются с помощью команды CREATE EVENT TRIGGER.
Для создания событийного триггера сначала должна быть создана функция со
специальным типом возвращаемого значения event_trigger. Данная функция
не должна (и не может) возвращать значение; тип возвращаемого значения служит лишь сигналом того, что функция вызывается в качестве событийного триггера.
Если для одного события определено несколько событийных триггеров, они будут срабатывать в алфавитном порядке их имен.
В определении триггера также может быть указано WHEN
условие, чтобы, например, ddl_command_start
триггер срабатывал только для определенных команд, которые необходимо перехватить. Обычно такие триггеры используются для ограничения набора DDL-операций, разрешенных пользователям.