Documentazione di PostgreSQL 9.0 > Programmazione del server > Trigger > Scrivere funzioni trigger in C
PrecedenteVisibilità del cambiamento dei datiUn esempio completo di triggerSuccessivo

36.3. Scrivere funzioni trigger in C

Questa sezione descrive i dettagli a basso livello dell'interfaccia verso una funzione trigger. Queste informazioni sono necessarie solo quando si scrive una funzione trigger in C. Se si sta usando un linguaggio di più alto livello allora questi dettagli sono gestiti per te. Nella maggior parte dei casi di dovrebbe prenderre in considerazione l'utilizzo di un linguaggio procedurale prima di scrivere un trigger in C. La documentazione di ogni linguaggio procedurale spiega come scrivere un trigger in quel linguaggio.

Le funzioni trigger devono usare l'interfaccia di gestione delle funzioni «version 1».

Quando una funzione viene chiamata dal gestore dei trigger, non viene passato nessun normale argomento, ma viene passato un puntatore «context» che punta a una struttura TriggerData. Le funzioni C possono controllare se sono state chiamate dal gestore dei trigger o no eseguendo la macro:

CALLED_AS_TRIGGER(fcinfo)

che si espande in:

((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))

Se questo restituisce true, allora è sicuro eseguire un cast fcinfo->context al tipo TriggerData * ed usare la struttura TriggerData. La funzione non deve modificate la struttura TriggerData o qualsiasi dato a cui punta.

La struttura TriggerData è definita in 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;

dove i membri sono definiti come segue:

type

Sempre T_TriggerData.

tg_event

Descrive l'evento per il quale la funzione è chiamata. Si possono usare le seguenti macro per esaminare tg_event:

TRIGGER_FIRED_BEFORE(tg_event)

Restituisce true se il trigger è avvenuto prima dell'operazione.

TRIGGER_FIRED_AFTER(tg_event)

Restituisce true se il trigger è avvenuto dopo l'operazione.

TRIGGER_FIRED_FOR_ROW(tg_event)

Restituisce true se il trigger è avvenuto per un evento a livello di riga.

TRIGGER_FIRED_FOR_STATEMENT(tg_event)

Restituisce true se il trigger è avvenuto per un evento a livello di istruzione.

TRIGGER_FIRED_BY_INSERT(tg_event)

Restituisce true se il trigger è stato attivato da un comando INSERT.

TRIGGER_FIRED_BY_UPDATE(tg_event)

Restituisce true se il trigger è stato attivato da un comando UPDATE.

TRIGGER_FIRED_BY_DELETE(tg_event)

Restituisce true se il trigger è stato atttivato da un comando DELETE.

TRIGGER_FIRED_BY_TRUNCATE(tg_event)

Restituisce true se il trigger è stato attivato da un comando TRUNCATE.

tg_relation

Un puntatore a una struttura che descrive la relazione per la quale il trigger si è attivato. Si veda utils/rel.h per dettagli su questa struttura. Le cose più interessanti sono tg_relation->rd_att (descrittore delle tuple della relazione) e tg_relation->rd_rel->relname (nome della relazione; il tipo non è char* ma NameData; usare SPI_getrelname(tg_relation) per ottenere un char* se si ha bisogno della copia del nome).

tg_trigtuple

Un puntatore alla riga per la quale è stato attivato il trigger. Questa è la riga che è stata inserita, aggiornata o cancellata. Se questo trigger è stato attivato con un INSERT o DELETE allora questo è quello che si dovrebbe restituire dalla funzione se non si vuole sostituire la riga con una diversa (nel caso di INSERT) o saltare l'operazione.

tg_newtuple

Un puntatore alla nuova versione della riga, se il trigger è stato attivato per un UPDATE, e NULL se è per un INSERT o un DELETE. Questo è quello che si deve restituire dalla funzione se l'evento è un UPDATE e non si vuole sostituire questa riga con una diversa o saltare l'operazione.

tg_trigger

Un puntatore a una struttura di tipo Trigger, definita in utils/rel.h:

typedef struct Trigger
{
    Oid         tgoid;
    char       *tgname;
    Oid         tgfoid;
    int16       tgtype;
    bool        tgenabled;
    bool        tgisinternal;
    Oid         tgconstrrelid;
    Oid         tgconstrindid;
    Oid         tgconstraint;
    bool        tgdeferrable;
    bool        tginitdeferred;
    int16       tgnargs;
    int16       tgnattr;
    int16      *tgattr;
    char      **tgargs;
    char       *tgqual;
} Trigger;

dove tgname è il nome del trigger, tgnargs è il numero di argomenti in tgargs, e tgargs è un array di puntatori agli argomenti specificati nell'istruzione CREATE TRIGGER. Gli altri membri sono solo per uso interno.

tg_trigtuplebuf

Il buffer contenente tg_trigtuple, o InvalidBuffer non c'è quella tupla o non è salvata in un buffer disco.

tg_newtuplebuf

Il buffer contenente tg_newtuple, o InvalidBuffer se non c'è quella tupla o non è salvata in un buffer disco.

Una funzione trigger deve restituire o un puntatore HeapTuple o un puntatore NULL (non un valore null SQL, cioè, non imposta isNull a true). Fare attenzione a restituire o tg_trigtuple o tg_newtuple, nel modo giusto, se non si vuole modificare la riga sulla quale si è operato.

Documentazione di PostgreSQL 9.0 > Programmazione del server > Trigger > Scrivere funzioni trigger in C
PrecedenteVisibilità del cambiamento dei datiUn esempio completo di triggerSuccessivo