40.3. Триггерные функции событий на языке C
В этом разделе описываются низкоуровневые детали интерфейса для событийных триггерных функций. Эта информация необходима только при разработке событийных триггерных функций событий на языке C. При использовании языка более высокого уровня эти детали не видны. В большинстве случаев стоит рассмотреть возможность использования процедурного языка, прежде чем начать разрабатывать событийные триггеры на C. В документации по каждому процедурному языку объясняется, как создавать событийные триггеры на этом языке.
Триггерные функции событий должны использовать «version 1» интерфейса диспетчера функций.
Когда функция вызывается диспетчером триггеров событий, ей не передаются обычные аргументы, но передаётся указатель «context», ссылающийся на структуру EventTriggerData
. Функции на C могут проверить вызваны ли они диспетчером триггеров событий или нет выполнив макрос:
CALLED_AS_EVENT_TRIGGER(fcinfo)
который разворачивается в:
EventTriggerData
Если возвращается истина, то fcinfo->context
можно безопасно привести к типу EventTriggerData *
и использовать указатель на структуру EventTriggerData
. Функция не должна изменять структуру EventTriggerData
или любые данные, которые на неё указывают.
struct EventTriggerData
определена в commands/event_trigger.h
:
typedef struct EventTriggerData { NodeTag type; const char *event; /* имя события */ Node *parsetree; /* дерево разбора */ const char *tag; /* тег команды */ } EventTriggerData;
со следующими членами структуры:
type
Всегда
T_EventTriggerData
.event
Описывает событие, для которого вызывается функция. Возможные значения:
"ddl_command_start"
,"ddl_command_end"
,"sql_drop"
,"table_rewrite"
. Суть этих событий описывается в Разделе 40.1.parsetree
Указатель на дерево разбора команды. Детали можно посмотреть в исходном коде Postgres Pro. Структура дерева разбора может быть изменена без предупреждений.
tag
Тег команды, для которой сработал триггер события. Например
"CREATE FUNCTION"
.
Функция триггера события должна возвращать указатель NULL
(но не SQL значение null, то есть не нужно устанавливать isNull
в истину).