39.1. 事件触发行为概述

每当与事件关联的事件在定义它的数据库中发生时,就会触发事件触发器。当前,仅支持的事件是ddl_command_startddl_command_endtable_rewritesql_drop。在将来的版本中可能会添加对其他事件的支持。

ddl_command_start事件恰好在执行CREATEALTERDROPSECURITY LABELCOMMENTGRANTREVOKE命令之前发生。在触发事件触发器之前,不检查受影响的对象是否存在。但是,作为 exception,针对共享对象(数据库,角色和表空间)的 DDL 命令或针对事件触发器自身的命令不会发生此事件。事件触发机制不支持这些对象类型。 ddl_command_start也恰好在执行SELECT INTO命令之前发生,因为它等效于CREATE TABLE AS

ddl_command_end事件在执行同一组命令后立即发生。要获取有关发生的 DDL 操作的更多详细信息,请使用ddl_command_end事件触发代码中的设置返回函数pg_event_trigger_ddl_commands()(请参见Section 9.28)。请注意,触发器在操作发生后(但在事务提交之前)触发,因此可以将系统目录读取为已更改。

对于任何删除数据库对象的操作,事件恰好在ddl_command_end事件触发器之前发生。要列出已删除的对象,请使用sql_drop事件触发代码中的设置返回函数pg_event_trigger_dropped_objects()(请参见Section 9.28)。请注意,触发器是在从系统目录中删除对象之后执行的,因此无法再查找它们。

table_rewrite事件发生在命令ALTER TABLEALTER TYPE的某些操作重写表之前。尽管可以使用其他控制语句来重写表,例如CLUSTERVACUUM,但是table_rewrite事件不是由它们触发的。

事件触发器(与其他函数一样)无法在异常终止的事务中执行。因此,如果 DDL 命令由于错误而失败,则将不执行任何关联的ddl_command_end触发器。相反,如果ddl_command_start触发器因错误而失败,则不会触发其他事件触发器,也不会尝试执行命令本身。同样,如果ddl_command_end触发器因错误而失败,则 DDL 语句的效果将被回滚,就像在其他任何情况下包含事务中止的情况一样。

有关事件触发机制支持的命令的完整列表,请参见Section 39.2

使用命令创建事件触发创建事件触发器。为了创建事件触发器,您必须首先创建具有特殊返回类型event_trigger的函数。该函数不需要(也可以不)返回值;返回类型仅用作将函数作为事件触发器调用的 signal。

如果为一个特定事件定义了多个事件触发器,则它们将按触发器名称的字母 Sequences 触发。

触发器定义也可以指定WHEN条件,以便例如仅针对用户希望拦截的特定命令触发ddl_command_start触发器。这种触发器的常见用法是限制用户可以执行的 DDL 操作的范围。