aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r--src/backend/commands/trigger.c1050
1 files changed, 528 insertions, 522 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2919df473fd..53ab1838cfe 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* trigger.c--
- * PostgreSQL TRIGGERs support code.
+ * PostgreSQL TRIGGERs support code.
*
*-------------------------------------------------------------------------
*/
@@ -32,581 +32,587 @@
#include "utils/syscache.h"
#endif
-TriggerData *CurrentTriggerData = NULL;
+TriggerData *CurrentTriggerData = NULL;
-void RelationBuildTriggers (Relation relation);
-void FreeTriggerDesc (Relation relation);
+void RelationBuildTriggers(Relation relation);
+void FreeTriggerDesc(Relation relation);
-static void DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger);
+static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger);
-extern void fmgr_info(Oid procedureId, func_ptr *function, int *nargs);
+extern void fmgr_info(Oid procedureId, func_ptr * function, int *nargs);
extern GlobalMemory CacheCxt;
void
-CreateTrigger (CreateTrigStmt *stmt)
+CreateTrigger(CreateTrigStmt * stmt)
{
- int16 tgtype;
- int16 tgattr[8] = {0};
- Datum values[Natts_pg_trigger];
- char nulls[Natts_pg_trigger];
- Relation rel;
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- Relation relrdesc;
- HeapTuple tuple;
- ItemPointerData oldTID;
- Relation idescs[Num_pg_trigger_indices];
- Relation ridescs[Num_pg_class_indices];
- MemoryContext oldcxt;
- Oid fargtypes[8];
- int found = 0;
- int i;
-
- if ( IsSystemRelationName (stmt->relname) )
- elog(WARN, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
+ int16 tgtype;
+ int16 tgattr[8] = {0};
+ Datum values[Natts_pg_trigger];
+ char nulls[Natts_pg_trigger];
+ Relation rel;
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ Relation relrdesc;
+ HeapTuple tuple;
+ ItemPointerData oldTID;
+ Relation idescs[Num_pg_trigger_indices];
+ Relation ridescs[Num_pg_class_indices];
+ MemoryContext oldcxt;
+ Oid fargtypes[8];
+ int found = 0;
+ int i;
+
+ if (IsSystemRelationName(stmt->relname))
+ elog(WARN, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
#ifndef NO_SECURITY
- if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
- elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
+ elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
-
- rel = heap_openr (stmt->relname);
- if ( !RelationIsValid (rel) )
- elog (WARN, "CreateTrigger: there is no relation %s", stmt->relname);
-
- RelationSetLockForWrite (rel);
-
- TRIGGER_CLEAR_TYPE (tgtype);
- if ( stmt->before )
- TRIGGER_SETT_BEFORE (tgtype);
- if ( stmt->row )
- TRIGGER_SETT_ROW (tgtype);
- for (i = 0; i < 3 && stmt->actions[i]; i++)
- {
- switch ( stmt->actions[i] )
- {
- case 'i':
- if ( TRIGGER_FOR_INSERT (tgtype) )
- elog (WARN, "CreateTrigger: double INSERT event specified");
- TRIGGER_SETT_INSERT (tgtype);
- break;
- case 'd':
- if ( TRIGGER_FOR_DELETE (tgtype) )
- elog (WARN, "CreateTrigger: double DELETE event specified");
- TRIGGER_SETT_DELETE (tgtype);
- break;
- case 'u':
- if ( TRIGGER_FOR_UPDATE (tgtype) )
- elog (WARN, "CreateTrigger: double UPDATE event specified");
- TRIGGER_SETT_UPDATE (tgtype);
- break;
- default:
- elog (WARN, "CreateTrigger: unknown event specified");
- break;
- }
- }
-
- /* Scan pg_trigger */
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
- while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
- {
- Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
- if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
- elog (WARN, "CreateTrigger: trigger %s already defined on relation %s",
- stmt->trigname, stmt->relname);
- else
- found++;
- }
- heap_endscan (tgscan);
-
- memset (fargtypes, 0, 8 * sizeof(Oid));
- tuple = SearchSysCacheTuple (PRONAME,
- PointerGetDatum (stmt->funcname),
- 0, PointerGetDatum (fargtypes), 0);
- if ( !HeapTupleIsValid (tuple) ||
- ((Form_pg_proc)GETSTRUCT(tuple))->prorettype != 0 ||
- ((Form_pg_proc)GETSTRUCT(tuple))->pronargs != 0 )
- elog (WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
-
- if ( ((Form_pg_proc)GETSTRUCT(tuple))->prolang != ClanguageId )
- elog (WARN, "CreateTrigger: only C functions are supported");
-
- memset (nulls, ' ', Natts_pg_trigger * sizeof (char));
-
- values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum (rel->rd_id);
- values[Anum_pg_trigger_tgname - 1] = NameGetDatum (namein (stmt->trigname));
- values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum (tuple->t_oid);
- values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum (tgtype);
- if ( stmt->args )
- {
- List *le;
- char *args;
- int16 nargs = length (stmt->args);
- int len = 0;
-
- foreach (le, stmt->args)
- {
- char *ar = (char *) lfirst (le);
- len += strlen (ar) + 4;
- }
- args = (char *) palloc (len + 1);
- args[0] = 0;
- foreach (le, stmt->args)
- sprintf (args + strlen (args), "%s\\000", (char *)lfirst (le));
- values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (nargs);
- values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (args));
- }
- else
- {
- values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (0);
- values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (""));
- }
- values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum (tgattr);
-
- tuple = heap_formtuple (tgrel->rd_att, values, nulls);
- heap_insert (tgrel, tuple);
- CatalogOpenIndices (Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
- CatalogIndexInsert (idescs, Num_pg_trigger_indices, tgrel, tuple);
- CatalogCloseIndices (Num_pg_trigger_indices, idescs);
- pfree (tuple);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
-
- pfree (DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
- pfree (DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
-
- /* update pg_class */
- relrdesc = heap_openr (RelationRelationName);
- tuple = ClassNameIndexScan (relrdesc, stmt->relname);
- if ( !PointerIsValid (tuple) )
- {
+
+ rel = heap_openr(stmt->relname);
+ if (!RelationIsValid(rel))
+ elog(WARN, "CreateTrigger: there is no relation %s", stmt->relname);
+
+ RelationSetLockForWrite(rel);
+
+ TRIGGER_CLEAR_TYPE(tgtype);
+ if (stmt->before)
+ TRIGGER_SETT_BEFORE(tgtype);
+ if (stmt->row)
+ TRIGGER_SETT_ROW(tgtype);
+ for (i = 0; i < 3 && stmt->actions[i]; i++)
+ {
+ switch (stmt->actions[i])
+ {
+ case 'i':
+ if (TRIGGER_FOR_INSERT(tgtype))
+ elog(WARN, "CreateTrigger: double INSERT event specified");
+ TRIGGER_SETT_INSERT(tgtype);
+ break;
+ case 'd':
+ if (TRIGGER_FOR_DELETE(tgtype))
+ elog(WARN, "CreateTrigger: double DELETE event specified");
+ TRIGGER_SETT_DELETE(tgtype);
+ break;
+ case 'u':
+ if (TRIGGER_FOR_UPDATE(tgtype))
+ elog(WARN, "CreateTrigger: double UPDATE event specified");
+ TRIGGER_SETT_UPDATE(tgtype);
+ break;
+ default:
+ elog(WARN, "CreateTrigger: unknown event specified");
+ break;
+ }
+ }
+
+ /* Scan pg_trigger */
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+ while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
+ elog(WARN, "CreateTrigger: trigger %s already defined on relation %s",
+ stmt->trigname, stmt->relname);
+ else
+ found++;
+ }
+ heap_endscan(tgscan);
+
+ memset(fargtypes, 0, 8 * sizeof(Oid));
+ tuple = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(stmt->funcname),
+ 0, PointerGetDatum(fargtypes), 0);
+ if (!HeapTupleIsValid(tuple) ||
+ ((Form_pg_proc) GETSTRUCT(tuple))->prorettype != 0 ||
+ ((Form_pg_proc) GETSTRUCT(tuple))->pronargs != 0)
+ elog(WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
+
+ if (((Form_pg_proc) GETSTRUCT(tuple))->prolang != ClanguageId)
+ elog(WARN, "CreateTrigger: only C functions are supported");
+
+ memset(nulls, ' ', Natts_pg_trigger * sizeof(char));
+
+ values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(rel->rd_id);
+ values[Anum_pg_trigger_tgname - 1] = NameGetDatum(namein(stmt->trigname));
+ values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(tuple->t_oid);
+ values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
+ if (stmt->args)
+ {
+ List *le;
+ char *args;
+ int16 nargs = length(stmt->args);
+ int len = 0;
+
+ foreach(le, stmt->args)
+ {
+ char *ar = (char *) lfirst(le);
+
+ len += strlen(ar) + 4;
+ }
+ args = (char *) palloc(len + 1);
+ args[0] = 0;
+ foreach(le, stmt->args)
+ sprintf(args + strlen(args), "%s\\000", (char *) lfirst(le));
+ values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
+ values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(args));
+ }
+ else
+ {
+ values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
+ values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(""));
+ }
+ values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
+
+ tuple = heap_formtuple(tgrel->rd_att, values, nulls);
+ heap_insert(tgrel, tuple);
+ CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
+ CatalogCloseIndices(Num_pg_trigger_indices, idescs);
+ pfree(tuple);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
+
+ pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
+ pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
+
+ /* update pg_class */
+ relrdesc = heap_openr(RelationRelationName);
+ tuple = ClassNameIndexScan(relrdesc, stmt->relname);
+ if (!PointerIsValid(tuple))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "CreateTrigger: relation %s not found in pg_class", stmt->relname);
+ }
+ ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
+ RelationInvalidateHeapTuple(relrdesc, tuple);
+ oldTID = tuple->t_ctid;
+ heap_replace(relrdesc, &oldTID, tuple);
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, ridescs);
+ pfree(tuple);
heap_close(relrdesc);
- elog(WARN, "CreateTrigger: relation %s not found in pg_class", stmt->relname);
- }
- ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
- RelationInvalidateHeapTuple (relrdesc, tuple);
- oldTID = tuple->t_ctid;
- heap_replace (relrdesc, &oldTID, tuple);
- CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
- CatalogCloseIndices (Num_pg_class_indices, ridescs);
- pfree(tuple);
- heap_close(relrdesc);
-
- CommandCounterIncrement ();
- oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
- FreeTriggerDesc (rel);
- rel->rd_rel->reltriggers = found + 1;
- RelationBuildTriggers (rel);
- MemoryContextSwitchTo (oldcxt);
- heap_close (rel);
- return;
+
+ CommandCounterIncrement();
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ FreeTriggerDesc(rel);
+ rel->rd_rel->reltriggers = found + 1;
+ RelationBuildTriggers(rel);
+ MemoryContextSwitchTo(oldcxt);
+ heap_close(rel);
+ return;
}
void
-DropTrigger (DropTrigStmt *stmt)
+DropTrigger(DropTrigStmt * stmt)
{
- Relation rel;
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- Relation relrdesc;
- HeapTuple tuple;
- ItemPointerData oldTID;
- Relation ridescs[Num_pg_class_indices];
- MemoryContext oldcxt;
- int found = 0;
- int tgfound = 0;
-
+ Relation rel;
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ Relation relrdesc;
+ HeapTuple tuple;
+ ItemPointerData oldTID;
+ Relation ridescs[Num_pg_class_indices];
+ MemoryContext oldcxt;
+ int found = 0;
+ int tgfound = 0;
+
#ifndef NO_SECURITY
- if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
- elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
+ elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
-
- rel = heap_openr (stmt->relname);
- if ( !RelationIsValid (rel) )
- elog (WARN, "DropTrigger: there is no relation %s", stmt->relname);
-
- RelationSetLockForWrite (rel);
-
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
- while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
- {
- Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
- if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
- {
- heap_delete (tgrel, &tuple->t_ctid);
- tgfound++;
- }
- else
- found++;
- }
- if ( tgfound == 0 )
- elog (WARN, "DropTrigger: there is no trigger %s on relation %s",
- stmt->trigname, stmt->relname);
- if ( tgfound > 1 )
- elog (NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
- tgfound, stmt->trigname, stmt->relname);
- heap_endscan (tgscan);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
-
- /* update pg_class */
- relrdesc = heap_openr (RelationRelationName);
- tuple = ClassNameIndexScan (relrdesc, stmt->relname);
- if ( !PointerIsValid (tuple) )
- {
+
+ rel = heap_openr(stmt->relname);
+ if (!RelationIsValid(rel))
+ elog(WARN, "DropTrigger: there is no relation %s", stmt->relname);
+
+ RelationSetLockForWrite(rel);
+
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+ while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
+ {
+ heap_delete(tgrel, &tuple->t_ctid);
+ tgfound++;
+ }
+ else
+ found++;
+ }
+ if (tgfound == 0)
+ elog(WARN, "DropTrigger: there is no trigger %s on relation %s",
+ stmt->trigname, stmt->relname);
+ if (tgfound > 1)
+ elog(NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
+ tgfound, stmt->trigname, stmt->relname);
+ heap_endscan(tgscan);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
+
+ /* update pg_class */
+ relrdesc = heap_openr(RelationRelationName);
+ tuple = ClassNameIndexScan(relrdesc, stmt->relname);
+ if (!PointerIsValid(tuple))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "DropTrigger: relation %s not found in pg_class", stmt->relname);
+ }
+ ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
+ RelationInvalidateHeapTuple(relrdesc, tuple);
+ oldTID = tuple->t_ctid;
+ heap_replace(relrdesc, &oldTID, tuple);
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, ridescs);
+ pfree(tuple);
heap_close(relrdesc);
- elog(WARN, "DropTrigger: relation %s not found in pg_class", stmt->relname);
- }
- ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
- RelationInvalidateHeapTuple (relrdesc, tuple);
- oldTID = tuple->t_ctid;
- heap_replace (relrdesc, &oldTID, tuple);
- CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
- CatalogCloseIndices (Num_pg_class_indices, ridescs);
- pfree(tuple);
- heap_close(relrdesc);
-
- CommandCounterIncrement ();
- oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
- FreeTriggerDesc (rel);
- rel->rd_rel->reltriggers = found;
- if ( found > 0 )
- RelationBuildTriggers (rel);
- MemoryContextSwitchTo (oldcxt);
- heap_close (rel);
- return;
+
+ CommandCounterIncrement();
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ FreeTriggerDesc(rel);
+ rel->rd_rel->reltriggers = found;
+ if (found > 0)
+ RelationBuildTriggers(rel);
+ MemoryContextSwitchTo(oldcxt);
+ heap_close(rel);
+ return;
}
-void
-RelationRemoveTriggers (Relation rel)
+void
+RelationRemoveTriggers(Relation rel)
{
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- HeapTuple tup;
-
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
-
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
-
- while (tup = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tup))
- heap_delete (tgrel, &tup->t_ctid);
-
- heap_endscan (tgscan);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+
+ while (tup = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tup))
+ heap_delete(tgrel, &tup->t_ctid);
+
+ heap_endscan(tgscan);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
}
void
-RelationBuildTriggers (Relation relation)
+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);
- RelationSetLockForRead (tgrel);
- 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->tgfoid = pg_trigger->tgfoid;
- build->tgfunc = NULL;
- 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_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;
- }
- }
- else
- build->tgargs = 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);
- RelationUnsetLockForRead (tgrel);
- heap_close (tgrel);
-
- /* Build trigdesc */
- trigdesc->triggers = triggers;
- for (found = 0; found < ntrigs; found++)
- {
- build = &(triggers[found]);
- DescribeTrigger (trigdesc, build);
- }
-
- relation->trigdesc = trigdesc;
-
+ 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);
+ RelationSetLockForRead(tgrel);
+ 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->tgfoid = pg_trigger->tgfoid;
+ build->tgfunc = NULL;
+ 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_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;
+ }
+ }
+ else
+ build->tgargs = 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);
+ RelationUnsetLockForRead(tgrel);
+ heap_close(tgrel);
+
+ /* Build trigdesc */
+ trigdesc->triggers = triggers;
+ for (found = 0; found < ntrigs; found++)
+ {
+ build = &(triggers[found]);
+ DescribeTrigger(trigdesc, build);
+ }
+
+ relation->trigdesc = trigdesc;
+
}
-void
-FreeTriggerDesc (Relation relation)
+void
+FreeTriggerDesc(Relation relation)
{
- TriggerDesc *trigdesc = relation->trigdesc;
- Trigger ***t;
- Trigger *trigger;
- int i;
-
- if ( trigdesc == NULL )
- return;
-
- t = trigdesc->tg_before_statement;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_before_row;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_after_row;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_after_statement;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
-
- trigger = trigdesc->triggers;
- for (i = 0; i < relation->rd_rel->reltriggers; i++)
- {
- pfree (trigger->tgname);
- if ( trigger->tgnargs > 0 )
- {
- while ( --(trigger->tgnargs) >= 0 )
- pfree (trigger->tgargs[trigger->tgnargs]);
- pfree (trigger->tgargs);
- }
- trigger++;
- }
- pfree (trigdesc->triggers);
- pfree (trigdesc);
- relation->trigdesc = NULL;
- return;
+ TriggerDesc *trigdesc = relation->trigdesc;
+ Trigger ***t;
+ Trigger *trigger;
+ int i;
+
+ if (trigdesc == NULL)
+ return;
+
+ t = trigdesc->tg_before_statement;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_before_row;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_after_row;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_after_statement;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+
+ trigger = trigdesc->triggers;
+ for (i = 0; i < relation->rd_rel->reltriggers; i++)
+ {
+ pfree(trigger->tgname);
+ if (trigger->tgnargs > 0)
+ {
+ while (--(trigger->tgnargs) >= 0)
+ pfree(trigger->tgargs[trigger->tgnargs]);
+ pfree(trigger->tgargs);
+ }
+ trigger++;
+ }
+ pfree(trigdesc->triggers);
+ pfree(trigdesc);
+ relation->trigdesc = NULL;
+ return;
}
static void
-DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
+DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
{
- uint16 *n;
- Trigger ***t, ***tp;
-
- if ( TRIGGER_FOR_ROW (trigger->tgtype) ) /* Is ROW/STATEMENT trigger */
- {
- if ( TRIGGER_FOR_BEFORE (trigger->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 (trigger->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 (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_INSERT]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_INSERT]] = trigger;
- (n[TRIGGER_EVENT_INSERT])++;
- }
-
- if ( TRIGGER_FOR_DELETE (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_DELETE]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_DELETE]] = trigger;
- (n[TRIGGER_EVENT_DELETE])++;
- }
-
- if ( TRIGGER_FOR_UPDATE (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_UPDATE]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_UPDATE]] = trigger;
- (n[TRIGGER_EVENT_UPDATE])++;
- }
-
+ uint16 *n;
+ Trigger ***t,
+ ***tp;
+
+ if (TRIGGER_FOR_ROW(trigger->tgtype)) /* Is ROW/STATEMENT
+ * trigger */
+ {
+ if (TRIGGER_FOR_BEFORE(trigger->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(trigger->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(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_INSERT]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_INSERT]] = trigger;
+ (n[TRIGGER_EVENT_INSERT])++;
+ }
+
+ if (TRIGGER_FOR_DELETE(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_DELETE]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_DELETE]] = trigger;
+ (n[TRIGGER_EVENT_DELETE])++;
+ }
+
+ if (TRIGGER_FOR_UPDATE(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_UPDATE]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_UPDATE]] = trigger;
+ (n[TRIGGER_EVENT_UPDATE])++;
+ }
+
}
-HeapTuple
-ExecBRInsertTriggers (Relation rel, HeapTuple tuple)
+HeapTuple
+ExecBRInsertTriggers(Relation rel, HeapTuple tuple)
{
- int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
- Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
- HeapTuple newtuple = tuple;
- int nargs;
- int i;
-
- CurrentTriggerData = (TriggerData *) palloc (sizeof (TriggerData));
- CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT|TRIGGER_EVENT_ROW;
- CurrentTriggerData->tg_relation = rel;
- CurrentTriggerData->tg_newtuple = NULL;
- for (i = 0; i < ntrigs; i++)
- {
- CurrentTriggerData->tg_trigtuple = newtuple;
- CurrentTriggerData->tg_trigger = trigger[i];
- if ( trigger[i]->tgfunc == NULL )
- fmgr_info (trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
- newtuple = (HeapTuple) ( (*(trigger[i]->tgfunc)) () );
- if ( newtuple == NULL )
- break;
- }
- pfree (CurrentTriggerData);
- CurrentTriggerData = NULL;
- return (newtuple);
+ int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
+ Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
+ HeapTuple newtuple = tuple;
+ int nargs;
+ int i;
+
+ CurrentTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
+ CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
+ CurrentTriggerData->tg_relation = rel;
+ CurrentTriggerData->tg_newtuple = NULL;
+ for (i = 0; i < ntrigs; i++)
+ {
+ CurrentTriggerData->tg_trigtuple = newtuple;
+ CurrentTriggerData->tg_trigger = trigger[i];
+ if (trigger[i]->tgfunc == NULL)
+ fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
+ newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
+ if (newtuple == NULL)
+ break;
+ }
+ pfree(CurrentTriggerData);
+ CurrentTriggerData = NULL;
+ return (newtuple);
}
void
-ExecARInsertTriggers (Relation rel, HeapTuple tuple)
+ExecARInsertTriggers(Relation rel, HeapTuple tuple)
{
-
- return;
+
+ return;
}
bool
-ExecBRDeleteTriggers (Relation rel, ItemPointer tupleid)
+ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
{
-
- return (true);
+
+ return (true);
}
void
-ExecARDeleteTriggers (Relation rel, ItemPointer tupleid)
+ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
{
-
- return;
+
+ return;
}
HeapTuple
-ExecBRUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
+ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
-
- return (tuple);
+
+ return (tuple);
}
void
-ExecARUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
+ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
-
- return;
+
+ return;
}