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.187 2005/04/28 21:47:11 tgl 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/syscache.h"
42 static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx);
43 static HeapTuple GetTupleForTrigger(EState *estate,
44 ResultRelInfo *relinfo,
47 TupleTableSlot **newSlot);
48 static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata,
51 Instrumentation *instr,
52 MemoryContext per_tuple_context);
53 static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
54 bool row_trigger, HeapTuple oldtup, HeapTuple newtup);
58 * Create a trigger. Returns the OID of the created trigger.
60 * forConstraint, if true, says that this trigger is being created to
61 * implement a constraint. The caller will then be expected to make
62 * a pg_depend entry linking the trigger to that constraint (and thereby
63 * to the owning relation(s)).
66 CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
70 Datum values[Natts_pg_trigger];
71 char nulls[Natts_pg_trigger];
79 Oid fargtypes[1]; /* dummy */
85 char constrtrigname[NAMEDATALEN];
88 Oid constrrelid = InvalidOid;
92 rel = heap_openrv(stmt->relation, AccessExclusiveLock);
94 if (stmt->constrrel != NULL)
95 constrrelid = RangeVarGetRelid(stmt->constrrel, false);
96 else if (stmt->isconstraint)
99 * If this trigger is a constraint (and a foreign key one) then we
100 * really need a constrrelid. Since we don't have one, we'll try
101 * to generate one from the argument information.
103 * This is really just a workaround for a long-ago pg_dump bug that
104 * omitted the FROM clause in dumped CREATE CONSTRAINT TRIGGER
105 * commands. We don't want to bomb out completely here if we
106 * can't determine the correct relation, because that would
107 * prevent loading the dump file. Instead, NOTICE here and ERROR
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
189 * If trigger is an RI constraint, use specified trigger name as
190 * constraint name and build a unique trigger name instead. This is
191 * mainly for backwards compatibility with CREATE CONSTRAINT TRIGGER
194 if (stmt->isconstraint)
196 snprintf(constrtrigname, sizeof(constrtrigname),
197 "RI_ConstraintTrigger_%u", trigoid);
198 trigname = constrtrigname;
199 constrname = stmt->trigname;
203 trigname = stmt->trigname;
207 TRIGGER_CLEAR_TYPE(tgtype);
209 TRIGGER_SETT_BEFORE(tgtype);
211 TRIGGER_SETT_ROW(tgtype);
213 for (i = 0; stmt->actions[i]; i++)
215 switch (stmt->actions[i])
218 if (TRIGGER_FOR_INSERT(tgtype))
220 (errcode(ERRCODE_SYNTAX_ERROR),
221 errmsg("multiple INSERT events specified")));
222 TRIGGER_SETT_INSERT(tgtype);
225 if (TRIGGER_FOR_DELETE(tgtype))
227 (errcode(ERRCODE_SYNTAX_ERROR),
228 errmsg("multiple DELETE events specified")));
229 TRIGGER_SETT_DELETE(tgtype);
232 if (TRIGGER_FOR_UPDATE(tgtype))
234 (errcode(ERRCODE_SYNTAX_ERROR),
235 errmsg("multiple UPDATE events specified")));
236 TRIGGER_SETT_UPDATE(tgtype);
239 elog(ERROR, "unrecognized trigger event: %d",
240 (int) stmt->actions[i]);
246 * Scan pg_trigger for existing triggers on relation. We do this
247 * mainly because we must count them; a secondary benefit is to give a
248 * nice error message if there's already a trigger of the same name.
249 * (The unique index on tgrelid/tgname would complain anyway.)
251 * NOTE that this is cool only because we have AccessExclusiveLock on the
252 * relation, so the trigger set won't be changing underneath us.
254 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
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
283 * see a 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
388 * backends (and this one too!) are sent SI message to make them
389 * rebuild relcache entries.
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
411 * upcoming CommandCounterIncrement...
415 * Record dependencies for trigger. Always place a normal dependency
416 * on the function. If we are doing this in response to an explicit
417 * CREATE TRIGGER command, also make trigger be auto-dropped if its
418 * relation is dropped or if the FK relation is dropped. (Auto drop
419 * is compatible with our pre-7.3 behavior.) If the trigger is being
420 * made for a constraint, we can skip the relation links; the
421 * dependency on the constraint will indirectly depend on the
424 referenced.classId = ProcedureRelationId;
425 referenced.objectId = funcoid;
426 referenced.objectSubId = 0;
427 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
431 referenced.classId = RelationRelationId;
432 referenced.objectId = RelationGetRelid(rel);
433 referenced.objectSubId = 0;
434 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
435 if (constrrelid != InvalidOid)
437 referenced.classId = RelationRelationId;
438 referenced.objectId = constrrelid;
439 referenced.objectSubId = 0;
440 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
444 /* Keep lock on target rel until end of xact */
445 heap_close(rel, NoLock);
451 * DropTrigger - drop an individual trigger by name
454 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
460 ObjectAddress object;
463 * Find the trigger, verify permissions, set up object address
465 tgrel = heap_open(TriggerRelationId, AccessShareLock);
467 ScanKeyInit(&skey[0],
468 Anum_pg_trigger_tgrelid,
469 BTEqualStrategyNumber, F_OIDEQ,
470 ObjectIdGetDatum(relid));
472 ScanKeyInit(&skey[1],
473 Anum_pg_trigger_tgname,
474 BTEqualStrategyNumber, F_NAMEEQ,
475 CStringGetDatum(trigname));
477 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
478 SnapshotNow, 2, skey);
480 tup = systable_getnext(tgscan);
482 if (!HeapTupleIsValid(tup))
484 (errcode(ERRCODE_UNDEFINED_OBJECT),
485 errmsg("trigger \"%s\" for table \"%s\" does not exist",
486 trigname, get_rel_name(relid))));
488 if (!pg_class_ownercheck(relid, GetUserId()))
489 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
490 get_rel_name(relid));
492 object.classId = TriggerRelationId;
493 object.objectId = HeapTupleGetOid(tup);
494 object.objectSubId = 0;
496 systable_endscan(tgscan);
497 heap_close(tgrel, AccessShareLock);
502 performDeletion(&object, behavior);
506 * Guts of trigger deletion.
509 RemoveTriggerById(Oid trigOid)
519 Form_pg_class classForm;
521 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
524 * Find the trigger to delete.
526 ScanKeyInit(&skey[0],
527 ObjectIdAttributeNumber,
528 BTEqualStrategyNumber, F_OIDEQ,
529 ObjectIdGetDatum(trigOid));
531 tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
532 SnapshotNow, 1, skey);
534 tup = systable_getnext(tgscan);
535 if (!HeapTupleIsValid(tup))
536 elog(ERROR, "could not find tuple for trigger %u", trigOid);
539 * Open and exclusive-lock the relation the trigger belongs to.
541 relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
543 rel = heap_open(relid, AccessExclusiveLock);
545 if (rel->rd_rel->relkind != RELKIND_RELATION)
547 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
548 errmsg("\"%s\" is not a table",
549 RelationGetRelationName(rel))));
551 if (!allowSystemTableMods && IsSystemRelation(rel))
553 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
554 errmsg("permission denied: \"%s\" is a system catalog",
555 RelationGetRelationName(rel))));
558 * Delete the pg_trigger tuple.
560 simple_heap_delete(tgrel, &tup->t_self);
562 systable_endscan(tgscan);
563 heap_close(tgrel, RowExclusiveLock);
566 * Update relation's pg_class entry. Crucial side-effect: other
567 * backends (and this one too!) are sent SI message to make them
568 * rebuild relcache entries.
570 * Note this is OK only because we have AccessExclusiveLock on the rel,
571 * so no one else is creating/deleting triggers on this rel at the
574 pgrel = heap_open(RelationRelationId, RowExclusiveLock);
575 tuple = SearchSysCacheCopy(RELOID,
576 ObjectIdGetDatum(relid),
578 if (!HeapTupleIsValid(tuple))
579 elog(ERROR, "cache lookup failed for relation %u", relid);
580 classForm = (Form_pg_class) GETSTRUCT(tuple);
582 if (classForm->reltriggers == 0) /* should not happen */
583 elog(ERROR, "relation \"%s\" has reltriggers = 0",
584 RelationGetRelationName(rel));
585 classForm->reltriggers--;
587 simple_heap_update(pgrel, &tuple->t_self, tuple);
589 CatalogUpdateIndexes(pgrel, tuple);
591 heap_freetuple(tuple);
593 heap_close(pgrel, RowExclusiveLock);
595 /* Keep lock on trigger's rel until end of xact */
596 heap_close(rel, NoLock);
600 * renametrig - changes the name of a trigger on a relation
602 * trigger name is changed in trigger catalog.
603 * No record of the previous name is kept.
605 * get proper relrelation from relation catalog (if not arg)
606 * scan trigger catalog
607 * for name conflict (within rel)
608 * for original trigger (if not arg)
609 * modify tgname in trigger tuple
610 * update row in catalog
613 renametrig(Oid relid,
624 * Grab an exclusive lock on the target table, which we will NOT
625 * release until end of transaction.
627 targetrel = heap_open(relid, AccessExclusiveLock);
630 * Scan pg_trigger twice for existing triggers on relation. We do
631 * this in order to ensure a trigger does not exist with newname (The
632 * unique index on tgrelid/tgname would complain anyway) and to ensure
633 * a trigger does exist with oldname.
635 * NOTE that this is cool only because we have AccessExclusiveLock on the
636 * relation, so the trigger set won't be changing underneath us.
638 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
641 * First pass -- look for name conflict
644 Anum_pg_trigger_tgrelid,
645 BTEqualStrategyNumber, F_OIDEQ,
646 ObjectIdGetDatum(relid));
648 Anum_pg_trigger_tgname,
649 BTEqualStrategyNumber, F_NAMEEQ,
650 PointerGetDatum(newname));
651 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
652 SnapshotNow, 2, key);
653 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
655 (errcode(ERRCODE_DUPLICATE_OBJECT),
656 errmsg("trigger \"%s\" for relation \"%s\" already exists",
657 newname, RelationGetRelationName(targetrel))));
658 systable_endscan(tgscan);
661 * Second pass -- look for trigger existing with oldname and update
664 Anum_pg_trigger_tgrelid,
665 BTEqualStrategyNumber, F_OIDEQ,
666 ObjectIdGetDatum(relid));
668 Anum_pg_trigger_tgname,
669 BTEqualStrategyNumber, F_NAMEEQ,
670 PointerGetDatum(oldname));
671 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
672 SnapshotNow, 2, key);
673 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
676 * Update pg_trigger tuple with new tgname.
678 tuple = heap_copytuple(tuple); /* need a modifiable copy */
680 namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname, newname);
682 simple_heap_update(tgrel, &tuple->t_self, tuple);
684 /* keep system catalog indexes current */
685 CatalogUpdateIndexes(tgrel, tuple);
688 * Invalidate relation's relcache entry so that other backends
689 * (and this one too!) are sent SI message to make them rebuild
690 * relcache entries. (Ideally this should happen
693 CacheInvalidateRelcache(targetrel);
698 (errcode(ERRCODE_UNDEFINED_OBJECT),
699 errmsg("trigger \"%s\" for table \"%s\" does not exist",
700 oldname, RelationGetRelationName(targetrel))));
703 systable_endscan(tgscan);
705 heap_close(tgrel, RowExclusiveLock);
708 * Close rel, but keep exclusive lock!
710 heap_close(targetrel, NoLock);
714 * Build trigger data to attach to the given relcache entry.
716 * Note that trigger data attached to a relcache entry must be stored in
717 * CacheMemoryContext to ensure it survives as long as the relcache entry.
718 * But we should be running in a less long-lived working context. To avoid
719 * leaking cache memory if this routine fails partway through, we build a
720 * temporary TriggerDesc in working memory and then copy the completed
721 * structure into cache memory.
724 RelationBuildTriggers(Relation relation)
726 TriggerDesc *trigdesc;
727 int ntrigs = relation->rd_rel->reltriggers;
734 MemoryContext oldContext;
736 Assert(ntrigs > 0); /* else I should not have been called */
738 triggers = (Trigger *) palloc(ntrigs * sizeof(Trigger));
741 * Note: since we scan the triggers using TriggerRelidNameIndexId, we
742 * will be reading the triggers in name order, except possibly during
743 * emergency-recovery operations (ie, IsIgnoringSystemIndexes). This
744 * in turn ensures that triggers will be fired in name order.
747 Anum_pg_trigger_tgrelid,
748 BTEqualStrategyNumber, F_OIDEQ,
749 ObjectIdGetDatum(RelationGetRelid(relation)));
751 tgrel = heap_open(TriggerRelationId, AccessShareLock);
752 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
753 SnapshotNow, 1, &skey);
755 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
757 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
761 elog(ERROR, "too many trigger records found for relation \"%s\"",
762 RelationGetRelationName(relation));
763 build = &(triggers[found]);
765 build->tgoid = HeapTupleGetOid(htup);
766 build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
767 NameGetDatum(&pg_trigger->tgname)));
768 build->tgfoid = pg_trigger->tgfoid;
769 build->tgtype = pg_trigger->tgtype;
770 build->tgenabled = pg_trigger->tgenabled;
771 build->tgisconstraint = pg_trigger->tgisconstraint;
772 build->tgconstrrelid = pg_trigger->tgconstrrelid;
773 build->tgdeferrable = pg_trigger->tgdeferrable;
774 build->tginitdeferred = pg_trigger->tginitdeferred;
775 build->tgnargs = pg_trigger->tgnargs;
776 /* tgattr is first var-width field, so OK to access directly */
777 build->tgnattr = pg_trigger->tgattr.dim1;
778 if (build->tgnattr > 0)
780 build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2));
781 memcpy(build->tgattr, &(pg_trigger->tgattr.values),
782 build->tgnattr * sizeof(int2));
785 build->tgattr = NULL;
786 if (build->tgnargs > 0)
794 DatumGetPointer(fastgetattr(htup,
795 Anum_pg_trigger_tgargs,
796 tgrel->rd_att, &isnull));
798 elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
799 RelationGetRelationName(relation));
800 p = (char *) VARDATA(val);
801 build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
802 for (i = 0; i < build->tgnargs; i++)
804 build->tgargs[i] = pstrdup(p);
809 build->tgargs = NULL;
814 systable_endscan(tgscan);
815 heap_close(tgrel, AccessShareLock);
818 elog(ERROR, "%d trigger record(s) not found for relation \"%s\"",
820 RelationGetRelationName(relation));
823 trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
824 trigdesc->triggers = triggers;
825 trigdesc->numtriggers = ntrigs;
826 for (found = 0; found < ntrigs; found++)
827 InsertTrigger(trigdesc, &(triggers[found]), found);
829 /* Copy completed trigdesc into cache storage */
830 oldContext = MemoryContextSwitchTo(CacheMemoryContext);
831 relation->trigdesc = CopyTriggerDesc(trigdesc);
832 MemoryContextSwitchTo(oldContext);
834 /* Release working memory */
835 FreeTriggerDesc(trigdesc);
839 * Insert the given trigger into the appropriate index list(s) for it
841 * To simplify storage management, we allocate each index list at the max
842 * possible size (trigdesc->numtriggers) if it's used at all. This does
843 * not waste space permanently since we're only building a temporary
844 * trigdesc at this point.
847 InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx)
853 if (TRIGGER_FOR_ROW(trigger->tgtype))
856 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
858 n = trigdesc->n_before_row;
859 t = trigdesc->tg_before_row;
863 n = trigdesc->n_after_row;
864 t = trigdesc->tg_after_row;
869 /* STATEMENT trigger */
870 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
872 n = trigdesc->n_before_statement;
873 t = trigdesc->tg_before_statement;
877 n = trigdesc->n_after_statement;
878 t = trigdesc->tg_after_statement;
882 if (TRIGGER_FOR_INSERT(trigger->tgtype))
884 tp = &(t[TRIGGER_EVENT_INSERT]);
886 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
887 (*tp)[n[TRIGGER_EVENT_INSERT]] = indx;
888 (n[TRIGGER_EVENT_INSERT])++;
891 if (TRIGGER_FOR_DELETE(trigger->tgtype))
893 tp = &(t[TRIGGER_EVENT_DELETE]);
895 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
896 (*tp)[n[TRIGGER_EVENT_DELETE]] = indx;
897 (n[TRIGGER_EVENT_DELETE])++;
900 if (TRIGGER_FOR_UPDATE(trigger->tgtype))
902 tp = &(t[TRIGGER_EVENT_UPDATE]);
904 *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
905 (*tp)[n[TRIGGER_EVENT_UPDATE]] = indx;
906 (n[TRIGGER_EVENT_UPDATE])++;
911 * Copy a TriggerDesc data structure.
913 * The copy is allocated in the current memory context.
916 CopyTriggerDesc(TriggerDesc *trigdesc)
918 TriggerDesc *newdesc;
925 if (trigdesc == NULL || trigdesc->numtriggers <= 0)
928 newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
929 memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
931 trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
932 memcpy(trigger, trigdesc->triggers,
933 trigdesc->numtriggers * sizeof(Trigger));
934 newdesc->triggers = trigger;
936 for (i = 0; i < trigdesc->numtriggers; i++)
938 trigger->tgname = pstrdup(trigger->tgname);
939 if (trigger->tgnattr > 0)
943 newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2));
944 memcpy(newattr, trigger->tgattr,
945 trigger->tgnattr * sizeof(int2));
946 trigger->tgattr = newattr;
948 if (trigger->tgnargs > 0)
953 newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
954 for (j = 0; j < trigger->tgnargs; j++)
955 newargs[j] = pstrdup(trigger->tgargs[j]);
956 trigger->tgargs = newargs;
961 n = newdesc->n_before_statement;
962 t = newdesc->tg_before_statement;
963 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
967 tnew = (int *) palloc(n[i] * sizeof(int));
968 memcpy(tnew, t[i], n[i] * sizeof(int));
974 n = newdesc->n_before_row;
975 t = newdesc->tg_before_row;
976 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
980 tnew = (int *) palloc(n[i] * sizeof(int));
981 memcpy(tnew, t[i], n[i] * sizeof(int));
987 n = newdesc->n_after_row;
988 t = newdesc->tg_after_row;
989 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
993 tnew = (int *) palloc(n[i] * sizeof(int));
994 memcpy(tnew, t[i], n[i] * sizeof(int));
1000 n = newdesc->n_after_statement;
1001 t = newdesc->tg_after_statement;
1002 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1006 tnew = (int *) palloc(n[i] * sizeof(int));
1007 memcpy(tnew, t[i], n[i] * sizeof(int));
1018 * Free a TriggerDesc data structure.
1021 FreeTriggerDesc(TriggerDesc *trigdesc)
1027 if (trigdesc == NULL)
1030 t = trigdesc->tg_before_statement;
1031 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1034 t = trigdesc->tg_before_row;
1035 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1038 t = trigdesc->tg_after_row;
1039 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1042 t = trigdesc->tg_after_statement;
1043 for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1047 trigger = trigdesc->triggers;
1048 for (i = 0; i < trigdesc->numtriggers; i++)
1050 pfree(trigger->tgname);
1051 if (trigger->tgnattr > 0)
1052 pfree(trigger->tgattr);
1053 if (trigger->tgnargs > 0)
1055 while (--(trigger->tgnargs) >= 0)
1056 pfree(trigger->tgargs[trigger->tgnargs]);
1057 pfree(trigger->tgargs);
1061 pfree(trigdesc->triggers);
1066 * Compare two TriggerDesc structures for logical equality.
1070 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
1076 * We need not examine the "index" data, just the trigger array
1077 * itself; if we have the same triggers with the same types, the
1078 * derived index data should match.
1080 * As of 7.3 we assume trigger set ordering is significant in the
1081 * comparison; so we just compare corresponding slots of the two sets.
1083 if (trigdesc1 != NULL)
1085 if (trigdesc2 == NULL)
1087 if (trigdesc1->numtriggers != trigdesc2->numtriggers)
1089 for (i = 0; i < trigdesc1->numtriggers; i++)
1091 Trigger *trig1 = trigdesc1->triggers + i;
1092 Trigger *trig2 = trigdesc2->triggers + i;
1094 if (trig1->tgoid != trig2->tgoid)
1096 if (strcmp(trig1->tgname, trig2->tgname) != 0)
1098 if (trig1->tgfoid != trig2->tgfoid)
1100 if (trig1->tgtype != trig2->tgtype)
1102 if (trig1->tgenabled != trig2->tgenabled)
1104 if (trig1->tgisconstraint != trig2->tgisconstraint)
1106 if (trig1->tgconstrrelid != trig2->tgconstrrelid)
1108 if (trig1->tgdeferrable != trig2->tgdeferrable)
1110 if (trig1->tginitdeferred != trig2->tginitdeferred)
1112 if (trig1->tgnargs != trig2->tgnargs)
1114 if (trig1->tgnattr != trig2->tgnattr)
1116 if (trig1->tgnattr > 0 &&
1117 memcmp(trig1->tgattr, trig2->tgattr,
1118 trig1->tgnattr * sizeof(int2)) != 0)
1120 for (j = 0; j < trig1->tgnargs; j++)
1121 if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
1125 else if (trigdesc2 != NULL)
1129 #endif /* NOT_USED */
1132 * Call a trigger function.
1134 * trigdata: trigger descriptor.
1135 * tgindx: trigger's index in finfo and instr arrays.
1136 * finfo: array of cached trigger function call information.
1137 * instr: optional array of EXPLAIN ANALYZE instrumentation state.
1138 * per_tuple_context: memory context to execute the function in.
1140 * Returns the tuple (or NULL) as returned by the function.
1143 ExecCallTriggerFunc(TriggerData *trigdata,
1146 Instrumentation *instr,
1147 MemoryContext per_tuple_context)
1149 FunctionCallInfoData fcinfo;
1151 MemoryContext oldContext;
1156 * We cache fmgr lookup info, to avoid making the lookup again on each
1159 if (finfo->fn_oid == InvalidOid)
1160 fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
1162 Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
1165 * If doing EXPLAIN ANALYZE, start charging time to this trigger.
1168 InstrStartNode(instr + tgindx);
1171 * Do the function evaluation in the per-tuple memory context, so that
1172 * leaked memory will be reclaimed once per tuple. Note in particular
1173 * that any new tuple created by the trigger function will live till
1174 * the end of the tuple cycle.
1176 oldContext = MemoryContextSwitchTo(per_tuple_context);
1179 * Call the function, passing no arguments but setting a context.
1181 InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
1183 result = FunctionCallInvoke(&fcinfo);
1185 MemoryContextSwitchTo(oldContext);
1188 * Trigger protocol allows function to return a null pointer, but NOT
1189 * to set the isnull result flag.
1193 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1194 errmsg("trigger function %u returned null value",
1195 fcinfo.flinfo->fn_oid)));
1198 * If doing EXPLAIN ANALYZE, stop charging time to this trigger,
1199 * and count one "tuple returned" (really the number of firings).
1202 InstrStopNode(instr + tgindx, true);
1204 return (HeapTuple) DatumGetPointer(result);
1208 ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1210 TriggerDesc *trigdesc;
1214 TriggerData LocTriggerData;
1216 trigdesc = relinfo->ri_TrigDesc;
1218 if (trigdesc == NULL)
1221 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_INSERT];
1222 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_INSERT];
1227 LocTriggerData.type = T_TriggerData;
1228 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1229 TRIGGER_EVENT_BEFORE;
1230 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1231 LocTriggerData.tg_trigtuple = NULL;
1232 LocTriggerData.tg_newtuple = NULL;
1233 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1234 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1235 for (i = 0; i < ntrigs; i++)
1237 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1240 if (!trigger->tgenabled)
1242 LocTriggerData.tg_trigger = trigger;
1243 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1245 relinfo->ri_TrigFunctions,
1246 relinfo->ri_TrigInstrument,
1247 GetPerTupleMemoryContext(estate));
1251 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1252 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1257 ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1259 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1261 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_INSERT] > 0)
1262 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1267 ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1268 HeapTuple trigtuple)
1270 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1271 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
1272 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
1273 HeapTuple newtuple = trigtuple;
1275 TriggerData LocTriggerData;
1278 LocTriggerData.type = T_TriggerData;
1279 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1281 TRIGGER_EVENT_BEFORE;
1282 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1283 LocTriggerData.tg_newtuple = NULL;
1284 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1285 for (i = 0; i < ntrigs; i++)
1287 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1289 if (!trigger->tgenabled)
1291 LocTriggerData.tg_trigtuple = oldtuple = newtuple;
1292 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1293 LocTriggerData.tg_trigger = trigger;
1294 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1296 relinfo->ri_TrigFunctions,
1297 relinfo->ri_TrigInstrument,
1298 GetPerTupleMemoryContext(estate));
1299 if (oldtuple != newtuple && oldtuple != trigtuple)
1300 heap_freetuple(oldtuple);
1301 if (newtuple == NULL)
1308 ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1309 HeapTuple trigtuple)
1311 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1313 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
1314 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1315 true, NULL, trigtuple);
1319 ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1321 TriggerDesc *trigdesc;
1325 TriggerData LocTriggerData;
1327 trigdesc = relinfo->ri_TrigDesc;
1329 if (trigdesc == NULL)
1332 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_DELETE];
1333 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_DELETE];
1338 LocTriggerData.type = T_TriggerData;
1339 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1340 TRIGGER_EVENT_BEFORE;
1341 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1342 LocTriggerData.tg_trigtuple = NULL;
1343 LocTriggerData.tg_newtuple = NULL;
1344 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1345 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1346 for (i = 0; i < ntrigs; i++)
1348 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1351 if (!trigger->tgenabled)
1353 LocTriggerData.tg_trigger = trigger;
1354 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1356 relinfo->ri_TrigFunctions,
1357 relinfo->ri_TrigInstrument,
1358 GetPerTupleMemoryContext(estate));
1362 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1363 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1368 ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1370 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1372 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_DELETE] > 0)
1373 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1378 ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1379 ItemPointer tupleid,
1382 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1383 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
1384 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
1385 TriggerData LocTriggerData;
1386 HeapTuple trigtuple;
1387 HeapTuple newtuple = NULL;
1388 TupleTableSlot *newSlot;
1391 trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1392 if (trigtuple == NULL)
1395 LocTriggerData.type = T_TriggerData;
1396 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1398 TRIGGER_EVENT_BEFORE;
1399 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1400 LocTriggerData.tg_newtuple = NULL;
1401 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1402 for (i = 0; i < ntrigs; i++)
1404 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1406 if (!trigger->tgenabled)
1408 LocTriggerData.tg_trigtuple = trigtuple;
1409 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1410 LocTriggerData.tg_trigger = trigger;
1411 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1413 relinfo->ri_TrigFunctions,
1414 relinfo->ri_TrigInstrument,
1415 GetPerTupleMemoryContext(estate));
1416 if (newtuple == NULL)
1418 if (newtuple != trigtuple)
1419 heap_freetuple(newtuple);
1421 heap_freetuple(trigtuple);
1423 return (newtuple == NULL) ? false : true;
1427 ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1428 ItemPointer tupleid)
1430 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1432 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
1434 HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo,
1439 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1440 true, trigtuple, NULL);
1441 heap_freetuple(trigtuple);
1446 ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1448 TriggerDesc *trigdesc;
1452 TriggerData LocTriggerData;
1454 trigdesc = relinfo->ri_TrigDesc;
1456 if (trigdesc == NULL)
1459 ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_UPDATE];
1460 tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_UPDATE];
1465 LocTriggerData.type = T_TriggerData;
1466 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1467 TRIGGER_EVENT_BEFORE;
1468 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1469 LocTriggerData.tg_trigtuple = NULL;
1470 LocTriggerData.tg_newtuple = NULL;
1471 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1472 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1473 for (i = 0; i < ntrigs; i++)
1475 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1478 if (!trigger->tgenabled)
1480 LocTriggerData.tg_trigger = trigger;
1481 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1483 relinfo->ri_TrigFunctions,
1484 relinfo->ri_TrigInstrument,
1485 GetPerTupleMemoryContext(estate));
1489 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1490 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1495 ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1497 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1499 if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_UPDATE] > 0)
1500 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1505 ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1506 ItemPointer tupleid, HeapTuple newtuple,
1509 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1510 int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
1511 int *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
1512 TriggerData LocTriggerData;
1513 HeapTuple trigtuple;
1515 HeapTuple intuple = newtuple;
1516 TupleTableSlot *newSlot;
1519 trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1520 if (trigtuple == NULL)
1524 * In READ COMMITTED isolation level it's possible that newtuple was
1525 * changed due to concurrent update.
1527 if (newSlot != NULL)
1528 intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);
1530 LocTriggerData.type = T_TriggerData;
1531 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1533 TRIGGER_EVENT_BEFORE;
1534 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1535 for (i = 0; i < ntrigs; i++)
1537 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
1539 if (!trigger->tgenabled)
1541 LocTriggerData.tg_trigtuple = trigtuple;
1542 LocTriggerData.tg_newtuple = oldtuple = newtuple;
1543 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1544 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1545 LocTriggerData.tg_trigger = trigger;
1546 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1548 relinfo->ri_TrigFunctions,
1549 relinfo->ri_TrigInstrument,
1550 GetPerTupleMemoryContext(estate));
1551 if (oldtuple != newtuple && oldtuple != intuple)
1552 heap_freetuple(oldtuple);
1553 if (newtuple == NULL)
1556 heap_freetuple(trigtuple);
1561 ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1562 ItemPointer tupleid, HeapTuple newtuple)
1564 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1566 if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
1568 HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo,
1573 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1574 true, trigtuple, newtuple);
1575 heap_freetuple(trigtuple);
1581 GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
1582 ItemPointer tid, CommandId cid,
1583 TupleTableSlot **newSlot)
1585 Relation relation = relinfo->ri_RelationDesc;
1586 HeapTupleData tuple;
1590 if (newSlot != NULL)
1595 * lock tuple for update
1598 tuple.t_self = *tid;
1600 test = heap_lock_tuple(relation, &tuple, &buffer, cid, LockTupleExclusive);
1603 case HeapTupleSelfUpdated:
1604 /* treat it as deleted; do not process */
1605 ReleaseBuffer(buffer);
1608 case HeapTupleMayBeUpdated:
1611 case HeapTupleUpdated:
1612 ReleaseBuffer(buffer);
1613 if (IsXactIsoLevelSerializable)
1615 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1616 errmsg("could not serialize access due to concurrent update")));
1617 else if (!(ItemPointerEquals(&(tuple.t_self), tid)))
1619 TupleTableSlot *epqslot = EvalPlanQual(estate,
1620 relinfo->ri_RangeTableIndex,
1623 if (!(TupIsNull(epqslot)))
1625 *tid = tuple.t_self;
1632 * if tuple was deleted or PlanQual failed for updated
1633 * tuple - we have not process this tuple!
1638 ReleaseBuffer(buffer);
1639 elog(ERROR, "invalid heap_lock_tuple status: %d", test);
1640 return NULL; /* keep compiler quiet */
1648 buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
1650 dp = (PageHeader) BufferGetPage(buffer);
1651 lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
1653 Assert(ItemIdIsUsed(lp));
1655 tuple.t_datamcxt = NULL;
1656 tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
1657 tuple.t_len = ItemIdGetLength(lp);
1658 tuple.t_self = *tid;
1661 result = heap_copytuple(&tuple);
1662 ReleaseBuffer(buffer);
1669 * After-trigger stuff
1671 * The AfterTriggersData struct holds data about pending AFTER trigger events
1672 * during the current transaction tree. (BEFORE triggers are fired
1673 * immediately so we don't need any persistent state about them.) The struct
1674 * and most of its subsidiary data are kept in TopTransactionContext; however
1675 * the individual event records are kept in CurTransactionContext, so that
1676 * they will easily go away during subtransaction abort.
1678 * Because the list of pending events can grow large, we go to some effort
1679 * to minimize memory consumption. We do not use the generic List mechanism
1680 * but thread the events manually.
1682 * XXX We need to be able to save the per-event data in a file if it grows too
1687 /* Per-trigger SET CONSTRAINT status */
1688 typedef struct SetConstraintTriggerData
1691 bool sct_tgisdeferred;
1692 } SetConstraintTriggerData;
1694 typedef struct SetConstraintTriggerData *SetConstraintTrigger;
1697 * SET CONSTRAINT intra-transaction status.
1699 * We make this a single palloc'd object so it can be copied and freed easily.
1701 * all_isset and all_isdeferred are used to keep track
1702 * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
1704 * trigstates[] stores per-trigger tgisdeferred settings.
1706 typedef struct SetConstraintStateData
1709 bool all_isdeferred;
1710 int numstates; /* number of trigstates[] entries in use */
1711 int numalloc; /* allocated size of trigstates[] */
1712 SetConstraintTriggerData trigstates[1]; /* VARIABLE LENGTH ARRAY */
1713 } SetConstraintStateData;
1715 typedef SetConstraintStateData *SetConstraintState;
1719 * Per-trigger-event data
1721 * Note: ate_firing_id is meaningful when either AFTER_TRIGGER_DONE
1722 * or AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
1723 * cycle the trigger was or will be fired in.
1725 typedef struct AfterTriggerEventData *AfterTriggerEvent;
1727 typedef struct AfterTriggerEventData
1729 AfterTriggerEvent ate_next; /* list link */
1730 TriggerEvent ate_event; /* event type and status bits */
1731 CommandId ate_firing_id; /* ID for firing cycle */
1732 Oid ate_tgoid; /* the trigger's ID */
1733 Oid ate_relid; /* the relation it's on */
1734 ItemPointerData ate_oldctid; /* specific tuple(s) involved */
1735 ItemPointerData ate_newctid;
1736 } AfterTriggerEventData;
1738 /* A list of events */
1739 typedef struct AfterTriggerEventList
1741 AfterTriggerEvent head;
1742 AfterTriggerEvent tail;
1743 } AfterTriggerEventList;
1747 * All per-transaction data for the AFTER TRIGGERS module.
1749 * AfterTriggersData has the following fields:
1751 * firing_counter is incremented for each call of afterTriggerInvokeEvents.
1752 * We mark firable events with the current firing cycle's ID so that we can
1753 * tell which ones to work on. This ensures sane behavior if a trigger
1754 * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
1755 * only fire those events that weren't already scheduled for firing.
1757 * state keeps track of the transaction-local effects of SET CONSTRAINTS.
1758 * This is saved and restored across failed subtransactions.
1760 * events is the current list of deferred events. This is global across
1761 * all subtransactions of the current transaction. In a subtransaction
1762 * abort, we know that the events added by the subtransaction are at the
1763 * end of the list, so it is relatively easy to discard them.
1765 * query_depth is the current depth of nested AfterTriggerBeginQuery calls
1766 * (-1 when the stack is empty).
1768 * query_stack[query_depth] is a list of AFTER trigger events queued by the
1769 * current query (and the query_stack entries below it are lists of trigger
1770 * events queued by calling queries). None of these are valid until the
1771 * matching AfterTriggerEndQuery call occurs. At that point we fire
1772 * immediate-mode triggers, and append any deferred events to the main events
1775 * maxquerydepth is just the allocated length of query_stack.
1777 * state_stack is a stack of pointers to saved copies of the SET CONSTRAINTS
1778 * state data; each subtransaction level that modifies that state first
1779 * saves a copy, which we use to restore the state if we abort.
1781 * events_stack is a stack of copies of the events head/tail pointers,
1782 * which we use to restore those values during subtransaction abort.
1784 * depth_stack is a stack of copies of subtransaction-start-time query_depth,
1785 * which we similarly use to clean up at subtransaction abort.
1787 * firing_stack is a stack of copies of subtransaction-start-time
1788 * firing_counter. We use this to recognize which deferred triggers were
1789 * fired (or marked for firing) within an aborted subtransaction.
1791 * We use GetCurrentTransactionNestLevel() to determine the correct array
1792 * index in these stacks. maxtransdepth is the number of allocated entries in
1793 * each stack. (By not keeping our own stack pointer, we can avoid trouble
1794 * in cases where errors during subxact abort cause multiple invocations
1795 * of AfterTriggerEndSubXact() at the same nesting depth.)
1797 typedef struct AfterTriggersData
1799 CommandId firing_counter; /* next firing ID to assign */
1800 SetConstraintState state; /* the active S C state */
1801 AfterTriggerEventList events; /* deferred-event list */
1802 int query_depth; /* current query list index */
1803 AfterTriggerEventList *query_stack; /* events pending from each query */
1804 int maxquerydepth; /* allocated len of above array */
1806 /* these fields are just for resetting at subtrans abort: */
1808 SetConstraintState *state_stack; /* stacked S C states */
1809 AfterTriggerEventList *events_stack; /* stacked list pointers */
1810 int *depth_stack; /* stacked query_depths */
1811 CommandId *firing_stack; /* stacked firing_counters */
1812 int maxtransdepth; /* allocated len of above arrays */
1813 } AfterTriggersData;
1815 typedef AfterTriggersData *AfterTriggers;
1817 static AfterTriggers afterTriggers;
1820 static void AfterTriggerExecute(AfterTriggerEvent event,
1821 Relation rel, TriggerDesc *trigdesc,
1823 Instrumentation *instr,
1824 MemoryContext per_tuple_context);
1825 static SetConstraintState SetConstraintStateCreate(int numalloc);
1826 static SetConstraintState SetConstraintStateCopy(SetConstraintState state);
1827 static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
1828 Oid tgoid, bool tgisdeferred);
1832 * afterTriggerCheckState()
1834 * Returns true if the trigger identified by tgoid is actually
1835 * in state DEFERRED.
1839 afterTriggerCheckState(Oid tgoid, TriggerEvent eventstate)
1841 SetConstraintState state = afterTriggers->state;
1845 * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
1846 * constraints declared NOT DEFERRABLE), the state is always false.
1848 if ((eventstate & AFTER_TRIGGER_DEFERRABLE) == 0)
1852 * Check if SET CONSTRAINTS has been executed for this specific trigger.
1854 for (i = 0; i < state->numstates; i++)
1856 if (state->trigstates[i].sct_tgoid == tgoid)
1857 return state->trigstates[i].sct_tgisdeferred;
1861 * Check if SET CONSTRAINTS ALL has been executed; if so use that.
1863 if (state->all_isset)
1864 return state->all_isdeferred;
1867 * Otherwise return the default state for the trigger.
1869 return ((eventstate & AFTER_TRIGGER_INITDEFERRED) != 0);
1874 * afterTriggerAddEvent()
1876 * Add a new trigger event to the current query's queue.
1880 afterTriggerAddEvent(AfterTriggerEvent event)
1882 AfterTriggerEventList *events;
1884 Assert(event->ate_next == NULL);
1886 /* Must be inside a query */
1887 Assert(afterTriggers->query_depth >= 0);
1889 events = &afterTriggers->query_stack[afterTriggers->query_depth];
1890 if (events->tail == NULL)
1892 /* first list entry */
1893 events->head = event;
1894 events->tail = event;
1898 events->tail->ate_next = event;
1899 events->tail = event;
1905 * AfterTriggerExecute()
1907 * Fetch the required tuples back from the heap and fire one
1908 * single trigger function.
1910 * Frequently, this will be fired many times in a row for triggers of
1911 * a single relation. Therefore, we cache the open relation and provide
1912 * fmgr lookup cache space at the caller level. (For triggers fired at
1913 * the end of a query, we can even piggyback on the executor's state.)
1915 * event: event currently being fired.
1916 * rel: open relation for event.
1917 * trigdesc: working copy of rel's trigger info.
1918 * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
1919 * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
1920 * or NULL if no instrumentation is wanted.
1921 * per_tuple_context: memory context to call trigger function in.
1925 AfterTriggerExecute(AfterTriggerEvent event,
1926 Relation rel, TriggerDesc *trigdesc,
1927 FmgrInfo *finfo, Instrumentation *instr,
1928 MemoryContext per_tuple_context)
1930 Oid tgoid = event->ate_tgoid;
1931 TriggerData LocTriggerData;
1932 HeapTupleData oldtuple;
1933 HeapTupleData newtuple;
1935 Buffer oldbuffer = InvalidBuffer;
1936 Buffer newbuffer = InvalidBuffer;
1940 * Locate trigger in trigdesc.
1942 LocTriggerData.tg_trigger = NULL;
1943 for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
1945 if (trigdesc->triggers[tgindx].tgoid == tgoid)
1947 LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
1951 if (LocTriggerData.tg_trigger == NULL)
1952 elog(ERROR, "could not find trigger %u", tgoid);
1955 * If doing EXPLAIN ANALYZE, start charging time to this trigger.
1956 * We want to include time spent re-fetching tuples in the trigger cost.
1959 InstrStartNode(instr + tgindx);
1962 * Fetch the required OLD and NEW tuples.
1964 if (ItemPointerIsValid(&(event->ate_oldctid)))
1966 ItemPointerCopy(&(event->ate_oldctid), &(oldtuple.t_self));
1967 if (!heap_fetch(rel, SnapshotAny, &oldtuple, &oldbuffer, false, NULL))
1968 elog(ERROR, "failed to fetch old tuple for AFTER trigger");
1971 if (ItemPointerIsValid(&(event->ate_newctid)))
1973 ItemPointerCopy(&(event->ate_newctid), &(newtuple.t_self));
1974 if (!heap_fetch(rel, SnapshotAny, &newtuple, &newbuffer, false, NULL))
1975 elog(ERROR, "failed to fetch new tuple for AFTER trigger");
1979 * Setup the trigger information
1981 LocTriggerData.type = T_TriggerData;
1982 LocTriggerData.tg_event =
1983 event->ate_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
1984 LocTriggerData.tg_relation = rel;
1986 switch (event->ate_event & TRIGGER_EVENT_OPMASK)
1988 case TRIGGER_EVENT_INSERT:
1989 LocTriggerData.tg_trigtuple = &newtuple;
1990 LocTriggerData.tg_newtuple = NULL;
1991 LocTriggerData.tg_trigtuplebuf = newbuffer;
1992 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1995 case TRIGGER_EVENT_UPDATE:
1996 LocTriggerData.tg_trigtuple = &oldtuple;
1997 LocTriggerData.tg_newtuple = &newtuple;
1998 LocTriggerData.tg_trigtuplebuf = oldbuffer;
1999 LocTriggerData.tg_newtuplebuf = newbuffer;
2002 case TRIGGER_EVENT_DELETE:
2003 LocTriggerData.tg_trigtuple = &oldtuple;
2004 LocTriggerData.tg_newtuple = NULL;
2005 LocTriggerData.tg_trigtuplebuf = oldbuffer;
2006 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2010 MemoryContextReset(per_tuple_context);
2013 * Call the trigger and throw away any possibly returned updated
2014 * tuple. (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
2016 rettuple = ExecCallTriggerFunc(&LocTriggerData,
2021 if (rettuple != NULL && rettuple != &oldtuple && rettuple != &newtuple)
2022 heap_freetuple(rettuple);
2027 if (oldbuffer != InvalidBuffer)
2028 ReleaseBuffer(oldbuffer);
2029 if (newbuffer != InvalidBuffer)
2030 ReleaseBuffer(newbuffer);
2033 * If doing EXPLAIN ANALYZE, stop charging time to this trigger,
2034 * and count one "tuple returned" (really the number of firings).
2037 InstrStopNode(instr + tgindx, true);
2042 * afterTriggerMarkEvents()
2044 * Scan the given event list for not yet invoked events. Mark the ones
2045 * that can be invoked now with the current firing ID.
2047 * If move_list isn't NULL, events that are not to be invoked now are
2048 * removed from the given list and appended to move_list.
2050 * When immediate_only is TRUE, do not invoke currently-deferred triggers.
2051 * (This will be FALSE only at main transaction exit.)
2053 * Returns TRUE if any invokable events were found.
2056 afterTriggerMarkEvents(AfterTriggerEventList *events,
2057 AfterTriggerEventList *move_list,
2058 bool immediate_only)
2061 AfterTriggerEvent event,
2065 event = events->head;
2067 while (event != NULL)
2069 bool defer_it = false;
2070 AfterTriggerEvent next_event;
2072 if (!(event->ate_event &
2073 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS)))
2076 * This trigger hasn't been called or scheduled yet. Check if we
2077 * should call it now.
2079 if (immediate_only &&
2080 afterTriggerCheckState(event->ate_tgoid, event->ate_event))
2087 * Mark it as to be fired in this firing cycle.
2089 event->ate_firing_id = afterTriggers->firing_counter;
2090 event->ate_event |= AFTER_TRIGGER_IN_PROGRESS;
2096 * If it's deferred, move it to move_list, if requested.
2098 next_event = event->ate_next;
2100 if (defer_it && move_list != NULL)
2102 /* Delink it from input list */
2104 prev_event->ate_next = next_event;
2106 events->head = next_event;
2107 /* and add it to move_list */
2108 event->ate_next = NULL;
2109 if (move_list->tail == NULL)
2111 /* first list entry */
2112 move_list->head = event;
2113 move_list->tail = event;
2117 move_list->tail->ate_next = event;
2118 move_list->tail = event;
2123 /* Keep it in input list */
2130 /* Update list tail pointer in case we moved tail event */
2131 events->tail = prev_event;
2137 * afterTriggerInvokeEvents()
2139 * Scan the given event list for events that are marked as to be fired
2140 * in the current firing cycle, and fire them.
2142 * If estate isn't NULL, then we expect that all the firable events are
2143 * for triggers of the relations included in the estate's result relation
2144 * array. This allows us to re-use the estate's open relations and
2145 * trigger cache info. When estate is NULL, we have to find the relations
2148 * When delete_ok is TRUE, it's okay to delete fully-processed events.
2149 * The events list pointers are updated.
2153 afterTriggerInvokeEvents(AfterTriggerEventList *events,
2154 CommandId firing_id,
2158 AfterTriggerEvent event,
2160 MemoryContext per_tuple_context;
2161 Relation rel = NULL;
2162 TriggerDesc *trigdesc = NULL;
2163 FmgrInfo *finfo = NULL;
2164 Instrumentation *instr = NULL;
2166 /* Make a per-tuple memory context for trigger function calls */
2168 AllocSetContextCreate(CurrentMemoryContext,
2169 "AfterTriggerTupleContext",
2170 ALLOCSET_DEFAULT_MINSIZE,
2171 ALLOCSET_DEFAULT_INITSIZE,
2172 ALLOCSET_DEFAULT_MAXSIZE);
2175 event = events->head;
2177 while (event != NULL)
2179 AfterTriggerEvent next_event;
2182 * Is it one for me to fire?
2184 if ((event->ate_event & AFTER_TRIGGER_IN_PROGRESS) &&
2185 event->ate_firing_id == firing_id)
2188 * So let's fire it... but first, open the correct
2189 * relation if this is not the same relation as before.
2191 if (rel == NULL || rel->rd_id != event->ate_relid)
2195 /* Find target relation among estate's result rels */
2196 ResultRelInfo *rInfo;
2199 rInfo = estate->es_result_relations;
2200 nr = estate->es_num_result_relations;
2203 if (rInfo->ri_RelationDesc->rd_id == event->ate_relid)
2208 if (nr <= 0) /* should not happen */
2209 elog(ERROR, "could not find relation %u among query result relations",
2211 rel = rInfo->ri_RelationDesc;
2212 trigdesc = rInfo->ri_TrigDesc;
2213 finfo = rInfo->ri_TrigFunctions;
2214 instr = rInfo->ri_TrigInstrument;
2218 /* Hard way: we manage the resources for ourselves */
2220 heap_close(rel, NoLock);
2222 FreeTriggerDesc(trigdesc);
2225 Assert(instr == NULL); /* never used in this case */
2228 * We assume that an appropriate lock is still held by
2229 * the executor, so grab no new lock here.
2231 rel = heap_open(event->ate_relid, NoLock);
2234 * Copy relation's trigger info so that we have a
2235 * stable copy no matter what the called triggers do.
2237 trigdesc = CopyTriggerDesc(rel->trigdesc);
2239 if (trigdesc == NULL) /* should not happen */
2240 elog(ERROR, "relation %u has no triggers",
2244 * Allocate space to cache fmgr lookup info for
2247 finfo = (FmgrInfo *)
2248 palloc0(trigdesc->numtriggers * sizeof(FmgrInfo));
2250 /* Never any EXPLAIN info in this case */
2255 * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is still
2256 * set, so recursive examinations of the event list won't try
2259 AfterTriggerExecute(event, rel, trigdesc, finfo, instr,
2263 * Mark the event as done.
2265 event->ate_event &= ~AFTER_TRIGGER_IN_PROGRESS;
2266 event->ate_event |= AFTER_TRIGGER_DONE;
2270 * If it's now done, throw it away, if allowed.
2272 * NB: it's possible the trigger call above added more events to the
2273 * queue, or that calls we will do later will want to add more, so
2274 * we have to be careful about maintaining list validity at all
2277 next_event = event->ate_next;
2279 if ((event->ate_event & AFTER_TRIGGER_DONE) && delete_ok)
2281 /* Delink it from list and free it */
2283 prev_event->ate_next = next_event;
2285 events->head = next_event;
2290 /* Keep it in list */
2297 /* Update list tail pointer in case we just deleted tail event */
2298 events->tail = prev_event;
2300 /* Release working resources */
2304 heap_close(rel, NoLock);
2306 FreeTriggerDesc(trigdesc);
2309 Assert(instr == NULL); /* never used in this case */
2311 MemoryContextDelete(per_tuple_context);
2316 * AfterTriggerBeginXact()
2318 * Called at transaction start (either BEGIN or implicit for single
2319 * statement outside of transaction block).
2323 AfterTriggerBeginXact(void)
2325 Assert(afterTriggers == NULL);
2328 * Build empty after-trigger state structure
2330 afterTriggers = (AfterTriggers)
2331 MemoryContextAlloc(TopTransactionContext,
2332 sizeof(AfterTriggersData));
2334 afterTriggers->firing_counter = FirstCommandId;
2335 afterTriggers->state = SetConstraintStateCreate(8);
2336 afterTriggers->events.head = NULL;
2337 afterTriggers->events.tail = NULL;
2338 afterTriggers->query_depth = -1;
2340 /* We initialize the query stack to a reasonable size */
2341 afterTriggers->query_stack = (AfterTriggerEventList *)
2342 MemoryContextAlloc(TopTransactionContext,
2343 8 * sizeof(AfterTriggerEventList));
2344 afterTriggers->maxquerydepth = 8;
2346 /* Subtransaction stack is empty until/unless needed */
2347 afterTriggers->state_stack = NULL;
2348 afterTriggers->events_stack = NULL;
2349 afterTriggers->depth_stack = NULL;
2350 afterTriggers->firing_stack = NULL;
2351 afterTriggers->maxtransdepth = 0;
2356 * AfterTriggerBeginQuery()
2358 * Called just before we start processing a single query within a
2359 * transaction (or subtransaction). Set up to record AFTER trigger
2360 * events queued by the query. Note that it is allowed to have
2361 * nested queries within a (sub)transaction.
2365 AfterTriggerBeginQuery(void)
2367 /* Must be inside a transaction */
2368 Assert(afterTriggers != NULL);
2370 /* Increase the query stack depth */
2371 afterTriggers->query_depth++;
2374 * Allocate more space in the query stack if needed.
2376 if (afterTriggers->query_depth >= afterTriggers->maxquerydepth)
2378 /* repalloc will keep the stack in the same context */
2379 int new_alloc = afterTriggers->maxquerydepth * 2;
2381 afterTriggers->query_stack = (AfterTriggerEventList *)
2382 repalloc(afterTriggers->query_stack,
2383 new_alloc * sizeof(AfterTriggerEventList));
2384 afterTriggers->maxquerydepth = new_alloc;
2387 /* Initialize this query's list to empty */
2388 afterTriggers->query_stack[afterTriggers->query_depth].head = NULL;
2389 afterTriggers->query_stack[afterTriggers->query_depth].tail = NULL;
2394 * AfterTriggerEndQuery()
2396 * Called after one query has been completely processed. At this time
2397 * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
2398 * transfer deferred trigger events to the global deferred-trigger list.
2400 * Note that this should be called just BEFORE closing down the executor
2401 * with ExecutorEnd, because we make use of the EState's info about
2406 AfterTriggerEndQuery(EState *estate)
2408 AfterTriggerEventList *events;
2410 /* Must be inside a transaction */
2411 Assert(afterTriggers != NULL);
2413 /* Must be inside a query, too */
2414 Assert(afterTriggers->query_depth >= 0);
2417 * Process all immediate-mode triggers queued by the query, and move
2418 * the deferred ones to the main list of deferred events.
2420 * Notice that we decide which ones will be fired, and put the deferred
2421 * ones on the main list, before anything is actually fired. This
2422 * ensures reasonably sane behavior if a trigger function does
2423 * SET CONSTRAINTS ... IMMEDIATE: all events we have decided to defer
2424 * will be available for it to fire.
2426 * If we find no firable events, we don't have to increment firing_counter.
2428 events = &afterTriggers->query_stack[afterTriggers->query_depth];
2429 if (afterTriggerMarkEvents(events, &afterTriggers->events, true))
2431 CommandId firing_id = afterTriggers->firing_counter++;
2433 /* OK to delete the immediate events after processing them */
2434 afterTriggerInvokeEvents(events, firing_id, estate, true);
2437 afterTriggers->query_depth--;
2442 * AfterTriggerFireDeferred()
2444 * Called just before the current transaction is committed. At this
2445 * time we invoke all pending DEFERRED triggers.
2447 * It is possible for other modules to queue additional deferred triggers
2448 * during pre-commit processing; therefore xact.c may have to call this
2453 AfterTriggerFireDeferred(void)
2455 AfterTriggerEventList *events;
2457 /* Must be inside a transaction */
2458 Assert(afterTriggers != NULL);
2460 /* ... but not inside a query */
2461 Assert(afterTriggers->query_depth == -1);
2464 * If there are any triggers to fire, make sure we have set a snapshot
2465 * for them to use. (Since PortalRunUtility doesn't set a snap for
2466 * COMMIT, we can't assume ActiveSnapshot is valid on entry.)
2468 events = &afterTriggers->events;
2469 if (events->head != NULL)
2470 ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
2473 * Run all the remaining triggers. Loop until they are all gone,
2474 * just in case some trigger queues more for us to do.
2476 while (afterTriggerMarkEvents(events, NULL, false))
2478 CommandId firing_id = afterTriggers->firing_counter++;
2480 afterTriggerInvokeEvents(events, firing_id, NULL, true);
2483 Assert(events->head == NULL);
2488 * AfterTriggerEndXact()
2490 * The current transaction is finishing.
2492 * Any unfired triggers are canceled so we simply throw
2493 * away anything we know.
2495 * Note: it is possible for this to be called repeatedly in case of
2496 * error during transaction abort; therefore, do not complain if
2497 * already closed down.
2501 AfterTriggerEndXact(bool isCommit)
2504 * Forget everything we know about AFTER triggers.
2506 * Since all the info is in TopTransactionContext or children thereof, we
2507 * need do nothing special to reclaim memory.
2509 afterTriggers = NULL;
2513 * AfterTriggerBeginSubXact()
2515 * Start a subtransaction.
2518 AfterTriggerBeginSubXact(void)
2520 int my_level = GetCurrentTransactionNestLevel();
2523 * Ignore call if the transaction is in aborted state. (Probably
2524 * shouldn't happen?)
2526 if (afterTriggers == NULL)
2530 * Allocate more space in the stacks if needed.
2532 while (my_level >= afterTriggers->maxtransdepth)
2534 if (afterTriggers->maxtransdepth == 0)
2536 MemoryContext old_cxt;
2538 old_cxt = MemoryContextSwitchTo(TopTransactionContext);
2540 #define DEFTRIG_INITALLOC 8
2541 afterTriggers->state_stack = (SetConstraintState *)
2542 palloc(DEFTRIG_INITALLOC * sizeof(SetConstraintState));
2543 afterTriggers->events_stack = (AfterTriggerEventList *)
2544 palloc(DEFTRIG_INITALLOC * sizeof(AfterTriggerEventList));
2545 afterTriggers->depth_stack = (int *)
2546 palloc(DEFTRIG_INITALLOC * sizeof(int));
2547 afterTriggers->firing_stack = (CommandId *)
2548 palloc(DEFTRIG_INITALLOC * sizeof(CommandId));
2549 afterTriggers->maxtransdepth = DEFTRIG_INITALLOC;
2551 MemoryContextSwitchTo(old_cxt);
2555 /* repalloc will keep the stacks in the same context */
2556 int new_alloc = afterTriggers->maxtransdepth * 2;
2558 afterTriggers->state_stack = (SetConstraintState *)
2559 repalloc(afterTriggers->state_stack,
2560 new_alloc * sizeof(SetConstraintState));
2561 afterTriggers->events_stack = (AfterTriggerEventList *)
2562 repalloc(afterTriggers->events_stack,
2563 new_alloc * sizeof(AfterTriggerEventList));
2564 afterTriggers->depth_stack = (int *)
2565 repalloc(afterTriggers->depth_stack,
2566 new_alloc * sizeof(int));
2567 afterTriggers->firing_stack = (CommandId *)
2568 repalloc(afterTriggers->firing_stack,
2569 new_alloc * sizeof(CommandId));
2570 afterTriggers->maxtransdepth = new_alloc;
2575 * Push the current information into the stack. The SET CONSTRAINTS
2576 * state is not saved until/unless changed.
2578 afterTriggers->state_stack[my_level] = NULL;
2579 afterTriggers->events_stack[my_level] = afterTriggers->events;
2580 afterTriggers->depth_stack[my_level] = afterTriggers->query_depth;
2581 afterTriggers->firing_stack[my_level] = afterTriggers->firing_counter;
2585 * AfterTriggerEndSubXact()
2587 * The current subtransaction is ending.
2590 AfterTriggerEndSubXact(bool isCommit)
2592 int my_level = GetCurrentTransactionNestLevel();
2593 SetConstraintState state;
2594 AfterTriggerEvent event;
2595 CommandId subxact_firing_id;
2598 * Ignore call if the transaction is in aborted state. (Probably unneeded)
2600 if (afterTriggers == NULL)
2604 * Pop the prior state if needed.
2606 Assert(my_level < afterTriggers->maxtransdepth);
2610 /* If we saved a prior state, we don't need it anymore */
2611 state = afterTriggers->state_stack[my_level];
2614 /* this avoids double pfree if error later: */
2615 afterTriggers->state_stack[my_level] = NULL;
2616 Assert(afterTriggers->query_depth ==
2617 afterTriggers->depth_stack[my_level]);
2622 * Aborting --- restore the pointers from the stacks.
2624 afterTriggers->events = afterTriggers->events_stack[my_level];
2625 afterTriggers->query_depth = afterTriggers->depth_stack[my_level];
2628 * Cleanup the tail of the list.
2630 if (afterTriggers->events.tail != NULL)
2631 afterTriggers->events.tail->ate_next = NULL;
2634 * We don't need to free the subtransaction's items, since the
2635 * CurTransactionContext will be reset shortly.
2639 * Restore the trigger state. If the saved state is NULL, then
2640 * this subxact didn't save it, so it doesn't need restoring.
2642 state = afterTriggers->state_stack[my_level];
2645 pfree(afterTriggers->state);
2646 afterTriggers->state = state;
2648 /* this avoids double pfree if error later: */
2649 afterTriggers->state_stack[my_level] = NULL;
2652 * Scan for any remaining deferred events that were marked DONE
2653 * or IN PROGRESS by this subxact or a child, and un-mark them.
2654 * We can recognize such events because they have a firing ID
2655 * greater than or equal to the firing_counter value we saved at
2656 * subtransaction start. (This essentially assumes that the
2657 * current subxact includes all subxacts started after it.)
2659 subxact_firing_id = afterTriggers->firing_stack[my_level];
2660 for (event = afterTriggers->events.head;
2662 event = event->ate_next)
2664 if (event->ate_event &
2665 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))
2667 if (event->ate_firing_id >= subxact_firing_id)
2669 ~(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS);
2676 * Create an empty SetConstraintState with room for numalloc trigstates
2678 static SetConstraintState
2679 SetConstraintStateCreate(int numalloc)
2681 SetConstraintState state;
2683 /* Behave sanely with numalloc == 0 */
2688 * We assume that zeroing will correctly initialize the state values.
2690 state = (SetConstraintState)
2691 MemoryContextAllocZero(TopTransactionContext,
2692 sizeof(SetConstraintStateData) +
2693 (numalloc - 1) *sizeof(SetConstraintTriggerData));
2695 state->numalloc = numalloc;
2701 * Copy a SetConstraintState
2703 static SetConstraintState
2704 SetConstraintStateCopy(SetConstraintState origstate)
2706 SetConstraintState state;
2708 state = SetConstraintStateCreate(origstate->numstates);
2710 state->all_isset = origstate->all_isset;
2711 state->all_isdeferred = origstate->all_isdeferred;
2712 state->numstates = origstate->numstates;
2713 memcpy(state->trigstates, origstate->trigstates,
2714 origstate->numstates * sizeof(SetConstraintTriggerData));
2720 * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
2721 * pointer to the state object (it will change if we have to repalloc).
2723 static SetConstraintState
2724 SetConstraintStateAddItem(SetConstraintState state,
2725 Oid tgoid, bool tgisdeferred)
2727 if (state->numstates >= state->numalloc)
2729 int newalloc = state->numalloc * 2;
2731 newalloc = Max(newalloc, 8); /* in case original has size 0 */
2732 state = (SetConstraintState)
2734 sizeof(SetConstraintStateData) +
2735 (newalloc - 1) *sizeof(SetConstraintTriggerData));
2736 state->numalloc = newalloc;
2737 Assert(state->numstates < state->numalloc);
2740 state->trigstates[state->numstates].sct_tgoid = tgoid;
2741 state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
2748 * AfterTriggerSetState()
2750 * Execute the SET CONSTRAINTS ... utility command.
2754 AfterTriggerSetState(ConstraintsSetStmt *stmt)
2756 int my_level = GetCurrentTransactionNestLevel();
2759 * Ignore call if we aren't in a transaction. (Shouldn't happen?)
2761 if (afterTriggers == NULL)
2765 * If in a subtransaction, and we didn't save the current state
2766 * already, save it so it can be restored if the subtransaction
2770 afterTriggers->state_stack[my_level] == NULL)
2772 afterTriggers->state_stack[my_level] =
2773 SetConstraintStateCopy(afterTriggers->state);
2777 * Handle SET CONSTRAINTS ALL ...
2779 if (stmt->constraints == NIL)
2782 * Forget any previous SET CONSTRAINTS commands in this transaction.
2784 afterTriggers->state->numstates = 0;
2787 * Set the per-transaction ALL state to known.
2789 afterTriggers->state->all_isset = true;
2790 afterTriggers->state->all_isdeferred = stmt->deferred;
2796 List *oidlist = NIL;
2799 * Handle SET CONSTRAINTS constraint-name [, ...]
2800 * First lookup all trigger Oid's for the constraint names.
2803 tgrel = heap_open(TriggerRelationId, AccessShareLock);
2805 foreach(l, stmt->constraints)
2807 char *cname = strVal(lfirst(l));
2814 * Check that only named constraints are set explicitly
2816 if (strlen(cname) == 0)
2818 (errcode(ERRCODE_INVALID_NAME),
2819 errmsg("unnamed constraints cannot be set explicitly")));
2822 * Setup to scan pg_trigger by tgconstrname ...
2825 Anum_pg_trigger_tgconstrname,
2826 BTEqualStrategyNumber, F_NAMEEQ,
2827 PointerGetDatum(cname));
2829 tgscan = systable_beginscan(tgrel, TriggerConstrNameIndexId, true,
2830 SnapshotNow, 1, &skey);
2833 * ... and search for the constraint trigger row
2837 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
2839 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
2842 * If we found some, check that they fit the deferrability
2843 * but skip referential action ones, since they are
2844 * silently never deferrable.
2846 if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
2847 pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL &&
2848 pg_trigger->tgfoid != F_RI_FKEY_CASCADE_UPD &&
2849 pg_trigger->tgfoid != F_RI_FKEY_CASCADE_DEL &&
2850 pg_trigger->tgfoid != F_RI_FKEY_SETNULL_UPD &&
2851 pg_trigger->tgfoid != F_RI_FKEY_SETNULL_DEL &&
2852 pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_UPD &&
2853 pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_DEL)
2855 if (stmt->deferred && !pg_trigger->tgdeferrable)
2857 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2858 errmsg("constraint \"%s\" is not deferrable",
2860 oidlist = lappend_oid(oidlist, HeapTupleGetOid(htup));
2865 systable_endscan(tgscan);
2872 (errcode(ERRCODE_UNDEFINED_OBJECT),
2873 errmsg("constraint \"%s\" does not exist",
2876 heap_close(tgrel, AccessShareLock);
2879 * Set the trigger states of individual triggers for this xact.
2883 Oid tgoid = lfirst_oid(l);
2884 SetConstraintState state = afterTriggers->state;
2888 for (i = 0; i < state->numstates; i++)
2890 if (state->trigstates[i].sct_tgoid == tgoid)
2892 state->trigstates[i].sct_tgisdeferred = stmt->deferred;
2899 afterTriggers->state =
2900 SetConstraintStateAddItem(state, tgoid, stmt->deferred);
2906 * SQL99 requires that when a constraint is set to IMMEDIATE, any
2907 * deferred checks against that constraint must be made when the SET
2908 * CONSTRAINTS command is executed -- i.e. the effects of the SET
2909 * CONSTRAINTS command apply retroactively. We've updated the
2910 * constraints state, so scan the list of previously deferred events
2911 * to fire any that have now become immediate.
2913 * Obviously, if this was SET ... DEFERRED then it can't have converted
2914 * any unfired events to immediate, so we need do nothing in that case.
2916 if (!stmt->deferred)
2918 AfterTriggerEventList *events = &afterTriggers->events;
2920 if (afterTriggerMarkEvents(events, NULL, true))
2922 CommandId firing_id = afterTriggers->firing_counter++;
2925 * We can delete fired events if we are at top transaction
2926 * level, but we'd better not if inside a subtransaction, since
2927 * the subtransaction could later get rolled back.
2929 afterTriggerInvokeEvents(events, firing_id, NULL,
2930 !IsSubTransaction());
2937 * AfterTriggerSaveEvent()
2939 * Called by ExecA[RS]...Triggers() to add the event to the queue.
2941 * NOTE: should be called only if we've determined that an event must
2942 * be added to the queue.
2946 AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
2947 HeapTuple oldtup, HeapTuple newtup)
2949 Relation rel = relinfo->ri_RelationDesc;
2950 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2951 AfterTriggerEvent new_event;
2955 ItemPointerData oldctid;
2956 ItemPointerData newctid;
2958 if (afterTriggers == NULL)
2959 elog(ERROR, "AfterTriggerSaveEvent() called outside of transaction");
2962 * Get the CTID's of OLD and NEW
2965 ItemPointerCopy(&(oldtup->t_self), &(oldctid));
2967 ItemPointerSetInvalid(&(oldctid));
2969 ItemPointerCopy(&(newtup->t_self), &(newctid));
2971 ItemPointerSetInvalid(&(newctid));
2974 * Scan the appropriate set of triggers
2978 ntriggers = trigdesc->n_after_row[event];
2979 tgindx = trigdesc->tg_after_row[event];
2983 ntriggers = trigdesc->n_after_statement[event];
2984 tgindx = trigdesc->tg_after_statement[event];
2987 for (i = 0; i < ntriggers; i++)
2989 Trigger *trigger = &trigdesc->triggers[tgindx[i]];
2991 /* Ignore disabled triggers */
2992 if (!trigger->tgenabled)
2996 * If it is an RI UPDATE trigger, and the referenced keys have
2997 * not changed, short-circuit queuing of the event; there's no
2998 * need to fire the trigger.
3000 if ((event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE)
3004 switch (trigger->tgfoid)
3006 case F_RI_FKEY_NOACTION_UPD:
3007 case F_RI_FKEY_CASCADE_UPD:
3008 case F_RI_FKEY_RESTRICT_UPD:
3009 case F_RI_FKEY_SETNULL_UPD:
3010 case F_RI_FKEY_SETDEFAULT_UPD:
3011 is_ri_trigger = true;
3015 is_ri_trigger = false;
3021 TriggerData LocTriggerData;
3023 LocTriggerData.type = T_TriggerData;
3024 LocTriggerData.tg_event =
3025 TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW;
3026 LocTriggerData.tg_relation = rel;
3027 LocTriggerData.tg_trigtuple = oldtup;
3028 LocTriggerData.tg_newtuple = newtup;
3029 LocTriggerData.tg_trigger = trigger;
3031 * We do not currently know which buffers the passed tuples
3032 * are in, but it does not matter because RI_FKey_keyequal_upd
3033 * does not care. We could expand the API of this function
3034 * if it becomes necessary to set these fields accurately.
3036 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
3037 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
3039 if (RI_FKey_keyequal_upd(&LocTriggerData))
3041 /* key unchanged, so skip queuing this event */
3048 * Create a new event. We use the CurTransactionContext so the event
3049 * will automatically go away if the subtransaction aborts.
3051 new_event = (AfterTriggerEvent)
3052 MemoryContextAlloc(CurTransactionContext,
3053 sizeof(AfterTriggerEventData));
3054 new_event->ate_next = NULL;
3055 new_event->ate_event =
3056 (event & TRIGGER_EVENT_OPMASK) |
3057 (row_trigger ? TRIGGER_EVENT_ROW : 0) |
3058 (trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
3059 (trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
3060 new_event->ate_firing_id = 0;
3061 new_event->ate_tgoid = trigger->tgoid;
3062 new_event->ate_relid = rel->rd_id;
3063 ItemPointerCopy(&oldctid, &(new_event->ate_oldctid));
3064 ItemPointerCopy(&newctid, &(new_event->ate_newctid));
3067 * Add the new event to the queue.
3069 afterTriggerAddEvent(new_event);