40.1. 事件触发器行为总览

只要与一个事件触发器相关的事件在事件触发器所在的数据库中发生, 该事件触发器就会被引发。当前支持的事件是 ddl_command_startddl_command_endtable_rewritesql_drop。未来的发行版 中可能会增加对更多事件的支持。

ddl_command_start事件就在CREATEALTERDROPSECURITY LABELCOMMENTGRANT或者REVOKE 命令的执行之前发生。在事件触发器引发前不会做受影响对象是否存在的检查。 不过,一个例外是,这个事件不会为目标是共享对象 — 数据库、角色 以及表空间 — 的 DDL 命令发生,也不会为目标是事件触发器的 DDL 命令发生。事件触发器机制不支持这些对象类型。 ddl_command_start也会在SELECT INTO 命令的执行之前发生,因为这等价于 CREATE TABLE AS

ddl_command_end事件就在同一组命令的执行之后发生。为了 得到发生的DDL操作的更多细节,可以从 ddl_command_end事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 Section 10.29)。注意该触发器是在那些动作 已经发生之后(但是在事务提交前)引发,并且因此系统目录会被读作已更改。

sql_drop事件为任何删除数据库对象的操作在 ddl_command_end事件触发器之前发生。要列出已经被删除的 对象,可以从sql_drop事件触发器代码中使用集合返回函数 pg_event_trigger_dropped_objects()Section 10.29)。注意该触发器是在对象已经 从系统目录删除以后执行,因此不能再查看它们。

table_rewrite事件在表被命令ALTER TABLEALTER TYPE的某些动作重写之前发生。虽然其他控制语句(例如 CLUSTERVACUUM)也可以用来重 写表,但是它们不会触发table_rewrite事件。

不能在一个中止的事务中执行事件触发器(其他函数也一样)。因此,如果一个 DDL 命令出现错误失败,将不会执行任何相关的 ddl_command_end触发器。反过来,如果一个 ddl_command_start触发器出现错误失败,将不会引发进一步的 事件触发器,并且不会尝试执行该命令本身。类似地,如果一个 ddl_command_end触发器出现错误失败,DDL 命令的效果将被 回滚,就像其他包含事务中止的情况中那样。

Section 40.2中有事件触发器机制所支持的完整 命令列表。

事件触发器通过命令CREATE EVENT TRIGGER创建。为了 创建一个事件触发器,你必须首先创建一个有特殊返回类型 event_trigger的函数。这个函数不一定需要返回一个值, 该返回类型仅仅是作为一种信号表示该函数要被作为一个事件触发器调用。

如果对于一个特定的事件定义了多于一个事件触发器,它们将按照触发器名称 的字母表顺序被引发。

一个触发器定义也可以指定一个WHEN条件,这样事件触 发器(例如ddl_command_start触发器)就可以只对用户 希望介入的特定命令触发。这类触发器的通常用法是用于限制用户可能执行的 DDL 操作的范围。