Esta seção descreve os detalhes de baixo nível da interface com a função de gatilho. Estas informações somente são necessárias para se escrever funções de gatilho em C. Se estiver sendo utilizada uma linguagem de nível mais alto, então estes detalhes são tratados para você. A documentação de cada linguagem procedural explica como escrever gatilhos nesta linguagem.
A função de gatilho deve utilizar a interface de gerência de função "versão 1".
Quando uma função é chamada pelo gerenciador de gatilho não é passado nenhum argumento normal, mas é passado um ponteiro de "contexto" apontando para a estrutura TriggerData. As funções em C podem verificar se foram chamadas pelo gerenciador de gatilhos executando a macro
CALLED_AS_TRIGGER(fcinfo)
que expande para
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
Se retornar verdade, então é seguro converter fcinfo->context no tipo TriggerData * e fazer uso da estrutura TriggerData apontada. A função não deve alterar a estrutura de TriggerData ou de qualquer dado apontado por esta.
A struct TriggerData está definida em commands/trigger.h:
typedef struct TriggerData { NodeTag type; TriggerEvent tg_event; Relation tg_relation; HeapTuple tg_trigtuple; HeapTuple tg_newtuple; Trigger *tg_trigger; Buffer tg_trigtuplebuf; Buffer tg_newtuplebuf; } TriggerData;
onde os membros estão definidos conforme mostrado abaixo:
Sempre T_TriggerData.
Descreve o evento para o qual a função foi chamada. Podem ser utilizadas as seguintes macros para examinar tg_event:
Retorna verdade se o gatilho disparou antes da operação.
Retorna verdade se o gatilho disparou depois da operação.
Retorna verdade se o gatilho disparou para um evento no nível-de-linha.
Retorna verdade se o gatilho disparou para um evento no nível-de-instrução.
Retorna verdade se o gatilho foi disparado por um comando INSERT.
Retorna verdade se o gatilho foi disparado por um comando UPDATE.
Retorna verdade se o gatilho foi disparado por um comando DELETE.
Um ponteiro para a estrutura que descreve a relação para a qual o gatilho foi disparado. Os detalhes sobre esta estrutura devem ser procurados no arquivo utils/rel.h. Os itens mais interessantes são tg_relation->rd_att (descritor das tuplas da relação) e tg_relation->rd_rel->relname (nome da relação; o tipo não é char*, e sim NameData; deve ser utilizado SPI_getrelname(tg_relation) para obter char* se for necessário copiar o nome).
Ponteiro para a linha para a qual o gatilho foi disparado. Esta é a linha sendo inserida, atualizada ou excluída. Se este gatilho foi disparado por um INSERT ou DELETE, então é o que deve ser retornado pela função se não for desejado substituir a linha por outra diferente (no caso do INSERT) ou saltar a operação.
Ponteiro para a nova versão da linha, se o gatilho foi disparado por um UPDATE, ou NULL, se foi disparado por um INSERT ou DELETE. É o que deve ser retornado pela função se o evento for um UPDATE e não for desejado substituir a linha por outra diferente ou saltar a operação.
Um ponteiro para a estrutura do tipo Trigger, definida no arquivo utils/rel.h:
typedef struct Trigger { Oid tgoid; char *tgname; Oid tgfoid; int16 tgtype; bool tgenabled; bool tgisconstraint; Oid tgconstrrelid; bool tgdeferrable; bool tginitdeferred; int16 tgnargs; int16 tgattr[FUNC_MAX_ARGS]; char **tgargs; } Trigger;
onde tgname é o nome do gatilho, tgnargs é o número de argumentos em tgargs, e tgargs é uma matriz de ponteiros para os argumentos especificados na declaração CREATE TRIGGER. Os outros membros são para uso interno apenas.
Um buffer contendo tg_trigtuple, ou InvalidBuffer se a tupla não existir ou não estiver armazenada em um buffer de disco.
Um buffer contendo tg_newtuple, ou InvalidBuffer se a tupla não existir ou não estiver armazenada em um buffer de disco.
Uma função de gatilho deve retornar um ponteiro para HeapTuple ou um ponteiro NULL (não um valor SQL nulo, ou seja, não se deve definir isNull como verdade). Deve-se tomar o cuidado de retornar tg_trigtuple ou tg_newtuple, conforme seja apropriado, se não for desejado modificar a linha onde está sendo realizada a operação.