diff options
author | Vadim B. Mikheev <vadim4o@yahoo.com> | 1997-09-01 07:59:06 +0000 |
---|---|---|
committer | Vadim B. Mikheev <vadim4o@yahoo.com> | 1997-09-01 07:59:06 +0000 |
commit | 8c798538b8d81a5ada0d83e7bcd3923891b58d79 (patch) | |
tree | d93e64747aad7178fb268065e54a92c877222dc5 /src/backend/commands/trigger.c | |
parent | c2efeafe9c824399d7b03f87dbb6217eb8729d04 (diff) | |
download | postgresql-8c798538b8d81a5ada0d83e7bcd3923891b58d79.tar.gz postgresql-8c798538b8d81a5ada0d83e7bcd3923891b58d79.zip |
BEFORE/AFTER ROW INSERT triggers startup from CopyFrom()
RelationBuildTriggers() & FreeTriggerDesc() in trigger.c
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r-- | src/backend/commands/trigger.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index a4b5647e02a..2c07e49f21e 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -5,13 +5,24 @@ * *------------------------------------------------------------------------- */ +#include <string.h> #include "postgres.h" #include "nodes/parsenodes.h" #include "commands/trigger.h" +#include "catalog/catname.h" +#include "catalog/indexing.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_language.h" #include "catalog/pg_trigger.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "storage/bufmgr.h" #include "utils/builtins.h" +void RelationBuildTriggers (Relation relation); +void FreeTriggerDesc (Relation relation); + void CreateTrigger (CreateTrigStmt *stmt) { @@ -25,3 +36,248 @@ DropTrigger (DropTrigStmt *stmt) return; } + +void +RelationBuildTriggers (Relation relation) +{ + TriggerDesc *trigdesc = (TriggerDesc *) palloc (sizeof (TriggerDesc)); + int ntrigs = relation->rd_rel->reltriggers; + Trigger *triggers = NULL; + Trigger *build; + Relation tgrel; + Form_pg_trigger pg_trigger; + Relation irel; + ScanKeyData skey; + HeapTuple tuple; + IndexScanDesc sd; + RetrieveIndexResult indexRes; + Buffer buffer; + ItemPointer iptr; + struct varlena *val; + bool isnull; + int found; + + memset (trigdesc, 0, sizeof (TriggerDesc)); + + ScanKeyEntryInitialize(&skey, + (bits16)0x0, + (AttrNumber)1, + (RegProcedure)ObjectIdEqualRegProcedure, + ObjectIdGetDatum(relation->rd_id)); + + tgrel = heap_openr(TriggerRelationName); + irel = index_openr(TriggerRelidIndex); + sd = index_beginscan(irel, false, 1, &skey); + + for (found = 0; ; ) + { + indexRes = index_getnext(sd, ForwardScanDirection); + if (!indexRes) + break; + + iptr = &indexRes->heap_iptr; + tuple = heap_fetch(tgrel, NowTimeQual, iptr, &buffer); + pfree(indexRes); + if (!HeapTupleIsValid(tuple)) + continue; + if ( found == ntrigs ) + elog (WARN, "RelationBuildTriggers: unexpected record found for rel %.*s", + NAMEDATALEN, relation->rd_rel->relname.data); + + pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple); + + if ( triggers == NULL ) + triggers = (Trigger *) palloc (sizeof (Trigger)); + else + triggers = (Trigger *) repalloc (triggers, (found + 1) * sizeof (Trigger)); + build = &(triggers[found]); + + build->tgname = nameout (&(pg_trigger->tgname)); + build->tgfunc = nameout (&(pg_trigger->tgfunc)); + build->tglang = pg_trigger->tglang; + if ( build->tglang != ClanguageId ) + elog (WARN, "RelationBuildTriggers: unsupported language %u for trigger %s of rel %.*s", + build->tglang, build->tgname, NAMEDATALEN, relation->rd_rel->relname.data); + build->tgtype = pg_trigger->tgtype; + build->tgnargs = pg_trigger->tgnargs; + memcpy (build->tgattr, &(pg_trigger->tgattr), 8 * sizeof (int16)); + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_trigger_tgtext, + tgrel->rd_att, &isnull); + if ( isnull ) + elog (WARN, "RelationBuildTriggers: tgtext IS NULL for rel %.*s", + NAMEDATALEN, relation->rd_rel->relname.data); + build->tgtext = byteaout (val); + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_trigger_tgargs, + tgrel->rd_att, &isnull); + if ( isnull ) + elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s", + NAMEDATALEN, relation->rd_rel->relname.data); + if ( build->tgnargs > 0 ) + { + char *p; + int i; + + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_trigger_tgargs, + tgrel->rd_att, &isnull); + if ( isnull ) + elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s", + NAMEDATALEN, relation->rd_rel->relname.data); + p = (char *) VARDATA (val); + build->tgargs = (char**) palloc (build->tgnargs * sizeof (char*)); + for (i = 0; i < build->tgnargs; i++) + { + build->tgargs[i] = (char*) palloc (strlen (p) + 1); + strcpy (build->tgargs[i], p); + p += strlen (p) + 1; + } + } + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_trigger_tgwhen, + tgrel->rd_att, &isnull); + if ( !isnull ) + build->tgwhen = textout (val); + else + build->tgwhen = NULL; + + found++; + ReleaseBuffer(buffer); + } + + if ( found < ntrigs ) + elog (WARN, "RelationBuildTriggers: %d record not found for rel %.*s", + ntrigs - found, + NAMEDATALEN, relation->rd_rel->relname.data); + + index_endscan (sd); + pfree (sd); + index_close (irel); + heap_close (tgrel); + + /* Build trigdesc */ + trigdesc->triggers = triggers; + for (found = 0; found < ntrigs; found++) + { + uint16 *n; + Trigger ***t, ***tp; + + build = &(triggers[found]); + + if ( TRIGGER_FOR_ROW (build->tgtype) ) /* Is ROW/STATEMENT trigger */ + { + if ( TRIGGER_FOR_BEFORE (build->tgtype) ) + { + n = trigdesc->n_before_row; + t = trigdesc->tg_before_row; + } + else + { + n = trigdesc->n_after_row; + t = trigdesc->tg_after_row; + } + } + else /* STATEMENT (NI) */ + { + if ( TRIGGER_FOR_BEFORE (build->tgtype) ) + { + n = trigdesc->n_before_statement; + t = trigdesc->tg_before_statement; + } + else + { + n = trigdesc->n_after_statement; + t = trigdesc->tg_after_statement; + } + } + + if ( TRIGGER_FOR_INSERT (build->tgtype) ) + { + tp = &(t[TRIGGER_ACTION_INSERT]); + if ( *tp == NULL ) + *tp = (Trigger **) palloc (sizeof (Trigger *)); + else + *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_ACTION_INSERT] + 1) * + sizeof (Trigger *)); + (*tp)[n[TRIGGER_ACTION_INSERT]] = build; + (n[TRIGGER_ACTION_INSERT])++; + } + + if ( TRIGGER_FOR_DELETE (build->tgtype) ) + { + tp = &(t[TRIGGER_ACTION_DELETE]); + if ( *tp == NULL ) + *tp = (Trigger **) palloc (sizeof (Trigger *)); + else + *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_ACTION_DELETE] + 1) * + sizeof (Trigger *)); + (*tp)[n[TRIGGER_ACTION_DELETE]] = build; + (n[TRIGGER_ACTION_DELETE])++; + } + + if ( TRIGGER_FOR_UPDATE (build->tgtype) ) + { + tp = &(t[TRIGGER_ACTION_UPDATE]); + if ( *tp == NULL ) + *tp = (Trigger **) palloc (sizeof (Trigger *)); + else + *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_ACTION_UPDATE] + 1) * + sizeof (Trigger *)); + (*tp)[n[TRIGGER_ACTION_UPDATE]] = build; + (n[TRIGGER_ACTION_UPDATE])++; + } + } + + relation->trigdesc = trigdesc; + +} + +void +FreeTriggerDesc (Relation relation) +{ + + return; +} + +HeapTuple +ExecBRInsertTriggers (Relation rel, HeapTuple tuple) +{ + + return (tuple); +} + +void +ExecARInsertTriggers (Relation rel, HeapTuple tuple) +{ + + return; +} + +bool +ExecBRDeleteTriggers (Relation rel, ItemPointer tupleid) +{ + + return (true); +} + +void +ExecARDeleteTriggers (Relation rel, ItemPointer tupleid) +{ + + return; +} + +HeapTuple +ExecBRUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple) +{ + + return (tuple); +} + +void +ExecARUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple) +{ + + return; +} |