20.2. 与触发器管理器的交互 #
本节描述触发器函数接口的底层细节。只有用 C 编写触发器函数时才需要这些信息。如果你使用的是更高层次的函数语言,那么这些细节会替你处理。
注意
这里描述的接口适用于 PostgreSQL 7.1 及之后的版本。更早的版本通过一个全局变量 CurrentTriggerData 传递 TriggerData 指针。
当函数被触发器管理器调用时,它不会被传递任何普通参数,而是被传递一个指向 TriggerData 结构的“上下文”指针。C 函数可以通过执行宏
CALLED_AS_TRIGGER(fcinfo) 来检查自己是否是被触发器管理器调用的,该宏展开为
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
如果它返回 TRUE,那么就可以安全地把 fcinfo->context 转换为
TriggerData * 类型并使用所指向的
TriggerData 结构。该函数不得修改
TriggerData 结构或它指向的任何数据。
struct TriggerData 定义在 src/include/commands/trigger.h 中:
typedef struct TriggerData
{
NodeTag type;
TriggerEvent tg_event;
Relation tg_relation;
HeapTuple tg_trigtuple;
HeapTuple tg_newtuple;
Trigger *tg_trigger;
} TriggerData;其成员的含义如下:
- type
如果这是一个触发器事件,则总是
T_TriggerData。- tg_event
描述引发该函数调用的事件。你可以使用下列宏来检查
tg_event:- TRIGGER_FIRED_BEFORE(tg_event)
如果触发器在之前(BEFORE)触发则返回 TRUE。
- TRIGGER_FIRED_AFTER(tg_event)
如果触发器在之后(AFTER)触发则返回 TRUE。
- TRIGGER_FIRED_FOR_ROW(event)
如果触发器针对行(ROW)级事件触发则返回 TRUE。
- TRIGGER_FIRED_FOR_STATEMENT(event)
如果触发器针对语句(STATEMENT)级事件触发则返回 TRUE。
- TRIGGER_FIRED_BY_INSERT(event)
如果触发器由 INSERT 引发则返回 TRUE。
- TRIGGER_FIRED_BY_DELETE(event)
如果触发器由 DELETE 引发则返回 TRUE。
- TRIGGER_FIRED_BY_UPDATE(event)
如果触发器由 UPDATE 引发则返回 TRUE。
- tg_relation
一个指针,指向描述被触发关系的结构体。关于这个结构体的细节请参看 src/include/utils/rel.h。其中最令人感兴趣的是 tg_relation->rd_att(关系元组的描述符)和 tg_relation->rd_rel->relname(关系名。它不是 char*,而是 NameData。如果你需要名称的一个副本,可以使用 SPI_getrelname(tg_relation) 来获得 char*)。
- tg_trigtuple
一个指针,指向引发该触发器的元组。这就是正在被插入(INSERT)、删除(DELETE)或更新(UPDATE)的元组。如果是 INSERT/DELETE,那么当你不想(INSERT 的情形下)用另一个元组替换该元组或跳过该操作时,就应当把它返回给执行器。
- tg_newtuple
一个指针,指向元组的新版本(如果 UPDATE);如果是 INSERT 或 DELETE 则为 NULL。当事件是 UPDATE 而你不想用另一个元组替换该元组或跳过该操作时,就应当把它返回给执行器。
- tg_trigger
一个指针,指向 Trigger 结构,它定义在 src/include/utils/rel.h 中:
typedef struct Trigger { Oid tgoid; char *tgname; Oid tgfoid; int16 tgtype; bool tgenabled; bool tgisconstraint; bool tgdeferrable; bool tginitdeferred; int16 tgnargs; int16 tgattr[FUNC_MAX_ARGS]; char **tgargs; } Trigger;其中 tgname 是触发器的名称,tgnargs 是 tgargs 中参数的数量,tgargs 是一个指针数组,指向 CREATE TRIGGER 语句中指定的参数。其他成员仅供内部使用。