1 /*-------------------------------------------------------------------------
4 * PostgreSQL TRIGGERs support code.
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.198 2006/01/05 10:07:45 petere Exp $
12 *-------------------------------------------------------------------------
16 #include "access/genam.h"
17 #include "access/heapam.h"
18 #include "access/xact.h"
19 #include "catalog/catalog.h"
20 #include "catalog/dependency.h"
21 #include "catalog/indexing.h"
22 #include "catalog/namespace.h"
23 #include "catalog/pg_language.h"
24 #include "catalog/pg_proc.h"
25 #include "catalog/pg_trigger.h"
26 #include "catalog/pg_type.h"
27 #include "commands/defrem.h"
28 #include "commands/trigger.h"
29 #include "executor/executor.h"
30 #include "executor/instrument.h"
31 #include "miscadmin.h"
32 #include "nodes/makefuncs.h"
33 #include "parser/parse_func.h"
34 #include "utils/acl.h"
35 #include "utils/builtins.h"
36 #include "utils/fmgroids.h"
37 #include "utils/inval.h"
38 #include "utils/lsyscache.h"
39 #include "utils/memutils.h"
40 #include "utils/syscache.h"
43 static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx);
44 static HeapTuple GetTupleForTrigger(EState *estate,
45 ResultRelInfo *relinfo,
48 TupleTableSlot **newSlot);
49 static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata,
52 Instrumentation *instr,
53 MemoryContext per_tuple_context);
54 static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
55 bool row_trigger, HeapTuple oldtup, HeapTuple newtup);
59 * Create a trigger. Returns the OID of the created trigger.
61 * forConstraint, if true, says that this trigger is being created to
62 * implement a constraint. The caller will then be expected to make
63 * a pg_depend entry linking the trigger to that constraint (and thereby
64 * to the owning relation(s)).
67 CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
71 Datum values[Natts_pg_trigger];
72 char nulls[Natts_pg_trigger];
80 Oid fargtypes[1]; /* dummy */
86 char constrtrigname[NAMEDATALEN];
89 Oid constrrelid = InvalidOid;
93 rel = heap_openrv(stmt->relation, AccessExclusiveLock);
95 if (stmt->constrrel != NULL)
96 constrrelid = RangeVarGetRelid(stmt->constrrel, false);
97 else if (stmt->isconstraint)
100 * If this trigger is a constraint (and a foreign key one) then we
101 * really need a constrrelid. Since we don't have one, we'll try to
102 * generate one from the argument information.
104 * This is really just a workaround for a long-ago pg_dump bug that
105 * omitted the FROM clause in dumped CREATE CONSTRAINT TRIGGER
106 * commands. We don't want to bomb out completely here if we can't
107 * determine the correct relation, because that would prevent loading
108 * the dump file. Instead, NOTICE here and ERROR in the trigger.
110 bool needconstrrelid = false;
113 if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_check_", 14) == 0)
115 /* A trigger on FK table. */
116 needconstrrelid = true;
117 if (list_length(stmt->args) > RI_PK_RELNAME_ARGNO)
118 elem = list_nth(stmt->args, RI_PK_RELNAME_ARGNO);
120 else if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_", 8) == 0)
122 /* A trigger on PK table. */
123 needconstrrelid = true;
124 if (list_length(stmt->args) > RI_FK_RELNAME_ARGNO)
125 elem = list_nth(stmt->args, RI_FK_RELNAME_ARGNO);
129 RangeVar *rel = makeRangeVar(NULL, strVal(elem));
131 constrrelid = RangeVarGetRelid(rel, true);
133 if (needconstrrelid && constrrelid == InvalidOid)
135 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
136 errmsg("could not determine referenced table for constraint \"%s\"",
140 if (rel->rd_rel->relkind != RELKIND_RELATION)
142 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
143 errmsg("\"%s\" is not a table",
144 RelationGetRelationName(rel))));
146 if (!allowSystemTableMods && IsSystemRelation(rel))
148 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
149 errmsg("permission denied: \"%s\" is a system catalog",
150 RelationGetRelationName(rel))));
152 /* permission checks */
154 if (stmt->isconstraint)
156 /* foreign key constraint trigger */
158 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
160 if (aclresult != ACLCHECK_OK)
161 aclcheck_error(aclresult, ACL_KIND_CLASS,
162 RelationGetRelationName(rel));
163 if (constrrelid != InvalidOid)
165 aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
167 if (aclresult != ACLCHECK_OK)
168 aclcheck_error(aclresult, ACL_KIND_CLASS,
169 get_rel_name(constrrelid));
175 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
177 if (aclresult != ACLCHECK_OK)
178 aclcheck_error(aclresult, ACL_KIND_CLASS,
179 RelationGetRelationName(rel));
183 * Generate the trigger's OID now, so that we can use it in the name if
186 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
188 trigoid = GetNewOid(tgrel);
191 * If trigger is an RI constraint, use specified trigger name as
192 * constraint name and build a unique trigger name instead. This is mainly
193 * for backwards compatibility with CREATE CONSTRAINT TRIGGER commands.
195 if (stmt->isconstraint)
197 snprintf(constrtrigname, sizeof(constrtrigname),
198 "RI_ConstraintTrigger_%u", trigoid);
199 trigname = constrtrigname;
200 constrname = stmt->trigname;
204 trigname = stmt->trigname;
208 TRIGGER_CLEAR_TYPE(tgtype);
210 TRIGGER_SETT_BEFORE(tgtype);
212 TRIGGER_SETT_ROW(tgtype);
214 for (i = 0; stmt->actions[i]; i++)
216 switch (stmt->actions[i])
219 if (TRIGGER_FOR_INSERT(tgtype))
221 (errcode(ERRCODE_SYNTAX_ERROR),
222 errmsg("multiple INSERT events specified")));
223 TRIGGER_SETT_INSERT(tgtype);
226 if (TRIGGER_FOR_DELETE(tgtype))
228 (errcode(ERRCODE_SYNTAX_ERROR),
229 errmsg("multiple DELETE events specified")));
230 TRIGGER_SETT_DELETE(tgtype);
233 if (TRIGGER_FOR_UPDATE(tgtype))
235 (errcode(ERRCODE_SYNTAX_ERROR),
236 errmsg("multiple UPDATE events specified")));
237 TRIGGER_SETT_UPDATE(tgtype);
240 elog(ERROR, "unrecognized trigger event: %d",
241 (int) stmt->actions[i]);
247 * Scan pg_trigger for existing triggers on relation. We do this mainly
248 * because we must count them; a secondary benefit is to give a nice error
249 * message if there's already a trigger of the same name. (The unique
250 * index on tgrelid/tgname would complain anyway.)
252 * NOTE that this is cool only because we have AccessExclusiveLock on the
253 * relation, so the trigger set won't be changing underneath us.
256 Anum_pg_trigger_tgrelid,
257 BTEqualStrategyNumber, F_OIDEQ,
258 ObjectIdGetDatum(RelationGetRelid(rel)));
259 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
260 SnapshotNow, 1, &key);
261 while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
263 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
265 if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
267 (errcode(ERRCODE_DUPLICATE_OBJECT),
268 errmsg("trigger \"%s\" for relation \"%s\" already exists",
269 trigname, stmt->relation->relname)));
272 systable_endscan(tgscan);
275 * Find and validate the trigger function.
277 funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
278 funcrettype = get_func_rettype(funcoid);
279 if (funcrettype != TRIGGEROID)
282 * We allow OPAQUE just so we can load old dump files. When we see a
283 * trigger function declared OPAQUE, change it to TRIGGER.
285 if (funcrettype == OPAQUEOID)
288 (errmsg("changing return type of function %s from \"opaque\" to \"trigger\"",
289 NameListToString(stmt->funcname))));
290 SetFunctionReturnType(funcoid, TRIGGEROID);
294 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
295 errmsg("function %s must return type \"trigger\"",
296 NameListToString(stmt->funcname))));
300 * Build the new pg_trigger tuple.
302 MemSet(nulls, ' ', Natts_pg_trigger * sizeof(char));
304 values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
305 values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
306 CStringGetDatum(trigname));
307 values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
308 values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
309 values[Anum_pg_trigger_tgenabled - 1] = BoolGetDatum(true);
310 values[Anum_pg_trigger_tgisconstraint - 1] = BoolGetDatum(stmt->isconstraint);
311 values[Anum_pg_trigger_tgconstrname - 1] = DirectFunctionCall1(namein,
312 CStringGetDatum(constrname));
313 values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
314 values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
315 values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);
321 int16 nargs = list_length(stmt->args);
324 foreach(le, stmt->args)
326 char *ar = strVal(lfirst(le));
328 len += strlen(ar) + 4;
335 args = (char *) palloc(len + 1);
337 foreach(le, stmt->args)
339 char *s = strVal(lfirst(le));
340 char *d = args + strlen(args);
350 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
351 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
352 CStringGetDatum(args));
356 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
357 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
358 CStringGetDatum(""));
360 /* tgattr is currently always a zero-length array */
361 tgattr = buildint2vector(NULL, 0);
362 values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
364 tuple = heap_formtuple(tgrel->rd_att, values, nulls);
366 /* force tuple to have the desired OID */
367 HeapTupleSetOid(tuple, trigoid);
370 * Insert tuple into pg_trigger.
372 simple_heap_insert(tgrel, tuple);
374 CatalogUpdateIndexes(tgrel, tuple);
376 myself.classId = TriggerRelationId;
377 myself.objectId = trigoid;
378 myself.objectSubId = 0;
380 heap_freetuple(tuple);
381 heap_close(tgrel, RowExclusiveLock);
383 pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
384 pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
387 * Update relation's pg_class entry. Crucial side-effect: other backends
388 * (and this one too!) are sent SI message to make them rebuild relcache
391 pgrel = heap_open(RelationRelationId, RowExclusiveLock);
392 tuple = SearchSysCacheCopy(RELOID,
393 ObjectIdGetDatum(RelationGetRelid(rel)),
395 if (!HeapTupleIsValid(tuple))
396 elog(ERROR, "cache lookup failed for relation %u",
397 RelationGetRelid(rel));
399 ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
401 simple_heap_update(pgrel, &tuple->t_self, tuple);
403 CatalogUpdateIndexes(pgrel, tuple);
405 heap_freetuple(tuple);
406 heap_close(pgrel, RowExclusiveLock);
409 * We used to try to update the rel's relcache entry here, but that's
410 * fairly pointless since it will happen as a byproduct of the upcoming
411 * CommandCounterIncrement...
415 * Record dependencies for trigger. Always place a normal dependency on
416 * the function. If we are doing this in response to an explicit CREATE
417 * TRIGGER command, also make trigger be auto-dropped if its relation is
418 * dropped or if the FK relation is dropped. (Auto drop is compatible
419 * with our pre-7.3 behavior.) If the trigger is being made for a
420 * constraint, we can skip the relation links; the dependency on the
421 * constraint will indirectly depend on the relations.
423 referenced.classId = ProcedureRelationId;
424 referenced.objectId = funcoid;
425 referenced.objectSubId = 0;
426 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
430 referenced.classId = RelationRelationId;
431 referenced.objectId = RelationGetRelid(rel);
432 referenced.objectSubId = 0;
433 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
434 if (constrrelid != InvalidOid)
436 referenced.classId = RelationRelationId;
437 referenced.objectId = constrrelid;
438 referenced.objectSubId = 0;
439 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
443 /* Keep lock on target rel until end of xact */
444 heap_close(rel, NoLock);
450 * DropTrigger - drop an individual trigger by name
453 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
459 ObjectAddress object;
462 * Find the trigger, verify permissions, set up object address
464 tgrel = heap_open(TriggerRelationId, AccessShareLock);
466 ScanKeyInit(&skey[0],
467 Anum_pg_trigger_tgrelid,
468 BTEqualStrategyNumber, F_OIDEQ,
469 ObjectIdGetDatum(relid));
471 ScanKeyInit(&skey[1],
472 Anum_pg_trigger_tgname,
473 BTEqualStrategyNumber, F_NAMEEQ,
474 CStringGetDatum(trigname));
476 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
477 SnapshotNow, 2, skey);
479 tup = systable_getnext(tgscan);
481 if (!HeapTupleIsValid(tup))
483 (errcode(ERRCODE_UNDEFINED_OBJECT),
484 errmsg("trigger \"%s\" for table \"%s\" does not exist",
485 trigname, get_rel_name(relid))));
487 if (!pg_class_ownercheck(relid, GetUserId()))
488 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
489 get_rel_name(relid));
491 object.classId = TriggerRelationId;
492 object.objectId = HeapTupleGetOid(tup);
493 object.objectSubId = 0;
495 systable_endscan(tgscan);
496 heap_close(tgrel, AccessShareLock);
501 performDeletion(&object, behavior);
505 * Guts of trigger deletion.
508 RemoveTriggerById(Oid trigOid)
518 Form_pg_class classForm;
520 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
523 * Find the trigger to delete.
525 ScanKeyInit(&skey[0],
526 ObjectIdAttributeNumber,
527 BTEqualStrategyNumber, F_OIDEQ,
528 ObjectIdGetDatum(trigOid));
530 tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
531 SnapshotNow, 1, skey);
533 tup = systable_getnext(tgscan);
534 if (!HeapTupleIsValid(tup))
535 elog(ERROR, "could not find tuple for trigger %u", trigOid);
538 * Open and exclusive-lock the relation the trigger belongs to.
540 relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
542 rel = heap_open(relid, AccessExclusiveLock);
544 if (rel->rd_rel->relkind != RELKIND_RELATION)
546 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
547 errmsg("\"%s\" is not a table",
548 RelationGetRelationName(rel))));
550 if (!allowSystemTableMods && IsSystemRelation(rel))
552 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
553 errmsg("permission denied: \"%s\" is a system catalog",
554 RelationGetRelationName(rel))));
557 * Delete the pg_trigger tuple.
559 simple_heap_delete(tgrel, &tup->t_self);
561 systable_endscan(tgscan);
562 heap_close(tgrel, RowExclusiveLock);
565 * Update relation's pg_class entry. Crucial side-effect: other backends
566 * (and this one too!) are sent SI message to make them rebuild relcache
569 * Note this is OK only because we have AccessExclusiveLock on the rel, so
570 * no one else is creating/deleting triggers on this rel at the same time.
572 pgrel = heap_open(RelationRelationId, RowExclusiveLock);
573 tuple = SearchSysCacheCopy(RELOID,
574 ObjectIdGetDatum(relid),
576 if (!HeapTupleIsValid(tuple))
577 elog(ERROR, "cache lookup failed for relation %u", relid);
578 classForm = (Form_pg_class) GETSTRUCT(tuple);
580 if (classForm->reltriggers == 0) /* should not happen */
581 elog(ERROR, "relation \"%s\" has reltriggers = 0",
582 RelationGetRelationName(rel));
583 classForm->reltriggers--;
585 simple_heap_update(pgrel, &tuple->t_self, tuple);
587 CatalogUpdateIndexes(pgrel, tuple);
589 heap_freetuple(tuple);
591 heap_close(pgrel, RowExclusiveLock);
593 /* Keep lock on trigger's rel until end of xact */
594 heap_close(rel, NoLock);
598 * renametrig - changes the name of a trigger on a relation
600 * trigger name is changed in trigger catalog.
601 * No record of the previous name is kept.
603 * get proper relrelation from relation catalog (if not arg)
604 * scan trigger catalog
605 * for name conflict (within rel)
606 * for original trigger (if not arg)
607 * modify tgname in trigger tuple
608 * update row in catalog
611 renametrig(Oid relid,
622 * Grab an exclusive lock on the target table, which we will NOT release
623 * until end of transaction.
625 targetrel = heap_open(relid, AccessExclusiveLock);
628 * Scan pg_trigger twice for existing triggers on relation. We do this in
629 * order to ensure a trigger does not exist with newname (The unique index
630 * on tgrelid/tgname would complain anyway) and to ensure a trigger does
631 * exist with oldname.
633 * NOTE that this is cool only because we have AccessExclusiveLock on the
634 * relation, so the trigger set won't be changing underneath us.
636 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
639 * First pass -- look for name conflict
642 Anum_pg_trigger_tgrelid,
643 BTEqualStrategyNumber, F_OIDEQ,
644 ObjectIdGetDatum(relid));
646 Anum_pg_trigger_tgname,
647 BTEqualStrategyNumber, F_NAMEEQ,
648 PointerGetDatum(newname));
649 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
650 SnapshotNow, 2, key);
651 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
653 (errcode(ERRCODE_DUPLICATE_OBJECT),
654 errmsg("trigger \"%s\" for relation \"%s\" already exists",
655 newname, RelationGetRelationName(targetrel))));
656 systable_endscan(tgscan);
659 * Second pass -- look for trigger existing with oldname and update
662 Anum_pg_trigger_tgrelid,
663 BTEqualStrategyNumber, F_OIDEQ,
664 ObjectIdGetDatum(relid));
666 Anum_pg_trigger_tgname,
667 BTEqualStrategyNumber, F_NAMEEQ,
668 PointerGetDatum(oldname));
669 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
670 SnapshotNow, 2, key);
671 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
674 * Update pg_trigger tuple with new tgname.
676 tuple = heap_copytuple(tuple); /* need a modifiable copy */
678 namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname, newname);
680 simple_heap_update(tgrel, &tuple->t_self, tuple);
682 /* keep system catalog indexes current */
683 CatalogUpdateIndexes(tgrel, tuple);
686 * Invalidate relation's relcache entry so that other backends (and
687 * this one too!) are sent SI message to make them rebuild relcache
688 * entries. (Ideally this should happen automatically...)
690 CacheInvalidateRelcache(targetrel);
695 (errcode(ERRCODE_UNDEFINED_OBJECT),
696 errmsg("trigger \"%s\" for table \"%s\" does not exist",
697 oldname, RelationGetRelationName(targetrel))));
700 systable_endscan(tgscan);
702 heap_close(tgrel, RowExclusiveLock);
705 * Close rel, but keep exclusive lock!
707 heap_close(targetrel, NoLock);
712 * EnableDisableTrigger()
714 * Called by ALTER TABLE ENABLE/DISABLE TRIGGER
715 * to change 'tgenabled' flag for the specified trigger(s)
717 * rel: relation to process (caller must hold suitable lock on it)
718 * tgname: trigger to process, or NULL to scan all triggers
719 * enable: new value for tgenabled flag
720 * skip_system: if true, skip "system" triggers (constraint triggers)
722 * Caller should have checked permissions for the table; here we also
723 * enforce that superuser privilege is required to alter the state of
727 EnableDisableTrigger(Relation rel, const char *tgname,
728 bool enable, bool skip_system)
738 /* Scan the relevant entries in pg_triggers */
739 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
741 ScanKeyInit(&keys[0],
742 Anum_pg_trigger_tgrelid,
743 BTEqualStrategyNumber, F_OIDEQ,
744 ObjectIdGetDatum(RelationGetRelid(rel)));
747 ScanKeyInit(&keys[1],
748 Anum_pg_trigger_tgname,
749 BTEqualStrategyNumber, F_NAMEEQ,
750 CStringGetDatum(tgname));
756 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
757 SnapshotNow, nkeys, keys);
759 found = changed = false;
761 while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
763 Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
765 if (oldtrig->tgisconstraint)
767 /* system trigger ... ok to process? */
772 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
773 errmsg("permission denied: \"%s\" is a system trigger",
774 NameStr(oldtrig->tgname))));
779 if (oldtrig->tgenabled != enable)
781 /* need to change this one ... make a copy to scribble on */
782 HeapTuple newtup = heap_copytuple(tuple);
783 Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
785 newtrig->tgenabled = enable;
787 simple_heap_update(tgrel, &newtup->t_self, newtup);
789 /* Keep catalog indexes current */
790 CatalogUpdateIndexes(tgrel, newtup);
792 heap_freetuple(newtup);
798 systable_endscan(tgscan);
800 heap_close(tgrel, RowExclusiveLock);
802 if (tgname && !found)
804 (errcode(ERRCODE_UNDEFINED_OBJECT),
805 errmsg("trigger \"%s\" for table \"%s\" does not exist",
806 tgname, RelationGetRelationName(rel))));
809 * If we changed anything, broadcast a SI inval message to force each
810 * backend (including our own!) to rebuild relation's relcache entry.
811 * Otherwise they will fail to apply the change promptly.
814 CacheInvalidateRelcache(rel);
819 * Build trigger data to attach to the given relcache entry.
821 * Note that trigger data attached to a relcache entry must be stored in
822 * CacheMemoryContext to ensure it survives as long as the relcache entry.
823 * But we should be running in a less long-lived working context. To avoid
824 * leaking cache memory if this routine fails partway through, we build a
825 * temporary TriggerDesc in working memory and then copy the completed
826 * structure into cache memory.
829 RelationBuildTriggers(Relation relation)
831 TriggerDesc *trigdesc;
832 int ntrigs = relation->rd_rel->reltriggers;
839 MemoryContext oldContext;
841 Assert(ntrigs > 0); /* else I should not have been called */
843 triggers = (Trigger *) palloc(ntrigs * sizeof(Trigger));
846 * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
847 * be reading the triggers in name order, except possibly during
848 * emergency-recovery operations (ie, IgnoreSystemIndexes). This in
849 * turn ensures that triggers will be fired in name order.
852 Anum_pg_trigger_tgrelid,
853 BTEqualStrategyNumber, F_OIDEQ,
854 ObjectIdGetDatum(RelationGetRelid(relation)));
856 tgrel = heap_open(TriggerRelationId, AccessShareLock);
857 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
858 SnapshotNow, 1, &skey);
860 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
862 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
866 elog(ERROR, "too many trigger records found for relation \"%s\"",
867 RelationGetRelationName(relation));
868 build = &(triggers[found]);
870 build->tgoid = HeapTupleGetOid(htup);
871 build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
872 NameGetDatum(&pg_trigger->tgname)));
873 build->tgfoid = pg_trigger->tgfoid;
874 build->tgtype = pg_trigger->tgtype;
875 build->tgenabled = pg_trigger->tgenabled;
876 build->tgisconstraint = pg_trigger->tgisconstraint;
877 build->tgconstrrelid = pg_trigger->tgconstrrelid;
878 build->tgdeferrable = pg_trigger->tgdeferrable;
879 build->tginitdeferred = pg_trigger->tginitdeferred;
880 build->tgnargs = pg_trigger->tgnargs;
881 /* tgattr is first var-width field, so OK to access directly */
882 build->tgnattr = pg_trigger->tgattr.dim1;
883 if (build->tgnattr > 0)
885 build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2));
886 memcpy(build->tgattr, &(pg_trigger->tgattr.values),
887 build->tgnattr * sizeof(int2));
890 build->tgattr = NULL;
891 if (build->tgnargs > 0)
899 DatumGetPointer(fastgetattr(htup,
900 Anum_pg_trigger_tgargs,
901 tgrel->rd_att, &isnull));
903 elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
904 RelationGetRelationName(relation));
905 p = (char *) VARDATA(val);
906 build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
907 for (i = 0; i < build->tgnargs; i++)
909 build->tgargs[i] = pstrdup(p);
914 build->tgargs = NULL;
919 systable_endscan(tgscan);
920 heap_close(tgrel, AccessShareLock);
923 elog(ERROR, "%d trigger record(s) not found for relation \"%s\"",
925 RelationGetRelationName(relation));
928 trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
929 trigdesc->triggers = triggers;
930 trigdesc->numtriggers = ntrigs;
931 for (found = 0; found < ntrigs; found++)
932 InsertTrigger(trigdesc, &(triggers[found]), found);
934 /* Copy completed trigdesc into cache storage */
935 oldContext = MemoryContextSwitchTo(CacheMemoryContext);
936 relation->trigdesc = CopyTriggerDesc(trigdesc);
937 MemoryContextSwitchTo(oldContext);
939 /* Release working memory */
940 FreeTriggerDesc(trigdesc);
944 * Insert the given trigger into the appropriate index list(s) for it
946 * To simplify storage management, we allocate each index list at the max
947 * possible size (trigdesc->numtriggers) if it's used at all. This does
948 * not waste space permanently since we're only building a temporary
949 * trigdesc at this point.
952 InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx)
958 if (TRIGGER_FOR_ROW(trigger->tgtype))
961 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
963 n = trigdesc->n_before_row;
964 t = trigdesc->tg_before_row;
968 n = trigdesc->n_after_row;
969 t = trigdesc->tg_after_row;
974 /* STATEMENT trigger */
975 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
977 n = trigdesc->n_before_statement;
978 t = trigdesc->tg_before_statement;
982 n = trigdesc->n_after_statement;
983 t = trigdesc->tg_after_statement;
987 if (TRIGGER_FOR_INSERT(trigger->tgtype))
989 tp = &(t[TRIGGER_EVENT_INSERT]);
991 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
992 (*tp)[n[TRIGGER_EVENT_INSERT]] = indx;
993 (n[TRIGGER_EVENT_INSERT])++;
996 if (TRIGGER_FOR_DELETE(trigger->tgtype))
998 tp = &(t[TRIGGER_EVENT_DELETE]);
1000 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
1001 (*tp)[n[TRIGGER_EVENT_DELETE]] = indx;
1002 (n[TRIGGER_EVENT_DELETE])++;
1005 if (TRIGGER_FOR_UPDATE(trigger->tgtype))
1007 tp = &(t[TRIGGER_EVENT_UPDATE]);
1009 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
1010 (*tp)[n[TRIGGER_EVENT_UPDATE]] = indx;
1011 (n[TRIGGER_EVENT_UPDATE])++;
1016 * Copy a TriggerDesc data structure.
1018 * The copy is allocated in the current memory context.
1021 CopyTriggerDesc(TriggerDesc *trigdesc)
1023 TriggerDesc *newdesc;
1030 if (trigdesc == NULL || trigdesc->numtriggers <= 0)
1033 newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
1034 memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
1036 trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
1037 memcpy(trigger, trigdesc->triggers,
1038 trigdesc->numtriggers * sizeof(Trigger));
1039 newdesc->triggers = trigger;
1041 for (i = 0; i < trigdesc->numtriggers; i++)
1043 trigger->tgname = pstrdup(trigger->tgname);
1044 if (trigger->tgnattr > 0)
1048 newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2));
1049 memcpy(newattr, trigger->tgattr,
1050 trigger->tgnattr * sizeof(int2));
1051 trigger->tgattr = newattr;
1053 if (trigger->tgnargs > 0)
1058 newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
1059 for (j = 0; j < trigger->tgnargs; j++)
1060 newargs[j] = pstrdup(trigger->tgargs[j]);
1061 trigger->tgargs = newargs;
1066 n = newdesc->n_before_statement;
1067 t = newdesc->tg_before_statement;
1068 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1072 tnew = (int *) palloc(n[i] * sizeof(int));
1073 memcpy(tnew, t[i], n[i] * sizeof(int));
1079 n = newdesc->n_before_row;
1080 t = newdesc->tg_before_row;
1081 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1085 tnew = (int *) palloc(n[i] * sizeof(int));
1086 memcpy(tnew, t[i], n[i] * sizeof(int));
1092 n = newdesc->n_after_row;
1093 t = newdesc->tg_after_row;
1094 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1098 tnew = (int *) palloc(n[i] * sizeof(int));
1099 memcpy(tnew, t[i], n[i] * sizeof(int));
1105 n = newdesc->n_after_statement;
1106 t = newdesc->tg_after_statement;
1107 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1111 tnew = (int *) palloc(n[i] * sizeof(int));
1112 memcpy(tnew, t[i], n[i] * sizeof(int));
1123 * Free a TriggerDesc data structure.
1126 FreeTriggerDesc(TriggerDesc *trigdesc)
1132 if (trigdesc == NULL)
1135 t = trigdesc->tg_before_statement;
1136 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1139 t = trigdesc->tg_before_row;
1140 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1143 t = trigdesc->tg_after_row;
1144 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1147 t = trigdesc->tg_after_statement;
1148 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1152 trigger = trigdesc->triggers;
1153 for (i = 0; i < trigdesc->numtriggers; i++)
1155 pfree(trigger->tgname);
1156 if (trigger->tgnattr > 0)
1157 pfree(trigger->tgattr);
1158 if (trigger->tgnargs > 0)
1160 while (--(trigger->tgnargs) >= 0)
1161 pfree(trigger->tgargs[trigger->tgnargs]);
1162 pfree(trigger->tgargs);
1166 pfree(trigdesc->triggers);
1171 * Compare two TriggerDesc structures for logical equality.
1175 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
1181 * We need not examine the "index" data, just the trigger array itself; if
1182 * we have the same triggers with the same types, the derived index data
1185 * As of 7.3 we assume trigger set ordering is significant in the
1186 * comparison; so we just compare corresponding slots of the two sets.
1188 if (trigdesc1 != NULL)
1190 if (trigdesc2 == NULL)
1192 if (trigdesc1->numtriggers != trigdesc2->numtriggers)
1194 for (i = 0; i < trigdesc1->numtriggers; i++)
1196 Trigger *trig1 = trigdesc1->triggers + i;
1197 Trigger *trig2 = trigdesc2->triggers + i;
1199 if (trig1->tgoid != trig2->tgoid)
1201 if (strcmp(trig1->tgname, trig2->tgname) != 0)
1203 if (trig1->tgfoid != trig2->tgfoid)
1205 if (trig1->tgtype != trig2->tgtype)
1207 if (trig1->tgenabled != trig2->tgenabled)
1209 if (trig1->tgisconstraint != trig2->tgisconstraint)
1211 if (trig1->tgconstrrelid != trig2->tgconstrrelid)
1213 if (trig1->tgdeferrable != trig2->tgdeferrable)
1215 if (trig1->tginitdeferred != trig2->tginitdeferred)
1217 if (trig1->tgnargs != trig2->tgnargs)
1219 if (trig1->tgnattr != trig2->tgnattr)
1221 if (trig1->tgnattr > 0 &&
1222 memcmp(trig1->tgattr, trig2->tgattr,
1223 trig1->tgnattr * sizeof(int2)) != 0)
1225 for (j = 0; j < trig1->tgnargs; j++)
1226 if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
1230 else if (trigdesc2 != NULL)
1234 #endif /* NOT_USED */
1237 * Call a trigger function.
1239 * trigdata: trigger descriptor.
1240 * tgindx: trigger's index in finfo and instr arrays.
1241 * finfo: array of cached trigger function call information.
1242 * instr: optional array of EXPLAIN ANALYZE instrumentation state.
1243 * per_tuple_context: memory context to execute the function in.
1245 * Returns the tuple (or NULL) as returned by the function.
1248 ExecCallTriggerFunc(TriggerData *trigdata,
1251 Instrumentation *instr,
1252 MemoryContext per_tuple_context)
1254 FunctionCallInfoData fcinfo;
1256 MemoryContext oldContext;
1261 * We cache fmgr lookup info, to avoid making the lookup again on each
1264 if (finfo->fn_oid == InvalidOid)
1265 fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
1267 Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
1270 * If doing EXPLAIN ANALYZE, start charging time to this trigger.
1273 InstrStartNode(instr + tgindx);
1276 * Do the function evaluation in the per-tuple memory context, so that
1277 * leaked memory will be reclaimed once per tuple. Note in particular that
1278 * any new tuple created by the trigger function will live till the end of
1281 oldContext = MemoryContextSwitchTo(per_tuple_context);
1284 * Call the function, passing no arguments but setting a context.
1286 InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
1288 result = FunctionCallInvoke(&fcinfo);
1290 MemoryContextSwitchTo(oldContext);
1293 * Trigger protocol allows function to return a null pointer, but NOT to
1294 * set the isnull result flag.
1298 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1299 errmsg("trigger function %u returned null value",
1300 fcinfo.flinfo->fn_oid)));
1303 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
1304 * one "tuple returned" (really the number of firings).
1307 InstrStopNode(instr + tgindx, true);
1309 return (HeapTuple) DatumGetPointer(result);
1313 ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1315 TriggerDesc *trigdesc;
1319 TriggerData LocTriggerData;
1321 trigdesc = relinfo->ri_TrigDesc;
1323 if (trigdesc == NULL)
1326 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_INSERT];
1327 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_INSERT];
1332 LocTriggerData.type = T_TriggerData;
1333 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1334 TRIGGER_EVENT_BEFORE;
1335 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1336 LocTriggerData.tg_trigtuple = NULL;
1337 LocTriggerData.tg_newtuple = NULL;
1338 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1339 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1340 for (i = 0; i < ntrigs; i++)
1342 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1345 if (!trigger->tgenabled)
1347 LocTriggerData.tg_trigger = trigger;
1348 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1350 relinfo->ri_TrigFunctions,
1351 relinfo->ri_TrigInstrument,
1352 GetPerTupleMemoryContext(estate));
1356 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1357 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1362 ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1364 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1366 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_INSERT] > 0)
1367 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1372 ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1373 HeapTuple trigtuple)
1375 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1376 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
1377 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
1378 HeapTuple newtuple = trigtuple;
1380 TriggerData LocTriggerData;
1383 LocTriggerData.type = T_TriggerData;
1384 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1386 TRIGGER_EVENT_BEFORE;
1387 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1388 LocTriggerData.tg_newtuple = NULL;
1389 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1390 for (i = 0; i < ntrigs; i++)
1392 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1394 if (!trigger->tgenabled)
1396 LocTriggerData.tg_trigtuple = oldtuple = newtuple;
1397 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1398 LocTriggerData.tg_trigger = trigger;
1399 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1401 relinfo->ri_TrigFunctions,
1402 relinfo->ri_TrigInstrument,
1403 GetPerTupleMemoryContext(estate));
1404 if (oldtuple != newtuple && oldtuple != trigtuple)
1405 heap_freetuple(oldtuple);
1406 if (newtuple == NULL)
1413 ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1414 HeapTuple trigtuple)
1416 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1418 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
1419 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1420 true, NULL, trigtuple);
1424 ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1426 TriggerDesc *trigdesc;
1430 TriggerData LocTriggerData;
1432 trigdesc = relinfo->ri_TrigDesc;
1434 if (trigdesc == NULL)
1437 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_DELETE];
1438 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_DELETE];
1443 LocTriggerData.type = T_TriggerData;
1444 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1445 TRIGGER_EVENT_BEFORE;
1446 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1447 LocTriggerData.tg_trigtuple = NULL;
1448 LocTriggerData.tg_newtuple = NULL;
1449 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1450 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1451 for (i = 0; i < ntrigs; i++)
1453 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1456 if (!trigger->tgenabled)
1458 LocTriggerData.tg_trigger = trigger;
1459 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1461 relinfo->ri_TrigFunctions,
1462 relinfo->ri_TrigInstrument,
1463 GetPerTupleMemoryContext(estate));
1467 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1468 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1473 ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1475 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1477 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_DELETE] > 0)
1478 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1483 ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1484 ItemPointer tupleid,
1487 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1488 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
1489 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
1491 TriggerData LocTriggerData;
1492 HeapTuple trigtuple;
1494 TupleTableSlot *newSlot;
1497 trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1498 if (trigtuple == NULL)
1501 LocTriggerData.type = T_TriggerData;
1502 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1504 TRIGGER_EVENT_BEFORE;
1505 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1506 LocTriggerData.tg_newtuple = NULL;
1507 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1508 for (i = 0; i < ntrigs; i++)
1510 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1512 if (!trigger->tgenabled)
1514 LocTriggerData.tg_trigtuple = trigtuple;
1515 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1516 LocTriggerData.tg_trigger = trigger;
1517 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1519 relinfo->ri_TrigFunctions,
1520 relinfo->ri_TrigInstrument,
1521 GetPerTupleMemoryContext(estate));
1522 if (newtuple == NULL)
1524 result = false; /* tell caller to suppress delete */
1527 if (newtuple != trigtuple)
1528 heap_freetuple(newtuple);
1530 heap_freetuple(trigtuple);
1536 ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1537 ItemPointer tupleid)
1539 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1541 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
1543 HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo,
1548 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1549 true, trigtuple, NULL);
1550 heap_freetuple(trigtuple);
1555 ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1557 TriggerDesc *trigdesc;
1561 TriggerData LocTriggerData;
1563 trigdesc = relinfo->ri_TrigDesc;
1565 if (trigdesc == NULL)
1568 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_UPDATE];
1569 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_UPDATE];
1574 LocTriggerData.type = T_TriggerData;
1575 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1576 TRIGGER_EVENT_BEFORE;
1577 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1578 LocTriggerData.tg_trigtuple = NULL;
1579 LocTriggerData.tg_newtuple = NULL;
1580 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1581 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1582 for (i = 0; i < ntrigs; i++)
1584 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1587 if (!trigger->tgenabled)
1589 LocTriggerData.tg_trigger = trigger;
1590 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1592 relinfo->ri_TrigFunctions,
1593 relinfo->ri_TrigInstrument,
1594 GetPerTupleMemoryContext(estate));
1598 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1599 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1604 ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1606 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1608 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_UPDATE] > 0)
1609 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1614 ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1615 ItemPointer tupleid, HeapTuple newtuple,
1618 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1619 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
1620 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
1621 TriggerData LocTriggerData;
1622 HeapTuple trigtuple;
1624 HeapTuple intuple = newtuple;
1625 TupleTableSlot *newSlot;
1628 trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1629 if (trigtuple == NULL)
1633 * In READ COMMITTED isolation level it's possible that newtuple was
1634 * changed due to concurrent update.
1636 if (newSlot != NULL)
1637 intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);
1639 LocTriggerData.type = T_TriggerData;
1640 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1642 TRIGGER_EVENT_BEFORE;
1643 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1644 for (i = 0; i < ntrigs; i++)
1646 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1648 if (!trigger->tgenabled)
1650 LocTriggerData.tg_trigtuple = trigtuple;
1651 LocTriggerData.tg_newtuple = oldtuple = newtuple;
1652 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1653 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1654 LocTriggerData.tg_trigger = trigger;
1655 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1657 relinfo->ri_TrigFunctions,
1658 relinfo->ri_TrigInstrument,
1659 GetPerTupleMemoryContext(estate));
1660 if (oldtuple != newtuple && oldtuple != intuple)
1661 heap_freetuple(oldtuple);
1662 if (newtuple == NULL)
1665 heap_freetuple(trigtuple);
1670 ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1671 ItemPointer tupleid, HeapTuple newtuple)
1673 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1675 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
1677 HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo,
1682 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1683 true, trigtuple, newtuple);
1684 heap_freetuple(trigtuple);
1690 GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
1691 ItemPointer tid, CommandId cid,
1692 TupleTableSlot **newSlot)
1694 Relation relation = relinfo->ri_RelationDesc;
1695 HeapTupleData tuple;
1699 if (newSlot != NULL)
1702 ItemPointerData update_ctid;
1703 TransactionId update_xmax;
1708 * lock tuple for update
1711 tuple.t_self = *tid;
1712 test = heap_lock_tuple(relation, &tuple, &buffer,
1713 &update_ctid, &update_xmax, cid,
1714 LockTupleExclusive, false);
1717 case HeapTupleSelfUpdated:
1718 /* treat it as deleted; do not process */
1719 ReleaseBuffer(buffer);
1722 case HeapTupleMayBeUpdated:
1725 case HeapTupleUpdated:
1726 ReleaseBuffer(buffer);
1727 if (IsXactIsoLevelSerializable)
1729 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1730 errmsg("could not serialize access due to concurrent update")));
1731 else if (!ItemPointerEquals(&update_ctid, &tuple.t_self))
1733 /* it was updated, so look at the updated version */
1734 TupleTableSlot *epqslot;
1736 epqslot = EvalPlanQual(estate,
1737 relinfo->ri_RangeTableIndex,
1740 if (!TupIsNull(epqslot))
1749 * if tuple was deleted or PlanQual failed for updated tuple -
1750 * we have not process this tuple!
1755 ReleaseBuffer(buffer);
1756 elog(ERROR, "unrecognized heap_lock_tuple status: %u", test);
1757 return NULL; /* keep compiler quiet */
1765 buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
1767 dp = (PageHeader) BufferGetPage(buffer);
1768 lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
1770 Assert(ItemIdIsUsed(lp));
1772 tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
1773 tuple.t_len = ItemIdGetLength(lp);
1774 tuple.t_self = *tid;
1775 tuple.t_tableOid = RelationGetRelid(relation);
1778 result = heap_copytuple(&tuple);
1779 ReleaseBuffer(buffer);
1786 * After-trigger stuff
1788 * The AfterTriggersData struct holds data about pending AFTER trigger events
1789 * during the current transaction tree. (BEFORE triggers are fired
1790 * immediately so we don't need any persistent state about them.) The struct
1791 * and most of its subsidiary data are kept in TopTransactionContext; however
1792 * the individual event records are kept in CurTransactionContext, so that
1793 * they will easily go away during subtransaction abort.
1795 * Because the list of pending events can grow large, we go to some effort
1796 * to minimize memory consumption. We do not use the generic List mechanism
1797 * but thread the events manually.
1799 * XXX We need to be able to save the per-event data in a file if it grows too
1804 /* Per-trigger SET CONSTRAINT status */
1805 typedef struct SetConstraintTriggerData
1808 bool sct_tgisdeferred;
1809 } SetConstraintTriggerData;
1811 typedef struct SetConstraintTriggerData *SetConstraintTrigger;
1814 * SET CONSTRAINT intra-transaction status.
1816 * We make this a single palloc'd object so it can be copied and freed easily.
1818 * all_isset and all_isdeferred are used to keep track
1819 * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
1821 * trigstates[] stores per-trigger tgisdeferred settings.
1823 typedef struct SetConstraintStateData
1826 bool all_isdeferred;
1827 int numstates; /* number of trigstates[] entries in use */
1828 int numalloc; /* allocated size of trigstates[] */
1829 SetConstraintTriggerData trigstates[1]; /* VARIABLE LENGTH ARRAY */
1830 } SetConstraintStateData;
1832 typedef SetConstraintStateData *SetConstraintState;
1836 * Per-trigger-event data
1838 * Note: ate_firing_id is meaningful when either AFTER_TRIGGER_DONE
1839 * or AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
1840 * cycle the trigger was or will be fired in.
1842 typedef struct AfterTriggerEventData *AfterTriggerEvent;
1844 typedef struct AfterTriggerEventData
1846 AfterTriggerEvent ate_next; /* list link */
1847 TriggerEvent ate_event; /* event type and status bits */
1848 CommandId ate_firing_id; /* ID for firing cycle */
1849 Oid ate_tgoid; /* the trigger's ID */
1850 Oid ate_relid; /* the relation it's on */
1851 ItemPointerData ate_oldctid; /* specific tuple(s) involved */
1852 ItemPointerData ate_newctid;
1853 } AfterTriggerEventData;
1855 /* A list of events */
1856 typedef struct AfterTriggerEventList
1858 AfterTriggerEvent head;
1859 AfterTriggerEvent tail;
1860 } AfterTriggerEventList;
1864 * All per-transaction data for the AFTER TRIGGERS module.
1866 * AfterTriggersData has the following fields:
1868 * firing_counter is incremented for each call of afterTriggerInvokeEvents.
1869 * We mark firable events with the current firing cycle's ID so that we can
1870 * tell which ones to work on. This ensures sane behavior if a trigger
1871 * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
1872 * only fire those events that weren't already scheduled for firing.
1874 * state keeps track of the transaction-local effects of SET CONSTRAINTS.
1875 * This is saved and restored across failed subtransactions.
1877 * events is the current list of deferred events. This is global across
1878 * all subtransactions of the current transaction. In a subtransaction
1879 * abort, we know that the events added by the subtransaction are at the
1880 * end of the list, so it is relatively easy to discard them.
1882 * query_depth is the current depth of nested AfterTriggerBeginQuery calls
1883 * (-1 when the stack is empty).
1885 * query_stack[query_depth] is a list of AFTER trigger events queued by the
1886 * current query (and the query_stack entries below it are lists of trigger
1887 * events queued by calling queries). None of these are valid until the
1888 * matching AfterTriggerEndQuery call occurs. At that point we fire
1889 * immediate-mode triggers, and append any deferred events to the main events
1892 * maxquerydepth is just the allocated length of query_stack.
1894 * state_stack is a stack of pointers to saved copies of the SET CONSTRAINTS
1895 * state data; each subtransaction level that modifies that state first
1896 * saves a copy, which we use to restore the state if we abort.
1898 * events_stack is a stack of copies of the events head/tail pointers,
1899 * which we use to restore those values during subtransaction abort.
1901 * depth_stack is a stack of copies of subtransaction-start-time query_depth,
1902 * which we similarly use to clean up at subtransaction abort.
1904 * firing_stack is a stack of copies of subtransaction-start-time
1905 * firing_counter. We use this to recognize which deferred triggers were
1906 * fired (or marked for firing) within an aborted subtransaction.
1908 * We use GetCurrentTransactionNestLevel() to determine the correct array
1909 * index in these stacks. maxtransdepth is the number of allocated entries in
1910 * each stack. (By not keeping our own stack pointer, we can avoid trouble
1911 * in cases where errors during subxact abort cause multiple invocations
1912 * of AfterTriggerEndSubXact() at the same nesting depth.)
1914 typedef struct AfterTriggersData
1916 CommandId firing_counter; /* next firing ID to assign */
1917 SetConstraintState state; /* the active S C state */
1918 AfterTriggerEventList events; /* deferred-event list */
1919 int query_depth; /* current query list index */
1920 AfterTriggerEventList *query_stack; /* events pending from each query */
1921 int maxquerydepth; /* allocated len of above array */
1923 /* these fields are just for resetting at subtrans abort: */
1925 SetConstraintState *state_stack; /* stacked S C states */
1926 AfterTriggerEventList *events_stack; /* stacked list pointers */
1927 int *depth_stack; /* stacked query_depths */
1928 CommandId *firing_stack; /* stacked firing_counters */
1929 int maxtransdepth; /* allocated len of above arrays */
1930 } AfterTriggersData;
1932 typedef AfterTriggersData *AfterTriggers;
1934 static AfterTriggers afterTriggers;
1937 static void AfterTriggerExecute(AfterTriggerEvent event,
1938 Relation rel, TriggerDesc *trigdesc,
1940 Instrumentation *instr,
1941 MemoryContext per_tuple_context);
1942 static SetConstraintState SetConstraintStateCreate(int numalloc);
1943 static SetConstraintState SetConstraintStateCopy(SetConstraintState state);
1944 static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
1945 Oid tgoid, bool tgisdeferred);
1949 * afterTriggerCheckState()
1951 * Returns true if the trigger identified by tgoid is actually
1952 * in state DEFERRED.
1956 afterTriggerCheckState(Oid tgoid, TriggerEvent eventstate)
1958 SetConstraintState state = afterTriggers->state;
1962 * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
1963 * constraints declared NOT DEFERRABLE), the state is always false.
1965 if ((eventstate & AFTER_TRIGGER_DEFERRABLE) == 0)
1969 * Check if SET CONSTRAINTS has been executed for this specific trigger.
1971 for (i = 0; i < state->numstates; i++)
1973 if (state->trigstates[i].sct_tgoid == tgoid)
1974 return state->trigstates[i].sct_tgisdeferred;
1978 * Check if SET CONSTRAINTS ALL has been executed; if so use that.
1980 if (state->all_isset)
1981 return state->all_isdeferred;
1984 * Otherwise return the default state for the trigger.
1986 return ((eventstate & AFTER_TRIGGER_INITDEFERRED) != 0);
1991 * afterTriggerAddEvent()
1993 * Add a new trigger event to the current query's queue.
1997 afterTriggerAddEvent(AfterTriggerEvent event)
1999 AfterTriggerEventList *events;
2001 Assert(event->ate_next == NULL);
2003 /* Must be inside a query */
2004 Assert(afterTriggers->query_depth >= 0);
2006 events = &afterTriggers->query_stack[afterTriggers->query_depth];
2007 if (events->tail == NULL)
2009 /* first list entry */
2010 events->head = event;
2011 events->tail = event;
2015 events->tail->ate_next = event;
2016 events->tail = event;
2022 * AfterTriggerExecute()
2024 * Fetch the required tuples back from the heap and fire one
2025 * single trigger function.
2027 * Frequently, this will be fired many times in a row for triggers of
2028 * a single relation. Therefore, we cache the open relation and provide
2029 * fmgr lookup cache space at the caller level. (For triggers fired at
2030 * the end of a query, we can even piggyback on the executor's state.)
2032 * event: event currently being fired.
2033 * rel: open relation for event.
2034 * trigdesc: working copy of rel's trigger info.
2035 * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
2036 * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
2037 * or NULL if no instrumentation is wanted.
2038 * per_tuple_context: memory context to call trigger function in.
2042 AfterTriggerExecute(AfterTriggerEvent event,
2043 Relation rel, TriggerDesc *trigdesc,
2044 FmgrInfo *finfo, Instrumentation *instr,
2045 MemoryContext per_tuple_context)
2047 Oid tgoid = event->ate_tgoid;
2048 TriggerData LocTriggerData;
2049 HeapTupleData oldtuple;
2050 HeapTupleData newtuple;
2052 Buffer oldbuffer = InvalidBuffer;
2053 Buffer newbuffer = InvalidBuffer;
2057 * Locate trigger in trigdesc.
2059 LocTriggerData.tg_trigger = NULL;
2060 for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
2062 if (trigdesc->triggers[tgindx].tgoid == tgoid)
2064 LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
2068 if (LocTriggerData.tg_trigger == NULL)
2069 elog(ERROR, "could not find trigger %u", tgoid);
2072 * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
2073 * to include time spent re-fetching tuples in the trigger cost.
2076 InstrStartNode(instr + tgindx);
2079 * Fetch the required OLD and NEW tuples.
2081 if (ItemPointerIsValid(&(event->ate_oldctid)))
2083 ItemPointerCopy(&(event->ate_oldctid), &(oldtuple.t_self));
2084 if (!heap_fetch(rel, SnapshotAny, &oldtuple, &oldbuffer, false, NULL))
2085 elog(ERROR, "failed to fetch old tuple for AFTER trigger");
2088 if (ItemPointerIsValid(&(event->ate_newctid)))
2090 ItemPointerCopy(&(event->ate_newctid), &(newtuple.t_self));
2091 if (!heap_fetch(rel, SnapshotAny, &newtuple, &newbuffer, false, NULL))
2092 elog(ERROR, "failed to fetch new tuple for AFTER trigger");
2096 * Setup the trigger information
2098 LocTriggerData.type = T_TriggerData;
2099 LocTriggerData.tg_event =
2100 event->ate_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
2101 LocTriggerData.tg_relation = rel;
2103 switch (event->ate_event & TRIGGER_EVENT_OPMASK)
2105 case TRIGGER_EVENT_INSERT:
2106 LocTriggerData.tg_trigtuple = &newtuple;
2107 LocTriggerData.tg_newtuple = NULL;
2108 LocTriggerData.tg_trigtuplebuf = newbuffer;
2109 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2112 case TRIGGER_EVENT_UPDATE:
2113 LocTriggerData.tg_trigtuple = &oldtuple;
2114 LocTriggerData.tg_newtuple = &newtuple;
2115 LocTriggerData.tg_trigtuplebuf = oldbuffer;
2116 LocTriggerData.tg_newtuplebuf = newbuffer;
2119 case TRIGGER_EVENT_DELETE:
2120 LocTriggerData.tg_trigtuple = &oldtuple;
2121 LocTriggerData.tg_newtuple = NULL;
2122 LocTriggerData.tg_trigtuplebuf = oldbuffer;
2123 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2127 MemoryContextReset(per_tuple_context);
2130 * Call the trigger and throw away any possibly returned updated tuple.
2131 * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
2133 rettuple = ExecCallTriggerFunc(&LocTriggerData,
2138 if (rettuple != NULL && rettuple != &oldtuple && rettuple != &newtuple)
2139 heap_freetuple(rettuple);
2144 if (oldbuffer != InvalidBuffer)
2145 ReleaseBuffer(oldbuffer);
2146 if (newbuffer != InvalidBuffer)
2147 ReleaseBuffer(newbuffer);
2150 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
2151 * one "tuple returned" (really the number of firings).
2154 InstrStopNode(instr + tgindx, true);
2159 * afterTriggerMarkEvents()
2161 * Scan the given event list for not yet invoked events. Mark the ones
2162 * that can be invoked now with the current firing ID.
2164 * If move_list isn't NULL, events that are not to be invoked now are
2165 * removed from the given list and appended to move_list.
2167 * When immediate_only is TRUE, do not invoke currently-deferred triggers.
2168 * (This will be FALSE only at main transaction exit.)
2170 * Returns TRUE if any invokable events were found.
2173 afterTriggerMarkEvents(AfterTriggerEventList *events,
2174 AfterTriggerEventList *move_list,
2175 bool immediate_only)
2178 AfterTriggerEvent event,
2182 event = events->head;
2184 while (event != NULL)
2186 bool defer_it = false;
2187 AfterTriggerEvent next_event;
2189 if (!(event->ate_event &
2190 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS)))
2193 * This trigger hasn't been called or scheduled yet. Check if we
2194 * should call it now.
2196 if (immediate_only &&
2197 afterTriggerCheckState(event->ate_tgoid, event->ate_event))
2204 * Mark it as to be fired in this firing cycle.
2206 event->ate_firing_id = afterTriggers->firing_counter;
2207 event->ate_event |= AFTER_TRIGGER_IN_PROGRESS;
2213 * If it's deferred, move it to move_list, if requested.
2215 next_event = event->ate_next;
2217 if (defer_it && move_list != NULL)
2219 /* Delink it from input list */
2221 prev_event->ate_next = next_event;
2223 events->head = next_event;
2224 /* and add it to move_list */
2225 event->ate_next = NULL;
2226 if (move_list->tail == NULL)
2228 /* first list entry */
2229 move_list->head = event;
2230 move_list->tail = event;
2234 move_list->tail->ate_next = event;
2235 move_list->tail = event;
2240 /* Keep it in input list */
2247 /* Update list tail pointer in case we moved tail event */
2248 events->tail = prev_event;
2254 * afterTriggerInvokeEvents()
2256 * Scan the given event list for events that are marked as to be fired
2257 * in the current firing cycle, and fire them.
2259 * If estate isn't NULL, then we expect that all the firable events are
2260 * for triggers of the relations included in the estate's result relation
2261 * array. This allows us to re-use the estate's open relations and
2262 * trigger cache info. When estate is NULL, we have to find the relations
2265 * When delete_ok is TRUE, it's okay to delete fully-processed events.
2266 * The events list pointers are updated.
2270 afterTriggerInvokeEvents(AfterTriggerEventList *events,
2271 CommandId firing_id,
2275 AfterTriggerEvent event,
2277 MemoryContext per_tuple_context;
2278 Relation rel = NULL;
2279 TriggerDesc *trigdesc = NULL;
2280 FmgrInfo *finfo = NULL;
2281 Instrumentation *instr = NULL;
2283 /* Make a per-tuple memory context for trigger function calls */
2285 AllocSetContextCreate(CurrentMemoryContext,
2286 "AfterTriggerTupleContext",
2287 ALLOCSET_DEFAULT_MINSIZE,
2288 ALLOCSET_DEFAULT_INITSIZE,
2289 ALLOCSET_DEFAULT_MAXSIZE);
2292 event = events->head;
2294 while (event != NULL)
2296 AfterTriggerEvent next_event;
2299 * Is it one for me to fire?
2301 if ((event->ate_event & AFTER_TRIGGER_IN_PROGRESS) &&
2302 event->ate_firing_id == firing_id)
2305 * So let's fire it... but first, open the correct relation if
2306 * this is not the same relation as before.
2308 if (rel == NULL || rel->rd_id != event->ate_relid)
2312 /* Find target relation among estate's result rels */
2313 ResultRelInfo *rInfo;
2316 rInfo = estate->es_result_relations;
2317 nr = estate->es_num_result_relations;
2320 if (rInfo->ri_RelationDesc->rd_id == event->ate_relid)
2325 if (nr <= 0) /* should not happen */
2326 elog(ERROR, "could not find relation %u among query result relations",
2328 rel = rInfo->ri_RelationDesc;
2329 trigdesc = rInfo->ri_TrigDesc;
2330 finfo = rInfo->ri_TrigFunctions;
2331 instr = rInfo->ri_TrigInstrument;
2335 /* Hard way: we manage the resources for ourselves */
2337 heap_close(rel, NoLock);
2339 FreeTriggerDesc(trigdesc);
2342 Assert(instr == NULL); /* never used in this case */
2345 * We assume that an appropriate lock is still held by the
2346 * executor, so grab no new lock here.
2348 rel = heap_open(event->ate_relid, NoLock);
2351 * Copy relation's trigger info so that we have a stable
2352 * copy no matter what the called triggers do.
2354 trigdesc = CopyTriggerDesc(rel->trigdesc);
2356 if (trigdesc == NULL) /* should not happen */
2357 elog(ERROR, "relation %u has no triggers",
2361 * Allocate space to cache fmgr lookup info for triggers.
2363 finfo = (FmgrInfo *)
2364 palloc0(trigdesc->numtriggers * sizeof(FmgrInfo));
2366 /* Never any EXPLAIN info in this case */
2371 * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is still
2372 * set, so recursive examinations of the event list won't try to
2375 AfterTriggerExecute(event, rel, trigdesc, finfo, instr,
2379 * Mark the event as done.
2381 event->ate_event &= ~AFTER_TRIGGER_IN_PROGRESS;
2382 event->ate_event |= AFTER_TRIGGER_DONE;
2386 * If it's now done, throw it away, if allowed.
2388 * NB: it's possible the trigger call above added more events to the
2389 * queue, or that calls we will do later will want to add more, so we
2390 * have to be careful about maintaining list validity at all points
2393 next_event = event->ate_next;
2395 if ((event->ate_event & AFTER_TRIGGER_DONE) && delete_ok)
2397 /* Delink it from list and free it */
2399 prev_event->ate_next = next_event;
2401 events->head = next_event;
2406 /* Keep it in list */
2413 /* Update list tail pointer in case we just deleted tail event */
2414 events->tail = prev_event;
2416 /* Release working resources */
2420 heap_close(rel, NoLock);
2422 FreeTriggerDesc(trigdesc);
2425 Assert(instr == NULL); /* never used in this case */
2427 MemoryContextDelete(per_tuple_context);
2432 * AfterTriggerBeginXact()
2434 * Called at transaction start (either BEGIN or implicit for single
2435 * statement outside of transaction block).
2439 AfterTriggerBeginXact(void)
2441 Assert(afterTriggers == NULL);
2444 * Build empty after-trigger state structure
2446 afterTriggers = (AfterTriggers)
2447 MemoryContextAlloc(TopTransactionContext,
2448 sizeof(AfterTriggersData));
2450 afterTriggers->firing_counter = FirstCommandId;
2451 afterTriggers->state = SetConstraintStateCreate(8);
2452 afterTriggers->events.head = NULL;
2453 afterTriggers->events.tail = NULL;
2454 afterTriggers->query_depth = -1;
2456 /* We initialize the query stack to a reasonable size */
2457 afterTriggers->query_stack = (AfterTriggerEventList *)
2458 MemoryContextAlloc(TopTransactionContext,
2459 8 * sizeof(AfterTriggerEventList));
2460 afterTriggers->maxquerydepth = 8;
2462 /* Subtransaction stack is empty until/unless needed */
2463 afterTriggers->state_stack = NULL;
2464 afterTriggers->events_stack = NULL;
2465 afterTriggers->depth_stack = NULL;
2466 afterTriggers->firing_stack = NULL;
2467 afterTriggers->maxtransdepth = 0;
2472 * AfterTriggerBeginQuery()
2474 * Called just before we start processing a single query within a
2475 * transaction (or subtransaction). Set up to record AFTER trigger
2476 * events queued by the query. Note that it is allowed to have
2477 * nested queries within a (sub)transaction.
2481 AfterTriggerBeginQuery(void)
2483 /* Must be inside a transaction */
2484 Assert(afterTriggers != NULL);
2486 /* Increase the query stack depth */
2487 afterTriggers->query_depth++;
2490 * Allocate more space in the query stack if needed.
2492 if (afterTriggers->query_depth >= afterTriggers->maxquerydepth)
2494 /* repalloc will keep the stack in the same context */
2495 int new_alloc = afterTriggers->maxquerydepth * 2;
2497 afterTriggers->query_stack = (AfterTriggerEventList *)
2498 repalloc(afterTriggers->query_stack,
2499 new_alloc * sizeof(AfterTriggerEventList));
2500 afterTriggers->maxquerydepth = new_alloc;
2503 /* Initialize this query's list to empty */
2504 afterTriggers->query_stack[afterTriggers->query_depth].head = NULL;
2505 afterTriggers->query_stack[afterTriggers->query_depth].tail = NULL;
2510 * AfterTriggerEndQuery()
2512 * Called after one query has been completely processed. At this time
2513 * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
2514 * transfer deferred trigger events to the global deferred-trigger list.
2516 * Note that this should be called just BEFORE closing down the executor
2517 * with ExecutorEnd, because we make use of the EState's info about
2522 AfterTriggerEndQuery(EState *estate)
2524 AfterTriggerEventList *events;
2526 /* Must be inside a transaction */
2527 Assert(afterTriggers != NULL);
2529 /* Must be inside a query, too */
2530 Assert(afterTriggers->query_depth >= 0);
2533 * Process all immediate-mode triggers queued by the query, and move the
2534 * deferred ones to the main list of deferred events.
2536 * Notice that we decide which ones will be fired, and put the deferred
2537 * ones on the main list, before anything is actually fired. This ensures
2538 * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
2539 * IMMEDIATE: all events we have decided to defer will be available for it
2542 * If we find no firable events, we don't have to increment
2545 events = &afterTriggers->query_stack[afterTriggers->query_depth];
2546 if (afterTriggerMarkEvents(events, &afterTriggers->events, true))
2548 CommandId firing_id = afterTriggers->firing_counter++;
2550 /* OK to delete the immediate events after processing them */
2551 afterTriggerInvokeEvents(events, firing_id, estate, true);
2554 afterTriggers->query_depth--;
2559 * AfterTriggerFireDeferred()
2561 * Called just before the current transaction is committed. At this
2562 * time we invoke all pending DEFERRED triggers.
2564 * It is possible for other modules to queue additional deferred triggers
2565 * during pre-commit processing; therefore xact.c may have to call this
2570 AfterTriggerFireDeferred(void)
2572 AfterTriggerEventList *events;
2574 /* Must be inside a transaction */
2575 Assert(afterTriggers != NULL);
2577 /* ... but not inside a query */
2578 Assert(afterTriggers->query_depth == -1);
2581 * If there are any triggers to fire, make sure we have set a snapshot for
2582 * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we
2583 * can't assume ActiveSnapshot is valid on entry.)
2585 events = &afterTriggers->events;
2586 if (events->head != NULL)
2587 ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
2590 * Run all the remaining triggers. Loop until they are all gone, just in
2591 * case some trigger queues more for us to do.
2593 while (afterTriggerMarkEvents(events, NULL, false))
2595 CommandId firing_id = afterTriggers->firing_counter++;
2597 afterTriggerInvokeEvents(events, firing_id, NULL, true);
2600 Assert(events->head == NULL);
2605 * AfterTriggerEndXact()
2607 * The current transaction is finishing.
2609 * Any unfired triggers are canceled so we simply throw
2610 * away anything we know.
2612 * Note: it is possible for this to be called repeatedly in case of
2613 * error during transaction abort; therefore, do not complain if
2614 * already closed down.
2618 AfterTriggerEndXact(bool isCommit)
2621 * Forget everything we know about AFTER triggers.
2623 * Since all the info is in TopTransactionContext or children thereof, we
2624 * need do nothing special to reclaim memory.
2626 afterTriggers = NULL;
2630 * AfterTriggerBeginSubXact()
2632 * Start a subtransaction.
2635 AfterTriggerBeginSubXact(void)
2637 int my_level = GetCurrentTransactionNestLevel();
2640 * Ignore call if the transaction is in aborted state. (Probably
2641 * shouldn't happen?)
2643 if (afterTriggers == NULL)
2647 * Allocate more space in the stacks if needed.
2649 while (my_level >= afterTriggers->maxtransdepth)
2651 if (afterTriggers->maxtransdepth == 0)
2653 MemoryContext old_cxt;
2655 old_cxt = MemoryContextSwitchTo(TopTransactionContext);
2657 #define DEFTRIG_INITALLOC 8
2658 afterTriggers->state_stack = (SetConstraintState *)
2659 palloc(DEFTRIG_INITALLOC * sizeof(SetConstraintState));
2660 afterTriggers->events_stack = (AfterTriggerEventList *)
2661 palloc(DEFTRIG_INITALLOC * sizeof(AfterTriggerEventList));
2662 afterTriggers->depth_stack = (int *)
2663 palloc(DEFTRIG_INITALLOC * sizeof(int));
2664 afterTriggers->firing_stack = (CommandId *)
2665 palloc(DEFTRIG_INITALLOC * sizeof(CommandId));
2666 afterTriggers->maxtransdepth = DEFTRIG_INITALLOC;
2668 MemoryContextSwitchTo(old_cxt);
2672 /* repalloc will keep the stacks in the same context */
2673 int new_alloc = afterTriggers->maxtransdepth * 2;
2675 afterTriggers->state_stack = (SetConstraintState *)
2676 repalloc(afterTriggers->state_stack,
2677 new_alloc * sizeof(SetConstraintState));
2678 afterTriggers->events_stack = (AfterTriggerEventList *)
2679 repalloc(afterTriggers->events_stack,
2680 new_alloc * sizeof(AfterTriggerEventList));
2681 afterTriggers->depth_stack = (int *)
2682 repalloc(afterTriggers->depth_stack,
2683 new_alloc * sizeof(int));
2684 afterTriggers->firing_stack = (CommandId *)
2685 repalloc(afterTriggers->firing_stack,
2686 new_alloc * sizeof(CommandId));
2687 afterTriggers->maxtransdepth = new_alloc;
2692 * Push the current information into the stack. The SET CONSTRAINTS state
2693 * is not saved until/unless changed.
2695 afterTriggers->state_stack[my_level] = NULL;
2696 afterTriggers->events_stack[my_level] = afterTriggers->events;
2697 afterTriggers->depth_stack[my_level] = afterTriggers->query_depth;
2698 afterTriggers->firing_stack[my_level] = afterTriggers->firing_counter;
2702 * AfterTriggerEndSubXact()
2704 * The current subtransaction is ending.
2707 AfterTriggerEndSubXact(bool isCommit)
2709 int my_level = GetCurrentTransactionNestLevel();
2710 SetConstraintState state;
2711 AfterTriggerEvent event;
2712 CommandId subxact_firing_id;
2715 * Ignore call if the transaction is in aborted state. (Probably
2718 if (afterTriggers == NULL)
2722 * Pop the prior state if needed.
2724 Assert(my_level < afterTriggers->maxtransdepth);
2728 /* If we saved a prior state, we don't need it anymore */
2729 state = afterTriggers->state_stack[my_level];
2732 /* this avoids double pfree if error later: */
2733 afterTriggers->state_stack[my_level] = NULL;
2734 Assert(afterTriggers->query_depth ==
2735 afterTriggers->depth_stack[my_level]);
2740 * Aborting --- restore the pointers from the stacks.
2742 afterTriggers->events = afterTriggers->events_stack[my_level];
2743 afterTriggers->query_depth = afterTriggers->depth_stack[my_level];
2746 * Cleanup the tail of the list.
2748 if (afterTriggers->events.tail != NULL)
2749 afterTriggers->events.tail->ate_next = NULL;
2752 * We don't need to free the subtransaction's items, since the
2753 * CurTransactionContext will be reset shortly.
2757 * Restore the trigger state. If the saved state is NULL, then this
2758 * subxact didn't save it, so it doesn't need restoring.
2760 state = afterTriggers->state_stack[my_level];
2763 pfree(afterTriggers->state);
2764 afterTriggers->state = state;
2766 /* this avoids double pfree if error later: */
2767 afterTriggers->state_stack[my_level] = NULL;
2770 * Scan for any remaining deferred events that were marked DONE or IN
2771 * PROGRESS by this subxact or a child, and un-mark them. We can
2772 * recognize such events because they have a firing ID greater than or
2773 * equal to the firing_counter value we saved at subtransaction start.
2774 * (This essentially assumes that the current subxact includes all
2775 * subxacts started after it.)
2777 subxact_firing_id = afterTriggers->firing_stack[my_level];
2778 for (event = afterTriggers->events.head;
2780 event = event->ate_next)
2782 if (event->ate_event &
2783 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))
2785 if (event->ate_firing_id >= subxact_firing_id)
2787 ~(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS);
2794 * Create an empty SetConstraintState with room for numalloc trigstates
2796 static SetConstraintState
2797 SetConstraintStateCreate(int numalloc)
2799 SetConstraintState state;
2801 /* Behave sanely with numalloc == 0 */
2806 * We assume that zeroing will correctly initialize the state values.
2808 state = (SetConstraintState)
2809 MemoryContextAllocZero(TopTransactionContext,
2810 sizeof(SetConstraintStateData) +
2811 (numalloc - 1) *sizeof(SetConstraintTriggerData));
2813 state->numalloc = numalloc;
2819 * Copy a SetConstraintState
2821 static SetConstraintState
2822 SetConstraintStateCopy(SetConstraintState origstate)
2824 SetConstraintState state;
2826 state = SetConstraintStateCreate(origstate->numstates);
2828 state->all_isset = origstate->all_isset;
2829 state->all_isdeferred = origstate->all_isdeferred;
2830 state->numstates = origstate->numstates;
2831 memcpy(state->trigstates, origstate->trigstates,
2832 origstate->numstates * sizeof(SetConstraintTriggerData));
2838 * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
2839 * pointer to the state object (it will change if we have to repalloc).
2841 static SetConstraintState
2842 SetConstraintStateAddItem(SetConstraintState state,
2843 Oid tgoid, bool tgisdeferred)
2845 if (state->numstates >= state->numalloc)
2847 int newalloc = state->numalloc * 2;
2849 newalloc = Max(newalloc, 8); /* in case original has size 0 */
2850 state = (SetConstraintState)
2852 sizeof(SetConstraintStateData) +
2853 (newalloc - 1) *sizeof(SetConstraintTriggerData));
2854 state->numalloc = newalloc;
2855 Assert(state->numstates < state->numalloc);
2858 state->trigstates[state->numstates].sct_tgoid = tgoid;
2859 state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
2866 * AfterTriggerSetState()
2868 * Execute the SET CONSTRAINTS ... utility command.
2872 AfterTriggerSetState(ConstraintsSetStmt *stmt)
2874 int my_level = GetCurrentTransactionNestLevel();
2877 * Ignore call if we aren't in a transaction. (Shouldn't happen?)
2879 if (afterTriggers == NULL)
2883 * If in a subtransaction, and we didn't save the current state already,
2884 * save it so it can be restored if the subtransaction aborts.
2887 afterTriggers->state_stack[my_level] == NULL)
2889 afterTriggers->state_stack[my_level] =
2890 SetConstraintStateCopy(afterTriggers->state);
2894 * Handle SET CONSTRAINTS ALL ...
2896 if (stmt->constraints == NIL)
2899 * Forget any previous SET CONSTRAINTS commands in this transaction.
2901 afterTriggers->state->numstates = 0;
2904 * Set the per-transaction ALL state to known.
2906 afterTriggers->state->all_isset = true;
2907 afterTriggers->state->all_isdeferred = stmt->deferred;
2913 List *oidlist = NIL;
2916 * Handle SET CONSTRAINTS constraint-name [, ...]
2917 * First lookup all trigger Oid's for the constraint names.
2920 tgrel = heap_open(TriggerRelationId, AccessShareLock);
2922 foreach(l, stmt->constraints)
2924 char *cname = strVal(lfirst(l));
2931 * Check that only named constraints are set explicitly
2933 if (strlen(cname) == 0)
2935 (errcode(ERRCODE_INVALID_NAME),
2936 errmsg("unnamed constraints cannot be set explicitly")));
2939 * Setup to scan pg_trigger by tgconstrname ...
2942 Anum_pg_trigger_tgconstrname,
2943 BTEqualStrategyNumber, F_NAMEEQ,
2944 PointerGetDatum(cname));
2946 tgscan = systable_beginscan(tgrel, TriggerConstrNameIndexId, true,
2947 SnapshotNow, 1, &skey);
2950 * ... and search for the constraint trigger row
2954 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
2956 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
2959 * If we found some, check that they fit the deferrability but
2960 * skip referential action ones, since they are silently never
2963 if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
2964 pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL &&
2965 pg_trigger->tgfoid != F_RI_FKEY_CASCADE_UPD &&
2966 pg_trigger->tgfoid != F_RI_FKEY_CASCADE_DEL &&
2967 pg_trigger->tgfoid != F_RI_FKEY_SETNULL_UPD &&
2968 pg_trigger->tgfoid != F_RI_FKEY_SETNULL_DEL &&
2969 pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_UPD &&
2970 pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_DEL)
2972 if (stmt->deferred && !pg_trigger->tgdeferrable)
2974 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2975 errmsg("constraint \"%s\" is not deferrable",
2977 oidlist = lappend_oid(oidlist, HeapTupleGetOid(htup));
2982 systable_endscan(tgscan);
2989 (errcode(ERRCODE_UNDEFINED_OBJECT),
2990 errmsg("constraint \"%s\" does not exist",
2993 heap_close(tgrel, AccessShareLock);
2996 * Set the trigger states of individual triggers for this xact.
3000 Oid tgoid = lfirst_oid(l);
3001 SetConstraintState state = afterTriggers->state;
3005 for (i = 0; i < state->numstates; i++)
3007 if (state->trigstates[i].sct_tgoid == tgoid)
3009 state->trigstates[i].sct_tgisdeferred = stmt->deferred;
3016 afterTriggers->state =
3017 SetConstraintStateAddItem(state, tgoid, stmt->deferred);
3023 * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
3024 * checks against that constraint must be made when the SET CONSTRAINTS
3025 * command is executed -- i.e. the effects of the SET CONSTRAINTS command
3026 * apply retroactively. We've updated the constraints state, so scan the
3027 * list of previously deferred events to fire any that have now become
3030 * Obviously, if this was SET ... DEFERRED then it can't have converted
3031 * any unfired events to immediate, so we need do nothing in that case.
3033 if (!stmt->deferred)
3035 AfterTriggerEventList *events = &afterTriggers->events;
3037 if (afterTriggerMarkEvents(events, NULL, true))
3039 CommandId firing_id = afterTriggers->firing_counter++;
3042 * We can delete fired events if we are at top transaction level,
3043 * but we'd better not if inside a subtransaction, since the
3044 * subtransaction could later get rolled back.
3046 afterTriggerInvokeEvents(events, firing_id, NULL,
3047 !IsSubTransaction());
3054 * AfterTriggerSaveEvent()
3056 * Called by ExecA[RS]...Triggers() to add the event to the queue.
3058 * NOTE: should be called only if we've determined that an event must
3059 * be added to the queue.
3063 AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
3064 HeapTuple oldtup, HeapTuple newtup)
3066 Relation rel = relinfo->ri_RelationDesc;
3067 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3068 AfterTriggerEvent new_event;
3072 ItemPointerData oldctid;
3073 ItemPointerData newctid;
3075 if (afterTriggers == NULL)
3076 elog(ERROR, "AfterTriggerSaveEvent() called outside of transaction");
3079 * Get the CTID's of OLD and NEW
3082 ItemPointerCopy(&(oldtup->t_self), &(oldctid));
3084 ItemPointerSetInvalid(&(oldctid));
3086 ItemPointerCopy(&(newtup->t_self), &(newctid));
3088 ItemPointerSetInvalid(&(newctid));
3091 * Scan the appropriate set of triggers
3095 ntriggers = trigdesc->n_after_row[event];
3096 tgindx = trigdesc->tg_after_row[event];
3100 ntriggers = trigdesc->n_after_statement[event];
3101 tgindx = trigdesc->tg_after_statement[event];
3104 for (i = 0; i < ntriggers; i++)
3106 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
3108 /* Ignore disabled triggers */
3109 if (!trigger->tgenabled)
3113 * If this is an UPDATE of a PK table or FK table that does not change
3114 * the PK or FK respectively, we can skip queuing the event: there is
3115 * no need to fire the trigger.
3117 if ((event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE)
3119 switch (RI_FKey_trigger_type(trigger->tgfoid))
3122 /* Update on PK table */
3123 if (RI_FKey_keyequal_upd_pk(trigger, rel, oldtup, newtup))
3125 /* key unchanged, so skip queuing this event */
3133 * Update on FK table
3135 * There is one exception when updating FK tables: if the
3136 * updated row was inserted by our own transaction and the
3137 * FK is deferred, we still need to fire the trigger. This
3138 * is because our UPDATE will invalidate the INSERT so the
3139 * end-of-transaction INSERT RI trigger will not do
3140 * anything, so we have to do the check for the UPDATE
3143 if (HeapTupleHeaderGetXmin(oldtup->t_data) !=
3144 GetCurrentTransactionId() &&
3145 RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
3151 case RI_TRIGGER_NONE:
3152 /* Not an FK trigger */
3158 * Create a new event. We use the CurTransactionContext so the event
3159 * will automatically go away if the subtransaction aborts.
3161 new_event = (AfterTriggerEvent)
3162 MemoryContextAlloc(CurTransactionContext,
3163 sizeof(AfterTriggerEventData));
3164 new_event->ate_next = NULL;
3165 new_event->ate_event =
3166 (event & TRIGGER_EVENT_OPMASK) |
3167 (row_trigger ? TRIGGER_EVENT_ROW : 0) |
3168 (trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
3169 (trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
3170 new_event->ate_firing_id = 0;
3171 new_event->ate_tgoid = trigger->tgoid;
3172 new_event->ate_relid = rel->rd_id;
3173 ItemPointerCopy(&oldctid, &(new_event->ate_oldctid));
3174 ItemPointerCopy(&newctid, &(new_event->ate_newctid));
3177 * Add the new event to the queue.
3179 afterTriggerAddEvent(new_event);