1 /*-------------------------------------------------------------------------
4 * PostgreSQL TRIGGERs support code.
6 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/backend/commands/trigger.c
12 *-------------------------------------------------------------------------
16 #include "access/genam.h"
17 #include "access/heapam.h"
18 #include "access/sysattr.h"
19 #include "access/htup_details.h"
20 #include "access/xact.h"
21 #include "catalog/catalog.h"
22 #include "catalog/dependency.h"
23 #include "catalog/indexing.h"
24 #include "catalog/objectaccess.h"
25 #include "catalog/pg_constraint.h"
26 #include "catalog/pg_proc.h"
27 #include "catalog/pg_trigger.h"
28 #include "catalog/pg_type.h"
29 #include "commands/dbcommands.h"
30 #include "commands/defrem.h"
31 #include "commands/trigger.h"
32 #include "executor/executor.h"
33 #include "miscadmin.h"
34 #include "nodes/bitmapset.h"
35 #include "nodes/makefuncs.h"
36 #include "optimizer/clauses.h"
37 #include "optimizer/var.h"
38 #include "parser/parse_clause.h"
39 #include "parser/parse_collate.h"
40 #include "parser/parse_func.h"
41 #include "parser/parse_relation.h"
42 #include "parser/parsetree.h"
44 #include "rewrite/rewriteManip.h"
45 #include "storage/bufmgr.h"
46 #include "storage/lmgr.h"
47 #include "tcop/utility.h"
48 #include "utils/acl.h"
49 #include "utils/builtins.h"
50 #include "utils/bytea.h"
51 #include "utils/fmgroids.h"
52 #include "utils/inval.h"
53 #include "utils/lsyscache.h"
54 #include "utils/memutils.h"
55 #include "utils/rel.h"
56 #include "utils/snapmgr.h"
57 #include "utils/syscache.h"
58 #include "utils/tqual.h"
59 #include "utils/tuplestore.h"
63 int SessionReplicationRole = SESSION_REPLICATION_ROLE_ORIGIN;
65 /* How many levels deep into trigger execution are we? */
66 static int MyTriggerDepth = 0;
69 * Note that similar macros also exists in executor/execMain.c. There does not
70 * appear to be any good header to put it into, given the structures that it
71 * uses, so we let them be duplicated. Be sure to update both if one needs to
72 * be changed, however.
74 #define GetUpdatedColumns(relinfo, estate) \
75 (rt_fetch((relinfo)->ri_RangeTableIndex, (estate)->es_range_table)->updatedCols)
77 /* Local function prototypes */
78 static void ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid);
79 static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger);
80 static HeapTuple GetTupleForTrigger(EState *estate,
82 ResultRelInfo *relinfo,
84 LockTupleMode lockmode,
85 TupleTableSlot **newSlot);
86 static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
87 Trigger *trigger, TriggerEvent event,
88 Bitmapset *modifiedCols,
89 HeapTuple oldtup, HeapTuple newtup);
90 static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata,
93 Instrumentation *instr,
94 MemoryContext per_tuple_context);
95 static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
96 int event, bool row_trigger,
97 HeapTuple oldtup, HeapTuple newtup,
98 List *recheckIndexes, Bitmapset *modifiedCols);
99 static void AfterTriggerEnlargeQueryState(void);
103 * Create a trigger. Returns the address of the created trigger.
105 * queryString is the source text of the CREATE TRIGGER command.
106 * This must be supplied if a whenClause is specified, else it can be NULL.
108 * relOid, if nonzero, is the relation on which the trigger should be
109 * created. If zero, the name provided in the statement will be looked up.
111 * refRelOid, if nonzero, is the relation to which the constraint trigger
112 * refers. If zero, the constraint relation name provided in the statement
113 * will be looked up as needed.
115 * constraintOid, if nonzero, says that this trigger is being created
116 * internally to implement that constraint. A suitable pg_depend entry will
117 * be made to link the trigger to that constraint. constraintOid is zero when
118 * executing a user-entered CREATE TRIGGER command. (For CREATE CONSTRAINT
119 * TRIGGER, we build a pg_constraint entry internally.)
121 * indexOid, if nonzero, is the OID of an index associated with the constraint.
122 * We do nothing with this except store it into pg_trigger.tgconstrindid.
124 * If isInternal is true then this is an internally-generated trigger.
125 * This argument sets the tgisinternal field of the pg_trigger entry, and
126 * if TRUE causes us to modify the given trigger name to ensure uniqueness.
128 * When isInternal is not true we require ACL_TRIGGER permissions on the
129 * relation, as well as ACL_EXECUTE on the trigger function. For internal
130 * triggers the caller must apply any required permission checks.
132 * Note: can return InvalidObjectAddress if we decided to not create a trigger
133 * at all, but a foreign-key constraint. This is a kluge for backwards
137 CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
138 Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid,
148 Datum values[Natts_pg_trigger];
149 bool nulls[Natts_pg_trigger];
157 Oid fargtypes[1]; /* dummy */
161 char internaltrigname[NAMEDATALEN];
163 Oid constrrelid = InvalidOid;
164 ObjectAddress myself,
167 if (OidIsValid(relOid))
168 rel = heap_open(relOid, ShareRowExclusiveLock);
170 rel = heap_openrv(stmt->relation, ShareRowExclusiveLock);
173 * Triggers must be on tables or views, and there are additional
174 * relation-type-specific restrictions.
176 if (rel->rd_rel->relkind == RELKIND_RELATION)
178 /* Tables can't have INSTEAD OF triggers */
179 if (stmt->timing != TRIGGER_TYPE_BEFORE &&
180 stmt->timing != TRIGGER_TYPE_AFTER)
182 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
183 errmsg("\"%s\" is a table",
184 RelationGetRelationName(rel)),
185 errdetail("Tables cannot have INSTEAD OF triggers.")));
187 else if (rel->rd_rel->relkind == RELKIND_VIEW)
190 * Views can have INSTEAD OF triggers (which we check below are
191 * row-level), or statement-level BEFORE/AFTER triggers.
193 if (stmt->timing != TRIGGER_TYPE_INSTEAD && stmt->row)
195 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
196 errmsg("\"%s\" is a view",
197 RelationGetRelationName(rel)),
198 errdetail("Views cannot have row-level BEFORE or AFTER triggers.")));
199 /* Disallow TRUNCATE triggers on VIEWs */
200 if (TRIGGER_FOR_TRUNCATE(stmt->events))
202 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
203 errmsg("\"%s\" is a view",
204 RelationGetRelationName(rel)),
205 errdetail("Views cannot have TRUNCATE triggers.")));
207 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
209 if (stmt->timing != TRIGGER_TYPE_BEFORE &&
210 stmt->timing != TRIGGER_TYPE_AFTER)
212 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
213 errmsg("\"%s\" is a foreign table",
214 RelationGetRelationName(rel)),
215 errdetail("Foreign tables cannot have INSTEAD OF triggers.")));
217 if (TRIGGER_FOR_TRUNCATE(stmt->events))
219 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
220 errmsg("\"%s\" is a foreign table",
221 RelationGetRelationName(rel)),
222 errdetail("Foreign tables cannot have TRUNCATE triggers.")));
224 if (stmt->isconstraint)
226 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
227 errmsg("\"%s\" is a foreign table",
228 RelationGetRelationName(rel)),
229 errdetail("Foreign tables cannot have constraint triggers.")));
233 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
234 errmsg("\"%s\" is not a table or view",
235 RelationGetRelationName(rel))));
237 if (!allowSystemTableMods && IsSystemRelation(rel))
239 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
240 errmsg("permission denied: \"%s\" is a system catalog",
241 RelationGetRelationName(rel))));
243 if (stmt->isconstraint)
246 * We must take a lock on the target relation to protect against
247 * concurrent drop. It's not clear that AccessShareLock is strong
248 * enough, but we certainly need at least that much... otherwise, we
249 * might end up creating a pg_constraint entry referencing a
252 if (OidIsValid(refRelOid))
254 LockRelationOid(refRelOid, AccessShareLock);
255 constrrelid = refRelOid;
257 else if (stmt->constrrel != NULL)
258 constrrelid = RangeVarGetRelid(stmt->constrrel, AccessShareLock,
262 /* permission checks */
265 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
267 if (aclresult != ACLCHECK_OK)
268 aclcheck_error(aclresult, ACL_KIND_CLASS,
269 RelationGetRelationName(rel));
271 if (OidIsValid(constrrelid))
273 aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
275 if (aclresult != ACLCHECK_OK)
276 aclcheck_error(aclresult, ACL_KIND_CLASS,
277 get_rel_name(constrrelid));
282 TRIGGER_CLEAR_TYPE(tgtype);
284 TRIGGER_SETT_ROW(tgtype);
285 tgtype |= stmt->timing;
286 tgtype |= stmt->events;
288 /* Disallow ROW-level TRUNCATE triggers */
289 if (TRIGGER_FOR_ROW(tgtype) && TRIGGER_FOR_TRUNCATE(tgtype))
291 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
292 errmsg("TRUNCATE FOR EACH ROW triggers are not supported")));
294 /* INSTEAD triggers must be row-level, and can't have WHEN or columns */
295 if (TRIGGER_FOR_INSTEAD(tgtype))
297 if (!TRIGGER_FOR_ROW(tgtype))
299 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
300 errmsg("INSTEAD OF triggers must be FOR EACH ROW")));
301 if (stmt->whenClause)
303 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
304 errmsg("INSTEAD OF triggers cannot have WHEN conditions")));
305 if (stmt->columns != NIL)
307 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
308 errmsg("INSTEAD OF triggers cannot have column lists")));
312 * Parse the WHEN clause, if any
314 if (stmt->whenClause)
321 /* Set up a pstate to parse with */
322 pstate = make_parsestate(NULL);
323 pstate->p_sourcetext = queryString;
326 * Set up RTEs for OLD and NEW references.
328 * 'OLD' must always have varno equal to 1 and 'NEW' equal to 2.
330 rte = addRangeTableEntryForRelation(pstate, rel,
331 makeAlias("old", NIL),
333 addRTEtoQuery(pstate, rte, false, true, true);
334 rte = addRangeTableEntryForRelation(pstate, rel,
335 makeAlias("new", NIL),
337 addRTEtoQuery(pstate, rte, false, true, true);
339 /* Transform expression. Copy to be sure we don't modify original */
340 whenClause = transformWhereClause(pstate,
341 copyObject(stmt->whenClause),
342 EXPR_KIND_TRIGGER_WHEN,
344 /* we have to fix its collations too */
345 assign_expr_collations(pstate, whenClause);
348 * Check for disallowed references to OLD/NEW.
350 * NB: pull_var_clause is okay here only because we don't allow
351 * subselects in WHEN clauses; it would fail to examine the contents
354 varList = pull_var_clause(whenClause,
355 PVC_REJECT_AGGREGATES,
356 PVC_REJECT_PLACEHOLDERS);
359 Var *var = (Var *) lfirst(lc);
364 if (!TRIGGER_FOR_ROW(tgtype))
366 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
367 errmsg("statement trigger's WHEN condition cannot reference column values"),
368 parser_errposition(pstate, var->location)));
369 if (TRIGGER_FOR_INSERT(tgtype))
371 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
372 errmsg("INSERT trigger's WHEN condition cannot reference OLD values"),
373 parser_errposition(pstate, var->location)));
374 /* system columns are okay here */
377 if (!TRIGGER_FOR_ROW(tgtype))
379 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
380 errmsg("statement trigger's WHEN condition cannot reference column values"),
381 parser_errposition(pstate, var->location)));
382 if (TRIGGER_FOR_DELETE(tgtype))
384 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
385 errmsg("DELETE trigger's WHEN condition cannot reference NEW values"),
386 parser_errposition(pstate, var->location)));
387 if (var->varattno < 0 && TRIGGER_FOR_BEFORE(tgtype))
389 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
390 errmsg("BEFORE trigger's WHEN condition cannot reference NEW system columns"),
391 parser_errposition(pstate, var->location)));
394 /* can't happen without add_missing_from, so just elog */
395 elog(ERROR, "trigger WHEN condition cannot contain references to other relations");
400 /* we'll need the rtable for recordDependencyOnExpr */
401 whenRtable = pstate->p_rtable;
403 qual = nodeToString(whenClause);
405 free_parsestate(pstate);
415 * Find and validate the trigger function.
417 funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
420 aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
421 if (aclresult != ACLCHECK_OK)
422 aclcheck_error(aclresult, ACL_KIND_PROC,
423 NameListToString(stmt->funcname));
425 funcrettype = get_func_rettype(funcoid);
426 if (funcrettype != TRIGGEROID)
429 * We allow OPAQUE just so we can load old dump files. When we see a
430 * trigger function declared OPAQUE, change it to TRIGGER.
432 if (funcrettype == OPAQUEOID)
435 (errmsg("changing return type of function %s from \"opaque\" to \"trigger\"",
436 NameListToString(stmt->funcname))));
437 SetFunctionReturnType(funcoid, TRIGGEROID);
441 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
442 errmsg("function %s must return type \"trigger\"",
443 NameListToString(stmt->funcname))));
447 * If the command is a user-entered CREATE CONSTRAINT TRIGGER command that
448 * references one of the built-in RI_FKey trigger functions, assume it is
449 * from a dump of a pre-7.3 foreign key constraint, and take steps to
450 * convert this legacy representation into a regular foreign key
451 * constraint. Ugly, but necessary for loading old dump files.
453 if (stmt->isconstraint && !isInternal &&
454 list_length(stmt->args) >= 6 &&
455 (list_length(stmt->args) % 2) == 0 &&
456 RI_FKey_trigger_type(funcoid) != RI_TRIGGER_NONE)
458 /* Keep lock on target rel until end of xact */
459 heap_close(rel, NoLock);
461 ConvertTriggerToFK(stmt, funcoid);
463 return InvalidObjectAddress;
467 * If it's a user-entered CREATE CONSTRAINT TRIGGER command, make a
468 * corresponding pg_constraint entry.
470 if (stmt->isconstraint && !OidIsValid(constraintOid))
472 /* Internal callers should have made their own constraints */
474 constraintOid = CreateConstraintEntry(stmt->trigname,
475 RelationGetNamespace(rel),
480 RelationGetRelid(rel),
481 NULL, /* no conkey */
483 InvalidOid, /* no domain */
484 InvalidOid, /* no index */
485 InvalidOid, /* no foreign key */
494 NULL, /* no exclusion */
495 NULL, /* no check constraint */
500 true, /* isnoinherit */
501 isInternal); /* is_internal */
505 * Generate the trigger's OID now, so that we can use it in the name if
508 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
510 trigoid = GetNewOid(tgrel);
513 * If trigger is internally generated, modify the provided trigger name to
514 * ensure uniqueness by appending the trigger OID. (Callers will usually
515 * supply a simple constant trigger name in these cases.)
519 snprintf(internaltrigname, sizeof(internaltrigname),
520 "%s_%u", stmt->trigname, trigoid);
521 trigname = internaltrigname;
525 /* user-defined trigger; use the specified trigger name as-is */
526 trigname = stmt->trigname;
530 * Scan pg_trigger for existing triggers on relation. We do this only to
531 * give a nice error message if there's already a trigger of the same
532 * name. (The unique index on tgrelid/tgname would complain anyway.) We
533 * can skip this for internally generated triggers, since the name
534 * modification above should be sufficient.
536 * NOTE that this is cool only because we have AccessExclusiveLock on the
537 * relation, so the trigger set won't be changing underneath us.
542 Anum_pg_trigger_tgrelid,
543 BTEqualStrategyNumber, F_OIDEQ,
544 ObjectIdGetDatum(RelationGetRelid(rel)));
545 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
547 while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
549 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
551 if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
553 (errcode(ERRCODE_DUPLICATE_OBJECT),
554 errmsg("trigger \"%s\" for relation \"%s\" already exists",
555 trigname, RelationGetRelationName(rel))));
557 systable_endscan(tgscan);
561 * Build the new pg_trigger tuple.
563 memset(nulls, false, sizeof(nulls));
565 values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
566 values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
567 CStringGetDatum(trigname));
568 values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
569 values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
570 values[Anum_pg_trigger_tgenabled - 1] = CharGetDatum(TRIGGER_FIRES_ON_ORIGIN);
571 values[Anum_pg_trigger_tgisinternal - 1] = BoolGetDatum(isInternal);
572 values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
573 values[Anum_pg_trigger_tgconstrindid - 1] = ObjectIdGetDatum(indexOid);
574 values[Anum_pg_trigger_tgconstraint - 1] = ObjectIdGetDatum(constraintOid);
575 values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
576 values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);
582 int16 nargs = list_length(stmt->args);
585 foreach(le, stmt->args)
587 char *ar = strVal(lfirst(le));
589 len += strlen(ar) + 4;
596 args = (char *) palloc(len + 1);
598 foreach(le, stmt->args)
600 char *s = strVal(lfirst(le));
601 char *d = args + strlen(args);
611 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
612 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
613 CStringGetDatum(args));
617 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
618 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
619 CStringGetDatum(""));
622 /* build column number array if it's a column-specific trigger */
623 ncolumns = list_length(stmt->columns);
631 columns = (int16 *) palloc(ncolumns * sizeof(int16));
632 foreach(cell, stmt->columns)
634 char *name = strVal(lfirst(cell));
638 /* Lookup column name. System columns are not allowed */
639 attnum = attnameAttNum(rel, name, false);
640 if (attnum == InvalidAttrNumber)
642 (errcode(ERRCODE_UNDEFINED_COLUMN),
643 errmsg("column \"%s\" of relation \"%s\" does not exist",
644 name, RelationGetRelationName(rel))));
646 /* Check for duplicates */
647 for (j = i - 1; j >= 0; j--)
649 if (columns[j] == attnum)
651 (errcode(ERRCODE_DUPLICATE_COLUMN),
652 errmsg("column \"%s\" specified more than once",
656 columns[i++] = attnum;
659 tgattr = buildint2vector(columns, ncolumns);
660 values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
662 /* set tgqual if trigger has WHEN clause */
664 values[Anum_pg_trigger_tgqual - 1] = CStringGetTextDatum(qual);
666 nulls[Anum_pg_trigger_tgqual - 1] = true;
668 tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
670 /* force tuple to have the desired OID */
671 HeapTupleSetOid(tuple, trigoid);
674 * Insert tuple into pg_trigger.
676 simple_heap_insert(tgrel, tuple);
678 CatalogUpdateIndexes(tgrel, tuple);
680 heap_freetuple(tuple);
681 heap_close(tgrel, RowExclusiveLock);
683 pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
684 pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
685 pfree(DatumGetPointer(values[Anum_pg_trigger_tgattr - 1]));
688 * Update relation's pg_class entry. Crucial side-effect: other backends
689 * (and this one too!) are sent SI message to make them rebuild relcache
692 pgrel = heap_open(RelationRelationId, RowExclusiveLock);
693 tuple = SearchSysCacheCopy1(RELOID,
694 ObjectIdGetDatum(RelationGetRelid(rel)));
695 if (!HeapTupleIsValid(tuple))
696 elog(ERROR, "cache lookup failed for relation %u",
697 RelationGetRelid(rel));
699 ((Form_pg_class) GETSTRUCT(tuple))->relhastriggers = true;
701 simple_heap_update(pgrel, &tuple->t_self, tuple);
703 CatalogUpdateIndexes(pgrel, tuple);
705 heap_freetuple(tuple);
706 heap_close(pgrel, RowExclusiveLock);
709 * We used to try to update the rel's relcache entry here, but that's
710 * fairly pointless since it will happen as a byproduct of the upcoming
711 * CommandCounterIncrement...
715 * Record dependencies for trigger. Always place a normal dependency on
718 myself.classId = TriggerRelationId;
719 myself.objectId = trigoid;
720 myself.objectSubId = 0;
722 referenced.classId = ProcedureRelationId;
723 referenced.objectId = funcoid;
724 referenced.objectSubId = 0;
725 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
727 if (isInternal && OidIsValid(constraintOid))
730 * Internally-generated trigger for a constraint, so make it an
731 * internal dependency of the constraint. We can skip depending on
732 * the relation(s), as there'll be an indirect dependency via the
735 referenced.classId = ConstraintRelationId;
736 referenced.objectId = constraintOid;
737 referenced.objectSubId = 0;
738 recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
743 * User CREATE TRIGGER, so place dependencies. We make trigger be
744 * auto-dropped if its relation is dropped or if the FK relation is
745 * dropped. (Auto drop is compatible with our pre-7.3 behavior.)
747 referenced.classId = RelationRelationId;
748 referenced.objectId = RelationGetRelid(rel);
749 referenced.objectSubId = 0;
750 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
751 if (OidIsValid(constrrelid))
753 referenced.classId = RelationRelationId;
754 referenced.objectId = constrrelid;
755 referenced.objectSubId = 0;
756 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
758 /* Not possible to have an index dependency in this case */
759 Assert(!OidIsValid(indexOid));
762 * If it's a user-specified constraint trigger, make the constraint
763 * internally dependent on the trigger instead of vice versa.
765 if (OidIsValid(constraintOid))
767 referenced.classId = ConstraintRelationId;
768 referenced.objectId = constraintOid;
769 referenced.objectSubId = 0;
770 recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
774 /* If column-specific trigger, add normal dependencies on columns */
779 referenced.classId = RelationRelationId;
780 referenced.objectId = RelationGetRelid(rel);
781 for (i = 0; i < ncolumns; i++)
783 referenced.objectSubId = columns[i];
784 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
789 * If it has a WHEN clause, add dependencies on objects mentioned in the
790 * expression (eg, functions, as well as any columns used).
792 if (whenClause != NULL)
793 recordDependencyOnExpr(&myself, whenClause, whenRtable,
796 /* Post creation hook for new trigger */
797 InvokeObjectPostCreateHookArg(TriggerRelationId, trigoid, 0,
800 /* Keep lock on target rel until end of xact */
801 heap_close(rel, NoLock);
808 * Convert legacy (pre-7.3) CREATE CONSTRAINT TRIGGER commands into
809 * full-fledged foreign key constraints.
811 * The conversion is complex because a pre-7.3 foreign key involved three
812 * separate triggers, which were reported separately in dumps. While the
813 * single trigger on the referencing table adds no new information, we need
814 * to know the trigger functions of both of the triggers on the referenced
815 * table to build the constraint declaration. Also, due to lack of proper
816 * dependency checking pre-7.3, it is possible that the source database had
817 * an incomplete set of triggers resulting in an only partially enforced
818 * FK constraint. (This would happen if one of the tables had been dropped
819 * and re-created, but only if the DB had been affected by a 7.0 pg_dump bug
820 * that caused loss of tgconstrrelid information.) We choose to translate to
821 * an FK constraint only when we've seen all three triggers of a set. This is
822 * implemented by storing unmatched items in a list in TopMemoryContext.
823 * We match triggers together by comparing the trigger arguments (which
824 * include constraint name, table and column names, so should be good enough).
828 List *args; /* list of (T_String) Values or NIL */
829 Oid funcoids[3]; /* OIDs of trigger functions */
830 /* The three function OIDs are stored in the order update, delete, child */
834 ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
836 static List *info_list = NIL;
838 static const char *const funcdescr[3] = {
839 gettext_noop("Found referenced table's UPDATE trigger."),
840 gettext_noop("Found referenced table's DELETE trigger."),
841 gettext_noop("Found referencing table's trigger.")
847 char fk_matchtype = FKCONSTR_MATCH_SIMPLE;
848 List *fk_attrs = NIL;
849 List *pk_attrs = NIL;
852 OldTriggerInfo *info = NULL;
856 /* Parse out the trigger arguments */
857 constr_name = strVal(linitial(stmt->args));
858 fk_table_name = strVal(lsecond(stmt->args));
859 pk_table_name = strVal(lthird(stmt->args));
861 foreach(l, stmt->args)
863 Value *arg = (Value *) lfirst(l);
866 if (i < 4) /* skip constraint and table names */
868 if (i == 4) /* handle match type */
870 if (strcmp(strVal(arg), "FULL") == 0)
871 fk_matchtype = FKCONSTR_MATCH_FULL;
873 fk_matchtype = FKCONSTR_MATCH_SIMPLE;
877 fk_attrs = lappend(fk_attrs, arg);
879 pk_attrs = lappend(pk_attrs, arg);
882 /* Prepare description of constraint for use in messages */
883 initStringInfo(&buf);
884 appendStringInfo(&buf, "FOREIGN KEY %s(",
885 quote_identifier(fk_table_name));
889 Value *arg = (Value *) lfirst(l);
892 appendStringInfoChar(&buf, ',');
893 appendStringInfoString(&buf, quote_identifier(strVal(arg)));
895 appendStringInfo(&buf, ") REFERENCES %s(",
896 quote_identifier(pk_table_name));
900 Value *arg = (Value *) lfirst(l);
903 appendStringInfoChar(&buf, ',');
904 appendStringInfoString(&buf, quote_identifier(strVal(arg)));
906 appendStringInfoChar(&buf, ')');
908 /* Identify class of trigger --- update, delete, or referencing-table */
911 case F_RI_FKEY_CASCADE_UPD:
912 case F_RI_FKEY_RESTRICT_UPD:
913 case F_RI_FKEY_SETNULL_UPD:
914 case F_RI_FKEY_SETDEFAULT_UPD:
915 case F_RI_FKEY_NOACTION_UPD:
919 case F_RI_FKEY_CASCADE_DEL:
920 case F_RI_FKEY_RESTRICT_DEL:
921 case F_RI_FKEY_SETNULL_DEL:
922 case F_RI_FKEY_SETDEFAULT_DEL:
923 case F_RI_FKEY_NOACTION_DEL:
932 /* See if we have a match to this trigger */
933 foreach(l, info_list)
935 info = (OldTriggerInfo *) lfirst(l);
936 if (info->funcoids[funcnum] == InvalidOid &&
937 equal(info->args, stmt->args))
939 info->funcoids[funcnum] = funcoid;
946 /* First trigger of set, so create a new list entry */
947 MemoryContext oldContext;
950 (errmsg("ignoring incomplete trigger group for constraint \"%s\" %s",
951 constr_name, buf.data),
952 errdetail_internal("%s", _(funcdescr[funcnum]))));
953 oldContext = MemoryContextSwitchTo(TopMemoryContext);
954 info = (OldTriggerInfo *) palloc0(sizeof(OldTriggerInfo));
955 info->args = copyObject(stmt->args);
956 info->funcoids[funcnum] = funcoid;
957 info_list = lappend(info_list, info);
958 MemoryContextSwitchTo(oldContext);
960 else if (info->funcoids[0] == InvalidOid ||
961 info->funcoids[1] == InvalidOid ||
962 info->funcoids[2] == InvalidOid)
964 /* Second trigger of set */
966 (errmsg("ignoring incomplete trigger group for constraint \"%s\" %s",
967 constr_name, buf.data),
968 errdetail_internal("%s", _(funcdescr[funcnum]))));
972 /* OK, we have a set, so make the FK constraint ALTER TABLE cmd */
973 AlterTableStmt *atstmt = makeNode(AlterTableStmt);
974 AlterTableCmd *atcmd = makeNode(AlterTableCmd);
975 Constraint *fkcon = makeNode(Constraint);
978 (errmsg("converting trigger group into constraint \"%s\" %s",
979 constr_name, buf.data),
980 errdetail_internal("%s", _(funcdescr[funcnum]))));
981 fkcon->contype = CONSTR_FOREIGN;
982 fkcon->location = -1;
985 /* This trigger is on the FK table */
986 atstmt->relation = stmt->relation;
988 fkcon->pktable = stmt->constrrel;
991 /* Work around ancient pg_dump bug that omitted constrrel */
992 fkcon->pktable = makeRangeVar(NULL, pk_table_name, -1);
997 /* This trigger is on the PK table */
998 fkcon->pktable = stmt->relation;
1000 atstmt->relation = stmt->constrrel;
1003 /* Work around ancient pg_dump bug that omitted constrrel */
1004 atstmt->relation = makeRangeVar(NULL, fk_table_name, -1);
1007 atstmt->cmds = list_make1(atcmd);
1008 atstmt->relkind = OBJECT_TABLE;
1009 atcmd->subtype = AT_AddConstraint;
1010 atcmd->def = (Node *) fkcon;
1011 if (strcmp(constr_name, "<unnamed>") == 0)
1012 fkcon->conname = NULL;
1014 fkcon->conname = constr_name;
1015 fkcon->fk_attrs = fk_attrs;
1016 fkcon->pk_attrs = pk_attrs;
1017 fkcon->fk_matchtype = fk_matchtype;
1018 switch (info->funcoids[0])
1020 case F_RI_FKEY_NOACTION_UPD:
1021 fkcon->fk_upd_action = FKCONSTR_ACTION_NOACTION;
1023 case F_RI_FKEY_CASCADE_UPD:
1024 fkcon->fk_upd_action = FKCONSTR_ACTION_CASCADE;
1026 case F_RI_FKEY_RESTRICT_UPD:
1027 fkcon->fk_upd_action = FKCONSTR_ACTION_RESTRICT;
1029 case F_RI_FKEY_SETNULL_UPD:
1030 fkcon->fk_upd_action = FKCONSTR_ACTION_SETNULL;
1032 case F_RI_FKEY_SETDEFAULT_UPD:
1033 fkcon->fk_upd_action = FKCONSTR_ACTION_SETDEFAULT;
1036 /* can't get here because of earlier checks */
1037 elog(ERROR, "confused about RI update function");
1039 switch (info->funcoids[1])
1041 case F_RI_FKEY_NOACTION_DEL:
1042 fkcon->fk_del_action = FKCONSTR_ACTION_NOACTION;
1044 case F_RI_FKEY_CASCADE_DEL:
1045 fkcon->fk_del_action = FKCONSTR_ACTION_CASCADE;
1047 case F_RI_FKEY_RESTRICT_DEL:
1048 fkcon->fk_del_action = FKCONSTR_ACTION_RESTRICT;
1050 case F_RI_FKEY_SETNULL_DEL:
1051 fkcon->fk_del_action = FKCONSTR_ACTION_SETNULL;
1053 case F_RI_FKEY_SETDEFAULT_DEL:
1054 fkcon->fk_del_action = FKCONSTR_ACTION_SETDEFAULT;
1057 /* can't get here because of earlier checks */
1058 elog(ERROR, "confused about RI delete function");
1060 fkcon->deferrable = stmt->deferrable;
1061 fkcon->initdeferred = stmt->initdeferred;
1062 fkcon->skip_validation = false;
1063 fkcon->initially_valid = true;
1065 /* ... and execute it */
1066 ProcessUtility((Node *) atstmt,
1067 "(generated ALTER TABLE ADD FOREIGN KEY command)",
1068 PROCESS_UTILITY_SUBCOMMAND, NULL,
1069 None_Receiver, NULL);
1071 /* Remove the matched item from the list */
1072 info_list = list_delete_ptr(info_list, info);
1074 /* We leak the copied args ... not worth worrying about */
1079 * Guts of trigger deletion.
1082 RemoveTriggerById(Oid trigOid)
1086 ScanKeyData skey[1];
1091 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
1094 * Find the trigger to delete.
1096 ScanKeyInit(&skey[0],
1097 ObjectIdAttributeNumber,
1098 BTEqualStrategyNumber, F_OIDEQ,
1099 ObjectIdGetDatum(trigOid));
1101 tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
1104 tup = systable_getnext(tgscan);
1105 if (!HeapTupleIsValid(tup))
1106 elog(ERROR, "could not find tuple for trigger %u", trigOid);
1109 * Open and exclusive-lock the relation the trigger belongs to.
1111 relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
1113 rel = heap_open(relid, AccessExclusiveLock);
1115 if (rel->rd_rel->relkind != RELKIND_RELATION &&
1116 rel->rd_rel->relkind != RELKIND_VIEW &&
1117 rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
1119 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1120 errmsg("\"%s\" is not a table, view, or foreign table",
1121 RelationGetRelationName(rel))));
1123 if (!allowSystemTableMods && IsSystemRelation(rel))
1125 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1126 errmsg("permission denied: \"%s\" is a system catalog",
1127 RelationGetRelationName(rel))));
1130 * Delete the pg_trigger tuple.
1132 simple_heap_delete(tgrel, &tup->t_self);
1134 systable_endscan(tgscan);
1135 heap_close(tgrel, RowExclusiveLock);
1138 * We do not bother to try to determine whether any other triggers remain,
1139 * which would be needed in order to decide whether it's safe to clear the
1140 * relation's relhastriggers. (In any case, there might be a concurrent
1141 * process adding new triggers.) Instead, just force a relcache inval to
1142 * make other backends (and this one too!) rebuild their relcache entries.
1143 * There's no great harm in leaving relhastriggers true even if there are
1146 CacheInvalidateRelcache(rel);
1148 /* Keep lock on trigger's rel until end of xact */
1149 heap_close(rel, NoLock);
1153 * get_trigger_oid - Look up a trigger by name to find its OID.
1155 * If missing_ok is false, throw an error if trigger not found. If
1156 * true, just return InvalidOid.
1159 get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
1162 ScanKeyData skey[2];
1168 * Find the trigger, verify permissions, set up object address
1170 tgrel = heap_open(TriggerRelationId, AccessShareLock);
1172 ScanKeyInit(&skey[0],
1173 Anum_pg_trigger_tgrelid,
1174 BTEqualStrategyNumber, F_OIDEQ,
1175 ObjectIdGetDatum(relid));
1176 ScanKeyInit(&skey[1],
1177 Anum_pg_trigger_tgname,
1178 BTEqualStrategyNumber, F_NAMEEQ,
1179 CStringGetDatum(trigname));
1181 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1184 tup = systable_getnext(tgscan);
1186 if (!HeapTupleIsValid(tup))
1190 (errcode(ERRCODE_UNDEFINED_OBJECT),
1191 errmsg("trigger \"%s\" for table \"%s\" does not exist",
1192 trigname, get_rel_name(relid))));
1197 oid = HeapTupleGetOid(tup);
1200 systable_endscan(tgscan);
1201 heap_close(tgrel, AccessShareLock);
1206 * Perform permissions and integrity checks before acquiring a relation lock.
1209 RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid,
1215 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1216 if (!HeapTupleIsValid(tuple))
1217 return; /* concurrently dropped */
1218 form = (Form_pg_class) GETSTRUCT(tuple);
1220 /* only tables and views can have triggers */
1221 if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_VIEW &&
1222 form->relkind != RELKIND_FOREIGN_TABLE)
1224 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1225 errmsg("\"%s\" is not a table, view, or foreign table",
1228 /* you must own the table to rename one of its triggers */
1229 if (!pg_class_ownercheck(relid, GetUserId()))
1230 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rv->relname);
1231 if (!allowSystemTableMods && IsSystemClass(relid, form))
1233 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1234 errmsg("permission denied: \"%s\" is a system catalog",
1237 ReleaseSysCache(tuple);
1241 * renametrig - changes the name of a trigger on a relation
1243 * trigger name is changed in trigger catalog.
1244 * No record of the previous name is kept.
1246 * get proper relrelation from relation catalog (if not arg)
1247 * scan trigger catalog
1248 * for name conflict (within rel)
1249 * for original trigger (if not arg)
1250 * modify tgname in trigger tuple
1251 * update row in catalog
1254 renametrig(RenameStmt *stmt)
1263 ObjectAddress address;
1266 * Look up name, check permissions, and acquire lock (which we will NOT
1267 * release until end of transaction).
1269 relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
1271 RangeVarCallbackForRenameTrigger,
1274 /* Have lock already, so just need to build relcache entry. */
1275 targetrel = relation_open(relid, NoLock);
1278 * Scan pg_trigger twice for existing triggers on relation. We do this in
1279 * order to ensure a trigger does not exist with newname (The unique index
1280 * on tgrelid/tgname would complain anyway) and to ensure a trigger does
1281 * exist with oldname.
1283 * NOTE that this is cool only because we have AccessExclusiveLock on the
1284 * relation, so the trigger set won't be changing underneath us.
1286 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
1289 * First pass -- look for name conflict
1291 ScanKeyInit(&key[0],
1292 Anum_pg_trigger_tgrelid,
1293 BTEqualStrategyNumber, F_OIDEQ,
1294 ObjectIdGetDatum(relid));
1295 ScanKeyInit(&key[1],
1296 Anum_pg_trigger_tgname,
1297 BTEqualStrategyNumber, F_NAMEEQ,
1298 PointerGetDatum(stmt->newname));
1299 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1301 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1303 (errcode(ERRCODE_DUPLICATE_OBJECT),
1304 errmsg("trigger \"%s\" for relation \"%s\" already exists",
1305 stmt->newname, RelationGetRelationName(targetrel))));
1306 systable_endscan(tgscan);
1309 * Second pass -- look for trigger existing with oldname and update
1311 ScanKeyInit(&key[0],
1312 Anum_pg_trigger_tgrelid,
1313 BTEqualStrategyNumber, F_OIDEQ,
1314 ObjectIdGetDatum(relid));
1315 ScanKeyInit(&key[1],
1316 Anum_pg_trigger_tgname,
1317 BTEqualStrategyNumber, F_NAMEEQ,
1318 PointerGetDatum(stmt->subname));
1319 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1321 if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1323 tgoid = HeapTupleGetOid(tuple);
1326 * Update pg_trigger tuple with new tgname.
1328 tuple = heap_copytuple(tuple); /* need a modifiable copy */
1330 namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname,
1333 simple_heap_update(tgrel, &tuple->t_self, tuple);
1335 /* keep system catalog indexes current */
1336 CatalogUpdateIndexes(tgrel, tuple);
1338 InvokeObjectPostAlterHook(TriggerRelationId,
1339 HeapTupleGetOid(tuple), 0);
1342 * Invalidate relation's relcache entry so that other backends (and
1343 * this one too!) are sent SI message to make them rebuild relcache
1344 * entries. (Ideally this should happen automatically...)
1346 CacheInvalidateRelcache(targetrel);
1351 (errcode(ERRCODE_UNDEFINED_OBJECT),
1352 errmsg("trigger \"%s\" for table \"%s\" does not exist",
1353 stmt->subname, RelationGetRelationName(targetrel))));
1356 ObjectAddressSet(address, TriggerRelationId, tgoid);
1358 systable_endscan(tgscan);
1360 heap_close(tgrel, RowExclusiveLock);
1363 * Close rel, but keep exclusive lock!
1365 relation_close(targetrel, NoLock);
1372 * EnableDisableTrigger()
1374 * Called by ALTER TABLE ENABLE/DISABLE [ REPLICA | ALWAYS ] TRIGGER
1375 * to change 'tgenabled' field for the specified trigger(s)
1377 * rel: relation to process (caller must hold suitable lock on it)
1378 * tgname: trigger to process, or NULL to scan all triggers
1379 * fires_when: new value for tgenabled field. In addition to generic
1380 * enablement/disablement, this also defines when the trigger
1381 * should be fired in session replication roles.
1382 * skip_system: if true, skip "system" triggers (constraint triggers)
1384 * Caller should have checked permissions for the table; here we also
1385 * enforce that superuser privilege is required to alter the state of
1389 EnableDisableTrigger(Relation rel, const char *tgname,
1390 char fires_when, bool skip_system)
1394 ScanKeyData keys[2];
1400 /* Scan the relevant entries in pg_triggers */
1401 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
1403 ScanKeyInit(&keys[0],
1404 Anum_pg_trigger_tgrelid,
1405 BTEqualStrategyNumber, F_OIDEQ,
1406 ObjectIdGetDatum(RelationGetRelid(rel)));
1409 ScanKeyInit(&keys[1],
1410 Anum_pg_trigger_tgname,
1411 BTEqualStrategyNumber, F_NAMEEQ,
1412 CStringGetDatum(tgname));
1418 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1421 found = changed = false;
1423 while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1425 Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
1427 if (oldtrig->tgisinternal)
1429 /* system trigger ... ok to process? */
1434 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1435 errmsg("permission denied: \"%s\" is a system trigger",
1436 NameStr(oldtrig->tgname))));
1441 if (oldtrig->tgenabled != fires_when)
1443 /* need to change this one ... make a copy to scribble on */
1444 HeapTuple newtup = heap_copytuple(tuple);
1445 Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
1447 newtrig->tgenabled = fires_when;
1449 simple_heap_update(tgrel, &newtup->t_self, newtup);
1451 /* Keep catalog indexes current */
1452 CatalogUpdateIndexes(tgrel, newtup);
1454 heap_freetuple(newtup);
1459 InvokeObjectPostAlterHook(TriggerRelationId,
1460 HeapTupleGetOid(tuple), 0);
1463 systable_endscan(tgscan);
1465 heap_close(tgrel, RowExclusiveLock);
1467 if (tgname && !found)
1469 (errcode(ERRCODE_UNDEFINED_OBJECT),
1470 errmsg("trigger \"%s\" for table \"%s\" does not exist",
1471 tgname, RelationGetRelationName(rel))));
1474 * If we changed anything, broadcast a SI inval message to force each
1475 * backend (including our own!) to rebuild relation's relcache entry.
1476 * Otherwise they will fail to apply the change promptly.
1479 CacheInvalidateRelcache(rel);
1484 * Build trigger data to attach to the given relcache entry.
1486 * Note that trigger data attached to a relcache entry must be stored in
1487 * CacheMemoryContext to ensure it survives as long as the relcache entry.
1488 * But we should be running in a less long-lived working context. To avoid
1489 * leaking cache memory if this routine fails partway through, we build a
1490 * temporary TriggerDesc in working memory and then copy the completed
1491 * structure into cache memory.
1494 RelationBuildTriggers(Relation relation)
1496 TriggerDesc *trigdesc;
1504 MemoryContext oldContext;
1508 * Allocate a working array to hold the triggers (the array is extended if
1512 triggers = (Trigger *) palloc(maxtrigs * sizeof(Trigger));
1516 * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
1517 * be reading the triggers in name order, except possibly during
1518 * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn
1519 * ensures that triggers will be fired in name order.
1522 Anum_pg_trigger_tgrelid,
1523 BTEqualStrategyNumber, F_OIDEQ,
1524 ObjectIdGetDatum(RelationGetRelid(relation)));
1526 tgrel = heap_open(TriggerRelationId, AccessShareLock);
1527 tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1530 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
1532 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
1537 if (numtrigs >= maxtrigs)
1540 triggers = (Trigger *) repalloc(triggers, maxtrigs * sizeof(Trigger));
1542 build = &(triggers[numtrigs]);
1544 build->tgoid = HeapTupleGetOid(htup);
1545 build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
1546 NameGetDatum(&pg_trigger->tgname)));
1547 build->tgfoid = pg_trigger->tgfoid;
1548 build->tgtype = pg_trigger->tgtype;
1549 build->tgenabled = pg_trigger->tgenabled;
1550 build->tgisinternal = pg_trigger->tgisinternal;
1551 build->tgconstrrelid = pg_trigger->tgconstrrelid;
1552 build->tgconstrindid = pg_trigger->tgconstrindid;
1553 build->tgconstraint = pg_trigger->tgconstraint;
1554 build->tgdeferrable = pg_trigger->tgdeferrable;
1555 build->tginitdeferred = pg_trigger->tginitdeferred;
1556 build->tgnargs = pg_trigger->tgnargs;
1557 /* tgattr is first var-width field, so OK to access directly */
1558 build->tgnattr = pg_trigger->tgattr.dim1;
1559 if (build->tgnattr > 0)
1561 build->tgattr = (int16 *) palloc(build->tgnattr * sizeof(int16));
1562 memcpy(build->tgattr, &(pg_trigger->tgattr.values),
1563 build->tgnattr * sizeof(int16));
1566 build->tgattr = NULL;
1567 if (build->tgnargs > 0)
1572 val = DatumGetByteaP(fastgetattr(htup,
1573 Anum_pg_trigger_tgargs,
1574 tgrel->rd_att, &isnull));
1576 elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
1577 RelationGetRelationName(relation));
1578 p = (char *) VARDATA(val);
1579 build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
1580 for (i = 0; i < build->tgnargs; i++)
1582 build->tgargs[i] = pstrdup(p);
1587 build->tgargs = NULL;
1588 datum = fastgetattr(htup, Anum_pg_trigger_tgqual,
1589 tgrel->rd_att, &isnull);
1591 build->tgqual = TextDatumGetCString(datum);
1593 build->tgqual = NULL;
1598 systable_endscan(tgscan);
1599 heap_close(tgrel, AccessShareLock);
1601 /* There might not be any triggers */
1608 /* Build trigdesc */
1609 trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
1610 trigdesc->triggers = triggers;
1611 trigdesc->numtriggers = numtrigs;
1612 for (i = 0; i < numtrigs; i++)
1613 SetTriggerFlags(trigdesc, &(triggers[i]));
1615 /* Copy completed trigdesc into cache storage */
1616 oldContext = MemoryContextSwitchTo(CacheMemoryContext);
1617 relation->trigdesc = CopyTriggerDesc(trigdesc);
1618 MemoryContextSwitchTo(oldContext);
1620 /* Release working memory */
1621 FreeTriggerDesc(trigdesc);
1625 * Update the TriggerDesc's hint flags to include the specified trigger
1628 SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger)
1630 int16 tgtype = trigger->tgtype;
1632 trigdesc->trig_insert_before_row |=
1633 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1634 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
1635 trigdesc->trig_insert_after_row |=
1636 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1637 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
1638 trigdesc->trig_insert_instead_row |=
1639 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1640 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_INSERT);
1641 trigdesc->trig_insert_before_statement |=
1642 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1643 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
1644 trigdesc->trig_insert_after_statement |=
1645 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1646 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
1647 trigdesc->trig_update_before_row |=
1648 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1649 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
1650 trigdesc->trig_update_after_row |=
1651 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1652 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
1653 trigdesc->trig_update_instead_row |=
1654 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1655 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_UPDATE);
1656 trigdesc->trig_update_before_statement |=
1657 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1658 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
1659 trigdesc->trig_update_after_statement |=
1660 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1661 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
1662 trigdesc->trig_delete_before_row |=
1663 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1664 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
1665 trigdesc->trig_delete_after_row |=
1666 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1667 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
1668 trigdesc->trig_delete_instead_row |=
1669 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1670 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_DELETE);
1671 trigdesc->trig_delete_before_statement |=
1672 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1673 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
1674 trigdesc->trig_delete_after_statement |=
1675 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1676 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
1677 /* there are no row-level truncate triggers */
1678 trigdesc->trig_truncate_before_statement |=
1679 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1680 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_TRUNCATE);
1681 trigdesc->trig_truncate_after_statement |=
1682 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1683 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_TRUNCATE);
1687 * Copy a TriggerDesc data structure.
1689 * The copy is allocated in the current memory context.
1692 CopyTriggerDesc(TriggerDesc *trigdesc)
1694 TriggerDesc *newdesc;
1698 if (trigdesc == NULL || trigdesc->numtriggers <= 0)
1701 newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
1702 memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
1704 trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
1705 memcpy(trigger, trigdesc->triggers,
1706 trigdesc->numtriggers * sizeof(Trigger));
1707 newdesc->triggers = trigger;
1709 for (i = 0; i < trigdesc->numtriggers; i++)
1711 trigger->tgname = pstrdup(trigger->tgname);
1712 if (trigger->tgnattr > 0)
1716 newattr = (int16 *) palloc(trigger->tgnattr * sizeof(int16));
1717 memcpy(newattr, trigger->tgattr,
1718 trigger->tgnattr * sizeof(int16));
1719 trigger->tgattr = newattr;
1721 if (trigger->tgnargs > 0)
1726 newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
1727 for (j = 0; j < trigger->tgnargs; j++)
1728 newargs[j] = pstrdup(trigger->tgargs[j]);
1729 trigger->tgargs = newargs;
1731 if (trigger->tgqual)
1732 trigger->tgqual = pstrdup(trigger->tgqual);
1740 * Free a TriggerDesc data structure.
1743 FreeTriggerDesc(TriggerDesc *trigdesc)
1748 if (trigdesc == NULL)
1751 trigger = trigdesc->triggers;
1752 for (i = 0; i < trigdesc->numtriggers; i++)
1754 pfree(trigger->tgname);
1755 if (trigger->tgnattr > 0)
1756 pfree(trigger->tgattr);
1757 if (trigger->tgnargs > 0)
1759 while (--(trigger->tgnargs) >= 0)
1760 pfree(trigger->tgargs[trigger->tgnargs]);
1761 pfree(trigger->tgargs);
1763 if (trigger->tgqual)
1764 pfree(trigger->tgqual);
1767 pfree(trigdesc->triggers);
1772 * Compare two TriggerDesc structures for logical equality.
1776 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
1782 * We need not examine the hint flags, just the trigger array itself; if
1783 * we have the same triggers with the same types, the flags should match.
1785 * As of 7.3 we assume trigger set ordering is significant in the
1786 * comparison; so we just compare corresponding slots of the two sets.
1788 * Note: comparing the stringToNode forms of the WHEN clauses means that
1789 * parse column locations will affect the result. This is okay as long as
1790 * this function is only used for detecting exact equality, as for example
1791 * in checking for staleness of a cache entry.
1793 if (trigdesc1 != NULL)
1795 if (trigdesc2 == NULL)
1797 if (trigdesc1->numtriggers != trigdesc2->numtriggers)
1799 for (i = 0; i < trigdesc1->numtriggers; i++)
1801 Trigger *trig1 = trigdesc1->triggers + i;
1802 Trigger *trig2 = trigdesc2->triggers + i;
1804 if (trig1->tgoid != trig2->tgoid)
1806 if (strcmp(trig1->tgname, trig2->tgname) != 0)
1808 if (trig1->tgfoid != trig2->tgfoid)
1810 if (trig1->tgtype != trig2->tgtype)
1812 if (trig1->tgenabled != trig2->tgenabled)
1814 if (trig1->tgisinternal != trig2->tgisinternal)
1816 if (trig1->tgconstrrelid != trig2->tgconstrrelid)
1818 if (trig1->tgconstrindid != trig2->tgconstrindid)
1820 if (trig1->tgconstraint != trig2->tgconstraint)
1822 if (trig1->tgdeferrable != trig2->tgdeferrable)
1824 if (trig1->tginitdeferred != trig2->tginitdeferred)
1826 if (trig1->tgnargs != trig2->tgnargs)
1828 if (trig1->tgnattr != trig2->tgnattr)
1830 if (trig1->tgnattr > 0 &&
1831 memcmp(trig1->tgattr, trig2->tgattr,
1832 trig1->tgnattr * sizeof(int16)) != 0)
1834 for (j = 0; j < trig1->tgnargs; j++)
1835 if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
1837 if (trig1->tgqual == NULL && trig2->tgqual == NULL)
1839 else if (trig1->tgqual == NULL || trig2->tgqual == NULL)
1841 else if (strcmp(trig1->tgqual, trig2->tgqual) != 0)
1845 else if (trigdesc2 != NULL)
1849 #endif /* NOT_USED */
1852 * Call a trigger function.
1854 * trigdata: trigger descriptor.
1855 * tgindx: trigger's index in finfo and instr arrays.
1856 * finfo: array of cached trigger function call information.
1857 * instr: optional array of EXPLAIN ANALYZE instrumentation state.
1858 * per_tuple_context: memory context to execute the function in.
1860 * Returns the tuple (or NULL) as returned by the function.
1863 ExecCallTriggerFunc(TriggerData *trigdata,
1866 Instrumentation *instr,
1867 MemoryContext per_tuple_context)
1869 FunctionCallInfoData fcinfo;
1870 PgStat_FunctionCallUsage fcusage;
1872 MemoryContext oldContext;
1877 * We cache fmgr lookup info, to avoid making the lookup again on each
1880 if (finfo->fn_oid == InvalidOid)
1881 fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
1883 Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
1886 * If doing EXPLAIN ANALYZE, start charging time to this trigger.
1889 InstrStartNode(instr + tgindx);
1892 * Do the function evaluation in the per-tuple memory context, so that
1893 * leaked memory will be reclaimed once per tuple. Note in particular that
1894 * any new tuple created by the trigger function will live till the end of
1897 oldContext = MemoryContextSwitchTo(per_tuple_context);
1900 * Call the function, passing no arguments but setting a context.
1902 InitFunctionCallInfoData(fcinfo, finfo, 0,
1903 InvalidOid, (Node *) trigdata, NULL);
1905 pgstat_init_function_usage(&fcinfo, &fcusage);
1910 result = FunctionCallInvoke(&fcinfo);
1920 pgstat_end_function_usage(&fcusage, true);
1922 MemoryContextSwitchTo(oldContext);
1925 * Trigger protocol allows function to return a null pointer, but NOT to
1926 * set the isnull result flag.
1930 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1931 errmsg("trigger function %u returned null value",
1932 fcinfo.flinfo->fn_oid)));
1935 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
1936 * one "tuple returned" (really the number of firings).
1939 InstrStopNode(instr + tgindx, 1);
1941 return (HeapTuple) DatumGetPointer(result);
1945 ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1947 TriggerDesc *trigdesc;
1949 TriggerData LocTriggerData;
1951 trigdesc = relinfo->ri_TrigDesc;
1953 if (trigdesc == NULL)
1955 if (!trigdesc->trig_insert_before_statement)
1958 LocTriggerData.type = T_TriggerData;
1959 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1960 TRIGGER_EVENT_BEFORE;
1961 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1962 LocTriggerData.tg_trigtuple = NULL;
1963 LocTriggerData.tg_newtuple = NULL;
1964 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1965 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1966 for (i = 0; i < trigdesc->numtriggers; i++)
1968 Trigger *trigger = &trigdesc->triggers[i];
1971 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
1972 TRIGGER_TYPE_STATEMENT,
1973 TRIGGER_TYPE_BEFORE,
1974 TRIGGER_TYPE_INSERT))
1976 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
1980 LocTriggerData.tg_trigger = trigger;
1981 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1983 relinfo->ri_TrigFunctions,
1984 relinfo->ri_TrigInstrument,
1985 GetPerTupleMemoryContext(estate));
1989 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1990 errmsg("BEFORE STATEMENT trigger cannot return a value")));
1995 ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1997 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1999 if (trigdesc && trigdesc->trig_insert_after_statement)
2000 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_INSERT,
2001 false, NULL, NULL, NIL, NULL);
2005 ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
2006 TupleTableSlot *slot)
2008 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2009 HeapTuple slottuple = ExecMaterializeSlot(slot);
2010 HeapTuple newtuple = slottuple;
2012 TriggerData LocTriggerData;
2015 LocTriggerData.type = T_TriggerData;
2016 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2018 TRIGGER_EVENT_BEFORE;
2019 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2020 LocTriggerData.tg_newtuple = NULL;
2021 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2022 for (i = 0; i < trigdesc->numtriggers; i++)
2024 Trigger *trigger = &trigdesc->triggers[i];
2026 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2028 TRIGGER_TYPE_BEFORE,
2029 TRIGGER_TYPE_INSERT))
2031 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2032 NULL, NULL, newtuple))
2035 LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2036 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2037 LocTriggerData.tg_trigger = trigger;
2038 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2040 relinfo->ri_TrigFunctions,
2041 relinfo->ri_TrigInstrument,
2042 GetPerTupleMemoryContext(estate));
2043 if (oldtuple != newtuple && oldtuple != slottuple)
2044 heap_freetuple(oldtuple);
2045 if (newtuple == NULL)
2046 return NULL; /* "do nothing" */
2049 if (newtuple != slottuple)
2052 * Return the modified tuple using the es_trig_tuple_slot. We assume
2053 * the tuple was allocated in per-tuple memory context, and therefore
2054 * will go away by itself. The tuple table slot should not try to
2057 TupleTableSlot *newslot = estate->es_trig_tuple_slot;
2058 TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
2060 if (newslot->tts_tupleDescriptor != tupdesc)
2061 ExecSetSlotDescriptor(newslot, tupdesc);
2062 ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
2069 ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo,
2070 HeapTuple trigtuple, List *recheckIndexes)
2072 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2074 if (trigdesc && trigdesc->trig_insert_after_row)
2075 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_INSERT,
2076 true, NULL, trigtuple, recheckIndexes, NULL);
2080 ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
2081 TupleTableSlot *slot)
2083 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2084 HeapTuple slottuple = ExecMaterializeSlot(slot);
2085 HeapTuple newtuple = slottuple;
2087 TriggerData LocTriggerData;
2090 LocTriggerData.type = T_TriggerData;
2091 LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2093 TRIGGER_EVENT_INSTEAD;
2094 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2095 LocTriggerData.tg_newtuple = NULL;
2096 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2097 for (i = 0; i < trigdesc->numtriggers; i++)
2099 Trigger *trigger = &trigdesc->triggers[i];
2101 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2103 TRIGGER_TYPE_INSTEAD,
2104 TRIGGER_TYPE_INSERT))
2106 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2107 NULL, NULL, newtuple))
2110 LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2111 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2112 LocTriggerData.tg_trigger = trigger;
2113 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2115 relinfo->ri_TrigFunctions,
2116 relinfo->ri_TrigInstrument,
2117 GetPerTupleMemoryContext(estate));
2118 if (oldtuple != newtuple && oldtuple != slottuple)
2119 heap_freetuple(oldtuple);
2120 if (newtuple == NULL)
2121 return NULL; /* "do nothing" */
2124 if (newtuple != slottuple)
2127 * Return the modified tuple using the es_trig_tuple_slot. We assume
2128 * the tuple was allocated in per-tuple memory context, and therefore
2129 * will go away by itself. The tuple table slot should not try to
2132 TupleTableSlot *newslot = estate->es_trig_tuple_slot;
2133 TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
2135 if (newslot->tts_tupleDescriptor != tupdesc)
2136 ExecSetSlotDescriptor(newslot, tupdesc);
2137 ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
2144 ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
2146 TriggerDesc *trigdesc;
2148 TriggerData LocTriggerData;
2150 trigdesc = relinfo->ri_TrigDesc;
2152 if (trigdesc == NULL)
2154 if (!trigdesc->trig_delete_before_statement)
2157 LocTriggerData.type = T_TriggerData;
2158 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2159 TRIGGER_EVENT_BEFORE;
2160 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2161 LocTriggerData.tg_trigtuple = NULL;
2162 LocTriggerData.tg_newtuple = NULL;
2163 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2164 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2165 for (i = 0; i < trigdesc->numtriggers; i++)
2167 Trigger *trigger = &trigdesc->triggers[i];
2170 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2171 TRIGGER_TYPE_STATEMENT,
2172 TRIGGER_TYPE_BEFORE,
2173 TRIGGER_TYPE_DELETE))
2175 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2179 LocTriggerData.tg_trigger = trigger;
2180 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2182 relinfo->ri_TrigFunctions,
2183 relinfo->ri_TrigInstrument,
2184 GetPerTupleMemoryContext(estate));
2188 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2189 errmsg("BEFORE STATEMENT trigger cannot return a value")));
2194 ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
2196 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2198 if (trigdesc && trigdesc->trig_delete_after_statement)
2199 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_DELETE,
2200 false, NULL, NULL, NIL, NULL);
2204 ExecBRDeleteTriggers(EState *estate, EPQState *epqstate,
2205 ResultRelInfo *relinfo,
2206 ItemPointer tupleid,
2207 HeapTuple fdw_trigtuple)
2209 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2211 TriggerData LocTriggerData;
2212 HeapTuple trigtuple;
2214 TupleTableSlot *newSlot;
2217 Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2218 if (fdw_trigtuple == NULL)
2220 trigtuple = GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2221 LockTupleExclusive, &newSlot);
2222 if (trigtuple == NULL)
2226 trigtuple = fdw_trigtuple;
2228 LocTriggerData.type = T_TriggerData;
2229 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2231 TRIGGER_EVENT_BEFORE;
2232 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2233 LocTriggerData.tg_newtuple = NULL;
2234 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2235 for (i = 0; i < trigdesc->numtriggers; i++)
2237 Trigger *trigger = &trigdesc->triggers[i];
2239 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2241 TRIGGER_TYPE_BEFORE,
2242 TRIGGER_TYPE_DELETE))
2244 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2245 NULL, trigtuple, NULL))
2248 LocTriggerData.tg_trigtuple = trigtuple;
2249 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2250 LocTriggerData.tg_trigger = trigger;
2251 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2253 relinfo->ri_TrigFunctions,
2254 relinfo->ri_TrigInstrument,
2255 GetPerTupleMemoryContext(estate));
2256 if (newtuple == NULL)
2258 result = false; /* tell caller to suppress delete */
2261 if (newtuple != trigtuple)
2262 heap_freetuple(newtuple);
2264 if (trigtuple != fdw_trigtuple)
2265 heap_freetuple(trigtuple);
2271 ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
2272 ItemPointer tupleid,
2273 HeapTuple fdw_trigtuple)
2275 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2277 if (trigdesc && trigdesc->trig_delete_after_row)
2279 HeapTuple trigtuple;
2281 Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2282 if (fdw_trigtuple == NULL)
2283 trigtuple = GetTupleForTrigger(estate,
2290 trigtuple = fdw_trigtuple;
2292 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_DELETE,
2293 true, trigtuple, NULL, NIL, NULL);
2294 if (trigtuple != fdw_trigtuple)
2295 heap_freetuple(trigtuple);
2300 ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
2301 HeapTuple trigtuple)
2303 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2304 TriggerData LocTriggerData;
2308 LocTriggerData.type = T_TriggerData;
2309 LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2311 TRIGGER_EVENT_INSTEAD;
2312 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2313 LocTriggerData.tg_newtuple = NULL;
2314 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2315 for (i = 0; i < trigdesc->numtriggers; i++)
2317 Trigger *trigger = &trigdesc->triggers[i];
2319 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2321 TRIGGER_TYPE_INSTEAD,
2322 TRIGGER_TYPE_DELETE))
2324 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2325 NULL, trigtuple, NULL))
2328 LocTriggerData.tg_trigtuple = trigtuple;
2329 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2330 LocTriggerData.tg_trigger = trigger;
2331 rettuple = ExecCallTriggerFunc(&LocTriggerData,
2333 relinfo->ri_TrigFunctions,
2334 relinfo->ri_TrigInstrument,
2335 GetPerTupleMemoryContext(estate));
2336 if (rettuple == NULL)
2337 return false; /* Delete was suppressed */
2338 if (rettuple != trigtuple)
2339 heap_freetuple(rettuple);
2345 ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
2347 TriggerDesc *trigdesc;
2349 TriggerData LocTriggerData;
2350 Bitmapset *updatedCols;
2352 trigdesc = relinfo->ri_TrigDesc;
2354 if (trigdesc == NULL)
2356 if (!trigdesc->trig_update_before_statement)
2359 updatedCols = GetUpdatedColumns(relinfo, estate);
2361 LocTriggerData.type = T_TriggerData;
2362 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2363 TRIGGER_EVENT_BEFORE;
2364 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2365 LocTriggerData.tg_trigtuple = NULL;
2366 LocTriggerData.tg_newtuple = NULL;
2367 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2368 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2369 for (i = 0; i < trigdesc->numtriggers; i++)
2371 Trigger *trigger = &trigdesc->triggers[i];
2374 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2375 TRIGGER_TYPE_STATEMENT,
2376 TRIGGER_TYPE_BEFORE,
2377 TRIGGER_TYPE_UPDATE))
2379 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2380 updatedCols, NULL, NULL))
2383 LocTriggerData.tg_trigger = trigger;
2384 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2386 relinfo->ri_TrigFunctions,
2387 relinfo->ri_TrigInstrument,
2388 GetPerTupleMemoryContext(estate));
2392 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2393 errmsg("BEFORE STATEMENT trigger cannot return a value")));
2398 ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
2400 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2402 if (trigdesc && trigdesc->trig_update_after_statement)
2403 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
2404 false, NULL, NULL, NIL,
2405 GetUpdatedColumns(relinfo, estate));
2409 ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
2410 ResultRelInfo *relinfo,
2411 ItemPointer tupleid,
2412 HeapTuple fdw_trigtuple,
2413 TupleTableSlot *slot)
2415 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2416 HeapTuple slottuple = ExecMaterializeSlot(slot);
2417 HeapTuple newtuple = slottuple;
2418 TriggerData LocTriggerData;
2419 HeapTuple trigtuple;
2421 TupleTableSlot *newSlot;
2423 Bitmapset *updatedCols;
2424 LockTupleMode lockmode;
2426 /* Determine lock mode to use */
2427 lockmode = ExecUpdateLockMode(estate, relinfo);
2429 Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2430 if (fdw_trigtuple == NULL)
2432 /* get a copy of the on-disk tuple we are planning to update */
2433 trigtuple = GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2434 lockmode, &newSlot);
2435 if (trigtuple == NULL)
2436 return NULL; /* cancel the update action */
2440 trigtuple = fdw_trigtuple;
2445 * In READ COMMITTED isolation level it's possible that target tuple was
2446 * changed due to concurrent update. In that case we have a raw subplan
2447 * output tuple in newSlot, and need to run it through the junk filter to
2448 * produce an insertable tuple.
2450 * Caution: more than likely, the passed-in slot is the same as the
2451 * junkfilter's output slot, so we are clobbering the original value of
2452 * slottuple by doing the filtering. This is OK since neither we nor our
2453 * caller have any more interest in the prior contents of that slot.
2455 if (newSlot != NULL)
2457 slot = ExecFilterJunk(relinfo->ri_junkFilter, newSlot);
2458 slottuple = ExecMaterializeSlot(slot);
2459 newtuple = slottuple;
2463 LocTriggerData.type = T_TriggerData;
2464 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2466 TRIGGER_EVENT_BEFORE;
2467 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2468 updatedCols = GetUpdatedColumns(relinfo, estate);
2469 for (i = 0; i < trigdesc->numtriggers; i++)
2471 Trigger *trigger = &trigdesc->triggers[i];
2473 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2475 TRIGGER_TYPE_BEFORE,
2476 TRIGGER_TYPE_UPDATE))
2478 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2479 updatedCols, trigtuple, newtuple))
2482 LocTriggerData.tg_trigtuple = trigtuple;
2483 LocTriggerData.tg_newtuple = oldtuple = newtuple;
2484 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2485 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2486 LocTriggerData.tg_trigger = trigger;
2487 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2489 relinfo->ri_TrigFunctions,
2490 relinfo->ri_TrigInstrument,
2491 GetPerTupleMemoryContext(estate));
2492 if (oldtuple != newtuple && oldtuple != slottuple)
2493 heap_freetuple(oldtuple);
2494 if (newtuple == NULL)
2496 if (trigtuple != fdw_trigtuple)
2497 heap_freetuple(trigtuple);
2498 return NULL; /* "do nothing" */
2501 if (trigtuple != fdw_trigtuple)
2502 heap_freetuple(trigtuple);
2504 if (newtuple != slottuple)
2507 * Return the modified tuple using the es_trig_tuple_slot. We assume
2508 * the tuple was allocated in per-tuple memory context, and therefore
2509 * will go away by itself. The tuple table slot should not try to
2512 TupleTableSlot *newslot = estate->es_trig_tuple_slot;
2513 TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
2515 if (newslot->tts_tupleDescriptor != tupdesc)
2516 ExecSetSlotDescriptor(newslot, tupdesc);
2517 ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
2524 ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
2525 ItemPointer tupleid,
2526 HeapTuple fdw_trigtuple,
2528 List *recheckIndexes)
2530 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2532 if (trigdesc && trigdesc->trig_update_after_row)
2534 HeapTuple trigtuple;
2536 Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2537 if (fdw_trigtuple == NULL)
2538 trigtuple = GetTupleForTrigger(estate,
2545 trigtuple = fdw_trigtuple;
2547 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
2548 true, trigtuple, newtuple, recheckIndexes,
2549 GetUpdatedColumns(relinfo, estate));
2550 if (trigtuple != fdw_trigtuple)
2551 heap_freetuple(trigtuple);
2556 ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
2557 HeapTuple trigtuple, TupleTableSlot *slot)
2559 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2560 HeapTuple slottuple = ExecMaterializeSlot(slot);
2561 HeapTuple newtuple = slottuple;
2562 TriggerData LocTriggerData;
2566 LocTriggerData.type = T_TriggerData;
2567 LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2569 TRIGGER_EVENT_INSTEAD;
2570 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2571 for (i = 0; i < trigdesc->numtriggers; i++)
2573 Trigger *trigger = &trigdesc->triggers[i];
2575 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2577 TRIGGER_TYPE_INSTEAD,
2578 TRIGGER_TYPE_UPDATE))
2580 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2581 NULL, trigtuple, newtuple))
2584 LocTriggerData.tg_trigtuple = trigtuple;
2585 LocTriggerData.tg_newtuple = oldtuple = newtuple;
2586 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2587 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2588 LocTriggerData.tg_trigger = trigger;
2589 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2591 relinfo->ri_TrigFunctions,
2592 relinfo->ri_TrigInstrument,
2593 GetPerTupleMemoryContext(estate));
2594 if (oldtuple != newtuple && oldtuple != slottuple)
2595 heap_freetuple(oldtuple);
2596 if (newtuple == NULL)
2597 return NULL; /* "do nothing" */
2600 if (newtuple != slottuple)
2603 * Return the modified tuple using the es_trig_tuple_slot. We assume
2604 * the tuple was allocated in per-tuple memory context, and therefore
2605 * will go away by itself. The tuple table slot should not try to
2608 TupleTableSlot *newslot = estate->es_trig_tuple_slot;
2609 TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
2611 if (newslot->tts_tupleDescriptor != tupdesc)
2612 ExecSetSlotDescriptor(newslot, tupdesc);
2613 ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
2620 ExecBSTruncateTriggers(EState *estate, ResultRelInfo *relinfo)
2622 TriggerDesc *trigdesc;
2624 TriggerData LocTriggerData;
2626 trigdesc = relinfo->ri_TrigDesc;
2628 if (trigdesc == NULL)
2630 if (!trigdesc->trig_truncate_before_statement)
2633 LocTriggerData.type = T_TriggerData;
2634 LocTriggerData.tg_event = TRIGGER_EVENT_TRUNCATE |
2635 TRIGGER_EVENT_BEFORE;
2636 LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2637 LocTriggerData.tg_trigtuple = NULL;
2638 LocTriggerData.tg_newtuple = NULL;
2639 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
2640 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2641 for (i = 0; i < trigdesc->numtriggers; i++)
2643 Trigger *trigger = &trigdesc->triggers[i];
2646 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2647 TRIGGER_TYPE_STATEMENT,
2648 TRIGGER_TYPE_BEFORE,
2649 TRIGGER_TYPE_TRUNCATE))
2651 if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2655 LocTriggerData.tg_trigger = trigger;
2656 newtuple = ExecCallTriggerFunc(&LocTriggerData,
2658 relinfo->ri_TrigFunctions,
2659 relinfo->ri_TrigInstrument,
2660 GetPerTupleMemoryContext(estate));
2664 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2665 errmsg("BEFORE STATEMENT trigger cannot return a value")));
2670 ExecASTruncateTriggers(EState *estate, ResultRelInfo *relinfo)
2672 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2674 if (trigdesc && trigdesc->trig_truncate_after_statement)
2675 AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_TRUNCATE,
2676 false, NULL, NULL, NIL, NULL);
2681 GetTupleForTrigger(EState *estate,
2683 ResultRelInfo *relinfo,
2685 LockTupleMode lockmode,
2686 TupleTableSlot **newSlot)
2688 Relation relation = relinfo->ri_RelationDesc;
2689 HeapTupleData tuple;
2693 if (newSlot != NULL)
2696 HeapUpdateFailureData hufd;
2700 /* caller must pass an epqstate if EvalPlanQual is possible */
2701 Assert(epqstate != NULL);
2704 * lock tuple for update
2707 tuple.t_self = *tid;
2708 test = heap_lock_tuple(relation, &tuple,
2709 estate->es_output_cid,
2710 lockmode, LockWaitBlock,
2711 false, &buffer, &hufd);
2714 case HeapTupleSelfUpdated:
2717 * The target tuple was already updated or deleted by the
2718 * current command, or by a later command in the current
2719 * transaction. We ignore the tuple in the former case, and
2720 * throw error in the latter case, for the same reasons
2721 * enumerated in ExecUpdate and ExecDelete in
2722 * nodeModifyTable.c.
2724 if (hufd.cmax != estate->es_output_cid)
2726 (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
2727 errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
2728 errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
2730 /* treat it as deleted; do not process */
2731 ReleaseBuffer(buffer);
2734 case HeapTupleMayBeUpdated:
2737 case HeapTupleUpdated:
2738 ReleaseBuffer(buffer);
2739 if (IsolationUsesXactSnapshot())
2741 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
2742 errmsg("could not serialize access due to concurrent update")));
2743 if (!ItemPointerEquals(&hufd.ctid, &tuple.t_self))
2745 /* it was updated, so look at the updated version */
2746 TupleTableSlot *epqslot;
2748 epqslot = EvalPlanQual(estate,
2751 relinfo->ri_RangeTableIndex,
2755 if (!TupIsNull(epqslot))
2761 * EvalPlanQual already locked the tuple, but we
2762 * re-call heap_lock_tuple anyway as an easy way of
2763 * re-fetching the correct tuple. Speed is hardly a
2764 * criterion in this path anyhow.
2771 * if tuple was deleted or PlanQual failed for updated tuple -
2772 * we must not process this tuple!
2776 case HeapTupleInvisible:
2777 elog(ERROR, "attempted to lock invisible tuple");
2780 ReleaseBuffer(buffer);
2781 elog(ERROR, "unrecognized heap_lock_tuple status: %u", test);
2782 return NULL; /* keep compiler quiet */
2790 buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
2793 * Although we already know this tuple is valid, we must lock the
2794 * buffer to ensure that no one has a buffer cleanup lock; otherwise
2795 * they might move the tuple while we try to copy it. But we can
2796 * release the lock before actually doing the heap_copytuple call,
2797 * since holding pin is sufficient to prevent anyone from getting a
2798 * cleanup lock they don't already hold.
2800 LockBuffer(buffer, BUFFER_LOCK_SHARE);
2802 page = BufferGetPage(buffer);
2803 lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
2805 Assert(ItemIdIsNormal(lp));
2807 tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
2808 tuple.t_len = ItemIdGetLength(lp);
2809 tuple.t_self = *tid;
2810 tuple.t_tableOid = RelationGetRelid(relation);
2812 LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
2815 result = heap_copytuple(&tuple);
2816 ReleaseBuffer(buffer);
2822 * Is trigger enabled to fire?
2825 TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
2826 Trigger *trigger, TriggerEvent event,
2827 Bitmapset *modifiedCols,
2828 HeapTuple oldtup, HeapTuple newtup)
2830 /* Check replication-role-dependent enable state */
2831 if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA)
2833 if (trigger->tgenabled == TRIGGER_FIRES_ON_ORIGIN ||
2834 trigger->tgenabled == TRIGGER_DISABLED)
2837 else /* ORIGIN or LOCAL role */
2839 if (trigger->tgenabled == TRIGGER_FIRES_ON_REPLICA ||
2840 trigger->tgenabled == TRIGGER_DISABLED)
2845 * Check for column-specific trigger (only possible for UPDATE, and in
2846 * fact we *must* ignore tgattr for other event types)
2848 if (trigger->tgnattr > 0 && TRIGGER_FIRED_BY_UPDATE(event))
2854 for (i = 0; i < trigger->tgnattr; i++)
2856 if (bms_is_member(trigger->tgattr[i] - FirstLowInvalidHeapAttributeNumber,
2867 /* Check for WHEN clause */
2868 if (trigger->tgqual)
2870 TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
2872 ExprContext *econtext;
2873 TupleTableSlot *oldslot = NULL;
2874 TupleTableSlot *newslot = NULL;
2875 MemoryContext oldContext;
2878 Assert(estate != NULL);
2881 * trigger is an element of relinfo->ri_TrigDesc->triggers[]; find the
2882 * matching element of relinfo->ri_TrigWhenExprs[]
2884 i = trigger - relinfo->ri_TrigDesc->triggers;
2885 predicate = &relinfo->ri_TrigWhenExprs[i];
2888 * If first time through for this WHEN expression, build expression
2889 * nodetrees for it. Keep them in the per-query memory context so
2890 * they'll survive throughout the query.
2892 if (*predicate == NIL)
2896 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
2897 tgqual = stringToNode(trigger->tgqual);
2898 /* Change references to OLD and NEW to INNER_VAR and OUTER_VAR */
2899 ChangeVarNodes(tgqual, PRS2_OLD_VARNO, INNER_VAR, 0);
2900 ChangeVarNodes(tgqual, PRS2_NEW_VARNO, OUTER_VAR, 0);
2901 /* ExecQual wants implicit-AND form */
2902 tgqual = (Node *) make_ands_implicit((Expr *) tgqual);
2903 *predicate = (List *) ExecPrepareExpr((Expr *) tgqual, estate);
2904 MemoryContextSwitchTo(oldContext);
2908 * We will use the EState's per-tuple context for evaluating WHEN
2909 * expressions (creating it if it's not already there).
2911 econtext = GetPerTupleExprContext(estate);
2914 * Put OLD and NEW tuples into tupleslots for expression evaluation.
2915 * These slots can be shared across the whole estate, but be careful
2916 * that they have the current resultrel's tupdesc.
2918 if (HeapTupleIsValid(oldtup))
2920 if (estate->es_trig_oldtup_slot == NULL)
2922 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
2923 estate->es_trig_oldtup_slot = ExecInitExtraTupleSlot(estate);
2924 MemoryContextSwitchTo(oldContext);
2926 oldslot = estate->es_trig_oldtup_slot;
2927 if (oldslot->tts_tupleDescriptor != tupdesc)
2928 ExecSetSlotDescriptor(oldslot, tupdesc);
2929 ExecStoreTuple(oldtup, oldslot, InvalidBuffer, false);
2931 if (HeapTupleIsValid(newtup))
2933 if (estate->es_trig_newtup_slot == NULL)
2935 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
2936 estate->es_trig_newtup_slot = ExecInitExtraTupleSlot(estate);
2937 MemoryContextSwitchTo(oldContext);
2939 newslot = estate->es_trig_newtup_slot;
2940 if (newslot->tts_tupleDescriptor != tupdesc)
2941 ExecSetSlotDescriptor(newslot, tupdesc);
2942 ExecStoreTuple(newtup, newslot, InvalidBuffer, false);
2946 * Finally evaluate the expression, making the old and/or new tuples
2947 * available as INNER_VAR/OUTER_VAR respectively.
2949 econtext->ecxt_innertuple = oldslot;
2950 econtext->ecxt_outertuple = newslot;
2951 if (!ExecQual(*predicate, econtext, false))
2960 * After-trigger stuff
2962 * The AfterTriggersData struct holds data about pending AFTER trigger events
2963 * during the current transaction tree. (BEFORE triggers are fired
2964 * immediately so we don't need any persistent state about them.) The struct
2965 * and most of its subsidiary data are kept in TopTransactionContext; however
2966 * the individual event records are kept in a separate sub-context. This is
2967 * done mainly so that it's easy to tell from a memory context dump how much
2968 * space is being eaten by trigger events.
2970 * Because the list of pending events can grow large, we go to some
2971 * considerable effort to minimize per-event memory consumption. The event
2972 * records are grouped into chunks and common data for similar events in the
2973 * same chunk is only stored once.
2975 * XXX We need to be able to save the per-event data in a file if it grows too
2980 /* Per-trigger SET CONSTRAINT status */
2981 typedef struct SetConstraintTriggerData
2984 bool sct_tgisdeferred;
2985 } SetConstraintTriggerData;
2987 typedef struct SetConstraintTriggerData *SetConstraintTrigger;
2990 * SET CONSTRAINT intra-transaction status.
2992 * We make this a single palloc'd object so it can be copied and freed easily.
2994 * all_isset and all_isdeferred are used to keep track
2995 * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
2997 * trigstates[] stores per-trigger tgisdeferred settings.
2999 typedef struct SetConstraintStateData
3002 bool all_isdeferred;
3003 int numstates; /* number of trigstates[] entries in use */
3004 int numalloc; /* allocated size of trigstates[] */
3005 SetConstraintTriggerData trigstates[FLEXIBLE_ARRAY_MEMBER];
3006 } SetConstraintStateData;
3008 typedef SetConstraintStateData *SetConstraintState;
3012 * Per-trigger-event data
3014 * The actual per-event data, AfterTriggerEventData, includes DONE/IN_PROGRESS
3015 * status bits and up to two tuple CTIDs. Each event record also has an
3016 * associated AfterTriggerSharedData that is shared across all instances of
3017 * similar events within a "chunk".
3019 * For row-level triggers, we arrange not to waste storage on unneeded ctid
3020 * fields. Updates of regular tables use two; inserts and deletes of regular
3021 * tables use one; foreign tables always use zero and save the tuple(s) to a
3022 * tuplestore. AFTER_TRIGGER_FDW_FETCH directs AfterTriggerExecute() to
3023 * retrieve a fresh tuple or pair of tuples from that tuplestore, while
3024 * AFTER_TRIGGER_FDW_REUSE directs it to use the most-recently-retrieved
3025 * tuple(s). This permits storing tuples once regardless of the number of
3026 * row-level triggers on a foreign table.
3028 * Statement-level triggers always bear AFTER_TRIGGER_1CTID, though they
3029 * require no ctid field. We lack the flag bit space to neatly represent that
3030 * distinct case, and it seems unlikely to be worth much trouble.
3032 * Note: ats_firing_id is initially zero and is set to something else when
3033 * AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
3034 * cycle the trigger will be fired in (or was fired in, if DONE is set).
3035 * Although this is mutable state, we can keep it in AfterTriggerSharedData
3036 * because all instances of the same type of event in a given event list will
3037 * be fired at the same time, if they were queued between the same firing
3038 * cycles. So we need only ensure that ats_firing_id is zero when attaching
3039 * a new event to an existing AfterTriggerSharedData record.
3041 typedef uint32 TriggerFlags;
3043 #define AFTER_TRIGGER_OFFSET 0x0FFFFFFF /* must be low-order
3045 #define AFTER_TRIGGER_DONE 0x10000000
3046 #define AFTER_TRIGGER_IN_PROGRESS 0x20000000
3047 /* bits describing the size and tuple sources of this event */
3048 #define AFTER_TRIGGER_FDW_REUSE 0x00000000
3049 #define AFTER_TRIGGER_FDW_FETCH 0x80000000
3050 #define AFTER_TRIGGER_1CTID 0x40000000
3051 #define AFTER_TRIGGER_2CTID 0xC0000000
3052 #define AFTER_TRIGGER_TUP_BITS 0xC0000000
3054 typedef struct AfterTriggerSharedData *AfterTriggerShared;
3056 typedef struct AfterTriggerSharedData
3058 TriggerEvent ats_event; /* event type indicator, see trigger.h */
3059 Oid ats_tgoid; /* the trigger's ID */
3060 Oid ats_relid; /* the relation it's on */
3061 CommandId ats_firing_id; /* ID for firing cycle */
3062 } AfterTriggerSharedData;
3064 typedef struct AfterTriggerEventData *AfterTriggerEvent;
3066 typedef struct AfterTriggerEventData
3068 TriggerFlags ate_flags; /* status bits and offset to shared data */
3069 ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3070 ItemPointerData ate_ctid2; /* new updated tuple */
3071 } AfterTriggerEventData;
3073 /* AfterTriggerEventData, minus ate_ctid2 */
3074 typedef struct AfterTriggerEventDataOneCtid
3076 TriggerFlags ate_flags; /* status bits and offset to shared data */
3077 ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3078 } AfterTriggerEventDataOneCtid;
3080 /* AfterTriggerEventData, minus ate_ctid1 and ate_ctid2 */
3081 typedef struct AfterTriggerEventDataZeroCtids
3083 TriggerFlags ate_flags; /* status bits and offset to shared data */
3084 } AfterTriggerEventDataZeroCtids;
3086 #define SizeofTriggerEvent(evt) \
3087 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3088 sizeof(AfterTriggerEventData) : \
3089 ((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3090 sizeof(AfterTriggerEventDataOneCtid) : \
3091 sizeof(AfterTriggerEventDataZeroCtids))
3093 #define GetTriggerSharedData(evt) \
3094 ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3097 * To avoid palloc overhead, we keep trigger events in arrays in successively-
3098 * larger chunks (a slightly more sophisticated version of an expansible
3099 * array). The space between CHUNK_DATA_START and freeptr is occupied by
3100 * AfterTriggerEventData records; the space between endfree and endptr is
3101 * occupied by AfterTriggerSharedData records.
3103 typedef struct AfterTriggerEventChunk
3105 struct AfterTriggerEventChunk *next; /* list link */
3106 char *freeptr; /* start of free space in chunk */
3107 char *endfree; /* end of free space in chunk */
3108 char *endptr; /* end of chunk */
3109 /* event data follows here */
3110 } AfterTriggerEventChunk;
3112 #define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3114 /* A list of events */
3115 typedef struct AfterTriggerEventList
3117 AfterTriggerEventChunk *head;
3118 AfterTriggerEventChunk *tail;
3119 char *tailfree; /* freeptr of tail chunk */
3120 } AfterTriggerEventList;
3122 /* Macros to help in iterating over a list of events */
3123 #define for_each_chunk(cptr, evtlist) \
3124 for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3125 #define for_each_event(eptr, cptr) \
3126 for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3127 (char *) eptr < (cptr)->freeptr; \
3128 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3129 /* Use this if no special per-chunk processing is needed */
3130 #define for_each_event_chunk(eptr, cptr, evtlist) \
3131 for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3135 * All per-transaction data for the AFTER TRIGGERS module.
3137 * AfterTriggersData has the following fields:
3139 * firing_counter is incremented for each call of afterTriggerInvokeEvents.
3140 * We mark firable events with the current firing cycle's ID so that we can
3141 * tell which ones to work on. This ensures sane behavior if a trigger
3142 * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
3143 * only fire those events that weren't already scheduled for firing.
3145 * state keeps track of the transaction-local effects of SET CONSTRAINTS.
3146 * This is saved and restored across failed subtransactions.
3148 * events is the current list of deferred events. This is global across
3149 * all subtransactions of the current transaction. In a subtransaction
3150 * abort, we know that the events added by the subtransaction are at the
3151 * end of the list, so it is relatively easy to discard them. The event
3152 * list chunks themselves are stored in event_cxt.
3154 * query_depth is the current depth of nested AfterTriggerBeginQuery calls
3155 * (-1 when the stack is empty).
3157 * query_stack[query_depth] is a list of AFTER trigger events queued by the
3158 * current query (and the query_stack entries below it are lists of trigger
3159 * events queued by calling queries). None of these are valid until the
3160 * matching AfterTriggerEndQuery call occurs. At that point we fire
3161 * immediate-mode triggers, and append any deferred events to the main events
3164 * fdw_tuplestores[query_depth] is a tuplestore containing the foreign tuples
3165 * needed for the current query.
3167 * maxquerydepth is just the allocated length of query_stack and
3170 * state_stack is a stack of pointers to saved copies of the SET CONSTRAINTS
3171 * state data; each subtransaction level that modifies that state first
3172 * saves a copy, which we use to restore the state if we abort.
3174 * events_stack is a stack of copies of the events head/tail pointers,
3175 * which we use to restore those values during subtransaction abort.
3177 * depth_stack is a stack of copies of subtransaction-start-time query_depth,
3178 * which we similarly use to clean up at subtransaction abort.
3180 * firing_stack is a stack of copies of subtransaction-start-time
3181 * firing_counter. We use this to recognize which deferred triggers were
3182 * fired (or marked for firing) within an aborted subtransaction.
3184 * We use GetCurrentTransactionNestLevel() to determine the correct array
3185 * index in these stacks. maxtransdepth is the number of allocated entries in
3186 * each stack. (By not keeping our own stack pointer, we can avoid trouble
3187 * in cases where errors during subxact abort cause multiple invocations
3188 * of AfterTriggerEndSubXact() at the same nesting depth.)
3190 typedef struct AfterTriggersData
3192 CommandId firing_counter; /* next firing ID to assign */
3193 SetConstraintState state; /* the active S C state */
3194 AfterTriggerEventList events; /* deferred-event list */
3195 int query_depth; /* current query list index */
3196 AfterTriggerEventList *query_stack; /* events pending from each query */
3197 Tuplestorestate **fdw_tuplestores; /* foreign tuples from each query */
3198 int maxquerydepth; /* allocated len of above array */
3199 MemoryContext event_cxt; /* memory context for events, if any */
3201 /* these fields are just for resetting at subtrans abort: */
3203 SetConstraintState *state_stack; /* stacked S C states */
3204 AfterTriggerEventList *events_stack; /* stacked list pointers */
3205 int *depth_stack; /* stacked query_depths */
3206 CommandId *firing_stack; /* stacked firing_counters */
3207 int maxtransdepth; /* allocated len of above arrays */
3208 } AfterTriggersData;
3210 static AfterTriggersData afterTriggers;
3212 static void AfterTriggerExecute(AfterTriggerEvent event,
3213 Relation rel, TriggerDesc *trigdesc,
3215 Instrumentation *instr,
3216 MemoryContext per_tuple_context,
3217 TupleTableSlot *trig_tuple_slot1,
3218 TupleTableSlot *trig_tuple_slot2);
3219 static SetConstraintState SetConstraintStateCreate(int numalloc);
3220 static SetConstraintState SetConstraintStateCopy(SetConstraintState state);
3221 static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
3222 Oid tgoid, bool tgisdeferred);
3226 * Gets the current query fdw tuplestore and initializes it if necessary
3228 static Tuplestorestate *
3229 GetCurrentFDWTuplestore()
3231 Tuplestorestate *ret;
3233 ret = afterTriggers.fdw_tuplestores[afterTriggers.query_depth];
3236 MemoryContext oldcxt;
3237 ResourceOwner saveResourceOwner;
3240 * Make the tuplestore valid until end of transaction. This is the
3241 * allocation lifespan of the associated events list, but we really
3242 * only need it until AfterTriggerEndQuery().
3244 oldcxt = MemoryContextSwitchTo(TopTransactionContext);
3245 saveResourceOwner = CurrentResourceOwner;
3248 CurrentResourceOwner = TopTransactionResourceOwner;
3249 ret = tuplestore_begin_heap(false, false, work_mem);
3253 CurrentResourceOwner = saveResourceOwner;
3257 CurrentResourceOwner = saveResourceOwner;
3258 MemoryContextSwitchTo(oldcxt);
3260 afterTriggers.fdw_tuplestores[afterTriggers.query_depth] = ret;
3267 * afterTriggerCheckState()
3269 * Returns true if the trigger event is actually in state DEFERRED.
3273 afterTriggerCheckState(AfterTriggerShared evtshared)
3275 Oid tgoid = evtshared->ats_tgoid;
3276 SetConstraintState state = afterTriggers.state;
3280 * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
3281 * constraints declared NOT DEFERRABLE), the state is always false.
3283 if ((evtshared->ats_event & AFTER_TRIGGER_DEFERRABLE) == 0)
3287 * If constraint state exists, SET CONSTRAINTS might have been executed
3288 * either for this trigger or for all triggers.
3292 /* Check for SET CONSTRAINTS for this specific trigger. */
3293 for (i = 0; i < state->numstates; i++)
3295 if (state->trigstates[i].sct_tgoid == tgoid)
3296 return state->trigstates[i].sct_tgisdeferred;
3299 /* Check for SET CONSTRAINTS ALL. */
3300 if (state->all_isset)
3301 return state->all_isdeferred;
3305 * Otherwise return the default state for the trigger.
3307 return ((evtshared->ats_event & AFTER_TRIGGER_INITDEFERRED) != 0);
3312 * afterTriggerAddEvent()
3314 * Add a new trigger event to the specified queue.
3315 * The passed-in event data is copied.
3319 afterTriggerAddEvent(AfterTriggerEventList *events,
3320 AfterTriggerEvent event, AfterTriggerShared evtshared)
3322 Size eventsize = SizeofTriggerEvent(event);
3323 Size needed = eventsize + sizeof(AfterTriggerSharedData);
3324 AfterTriggerEventChunk *chunk;
3325 AfterTriggerShared newshared;
3326 AfterTriggerEvent newevent;
3329 * If empty list or not enough room in the tail chunk, make a new chunk.
3330 * We assume here that a new shared record will always be needed.
3332 chunk = events->tail;
3333 if (chunk == NULL ||
3334 chunk->endfree - chunk->freeptr < needed)
3338 /* Create event context if we didn't already */
3339 if (afterTriggers.event_cxt == NULL)
3340 afterTriggers.event_cxt =
3341 AllocSetContextCreate(TopTransactionContext,
3342 "AfterTriggerEvents",
3343 ALLOCSET_DEFAULT_MINSIZE,
3344 ALLOCSET_DEFAULT_INITSIZE,
3345 ALLOCSET_DEFAULT_MAXSIZE);
3348 * Chunk size starts at 1KB and is allowed to increase up to 1MB.
3349 * These numbers are fairly arbitrary, though there is a hard limit at
3350 * AFTER_TRIGGER_OFFSET; else we couldn't link event records to their
3351 * shared records using the available space in ate_flags. Another
3352 * constraint is that if the chunk size gets too huge, the search loop
3353 * below would get slow given a (not too common) usage pattern with
3354 * many distinct event types in a chunk. Therefore, we double the
3355 * preceding chunk size only if there weren't too many shared records
3356 * in the preceding chunk; otherwise we halve it. This gives us some
3357 * ability to adapt to the actual usage pattern of the current query
3358 * while still having large chunk sizes in typical usage. All chunk
3359 * sizes used should be MAXALIGN multiples, to ensure that the shared
3360 * records will be aligned safely.
3362 #define MIN_CHUNK_SIZE 1024
3363 #define MAX_CHUNK_SIZE (1024*1024)
3365 #if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
3366 #error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
3370 chunksize = MIN_CHUNK_SIZE;
3373 /* preceding chunk size... */
3374 chunksize = chunk->endptr - (char *) chunk;
3375 /* check number of shared records in preceding chunk */
3376 if ((chunk->endptr - chunk->endfree) <=
3377 (100 * sizeof(AfterTriggerSharedData)))
3378 chunksize *= 2; /* okay, double it */
3380 chunksize /= 2; /* too many shared records */
3381 chunksize = Min(chunksize, MAX_CHUNK_SIZE);
3383 chunk = MemoryContextAlloc(afterTriggers.event_cxt, chunksize);
3385 chunk->freeptr = CHUNK_DATA_START(chunk);
3386 chunk->endptr = chunk->endfree = (char *) chunk + chunksize;
3387 Assert(chunk->endfree - chunk->freeptr >= needed);
3389 if (events->head == NULL)
3390 events->head = chunk;
3392 events->tail->next = chunk;
3393 events->tail = chunk;
3394 /* events->tailfree is now out of sync, but we'll fix it below */
3398 * Try to locate a matching shared-data record already in the chunk. If
3399 * none, make a new one.
3401 for (newshared = ((AfterTriggerShared) chunk->endptr) - 1;
3402 (char *) newshared >= chunk->endfree;
3405 if (newshared->ats_tgoid == evtshared->ats_tgoid &&
3406 newshared->ats_relid == evtshared->ats_relid &&
3407 newshared->ats_event == evtshared->ats_event &&
3408 newshared->ats_firing_id == 0)
3411 if ((char *) newshared < chunk->endfree)
3413 *newshared = *evtshared;
3414 newshared->ats_firing_id = 0; /* just to be sure */
3415 chunk->endfree = (char *) newshared;
3418 /* Insert the data */
3419 newevent = (AfterTriggerEvent) chunk->freeptr;
3420 memcpy(newevent, event, eventsize);
3421 /* ... and link the new event to its shared record */
3422 newevent->ate_flags &= ~AFTER_TRIGGER_OFFSET;
3423 newevent->ate_flags |= (char *) newshared - (char *) newevent;
3425 chunk->freeptr += eventsize;
3426 events->tailfree = chunk->freeptr;
3430 * afterTriggerFreeEventList()
3432 * Free all the event storage in the given list.
3436 afterTriggerFreeEventList(AfterTriggerEventList *events)
3438 AfterTriggerEventChunk *chunk;
3439 AfterTriggerEventChunk *next_chunk;
3441 for (chunk = events->head; chunk != NULL; chunk = next_chunk)
3443 next_chunk = chunk->next;
3446 events->head = NULL;
3447 events->tail = NULL;
3448 events->tailfree = NULL;
3452 * afterTriggerRestoreEventList()
3454 * Restore an event list to its prior length, removing all the events
3455 * added since it had the value old_events.
3459 afterTriggerRestoreEventList(AfterTriggerEventList *events,
3460 const AfterTriggerEventList *old_events)
3462 AfterTriggerEventChunk *chunk;
3463 AfterTriggerEventChunk *next_chunk;
3465 if (old_events->tail == NULL)
3467 /* restoring to a completely empty state, so free everything */
3468 afterTriggerFreeEventList(events);
3472 *events = *old_events;
3473 /* free any chunks after the last one we want to keep */
3474 for (chunk = events->tail->next; chunk != NULL; chunk = next_chunk)
3476 next_chunk = chunk->next;
3479 /* and clean up the tail chunk to be the right length */
3480 events->tail->next = NULL;
3481 events->tail->freeptr = events->tailfree;
3484 * We don't make any effort to remove now-unused shared data records.
3485 * They might still be useful, anyway.
3492 * AfterTriggerExecute()
3494 * Fetch the required tuples back from the heap and fire one
3495 * single trigger function.
3497 * Frequently, this will be fired many times in a row for triggers of
3498 * a single relation. Therefore, we cache the open relation and provide
3499 * fmgr lookup cache space at the caller level. (For triggers fired at
3500 * the end of a query, we can even piggyback on the executor's state.)
3502 * event: event currently being fired.
3503 * rel: open relation for event.
3504 * trigdesc: working copy of rel's trigger info.
3505 * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
3506 * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
3507 * or NULL if no instrumentation is wanted.
3508 * per_tuple_context: memory context to call trigger function in.
3509 * trig_tuple_slot1: scratch slot for tg_trigtuple (foreign tables only)
3510 * trig_tuple_slot2: scratch slot for tg_newtuple (foreign tables only)
3514 AfterTriggerExecute(AfterTriggerEvent event,
3515 Relation rel, TriggerDesc *trigdesc,
3516 FmgrInfo *finfo, Instrumentation *instr,
3517 MemoryContext per_tuple_context,
3518 TupleTableSlot *trig_tuple_slot1,
3519 TupleTableSlot *trig_tuple_slot2)
3521 AfterTriggerShared evtshared = GetTriggerSharedData(event);
3522 Oid tgoid = evtshared->ats_tgoid;
3523 TriggerData LocTriggerData;
3524 HeapTupleData tuple1;
3525 HeapTupleData tuple2;
3527 Buffer buffer1 = InvalidBuffer;
3528 Buffer buffer2 = InvalidBuffer;
3532 * Locate trigger in trigdesc.
3534 LocTriggerData.tg_trigger = NULL;
3535 for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
3537 if (trigdesc->triggers[tgindx].tgoid == tgoid)
3539 LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
3543 if (LocTriggerData.tg_trigger == NULL)
3544 elog(ERROR, "could not find trigger %u", tgoid);
3547 * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
3548 * to include time spent re-fetching tuples in the trigger cost.
3551 InstrStartNode(instr + tgindx);
3554 * Fetch the required tuple(s).
3556 switch (event->ate_flags & AFTER_TRIGGER_TUP_BITS)
3558 case AFTER_TRIGGER_FDW_FETCH:
3560 Tuplestorestate *fdw_tuplestore = GetCurrentFDWTuplestore();
3562 if (!tuplestore_gettupleslot(fdw_tuplestore, true, false,
3564 elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
3566 if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
3567 TRIGGER_EVENT_UPDATE &&
3568 !tuplestore_gettupleslot(fdw_tuplestore, true, false,
3570 elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
3573 case AFTER_TRIGGER_FDW_REUSE:
3576 * Using ExecMaterializeSlot() rather than ExecFetchSlotTuple()
3577 * ensures that tg_trigtuple does not reference tuplestore memory.
3578 * (It is formally possible for the trigger function to queue
3579 * trigger events that add to the same tuplestore, which can push
3580 * other tuples out of memory.) The distinction is academic,
3581 * because we start with a minimal tuple that ExecFetchSlotTuple()
3582 * must materialize anyway.
3584 LocTriggerData.tg_trigtuple =
3585 ExecMaterializeSlot(trig_tuple_slot1);
3586 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
3588 LocTriggerData.tg_newtuple =
3589 ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
3590 TRIGGER_EVENT_UPDATE) ?
3591 ExecMaterializeSlot(trig_tuple_slot2) : NULL;
3592 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
3597 if (ItemPointerIsValid(&(event->ate_ctid1)))
3599 ItemPointerCopy(&(event->ate_ctid1), &(tuple1.t_self));
3600 if (!heap_fetch(rel, SnapshotAny, &tuple1, &buffer1, false, NULL))
3601 elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
3602 LocTriggerData.tg_trigtuple = &tuple1;
3603 LocTriggerData.tg_trigtuplebuf = buffer1;
3607 LocTriggerData.tg_trigtuple = NULL;
3608 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
3611 /* don't touch ctid2 if not there */
3612 if ((event->ate_flags & AFTER_TRIGGER_TUP_BITS) ==
3613 AFTER_TRIGGER_2CTID &&
3614 ItemPointerIsValid(&(event->ate_ctid2)))
3616 ItemPointerCopy(&(event->ate_ctid2), &(tuple2.t_self));
3617 if (!heap_fetch(rel, SnapshotAny, &tuple2, &buffer2, false, NULL))
3618 elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
3619 LocTriggerData.tg_newtuple = &tuple2;
3620 LocTriggerData.tg_newtuplebuf = buffer2;
3624 LocTriggerData.tg_newtuple = NULL;
3625 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
3630 * Setup the remaining trigger information
3632 LocTriggerData.type = T_TriggerData;
3633 LocTriggerData.tg_event =
3634 evtshared->ats_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
3635 LocTriggerData.tg_relation = rel;
3637 MemoryContextReset(per_tuple_context);
3640 * Call the trigger and throw away any possibly returned updated tuple.
3641 * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
3643 rettuple = ExecCallTriggerFunc(&LocTriggerData,
3648 if (rettuple != NULL &&
3649 rettuple != LocTriggerData.tg_trigtuple &&
3650 rettuple != LocTriggerData.tg_newtuple)
3651 heap_freetuple(rettuple);
3656 if (buffer1 != InvalidBuffer)
3657 ReleaseBuffer(buffer1);
3658 if (buffer2 != InvalidBuffer)
3659 ReleaseBuffer(buffer2);
3662 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
3663 * one "tuple returned" (really the number of firings).
3666 InstrStopNode(instr + tgindx, 1);
3671 * afterTriggerMarkEvents()
3673 * Scan the given event list for not yet invoked events. Mark the ones
3674 * that can be invoked now with the current firing ID.
3676 * If move_list isn't NULL, events that are not to be invoked now are
3677 * transferred to move_list.
3679 * When immediate_only is TRUE, do not invoke currently-deferred triggers.
3680 * (This will be FALSE only at main transaction exit.)
3682 * Returns TRUE if any invokable events were found.
3685 afterTriggerMarkEvents(AfterTriggerEventList *events,
3686 AfterTriggerEventList *move_list,
3687 bool immediate_only)
3690 AfterTriggerEvent event;
3691 AfterTriggerEventChunk *chunk;
3693 for_each_event_chunk(event, chunk, *events)
3695 AfterTriggerShared evtshared = GetTriggerSharedData(event);
3696 bool defer_it = false;
3698 if (!(event->ate_flags &
3699 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS)))
3702 * This trigger hasn't been called or scheduled yet. Check if we
3703 * should call it now.
3705 if (immediate_only && afterTriggerCheckState(evtshared))
3712 * Mark it as to be fired in this firing cycle.
3714 evtshared->ats_firing_id = afterTriggers.firing_counter;
3715 event->ate_flags |= AFTER_TRIGGER_IN_PROGRESS;
3721 * If it's deferred, move it to move_list, if requested.
3723 if (defer_it && move_list != NULL)
3725 /* add it to move_list */
3726 afterTriggerAddEvent(move_list, event, evtshared);
3727 /* mark original copy "done" so we don't do it again */
3728 event->ate_flags |= AFTER_TRIGGER_DONE;
3736 * afterTriggerInvokeEvents()
3738 * Scan the given event list for events that are marked as to be fired
3739 * in the current firing cycle, and fire them.
3741 * If estate isn't NULL, we use its result relation info to avoid repeated
3742 * openings and closing of trigger target relations. If it is NULL, we
3743 * make one locally to cache the info in case there are multiple trigger
3746 * When delete_ok is TRUE, it's safe to delete fully-processed events.
3747 * (We are not very tense about that: we simply reset a chunk to be empty
3748 * if all its events got fired. The objective here is just to avoid useless
3749 * rescanning of events when a trigger queues new events during transaction
3750 * end, so it's not necessary to worry much about the case where only
3751 * some events are fired.)
3753 * Returns TRUE if no unfired events remain in the list (this allows us
3754 * to avoid repeating afterTriggerMarkEvents).
3757 afterTriggerInvokeEvents(AfterTriggerEventList *events,
3758 CommandId firing_id,
3762 bool all_fired = true;
3763 AfterTriggerEventChunk *chunk;
3764 MemoryContext per_tuple_context;
3765 bool local_estate = false;
3766 Relation rel = NULL;
3767 TriggerDesc *trigdesc = NULL;
3768 FmgrInfo *finfo = NULL;
3769 Instrumentation *instr = NULL;
3770 TupleTableSlot *slot1 = NULL,
3773 /* Make a local EState if need be */
3776 estate = CreateExecutorState();
3777 local_estate = true;
3780 /* Make a per-tuple memory context for trigger function calls */
3782 AllocSetContextCreate(CurrentMemoryContext,
3783 "AfterTriggerTupleContext",
3784 ALLOCSET_DEFAULT_MINSIZE,
3785 ALLOCSET_DEFAULT_INITSIZE,
3786 ALLOCSET_DEFAULT_MAXSIZE);
3788 for_each_chunk(chunk, *events)
3790 AfterTriggerEvent event;
3791 bool all_fired_in_chunk = true;
3793 for_each_event(event, chunk)
3795 AfterTriggerShared evtshared = GetTriggerSharedData(event);
3798 * Is it one for me to fire?
3800 if ((event->ate_flags & AFTER_TRIGGER_IN_PROGRESS) &&
3801 evtshared->ats_firing_id == firing_id)
3804 * So let's fire it... but first, find the correct relation if
3805 * this is not the same relation as before.
3807 if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid)
3809 ResultRelInfo *rInfo;
3811 rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid);
3812 rel = rInfo->ri_RelationDesc;
3813 trigdesc = rInfo->ri_TrigDesc;
3814 finfo = rInfo->ri_TrigFunctions;
3815 instr = rInfo->ri_TrigInstrument;
3816 if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
3820 ExecDropSingleTupleTableSlot(slot1);
3821 ExecDropSingleTupleTableSlot(slot2);
3823 slot1 = MakeSingleTupleTableSlot(rel->rd_att);
3824 slot2 = MakeSingleTupleTableSlot(rel->rd_att);
3826 if (trigdesc == NULL) /* should not happen */
3827 elog(ERROR, "relation %u has no triggers",
3828 evtshared->ats_relid);
3832 * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is
3833 * still set, so recursive examinations of the event list
3834 * won't try to re-fire it.
3836 AfterTriggerExecute(event, rel, trigdesc, finfo, instr,
3837 per_tuple_context, slot1, slot2);
3840 * Mark the event as done.
3842 event->ate_flags &= ~AFTER_TRIGGER_IN_PROGRESS;
3843 event->ate_flags |= AFTER_TRIGGER_DONE;
3845 else if (!(event->ate_flags & AFTER_TRIGGER_DONE))
3847 /* something remains to be done */
3848 all_fired = all_fired_in_chunk = false;
3852 /* Clear the chunk if delete_ok and nothing left of interest */
3853 if (delete_ok && all_fired_in_chunk)
3855 chunk->freeptr = CHUNK_DATA_START(chunk);
3856 chunk->endfree = chunk->endptr;
3859 * If it's last chunk, must sync event list's tailfree too. Note
3860 * that delete_ok must NOT be passed as true if there could be
3861 * stacked AfterTriggerEventList values pointing at this event
3862 * list, since we'd fail to fix their copies of tailfree.
3864 if (chunk == events->tail)
3865 events->tailfree = chunk->freeptr;
3870 ExecDropSingleTupleTableSlot(slot1);
3871 ExecDropSingleTupleTableSlot(slot2);
3874 /* Release working resources */
3875 MemoryContextDelete(per_tuple_context);
3881 foreach(l, estate->es_trig_target_relations)
3883 ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
3885 /* Close indices and then the relation itself */
3886 ExecCloseIndices(resultRelInfo);
3887 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
3889 FreeExecutorState(estate);
3897 * AfterTriggerBeginXact()
3899 * Called at transaction start (either BEGIN or implicit for single
3900 * statement outside of transaction block).
3904 AfterTriggerBeginXact(void)
3907 * Initialize after-trigger state structure to empty
3909 afterTriggers.firing_counter = (CommandId) 1; /* mustn't be 0 */
3910 afterTriggers.query_depth = -1;
3913 * Verify that there is no leftover state remaining. If these assertions
3914 * trip, it means that AfterTriggerEndXact wasn't called or didn't clean
3917 Assert(afterTriggers.state == NULL);
3918 Assert(afterTriggers.query_stack == NULL);
3919 Assert(afterTriggers.fdw_tuplestores == NULL);
3920 Assert(afterTriggers.maxquerydepth == 0);
3921 Assert(afterTriggers.event_cxt == NULL);
3922 Assert(afterTriggers.events.head == NULL);
3923 Assert(afterTriggers.state_stack == NULL);
3924 Assert(afterTriggers.events_stack == NULL);
3925 Assert(afterTriggers.depth_stack == NULL);
3926 Assert(afterTriggers.firing_stack == NULL);
3927 Assert(afterTriggers.maxtransdepth == 0);
3932 * AfterTriggerBeginQuery()
3934 * Called just before we start processing a single query within a
3935 * transaction (or subtransaction). Most of the real work gets deferred
3936 * until somebody actually tries to queue a trigger event.
3940 AfterTriggerBeginQuery(void)
3942 /* Increase the query stack depth */
3943 afterTriggers.query_depth++;
3948 * AfterTriggerEndQuery()
3950 * Called after one query has been completely processed. At this time
3951 * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
3952 * transfer deferred trigger events to the global deferred-trigger list.
3954 * Note that this must be called BEFORE closing down the executor
3955 * with ExecutorEnd, because we make use of the EState's info about
3956 * target relations. Normally it is called from ExecutorFinish.
3960 AfterTriggerEndQuery(EState *estate)
3962 AfterTriggerEventList *events;
3963 Tuplestorestate *fdw_tuplestore;
3965 /* Must be inside a query, too */
3966 Assert(afterTriggers.query_depth >= 0);
3969 * If we never even got as far as initializing the event stack, there
3970 * certainly won't be any events, so exit quickly.
3972 if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
3974 afterTriggers.query_depth--;
3979 * Process all immediate-mode triggers queued by the query, and move the
3980 * deferred ones to the main list of deferred events.
3982 * Notice that we decide which ones will be fired, and put the deferred
3983 * ones on the main list, before anything is actually fired. This ensures
3984 * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
3985 * IMMEDIATE: all events we have decided to defer will be available for it
3988 * We loop in case a trigger queues more events at the same query level.
3989 * Ordinary trigger functions, including all PL/pgSQL trigger functions,
3990 * will instead fire any triggers in a dedicated query level. Foreign key
3991 * enforcement triggers do add to the current query level, thanks to their
3992 * passing fire_triggers = false to SPI_execute_snapshot(). Other
3993 * C-language triggers might do likewise. Be careful here: firing a
3994 * trigger could result in query_stack being repalloc'd, so we can't save
3995 * its address across afterTriggerInvokeEvents calls.
3997 * If we find no firable events, we don't have to increment
4002 events = &afterTriggers.query_stack[afterTriggers.query_depth];
4003 if (afterTriggerMarkEvents(events, &afterTriggers.events, true))
4005 CommandId firing_id = afterTriggers.firing_counter++;
4007 /* OK to delete the immediate events after processing them */
4008 if (afterTriggerInvokeEvents(events, firing_id, estate, true))
4009 break; /* all fired */
4015 /* Release query-local storage for events, including tuplestore if any */
4016 fdw_tuplestore = afterTriggers.fdw_tuplestores[afterTriggers.query_depth];
4019 tuplestore_end(fdw_tuplestore);
4020 afterTriggers.fdw_tuplestores[afterTriggers.query_depth] = NULL;
4022 afterTriggerFreeEventList(&afterTriggers.query_stack[afterTriggers.query_depth]);
4024 afterTriggers.query_depth--;
4029 * AfterTriggerFireDeferred()
4031 * Called just before the current transaction is committed. At this
4032 * time we invoke all pending DEFERRED triggers.
4034 * It is possible for other modules to queue additional deferred triggers
4035 * during pre-commit processing; therefore xact.c may have to call this
4040 AfterTriggerFireDeferred(void)
4042 AfterTriggerEventList *events;
4043 bool snap_pushed = false;
4045 /* Must not be inside a query */
4046 Assert(afterTriggers.query_depth == -1);
4049 * If there are any triggers to fire, make sure we have set a snapshot for
4050 * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we
4051 * can't assume ActiveSnapshot is valid on entry.)
4053 events = &afterTriggers.events;
4054 if (events->head != NULL)
4056 PushActiveSnapshot(GetTransactionSnapshot());
4061 * Run all the remaining triggers. Loop until they are all gone, in case
4062 * some trigger queues more for us to do.
4064 while (afterTriggerMarkEvents(events, NULL, false))
4066 CommandId firing_id = afterTriggers.firing_counter++;
4068 if (afterTriggerInvokeEvents(events, firing_id, NULL, true))
4069 break; /* all fired */
4073 * We don't bother freeing the event list, since it will go away anyway
4074 * (and more efficiently than via pfree) in AfterTriggerEndXact.
4078 PopActiveSnapshot();
4083 * AfterTriggerEndXact()
4085 * The current transaction is finishing.
4087 * Any unfired triggers are canceled so we simply throw
4088 * away anything we know.
4090 * Note: it is possible for this to be called repeatedly in case of
4091 * error during transaction abort; therefore, do not complain if
4092 * already closed down.
4096 AfterTriggerEndXact(bool isCommit)
4099 * Forget the pending-events list.
4101 * Since all the info is in TopTransactionContext or children thereof, we
4102 * don't really need to do anything to reclaim memory. However, the
4103 * pending-events list could be large, and so it's useful to discard it as
4104 * soon as possible --- especially if we are aborting because we ran out
4105 * of memory for the list!
4107 if (afterTriggers.event_cxt)
4109 MemoryContextDelete(afterTriggers.event_cxt);
4110 afterTriggers.event_cxt = NULL;
4111 afterTriggers.events.head = NULL;
4112 afterTriggers.events.tail = NULL;
4113 afterTriggers.events.tailfree = NULL;
4117 * Forget any subtransaction state as well. Since this can't be very
4118 * large, we let the eventual reset of TopTransactionContext free the
4119 * memory instead of doing it here.
4121 afterTriggers.state_stack = NULL;
4122 afterTriggers.events_stack = NULL;
4123 afterTriggers.depth_stack = NULL;
4124 afterTriggers.firing_stack = NULL;
4125 afterTriggers.maxtransdepth = 0;
4129 * Forget the query stack and constrant-related state information. As
4130 * with the subtransaction state information, we don't bother freeing the
4133 afterTriggers.query_stack = NULL;
4134 afterTriggers.fdw_tuplestores = NULL;
4135 afterTriggers.maxquerydepth = 0;
4136 afterTriggers.state = NULL;
4138 /* No more afterTriggers manipulation until next transaction starts. */
4139 afterTriggers.query_depth = -1;
4143 * AfterTriggerBeginSubXact()
4145 * Start a subtransaction.
4148 AfterTriggerBeginSubXact(void)
4150 int my_level = GetCurrentTransactionNestLevel();
4153 * Allocate more space in the stacks if needed. (Note: because the
4154 * minimum nest level of a subtransaction is 2, we waste the first couple
4155 * entries of each array; not worth the notational effort to avoid it.)
4157 while (my_level >= afterTriggers.maxtransdepth)
4159 if (afterTriggers.maxtransdepth == 0)
4161 MemoryContext old_cxt;
4163 old_cxt = MemoryContextSwitchTo(TopTransactionContext);
4165 #define DEFTRIG_INITALLOC 8
4166 afterTriggers.state_stack = (SetConstraintState *)
4167 palloc(DEFTRIG_INITALLOC * sizeof(SetConstraintState));
4168 afterTriggers.events_stack = (AfterTriggerEventList *)
4169 palloc(DEFTRIG_INITALLOC * sizeof(AfterTriggerEventList));
4170 afterTriggers.depth_stack = (int *)
4171 palloc(DEFTRIG_INITALLOC * sizeof(int));
4172 afterTriggers.firing_stack = (CommandId *)
4173 palloc(DEFTRIG_INITALLOC * sizeof(CommandId));
4174 afterTriggers.maxtransdepth = DEFTRIG_INITALLOC;
4176 MemoryContextSwitchTo(old_cxt);
4180 /* repalloc will keep the stacks in the same context */
4181 int new_alloc = afterTriggers.maxtransdepth * 2;
4183 afterTriggers.state_stack = (SetConstraintState *)
4184 repalloc(afterTriggers.state_stack,
4185 new_alloc * sizeof(SetConstraintState));
4186 afterTriggers.events_stack = (AfterTriggerEventList *)
4187 repalloc(afterTriggers.events_stack,
4188 new_alloc * sizeof(AfterTriggerEventList));
4189 afterTriggers.depth_stack = (int *)
4190 repalloc(afterTriggers.depth_stack,
4191 new_alloc * sizeof(int));
4192 afterTriggers.firing_stack = (CommandId *)
4193 repalloc(afterTriggers.firing_stack,
4194 new_alloc * sizeof(CommandId));
4195 afterTriggers.maxtransdepth = new_alloc;
4200 * Push the current information into the stack. The SET CONSTRAINTS state
4201 * is not saved until/unless changed. Likewise, we don't make a
4202 * per-subtransaction event context until needed.
4204 afterTriggers.state_stack[my_level] = NULL;
4205 afterTriggers.events_stack[my_level] = afterTriggers.events;
4206 afterTriggers.depth_stack[my_level] = afterTriggers.query_depth;
4207 afterTriggers.firing_stack[my_level] = afterTriggers.firing_counter;
4211 * AfterTriggerEndSubXact()
4213 * The current subtransaction is ending.
4216 AfterTriggerEndSubXact(bool isCommit)
4218 int my_level = GetCurrentTransactionNestLevel();
4219 SetConstraintState state;
4220 AfterTriggerEvent event;
4221 AfterTriggerEventChunk *chunk;
4222 CommandId subxact_firing_id;
4225 * Pop the prior state if needed.
4229 Assert(my_level < afterTriggers.maxtransdepth);
4230 /* If we saved a prior state, we don't need it anymore */
4231 state = afterTriggers.state_stack[my_level];
4234 /* this avoids double pfree if error later: */
4235 afterTriggers.state_stack[my_level] = NULL;
4236 Assert(afterTriggers.query_depth ==
4237 afterTriggers.depth_stack[my_level]);
4242 * Aborting. It is possible subxact start failed before calling
4243 * AfterTriggerBeginSubXact, in which case we mustn't risk touching
4244 * stack levels that aren't there.
4246 if (my_level >= afterTriggers.maxtransdepth)
4250 * Release any event lists from queries being aborted, and restore
4251 * query_depth to its pre-subxact value. This assumes that a
4252 * subtransaction will not add events to query levels started in a
4253 * earlier transaction state.
4255 while (afterTriggers.query_depth > afterTriggers.depth_stack[my_level])
4257 if (afterTriggers.query_depth < afterTriggers.maxquerydepth)
4259 Tuplestorestate *ts;
4261 ts = afterTriggers.fdw_tuplestores[afterTriggers.query_depth];
4265 afterTriggers.fdw_tuplestores[afterTriggers.query_depth] = NULL;
4268 afterTriggerFreeEventList(&afterTriggers.query_stack[afterTriggers.query_depth]);
4271 afterTriggers.query_depth--;
4273 Assert(afterTriggers.query_depth ==
4274 afterTriggers.depth_stack[my_level]);
4277 * Restore the global deferred-event list to its former length,
4278 * discarding any events queued by the subxact.
4280 afterTriggerRestoreEventList(&afterTriggers.events,
4281 &afterTriggers.events_stack[my_level]);
4284 * Restore the trigger state. If the saved state is NULL, then this
4285 * subxact didn't save it, so it doesn't need restoring.
4287 state = afterTriggers.state_stack[my_level];
4290 pfree(afterTriggers.state);
4291 afterTriggers.state = state;
4293 /* this avoids double pfree if error later: */
4294 afterTriggers.state_stack[my_level] = NULL;
4297 * Scan for any remaining deferred events that were marked DONE or IN
4298 * PROGRESS by this subxact or a child, and un-mark them. We can
4299 * recognize such events because they have a firing ID greater than or
4300 * equal to the firing_counter value we saved at subtransaction start.
4301 * (This essentially assumes that the current subxact includes all
4302 * subxacts started after it.)
4304 subxact_firing_id = afterTriggers.firing_stack[my_level];
4305 for_each_event_chunk(event, chunk, afterTriggers.events)
4307 AfterTriggerShared evtshared = GetTriggerSharedData(event);
4309 if (event->ate_flags &
4310 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))
4312 if (evtshared->ats_firing_id >= subxact_firing_id)
4314 ~(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS);
4321 * AfterTriggerEnlargeQueryState()
4323 * Prepare the necessary state so that we can record AFTER trigger events
4324 * queued by a query. It is allowed to have nested queries within a
4325 * (sub)transaction, so we need to have separate state for each query
4330 AfterTriggerEnlargeQueryState(void)
4332 int init_depth = afterTriggers.maxquerydepth;
4334 Assert(afterTriggers.query_depth >= afterTriggers.maxquerydepth);
4336 if (afterTriggers.maxquerydepth == 0)
4338 int new_alloc = Max(afterTriggers.query_depth + 1, 8);
4340 afterTriggers.query_stack = (AfterTriggerEventList *)
4341 MemoryContextAlloc(TopTransactionContext,
4342 new_alloc * sizeof(AfterTriggerEventList));
4343 afterTriggers.fdw_tuplestores = (Tuplestorestate **)
4344 MemoryContextAllocZero(TopTransactionContext,
4345 new_alloc * sizeof(Tuplestorestate *));
4346 afterTriggers.maxquerydepth = new_alloc;
4350 /* repalloc will keep the stack in the same context */
4351 int old_alloc = afterTriggers.maxquerydepth;
4352 int new_alloc = Max(afterTriggers.query_depth + 1,
4355 afterTriggers.query_stack = (AfterTriggerEventList *)
4356 repalloc(afterTriggers.query_stack,
4357 new_alloc * sizeof(AfterTriggerEventList));
4358 afterTriggers.fdw_tuplestores = (Tuplestorestate **)
4359 repalloc(afterTriggers.fdw_tuplestores,
4360 new_alloc * sizeof(Tuplestorestate *));
4361 /* Clear newly-allocated slots for subsequent lazy initialization. */
4362 memset(afterTriggers.fdw_tuplestores + old_alloc,
4363 0, (new_alloc - old_alloc) * sizeof(Tuplestorestate *));
4364 afterTriggers.maxquerydepth = new_alloc;
4367 /* Initialize new query lists to empty */
4368 while (init_depth < afterTriggers.maxquerydepth)
4370 AfterTriggerEventList *events;
4372 events = &afterTriggers.query_stack[init_depth];
4373 events->head = NULL;
4374 events->tail = NULL;
4375 events->tailfree = NULL;
4382 * Create an empty SetConstraintState with room for numalloc trigstates
4384 static SetConstraintState
4385 SetConstraintStateCreate(int numalloc)
4387 SetConstraintState state;
4389 /* Behave sanely with numalloc == 0 */
4394 * We assume that zeroing will correctly initialize the state values.
4396 state = (SetConstraintState)
4397 MemoryContextAllocZero(TopTransactionContext,
4398 offsetof(SetConstraintStateData, trigstates) +
4399 numalloc * sizeof(SetConstraintTriggerData));
4401 state->numalloc = numalloc;
4407 * Copy a SetConstraintState
4409 static SetConstraintState
4410 SetConstraintStateCopy(SetConstraintState origstate)
4412 SetConstraintState state;
4414 state = SetConstraintStateCreate(origstate->numstates);
4416 state->all_isset = origstate->all_isset;
4417 state->all_isdeferred = origstate->all_isdeferred;
4418 state->numstates = origstate->numstates;
4419 memcpy(state->trigstates, origstate->trigstates,
4420 origstate->numstates * sizeof(SetConstraintTriggerData));
4426 * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
4427 * pointer to the state object (it will change if we have to repalloc).
4429 static SetConstraintState
4430 SetConstraintStateAddItem(SetConstraintState state,
4431 Oid tgoid, bool tgisdeferred)
4433 if (state->numstates >= state->numalloc)
4435 int newalloc = state->numalloc * 2;
4437 newalloc = Max(newalloc, 8); /* in case original has size 0 */
4438 state = (SetConstraintState)
4440 offsetof(SetConstraintStateData, trigstates) +
4441 newalloc * sizeof(SetConstraintTriggerData));
4442 state->numalloc = newalloc;
4443 Assert(state->numstates < state->numalloc);
4446 state->trigstates[state->numstates].sct_tgoid = tgoid;
4447 state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
4454 * AfterTriggerSetState()
4456 * Execute the SET CONSTRAINTS ... utility command.
4460 AfterTriggerSetState(ConstraintsSetStmt *stmt)
4462 int my_level = GetCurrentTransactionNestLevel();
4464 /* If we haven't already done so, initialize our state. */
4465 if (afterTriggers.state == NULL)
4466 afterTriggers.state = SetConstraintStateCreate(8);
4469 * If in a subtransaction, and we didn't save the current state already,
4470 * save it so it can be restored if the subtransaction aborts.
4473 afterTriggers.state_stack[my_level] == NULL)
4475 afterTriggers.state_stack[my_level] =
4476 SetConstraintStateCopy(afterTriggers.state);
4480 * Handle SET CONSTRAINTS ALL ...
4482 if (stmt->constraints == NIL)
4485 * Forget any previous SET CONSTRAINTS commands in this transaction.
4487 afterTriggers.state->numstates = 0;
4490 * Set the per-transaction ALL state to known.
4492 afterTriggers.state->all_isset = true;
4493 afterTriggers.state->all_isdeferred = stmt->deferred;
4499 List *conoidlist = NIL;
4500 List *tgoidlist = NIL;
4504 * Handle SET CONSTRAINTS constraint-name [, ...]
4506 * First, identify all the named constraints and make a list of their
4507 * OIDs. Since, unlike the SQL spec, we allow multiple constraints of
4508 * the same name within a schema, the specifications are not
4509 * necessarily unique. Our strategy is to target all matching
4510 * constraints within the first search-path schema that has any
4511 * matches, but disregard matches in schemas beyond the first match.
4512 * (This is a bit odd but it's the historical behavior.)
4514 conrel = heap_open(ConstraintRelationId, AccessShareLock);
4516 foreach(lc, stmt->constraints)
4518 RangeVar *constraint = lfirst(lc);
4520 List *namespacelist;
4523 if (constraint->catalogname)
4525 if (strcmp(constraint->catalogname, get_database_name(MyDatabaseId)) != 0)
4527 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4528 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
4529 constraint->catalogname, constraint->schemaname,
4530 constraint->relname)));
4534 * If we're given the schema name with the constraint, look only
4535 * in that schema. If given a bare constraint name, use the
4536 * search path to find the first matching constraint.
4538 if (constraint->schemaname)
4540 Oid namespaceId = LookupExplicitNamespace(constraint->schemaname,
4543 namespacelist = list_make1_oid(namespaceId);
4547 namespacelist = fetch_search_path(true);
4551 foreach(nslc, namespacelist)
4553 Oid namespaceId = lfirst_oid(nslc);
4554 SysScanDesc conscan;
4555 ScanKeyData skey[2];
4558 ScanKeyInit(&skey[0],
4559 Anum_pg_constraint_conname,
4560 BTEqualStrategyNumber, F_NAMEEQ,
4561 CStringGetDatum(constraint->relname));
4562 ScanKeyInit(&skey[1],
4563 Anum_pg_constraint_connamespace,
4564 BTEqualStrategyNumber, F_OIDEQ,
4565 ObjectIdGetDatum(namespaceId));
4567 conscan = systable_beginscan(conrel, ConstraintNameNspIndexId,
4568 true, NULL, 2, skey);
4570 while (HeapTupleIsValid(tup = systable_getnext(conscan)))
4572 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
4574 if (con->condeferrable)
4575 conoidlist = lappend_oid(conoidlist,
4576 HeapTupleGetOid(tup));
4577 else if (stmt->deferred)
4579 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4580 errmsg("constraint \"%s\" is not deferrable",
4581 constraint->relname)));
4585 systable_endscan(conscan);
4588 * Once we've found a matching constraint we do not search
4589 * later parts of the search path.
4595 list_free(namespacelist);
4602 (errcode(ERRCODE_UNDEFINED_OBJECT),
4603 errmsg("constraint \"%s\" does not exist",
4604 constraint->relname)));
4607 heap_close(conrel, AccessShareLock);
4610 * Now, locate the trigger(s) implementing each of these constraints,
4611 * and make a list of their OIDs.
4613 tgrel = heap_open(TriggerRelationId, AccessShareLock);
4615 foreach(lc, conoidlist)
4617 Oid conoid = lfirst_oid(lc);
4626 Anum_pg_trigger_tgconstraint,
4627 BTEqualStrategyNumber, F_OIDEQ,
4628 ObjectIdGetDatum(conoid));
4630 tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
4633 while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
4635 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
4638 * Silently skip triggers that are marked as non-deferrable in
4639 * pg_trigger. This is not an error condition, since a
4640 * deferrable RI constraint may have some non-deferrable
4643 if (pg_trigger->tgdeferrable)
4644 tgoidlist = lappend_oid(tgoidlist,
4645 HeapTupleGetOid(htup));
4650 systable_endscan(tgscan);
4652 /* Safety check: a deferrable constraint should have triggers */
4654 elog(ERROR, "no triggers found for constraint with OID %u",
4658 heap_close(tgrel, AccessShareLock);
4661 * Now we can set the trigger states of individual triggers for this
4664 foreach(lc, tgoidlist)
4666 Oid tgoid = lfirst_oid(lc);
4667 SetConstraintState state = afterTriggers.state;
4671 for (i = 0; i < state->numstates; i++)
4673 if (state->trigstates[i].sct_tgoid == tgoid)
4675 state->trigstates[i].sct_tgisdeferred = stmt->deferred;
4682 afterTriggers.state =
4683 SetConstraintStateAddItem(state, tgoid, stmt->deferred);
4689 * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
4690 * checks against that constraint must be made when the SET CONSTRAINTS
4691 * command is executed -- i.e. the effects of the SET CONSTRAINTS command
4692 * apply retroactively. We've updated the constraints state, so scan the
4693 * list of previously deferred events to fire any that have now become
4696 * Obviously, if this was SET ... DEFERRED then it can't have converted
4697 * any unfired events to immediate, so we need do nothing in that case.
4699 if (!stmt->deferred)
4701 AfterTriggerEventList *events = &afterTriggers.events;
4702 bool snapshot_set = false;
4704 while (afterTriggerMarkEvents(events, NULL, true))
4706 CommandId firing_id = afterTriggers.firing_counter++;
4709 * Make sure a snapshot has been established in case trigger
4710 * functions need one. Note that we avoid setting a snapshot if
4711 * we don't find at least one trigger that has to be fired now.
4712 * This is so that BEGIN; SET CONSTRAINTS ...; SET TRANSACTION
4713 * ISOLATION LEVEL SERIALIZABLE; ... works properly. (If we are
4714 * at the start of a transaction it's not possible for any trigger
4715 * events to be queued yet.)
4719 PushActiveSnapshot(GetTransactionSnapshot());
4720 snapshot_set = true;
4724 * We can delete fired events if we are at top transaction level,
4725 * but we'd better not if inside a subtransaction, since the
4726 * subtransaction could later get rolled back.
4728 if (afterTriggerInvokeEvents(events, firing_id, NULL,
4729 !IsSubTransaction()))
4730 break; /* all fired */
4734 PopActiveSnapshot();
4739 * AfterTriggerPendingOnRel()
4740 * Test to see if there are any pending after-trigger events for rel.
4742 * This is used by TRUNCATE, CLUSTER, ALTER TABLE, etc to detect whether
4743 * it is unsafe to perform major surgery on a relation. Note that only
4744 * local pending events are examined. We assume that having exclusive lock
4745 * on a rel guarantees there are no unserviced events in other backends ---
4746 * but having a lock does not prevent there being such events in our own.
4748 * In some scenarios it'd be reasonable to remove pending events (more
4749 * specifically, mark them DONE by the current subxact) but without a lot
4750 * of knowledge of the trigger semantics we can't do this in general.
4754 AfterTriggerPendingOnRel(Oid relid)
4756 AfterTriggerEvent event;
4757 AfterTriggerEventChunk *chunk;
4760 /* Scan queued events */
4761 for_each_event_chunk(event, chunk, afterTriggers.events)
4763 AfterTriggerShared evtshared = GetTriggerSharedData(event);
4766 * We can ignore completed events. (Even if a DONE flag is rolled
4767 * back by subxact abort, it's OK because the effects of the TRUNCATE
4768 * or whatever must get rolled back too.)
4770 if (event->ate_flags & AFTER_TRIGGER_DONE)
4773 if (evtshared->ats_relid == relid)
4778 * Also scan events queued by incomplete queries. This could only matter
4779 * if TRUNCATE/etc is executed by a function or trigger within an updating
4780 * query on the same relation, which is pretty perverse, but let's check.
4782 for (depth = 0; depth <= afterTriggers.query_depth && depth < afterTriggers.maxquerydepth; depth++)
4784 for_each_event_chunk(event, chunk, afterTriggers.query_stack[depth])
4786 AfterTriggerShared evtshared = GetTriggerSharedData(event);
4788 if (event->ate_flags & AFTER_TRIGGER_DONE)
4791 if (evtshared->ats_relid == relid)
4801 * AfterTriggerSaveEvent()
4803 * Called by ExecA[RS]...Triggers() to queue up the triggers that should
4804 * be fired for an event.
4806 * NOTE: this is called whenever there are any triggers associated with
4807 * the event (even if they are disabled). This function decides which
4808 * triggers actually need to be queued.
4812 AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
4813 int event, bool row_trigger,
4814 HeapTuple oldtup, HeapTuple newtup,
4815 List *recheckIndexes, Bitmapset *modifiedCols)
4817 Relation rel = relinfo->ri_RelationDesc;
4818 TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
4819 AfterTriggerEventData new_event;
4820 AfterTriggerSharedData new_shared;
4821 char relkind = relinfo->ri_RelationDesc->rd_rel->relkind;
4825 Tuplestorestate *fdw_tuplestore = NULL;
4828 * Check state. We use a normal test not Assert because it is possible to
4829 * reach here in the wrong state given misconfigured RI triggers, in
4830 * particular deferring a cascade action trigger.
4832 if (afterTriggers.query_depth < 0)
4833 elog(ERROR, "AfterTriggerSaveEvent() called outside of query");
4835 /* Be sure we have enough space to record events at this query depth. */
4836 if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4837 AfterTriggerEnlargeQueryState();
4840 * Validate the event code and collect the associated tuple CTIDs.
4842 * The event code will be used both as a bitmask and an array offset, so
4843 * validation is important to make sure we don't walk off the edge of our
4848 case TRIGGER_EVENT_INSERT:
4849 tgtype_event = TRIGGER_TYPE_INSERT;
4852 Assert(oldtup == NULL);
4853 Assert(newtup != NULL);
4854 ItemPointerCopy(&(newtup->t_self), &(new_event.ate_ctid1));
4855 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4859 Assert(oldtup == NULL);
4860 Assert(newtup == NULL);
4861 ItemPointerSetInvalid(&(new_event.ate_ctid1));
4862 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4865 case TRIGGER_EVENT_DELETE:
4866 tgtype_event = TRIGGER_TYPE_DELETE;
4869 Assert(oldtup != NULL);
4870 Assert(newtup == NULL);
4871 ItemPointerCopy(&(oldtup->t_self), &(new_event.ate_ctid1));
4872 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4876 Assert(oldtup == NULL);
4877 Assert(newtup == NULL);
4878 ItemPointerSetInvalid(&(new_event.ate_ctid1));
4879 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4882 case TRIGGER_EVENT_UPDATE:
4883 tgtype_event = TRIGGER_TYPE_UPDATE;
4886 Assert(oldtup != NULL);
4887 Assert(newtup != NULL);
4888 ItemPointerCopy(&(oldtup->t_self), &(new_event.ate_ctid1));
4889 ItemPointerCopy(&(newtup->t_self), &(new_event.ate_ctid2));
4893 Assert(oldtup == NULL);
4894 Assert(newtup == NULL);
4895 ItemPointerSetInvalid(&(new_event.ate_ctid1));
4896 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4899 case TRIGGER_EVENT_TRUNCATE:
4900 tgtype_event = TRIGGER_TYPE_TRUNCATE;
4901 Assert(oldtup == NULL);
4902 Assert(newtup == NULL);
4903 ItemPointerSetInvalid(&(new_event.ate_ctid1));
4904 ItemPointerSetInvalid(&(new_event.ate_ctid2));
4907 elog(ERROR, "invalid after-trigger event code: %d", event);
4908 tgtype_event = 0; /* keep compiler quiet */
4912 if (!(relkind == RELKIND_FOREIGN_TABLE && row_trigger))
4913 new_event.ate_flags = (row_trigger && event == TRIGGER_EVENT_UPDATE) ?
4914 AFTER_TRIGGER_2CTID : AFTER_TRIGGER_1CTID;
4915 /* else, we'll initialize ate_flags for each trigger */
4917 tgtype_level = (row_trigger ? TRIGGER_TYPE_ROW : TRIGGER_TYPE_STATEMENT);
4919 for (i = 0; i < trigdesc->numtriggers; i++)
4921 Trigger *trigger = &trigdesc->triggers[i];
4923 if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
4928 if (!TriggerEnabled(estate, relinfo, trigger, event,
4929 modifiedCols, oldtup, newtup))
4932 if (relkind == RELKIND_FOREIGN_TABLE && row_trigger)
4934 if (fdw_tuplestore == NULL)
4936 fdw_tuplestore = GetCurrentFDWTuplestore();
4937 new_event.ate_flags = AFTER_TRIGGER_FDW_FETCH;
4940 /* subsequent event for the same tuple */
4941 new_event.ate_flags = AFTER_TRIGGER_FDW_REUSE;
4945 * If the trigger is a foreign key enforcement trigger, there are
4946 * certain cases where we can skip queueing the event because we can
4947 * tell by inspection that the FK constraint will still pass.
4949 if (TRIGGER_FIRED_BY_UPDATE(event))
4951 switch (RI_FKey_trigger_type(trigger->tgfoid))
4954 /* Update on trigger's PK table */
4955 if (!RI_FKey_pk_upd_check_required(trigger, rel,
4958 /* skip queuing this event */
4964 /* Update on trigger's FK table */
4965 if (!RI_FKey_fk_upd_check_required(trigger, rel,
4968 /* skip queuing this event */
4973 case RI_TRIGGER_NONE:
4974 /* Not an FK trigger */
4980 * If the trigger is a deferred unique constraint check trigger, only
4981 * queue it if the unique constraint was potentially violated, which
4982 * we know from index insertion time.
4984 if (trigger->tgfoid == F_UNIQUE_KEY_RECHECK)
4986 if (!list_member_oid(recheckIndexes, trigger->tgconstrindid))
4987 continue; /* Uniqueness definitely not violated */
4991 * Fill in event structure and add it to the current query's queue.
4993 new_shared.ats_event =
4994 (event & TRIGGER_EVENT_OPMASK) |
4995 (row_trigger ? TRIGGER_EVENT_ROW : 0) |
4996 (trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
4997 (trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
4998 new_shared.ats_tgoid = trigger->tgoid;
4999 new_shared.ats_relid = RelationGetRelid(rel);
5000 new_shared.ats_firing_id = 0;
5002 afterTriggerAddEvent(&afterTriggers.query_stack[afterTriggers.query_depth],
5003 &new_event, &new_shared);
5007 * Finally, spool any foreign tuple(s). The tuplestore squashes them to
5008 * minimal tuples, so this loses any system columns. The executor lost
5009 * those columns before us, for an unrelated reason, so this is fine.
5014 tuplestore_puttuple(fdw_tuplestore, oldtup);
5016 tuplestore_puttuple(fdw_tuplestore, newtup);
5021 pg_trigger_depth(PG_FUNCTION_ARGS)
5023 PG_RETURN_INT32(MyTriggerDepth);