Documentation PostgreSQL 7.4.29 | ||||
---|---|---|---|---|
Précédent | Arrière rapide | Chapitre 35. Déclencheurs (triggers) | Avance rapide | Suivant |
Cette section décrit les détails de bas niveau de l'interface d'une fonction déclencheur. Ces informations ne sont nécessaires que lors de l'écriture d'une fonction déclencheur en C. Si vous utilisez un langage de plus haut niveau, ces détails sont gérés pour vous. La documentation de chaque langage procédural explique comment écrire un déclencheur dans ce langage.
Les fonctions déclencheurs doivent utiliser la << version 1 >> de l'interface du gestionnaire de fonctions.
Quand une fonction est appelée par le gestionnaire de déclencheur, elle ne reçoit aucun argument classique, mais un pointeur de << contexte >> pointant sur une structure TriggerData. Les fonctions C peuvent vérifier si elles sont appelées par le gestionnaire de déclencheurs ou pas en exécutant la macro
CALLED_AS_TRIGGER(fcinfo)
qui se décompose en
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
Si elle retourne la valeur vraie, alors il est bon de convertir fcinfo->context en type TriggerData * et de faire usage de la structure pointée TriggerData. La fonction ne doit pas modifier la structure TriggerData ou une donnée quelconque vers laquelle elle pointe.
struct TriggerData est définie dans commands/trigger.h :
typedef struct TriggerData { NodeTag type; TriggerEvent tg_event; Relation tg_relation; HeapTuple tg_trigtuple; HeapTuple tg_newtuple; Trigger *tg_trigger; } TriggerData;
où les membres sont définis comme suit :
Toujours T_TriggerData.
Décrit l'événement pour lequel la fonction est appelée. Vous pouvez utiliser les macros suivantes pour examiner tg_event :
Renvoie vrai si le déclencheur est lancé avant l'opération.
Renvoie vrai si le déclencheur est lancé après l'opération.
Renvoie vrai si le déclencheur est lancé pour un évènement de bas niveau.
Renvoie vrai si le déclencheur est lancé pour un évènement de niveau expression.
Retourne vrai si le déclencheur est lancé par une commande INSERT.
Retourne vrai si le déclencheur est lancé par une commande UPDATE.
Retourne vrai si le déclencheur est lancé par une commande DELETE.
Un pointeur vers une structure décrivant la relation pour laquelle le déclencheur est lancé. Voir utils/rel.h pour les détails sur cette structure. Les choses les plus intéressantes sont tg_relation->rd_att (descripteur de nuplets de la relation) et tg_relation->rd_rel->relname (nom de la relation ; le type n'est pas char* mais NameData; utilisez SPI_getrelname(tg_relation) pour obtenir un char* si vous avez besoin d'une copie du nom).
Un pointeur vers la ligne pour laquelle le déclencheur a été lancé. Il s'agit de la ligne étant insérée, mise à jour ou effacée. Si ce déclencheur a été lancé pour une commande INSERT ou DELETE, c'est ce que la fonction doit retourner si vous ne voulez pas remplacer la ligne par une ligne différente (dans le cas d'un INSERT) ou sauter l'opération.
Un pointeur vers la nouvelle version de la ligne, si le déclencheur a été lancé pour un UPDATE et NULL si c'est pour un INSERT ou un DELETE. C'est ce que devez faire retourner de la fonction si l'évènement est un UPDATE et que vous ne voulez pas remplacer cette ligne par une ligne différente ou bien sauter l'opération.
Un pointeur vers une structure de type Trigger, définie dans 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;
où tgname est le nom du déclencheur, tgnargs est le nombre d'arguments dans tgargs et tgargs est un tableau de pointeurs vers les arguments spécifiés dans l'expression contenant la commande CREATE TRIGGER. Les autres membres ne sont destinés qu'à un usage interne.
Une fonction déclencheur doit retourner soit NULL soit un pointeur HeapTuple. Faites attention de renvoyer soit un tg_trigtuple soit un tg_newtuple, comme approprié, si vous ne voulez pas changer la ligne en cours de modification.
Précédent | Sommaire | Suivant |
Visibilité des modifications des données | Niveau supérieur | Un exemple complet |